ddp_pcb.c revision 18207
115885Sjulian/* 215885Sjulian * Copyright (c) 1990,1994 Regents of The University of Michigan. 315885Sjulian * All Rights Reserved. See COPYRIGHT. 415885Sjulian */ 515885Sjulian 615885Sjulian#include <sys/errno.h> 715885Sjulian#include <sys/types.h> 815885Sjulian#include <sys/param.h> 915885Sjulian#include <sys/systm.h> 1015885Sjulian#include <sys/proc.h> 1115885Sjulian#include <sys/mbuf.h> 1215885Sjulian#include <sys/ioctl.h> 1315885Sjulian#include <sys/socket.h> 1415885Sjulian#include <sys/socketvar.h> 1515885Sjulian#include <sys/protosw.h> 1615885Sjulian#include <net/if.h> 1715885Sjulian#include <net/route.h> 1815885Sjulian#include <netinet/in.h> 1915885Sjulian#include <netinet/if_ether.h> 2015885Sjulian 2118207Sbde#include <netatalk/at.h> 2218207Sbde#include <netatalk/at_var.h> 2318207Sbde#include <netatalk/ddp_var.h> 2418207Sbde#include <netatalk/aarp.h> 2518207Sbde#include <netatalk/endian.h> 2615885Sjulian#include <netatalk/at_extern.h> 2715885Sjulian 2815885Sjulianstatic void at_pcbdisconnect( struct ddpcb *ddp ); 2915885Sjulianstatic void at_sockaddr( struct ddpcb *ddp, struct mbuf *addr ); 3015885Sjulianstatic int at_pcbsetaddr( struct ddpcb *ddp, struct mbuf *addr, struct proc *p); 3115885Sjulianstatic int at_pcbconnect( struct ddpcb *ddp, struct mbuf *addr, struct proc *p); 3215885Sjulianstatic void at_pcbdetach( struct socket *so, struct ddpcb *ddp); 3315885Sjulianstatic int at_pcballoc( struct socket *so ); 3415885Sjulian 3515885Sjulianstruct ddpcb *ddp_ports[ ATPORT_LAST ]; 3615885Sjulianstruct ddpcb *ddpcb = NULL; 3715885Sjulianu_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */ 3815885Sjulianu_long ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at )); 3915885Sjulian 4015885Sjulian/*ARGSUSED*/ 4115885Sjulianint 4215885Sjulianddp_usrreq( struct socket *so, int req, struct mbuf *m, 4315885Sjulian struct mbuf *addr, struct mbuf *rights) 4415885Sjulian{ 4515885Sjulian struct proc *p = curproc; /* XXX */ 4615885Sjulian struct ddpcb *ddp; 4715885Sjulian int error = 0; 4815885Sjulian 4915885Sjulian ddp = sotoddpcb( so ); 5015885Sjulian 5115885Sjulian if ( req == PRU_CONTROL ) { 5215885Sjulian return( at_control( (int) m, (caddr_t) addr, 5317254Sjulian (struct ifnet *) rights, (struct proc *)p )); 5415885Sjulian } 5515885Sjulian 5615885Sjulian if ( rights && rights->m_len ) { 5715885Sjulian error = EINVAL; 5815885Sjulian goto release; 5915885Sjulian } 6015885Sjulian 6115885Sjulian if ( ddp == NULL && req != PRU_ATTACH ) { 6215885Sjulian error = EINVAL; 6315885Sjulian goto release; 6415885Sjulian } 6515885Sjulian 6615885Sjulian switch ( req ) { 6715885Sjulian case PRU_ATTACH : 6815885Sjulian if ( ddp != NULL ) { 6915885Sjulian error = EINVAL; 7015885Sjulian break; 7115885Sjulian } 7215885Sjulian if (( error = at_pcballoc( so )) != 0 ) { 7315885Sjulian break; 7415885Sjulian } 7515885Sjulian error = soreserve( so, ddp_sendspace, ddp_recvspace ); 7615885Sjulian break; 7715885Sjulian 7815885Sjulian case PRU_DETACH : 7915885Sjulian at_pcbdetach( so, ddp ); 8015885Sjulian break; 8115885Sjulian 8215885Sjulian case PRU_BIND : 8317254Sjulian error = at_pcbsetaddr( ddp, addr, p ); 8415885Sjulian break; 8515885Sjulian 8615885Sjulian case PRU_SOCKADDR : 8715885Sjulian at_sockaddr( ddp, addr ); 8815885Sjulian break; 8915885Sjulian 9015885Sjulian case PRU_CONNECT: 9115885Sjulian if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) { 9215885Sjulian error = EISCONN; 9315885Sjulian break; 9415885Sjulian } 9515885Sjulian 9617254Sjulian error = at_pcbconnect( ddp, addr, p ); 9715885Sjulian if ( error == 0 ) 9815885Sjulian soisconnected( so ); 9915885Sjulian break; 10015885Sjulian 10115885Sjulian case PRU_DISCONNECT: 10215885Sjulian if ( ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE ) { 10315885Sjulian error = ENOTCONN; 10415885Sjulian break; 10515885Sjulian } 10615885Sjulian at_pcbdisconnect( ddp ); 10715885Sjulian soisdisconnected( so ); 10815885Sjulian break; 10915885Sjulian 11015885Sjulian case PRU_SHUTDOWN: 11115885Sjulian socantsendmore( so ); 11215885Sjulian break; 11315885Sjulian 11415885Sjulian case PRU_SEND: { 11515885Sjulian int s = 0; 11615885Sjulian 11715885Sjulian if ( addr ) { 11815885Sjulian if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) { 11915885Sjulian error = EISCONN; 12015885Sjulian break; 12115885Sjulian } 12215885Sjulian 12315885Sjulian s = splnet(); 12417254Sjulian error = at_pcbconnect( ddp, addr, p ); 12515885Sjulian if ( error ) { 12615885Sjulian splx( s ); 12715885Sjulian break; 12815885Sjulian } 12915885Sjulian } else { 13015885Sjulian if ( ddp->ddp_fsat.sat_port == ATADDR_ANYPORT ) { 13115885Sjulian error = ENOTCONN; 13215885Sjulian break; 13315885Sjulian } 13415885Sjulian } 13515885Sjulian 13615885Sjulian error = ddp_output( ddp, m ); 13715885Sjulian m = NULL; 13815885Sjulian if ( addr ) { 13915885Sjulian at_pcbdisconnect( ddp ); 14015885Sjulian splx( s ); 14115885Sjulian } 14215885Sjulian } 14315885Sjulian break; 14415885Sjulian 14515885Sjulian case PRU_ABORT: 14615885Sjulian soisdisconnected( so ); 14715885Sjulian at_pcbdetach( so, ddp ); 14815885Sjulian break; 14915885Sjulian 15015885Sjulian case PRU_LISTEN: 15115885Sjulian case PRU_CONNECT2: 15215885Sjulian case PRU_ACCEPT: 15315885Sjulian case PRU_SENDOOB: 15415885Sjulian case PRU_FASTTIMO: 15515885Sjulian case PRU_SLOWTIMO: 15615885Sjulian case PRU_PROTORCV: 15715885Sjulian case PRU_PROTOSEND: 15815885Sjulian error = EOPNOTSUPP; 15915885Sjulian break; 16015885Sjulian 16115885Sjulian case PRU_RCVD: 16215885Sjulian case PRU_RCVOOB: 16315885Sjulian /* 16415885Sjulian * Don't mfree. Good architecture... 16515885Sjulian */ 16615885Sjulian return( EOPNOTSUPP ); 16715885Sjulian 16815885Sjulian case PRU_SENSE: 16915885Sjulian /* 17015885Sjulian * 1. Don't return block size. 17115885Sjulian * 2. Don't mfree. 17215885Sjulian */ 17315885Sjulian return( 0 ); 17415885Sjulian 17515885Sjulian default: 17615885Sjulian error = EOPNOTSUPP; 17715885Sjulian } 17815885Sjulian 17915885Sjulianrelease: 18015885Sjulian if ( m != NULL ) { 18115885Sjulian m_freem( m ); 18215885Sjulian } 18315885Sjulian return( error ); 18415885Sjulian} 18515885Sjulian 18615885Sjulianstatic void 18715885Sjulianat_sockaddr( struct ddpcb *ddp, struct mbuf *addr) 18815885Sjulian{ 18915885Sjulian struct sockaddr_at *sat; 19015885Sjulian 19115885Sjulian addr->m_len = sizeof( struct sockaddr_at ); 19215885Sjulian sat = mtod( addr, struct sockaddr_at *); 19315885Sjulian *sat = ddp->ddp_lsat; 19415885Sjulian} 19515885Sjulian 19615885Sjulianstatic int 19715885Sjulianat_pcbsetaddr( struct ddpcb *ddp, struct mbuf *addr, struct proc *p ) 19815885Sjulian{ 19915885Sjulian struct sockaddr_at lsat, *sat; 20015885Sjulian struct at_ifaddr *aa; 20115885Sjulian struct ddpcb *ddpp; 20215885Sjulian 20315885Sjulian if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT ) { /* shouldn't be bound */ 20415885Sjulian return( EINVAL ); 20515885Sjulian } 20615885Sjulian 20715885Sjulian if ( addr != 0 ) { /* validate passed address */ 20815885Sjulian sat = mtod( addr, struct sockaddr_at *); 20915885Sjulian if ( addr->m_len != sizeof( *sat )) { 21015885Sjulian return( EINVAL ); 21115885Sjulian } 21215885Sjulian if ( sat->sat_family != AF_APPLETALK ) { 21315885Sjulian return( EAFNOSUPPORT ); 21415885Sjulian } 21515885Sjulian 21615885Sjulian if ( sat->sat_addr.s_node != ATADDR_ANYNODE || 21715885Sjulian sat->sat_addr.s_net != ATADDR_ANYNET ) { 21815885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 21915885Sjulian if (( sat->sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) && 22015885Sjulian ( sat->sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node )) { 22115885Sjulian break; 22215885Sjulian } 22315885Sjulian } 22415885Sjulian if ( !aa ) { 22515885Sjulian return( EADDRNOTAVAIL ); 22615885Sjulian } 22715885Sjulian } 22815885Sjulian 22915885Sjulian if ( sat->sat_port != ATADDR_ANYPORT ) { 23015885Sjulian if ( sat->sat_port < ATPORT_FIRST || 23115885Sjulian sat->sat_port >= ATPORT_LAST ) { 23215885Sjulian return( EINVAL ); 23315885Sjulian } 23415885Sjulian if ( sat->sat_port < ATPORT_RESERVED && 23517254Sjulian suser( p->p_ucred, &p->p_acflag ) ) { 23615885Sjulian return( EACCES ); 23715885Sjulian } 23815885Sjulian } 23915885Sjulian } else { 24015885Sjulian bzero( (caddr_t)&lsat, sizeof( struct sockaddr_at )); 24115885Sjulian lsat.sat_len = sizeof(struct sockaddr_at); 24215885Sjulian lsat.sat_addr.s_node = ATADDR_ANYNODE; 24315885Sjulian lsat.sat_addr.s_net = ATADDR_ANYNET; 24415885Sjulian lsat.sat_family = AF_APPLETALK; 24515885Sjulian sat = &lsat; 24615885Sjulian } 24715885Sjulian 24815885Sjulian if ( sat->sat_addr.s_node == ATADDR_ANYNODE && 24915885Sjulian sat->sat_addr.s_net == ATADDR_ANYNET ) { 25015885Sjulian if ( at_ifaddr == NULL ) { 25115885Sjulian return( EADDRNOTAVAIL ); 25215885Sjulian } 25315885Sjulian sat->sat_addr = AA_SAT( at_ifaddr )->sat_addr; 25415885Sjulian } 25515885Sjulian ddp->ddp_lsat = *sat; 25615885Sjulian 25715885Sjulian /* 25815885Sjulian * Choose port. 25915885Sjulian */ 26015885Sjulian if ( sat->sat_port == ATADDR_ANYPORT ) { 26115885Sjulian for ( sat->sat_port = ATPORT_RESERVED; 26215885Sjulian sat->sat_port < ATPORT_LAST; sat->sat_port++ ) { 26315885Sjulian if ( ddp_ports[ sat->sat_port - 1 ] == 0 ) { 26415885Sjulian break; 26515885Sjulian } 26615885Sjulian } 26715885Sjulian if ( sat->sat_port == ATPORT_LAST ) { 26815885Sjulian return( EADDRNOTAVAIL ); 26915885Sjulian } 27015885Sjulian ddp->ddp_lsat.sat_port = sat->sat_port; 27115885Sjulian ddp_ports[ sat->sat_port - 1 ] = ddp; 27215885Sjulian } else { 27315885Sjulian for ( ddpp = ddp_ports[ sat->sat_port - 1 ]; ddpp; 27415885Sjulian ddpp = ddpp->ddp_pnext ) { 27515885Sjulian if ( ddpp->ddp_lsat.sat_addr.s_net == sat->sat_addr.s_net && 27615885Sjulian ddpp->ddp_lsat.sat_addr.s_node == sat->sat_addr.s_node ) { 27715885Sjulian break; 27815885Sjulian } 27915885Sjulian } 28015885Sjulian if ( ddpp != NULL ) { 28115885Sjulian return( EADDRINUSE ); 28215885Sjulian } 28315885Sjulian ddp->ddp_pnext = ddp_ports[ sat->sat_port - 1 ]; 28415885Sjulian ddp_ports[ sat->sat_port - 1 ] = ddp; 28515885Sjulian if ( ddp->ddp_pnext ) { 28615885Sjulian ddp->ddp_pnext->ddp_pprev = ddp; 28715885Sjulian } 28815885Sjulian } 28915885Sjulian 29015885Sjulian return( 0 ); 29115885Sjulian} 29215885Sjulian 29315885Sjulianstatic int 29415885Sjulianat_pcbconnect( struct ddpcb *ddp, struct mbuf *addr, struct proc *p) 29515885Sjulian{ 29615885Sjulian struct sockaddr_at *sat = mtod( addr, struct sockaddr_at *); 29715885Sjulian struct route *ro; 29815885Sjulian struct at_ifaddr *aa = 0; 29915885Sjulian struct ifnet *ifp; 30015885Sjulian u_short hintnet = 0, net; 30115885Sjulian 30215885Sjulian if ( addr->m_len != sizeof( *sat )) 30315885Sjulian return( EINVAL ); 30415885Sjulian if ( sat->sat_family != AF_APPLETALK ) { 30515885Sjulian return( EAFNOSUPPORT ); 30615885Sjulian } 30715885Sjulian 30815885Sjulian /* 30915885Sjulian * Under phase 2, network 0 means "the network". We take "the 31015885Sjulian * network" to mean the network the control block is bound to. 31115885Sjulian * If the control block is not bound, there is an error. 31215885Sjulian */ 31315885Sjulian if ( sat->sat_addr.s_net == ATADDR_ANYNET 31415885Sjulian && sat->sat_addr.s_node != ATADDR_ANYNODE ) { 31515885Sjulian if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) { 31615885Sjulian return( EADDRNOTAVAIL ); 31715885Sjulian } 31815885Sjulian hintnet = ddp->ddp_lsat.sat_addr.s_net; 31915885Sjulian } 32015885Sjulian 32115885Sjulian ro = &ddp->ddp_route; 32215885Sjulian /* 32315885Sjulian * If we've got an old route for this pcb, check that it is valid. 32415885Sjulian * If we've changed our address, we may have an old "good looking" 32515885Sjulian * route here. Attempt to detect it. 32615885Sjulian */ 32715885Sjulian if ( ro->ro_rt ) { 32815885Sjulian if ( hintnet ) { 32915885Sjulian net = hintnet; 33015885Sjulian } else { 33115885Sjulian net = sat->sat_addr.s_net; 33215885Sjulian } 33315885Sjulian aa = 0; 33415885Sjulian if ( ifp = ro->ro_rt->rt_ifp ) { 33515885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 33615885Sjulian if ( aa->aa_ifp == ifp && 33715885Sjulian ntohs( net ) >= ntohs( aa->aa_firstnet ) && 33815885Sjulian ntohs( net ) <= ntohs( aa->aa_lastnet )) { 33915885Sjulian break; 34015885Sjulian } 34115885Sjulian } 34215885Sjulian } 34315885Sjulian if ( aa == NULL || ( satosat( &ro->ro_dst )->sat_addr.s_net != 34415885Sjulian ( hintnet ? hintnet : sat->sat_addr.s_net ) || 34515885Sjulian satosat( &ro->ro_dst )->sat_addr.s_node != 34615885Sjulian sat->sat_addr.s_node )) { 34715885Sjulian RTFREE( ro->ro_rt ); 34815885Sjulian ro->ro_rt = (struct rtentry *)0; 34915885Sjulian } 35015885Sjulian } 35115885Sjulian 35215885Sjulian /* 35315885Sjulian * If we've got no route for this interface, try to find one. 35415885Sjulian */ 35515885Sjulian if ( ro->ro_rt == (struct rtentry *)0 || 35615885Sjulian ro->ro_rt->rt_ifp == (struct ifnet *)0 ) { 35715885Sjulian ro->ro_dst.sa_len = sizeof( struct sockaddr_at ); 35815885Sjulian ro->ro_dst.sa_family = AF_APPLETALK; 35915885Sjulian if ( hintnet ) { 36015885Sjulian satosat( &ro->ro_dst )->sat_addr.s_net = hintnet; 36115885Sjulian } else { 36215885Sjulian satosat( &ro->ro_dst )->sat_addr.s_net = sat->sat_addr.s_net; 36315885Sjulian } 36415885Sjulian satosat( &ro->ro_dst )->sat_addr.s_node = sat->sat_addr.s_node; 36515885Sjulian rtalloc( ro ); 36615885Sjulian } 36715885Sjulian 36815885Sjulian /* 36915885Sjulian * Make sure any route that we have has a valid interface. 37015885Sjulian */ 37115885Sjulian aa = 0; 37215885Sjulian if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) { 37315885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 37415885Sjulian if ( aa->aa_ifp == ifp ) { 37515885Sjulian break; 37615885Sjulian } 37715885Sjulian } 37815885Sjulian } 37915885Sjulian if ( aa == 0 ) { 38015885Sjulian return( ENETUNREACH ); 38115885Sjulian } 38215885Sjulian 38315885Sjulian ddp->ddp_fsat = *sat; 38415885Sjulian if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) { 38517254Sjulian return( at_pcbsetaddr( ddp, (struct mbuf *)0, p )); 38615885Sjulian } 38715885Sjulian return( 0 ); 38815885Sjulian} 38915885Sjulian 39015885Sjulianstatic void 39115885Sjulianat_pcbdisconnect( struct ddpcb *ddp ) 39215885Sjulian{ 39315885Sjulian ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET; 39415885Sjulian ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE; 39515885Sjulian ddp->ddp_fsat.sat_port = ATADDR_ANYPORT; 39615885Sjulian} 39715885Sjulian 39815885Sjulianstatic int 39915885Sjulianat_pcballoc( struct socket *so ) 40015885Sjulian{ 40115885Sjulian struct ddpcb *ddp; 40215885Sjulian struct mbuf *m; 40315885Sjulian 40415885Sjulian m = m_getclr( M_WAIT, MT_PCB ); 40515885Sjulian ddp = mtod( m, struct ddpcb * ); 40615885Sjulian ddp->ddp_lsat.sat_port = ATADDR_ANYPORT; 40715885Sjulian 40815885Sjulian ddp->ddp_next = ddpcb; 40915885Sjulian ddp->ddp_prev = NULL; 41015885Sjulian ddp->ddp_pprev = NULL; 41115885Sjulian ddp->ddp_pnext = NULL; 41215885Sjulian if ( ddpcb ) { 41315885Sjulian ddpcb->ddp_prev = ddp; 41415885Sjulian } 41515885Sjulian ddpcb = ddp; 41615885Sjulian 41715885Sjulian ddp->ddp_socket = so; 41815885Sjulian so->so_pcb = (caddr_t)ddp; 41915885Sjulian return( 0 ); 42015885Sjulian} 42115885Sjulian 42215885Sjulianstatic void 42315885Sjulianat_pcbdetach( struct socket *so, struct ddpcb *ddp) 42415885Sjulian{ 42515885Sjulian soisdisconnected( so ); 42615885Sjulian so->so_pcb = 0; 42715885Sjulian sofree( so ); 42815885Sjulian 42915885Sjulian /* remove ddp from ddp_ports list */ 43015885Sjulian if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT && 43115885Sjulian ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] != NULL ) { 43215885Sjulian if ( ddp->ddp_pprev != NULL ) { 43315885Sjulian ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext; 43415885Sjulian } else { 43515885Sjulian ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] = ddp->ddp_pnext; 43615885Sjulian } 43715885Sjulian if ( ddp->ddp_pnext != NULL ) { 43815885Sjulian ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev; 43915885Sjulian } 44015885Sjulian } 44115885Sjulian 44215885Sjulian if ( ddp->ddp_route.ro_rt ) { 44315885Sjulian rtfree( ddp->ddp_route.ro_rt ); 44415885Sjulian } 44515885Sjulian 44615885Sjulian if ( ddp->ddp_prev ) { 44715885Sjulian ddp->ddp_prev->ddp_next = ddp->ddp_next; 44815885Sjulian } else { 44915885Sjulian ddpcb = ddp->ddp_next; 45015885Sjulian } 45115885Sjulian if ( ddp->ddp_next ) { 45215885Sjulian ddp->ddp_next->ddp_prev = ddp->ddp_prev; 45315885Sjulian } 45415885Sjulian 45515885Sjulian (void) m_free( dtom( ddp )); 45615885Sjulian} 45715885Sjulian 45815885Sjulian/* 45915885Sjulian * For the moment, this just find the pcb with the correct local address. 46015885Sjulian * In the future, this will actually do some real searching, so we can use 46115885Sjulian * the sender's address to do de-multiplexing on a single port to many 46215885Sjulian * sockets (pcbs). 46315885Sjulian */ 46415885Sjulianstruct ddpcb * 46515885Sjulianddp_search( struct sockaddr_at *from, struct sockaddr_at *to, 46615885Sjulian struct at_ifaddr *aa) 46715885Sjulian{ 46815885Sjulian struct ddpcb *ddp; 46915885Sjulian 47015885Sjulian /* 47115885Sjulian * Check for bad ports. 47215885Sjulian */ 47315885Sjulian if ( to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST ) { 47415885Sjulian return( NULL ); 47515885Sjulian } 47615885Sjulian 47715885Sjulian /* 47815885Sjulian * Make sure the local address matches the sent address. What about 47915885Sjulian * the interface? 48015885Sjulian */ 48115885Sjulian for ( ddp = ddp_ports[ to->sat_port - 1 ]; ddp; ddp = ddp->ddp_pnext ) { 48215885Sjulian /* XXX should we handle 0.YY? */ 48315885Sjulian 48415885Sjulian /* XXXX.YY to socket on destination interface */ 48515885Sjulian if ( to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net && 48615885Sjulian to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node ) { 48715885Sjulian break; 48815885Sjulian } 48915885Sjulian 49015885Sjulian /* 0.255 to socket on receiving interface */ 49115885Sjulian if ( to->sat_addr.s_node == ATADDR_BCAST && ( to->sat_addr.s_net == 0 || 49215885Sjulian to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net ) && 49315885Sjulian ddp->ddp_lsat.sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) { 49415885Sjulian break; 49515885Sjulian } 49615885Sjulian 49715885Sjulian /* XXXX.0 to socket on destination interface */ 49815885Sjulian if ( to->sat_addr.s_net == aa->aa_firstnet && 49915885Sjulian to->sat_addr.s_node == 0 && 50015885Sjulian ntohs( ddp->ddp_lsat.sat_addr.s_net ) >= 50115885Sjulian ntohs( aa->aa_firstnet ) && 50215885Sjulian ntohs( ddp->ddp_lsat.sat_addr.s_net ) <= 50315885Sjulian ntohs( aa->aa_lastnet )) { 50415885Sjulian break; 50515885Sjulian } 50615885Sjulian } 50715885Sjulian return( ddp ); 50815885Sjulian} 50915885Sjulian 51015885Sjulianvoid 51115885Sjulianddp_init(void ) 51215885Sjulian{ 51315885Sjulian atintrq1.ifq_maxlen = IFQ_MAXLEN; 51415885Sjulian atintrq2.ifq_maxlen = IFQ_MAXLEN; 51515885Sjulian} 51615885Sjulian 51717254Sjulian#if 0 51815885Sjulianstatic void 51915885Sjulianddp_clean(void ) 52015885Sjulian{ 52115885Sjulian struct ddpcb *ddp; 52215885Sjulian 52315885Sjulian for ( ddp = ddpcb; ddp; ddp = ddp->ddp_next ) { 52415885Sjulian at_pcbdetach( ddp->ddp_socket, ddp ); 52515885Sjulian } 52615885Sjulian} 52717254Sjulian#endif 528