ddp_pcb.c revision 111888
115885Sjulian/* 215885Sjulian * Copyright (c) 1990,1994 Regents of The University of Michigan. 315885Sjulian * All Rights Reserved. See COPYRIGHT. 467893Sphk * 567893Sphk * $FreeBSD: head/sys/netatalk/ddp_pcb.c 111888 2003-03-04 23:19:55Z jlemon $ 615885Sjulian */ 715885Sjulian 815885Sjulian#include <sys/param.h> 915885Sjulian#include <sys/systm.h> 1029024Sbde#include <sys/malloc.h> 1115885Sjulian#include <sys/mbuf.h> 1215885Sjulian#include <sys/socket.h> 1315885Sjulian#include <sys/socketvar.h> 1415885Sjulian#include <sys/protosw.h> 1515885Sjulian#include <net/if.h> 1615885Sjulian#include <net/route.h> 17111888Sjlemon#include <net/netisr.h> 1815885Sjulian 1918207Sbde#include <netatalk/at.h> 2018207Sbde#include <netatalk/at_var.h> 2118207Sbde#include <netatalk/ddp_var.h> 2215885Sjulian#include <netatalk/at_extern.h> 2315885Sjulian 2415885Sjulianstatic void at_pcbdisconnect( struct ddpcb *ddp ); 2528270Swollmanstatic void at_sockaddr(struct ddpcb *ddp, struct sockaddr **addr); 2628270Swollmanstatic int at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr, 2783366Sjulian struct thread *td); 2828270Swollmanstatic int at_pcbconnect(struct ddpcb *ddp, struct sockaddr *addr, 2983366Sjulian struct thread *td); 3028270Swollmanstatic void at_pcbdetach(struct socket *so, struct ddpcb *ddp); 3128270Swollmanstatic int at_pcballoc(struct socket *so); 3215885Sjulian 3315885Sjulianstruct ddpcb *ddp_ports[ ATPORT_LAST ]; 3415885Sjulianstruct ddpcb *ddpcb = NULL; 3533181Seivindstatic u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */ 3633181Seivindstatic u_long ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at )); 3715885Sjulian 38111888Sjlemonstatic struct ifqueue atintrq1, atintrq2, aarpintrq; 3925791Sjulian 4025791Sjulianstatic int 4183366Sjulianddp_attach(struct socket *so, int proto, struct thread *td) 4215885Sjulian{ 4325791Sjulian struct ddpcb *ddp; 4425791Sjulian int error = 0; 4525791Sjulian int s; 4625791Sjulian 4715885Sjulian 4825791Sjulian ddp = sotoddpcb( so ); 4915885Sjulian if ( ddp != NULL ) { 5025791Sjulian return( EINVAL); 5115885Sjulian } 5225791Sjulian 5325791Sjulian s = splnet(); 5425791Sjulian error = at_pcballoc( so ); 5525791Sjulian splx(s); 5625791Sjulian if (error) { 5725791Sjulian return (error); 5815885Sjulian } 5925791Sjulian return (soreserve( so, ddp_sendspace, ddp_recvspace )); 6025791Sjulian} 6115885Sjulian 6225791Sjulianstatic int 6325791Sjulianddp_detach(struct socket *so) 6425791Sjulian{ 6525791Sjulian struct ddpcb *ddp; 6625791Sjulian int s; 6725791Sjulian 6825791Sjulian ddp = sotoddpcb( so ); 6925791Sjulian if ( ddp == NULL ) { 7025791Sjulian return( EINVAL); 7125791Sjulian } 7225791Sjulian s = splnet(); 7315885Sjulian at_pcbdetach( so, ddp ); 7425791Sjulian splx(s); 7525791Sjulian return(0); 7625791Sjulian} 7715885Sjulian 7825791Sjulianstatic int 7983366Sjulianddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 8025791Sjulian{ 8125791Sjulian struct ddpcb *ddp; 8225791Sjulian int error = 0; 8325791Sjulian int s; 8425791Sjulian 8525791Sjulian ddp = sotoddpcb( so ); 8625791Sjulian if ( ddp == NULL ) { 8725791Sjulian return( EINVAL); 8825791Sjulian } 8925791Sjulian s = splnet(); 9083366Sjulian error = at_pcbsetaddr(ddp, nam, td); 9125791Sjulian splx(s); 9225791Sjulian return (error); 9325791Sjulian} 9415885Sjulian 9525791Sjulianstatic int 9683366Sjulianddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 9725791Sjulian{ 9825791Sjulian struct ddpcb *ddp; 9925791Sjulian int error = 0; 10025791Sjulian int s; 10125791Sjulian 10225791Sjulian ddp = sotoddpcb( so ); 10325791Sjulian if ( ddp == NULL ) { 10425791Sjulian return( EINVAL); 10525791Sjulian } 10615885Sjulian 10715885Sjulian if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) { 10825791Sjulian return(EISCONN); 10915885Sjulian } 11015885Sjulian 11125791Sjulian s = splnet(); 11283366Sjulian error = at_pcbconnect( ddp, nam, td ); 11325791Sjulian splx(s); 11497658Stanimura if ( error == 0 ) 11515885Sjulian soisconnected( so ); 11625791Sjulian return(error); 11725791Sjulian} 11815885Sjulian 11925791Sjulianstatic int 12025791Sjulianddp_disconnect(struct socket *so) 12125791Sjulian{ 12225791Sjulian 12325791Sjulian struct ddpcb *ddp; 12425791Sjulian int s; 12525791Sjulian 12625791Sjulian ddp = sotoddpcb( so ); 12725791Sjulian if ( ddp == NULL ) { 12825791Sjulian return( EINVAL); 12925791Sjulian } 13015885Sjulian if ( ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE ) { 13125791Sjulian return(ENOTCONN); 13215885Sjulian } 13325791Sjulian 13425791Sjulian s = splnet(); 13515885Sjulian at_pcbdisconnect( ddp ); 13625791Sjulian ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE; 13725791Sjulian splx(s); 13815885Sjulian soisdisconnected( so ); 13925791Sjulian return(0); 14025791Sjulian} 14115885Sjulian 14225791Sjulianstatic int 14325791Sjulianddp_shutdown(struct socket *so) 14425791Sjulian{ 14525791Sjulian struct ddpcb *ddp; 14641591Sarchie 14725791Sjulian ddp = sotoddpcb( so ); 14825791Sjulian if ( ddp == NULL ) { 14925791Sjulian return( EINVAL); 15025791Sjulian } 15115885Sjulian socantsendmore( so ); 15225791Sjulian return(0); 15325791Sjulian} 15415885Sjulian 15525791Sjulianstatic int 15628270Swollmanddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 15783366Sjulian struct mbuf *control, struct thread *td) 15825791Sjulian{ 15925791Sjulian struct ddpcb *ddp; 16025791Sjulian int error = 0; 16125791Sjulian int s; 16225791Sjulian 16325791Sjulian ddp = sotoddpcb( so ); 16425791Sjulian if ( ddp == NULL ) { 16525791Sjulian return(EINVAL); 16625791Sjulian } 16715885Sjulian 16825791Sjulian if ( control && control->m_len ) { 16925791Sjulian return(EINVAL); 17025791Sjulian } 17125791Sjulian 17215885Sjulian if ( addr ) { 17325791Sjulian if ( ddp->ddp_fsat.sat_port != ATADDR_ANYPORT ) { 17425791Sjulian return(EISCONN); 17525791Sjulian } 17615885Sjulian 17725791Sjulian s = splnet(); 17883366Sjulian error = at_pcbconnect(ddp, addr, td); 17915885Sjulian splx( s ); 18025791Sjulian if ( error ) { 18125791Sjulian return(error); 18225791Sjulian } 18315885Sjulian } else { 18425791Sjulian if ( ddp->ddp_fsat.sat_port == ATADDR_ANYPORT ) { 18525791Sjulian return(ENOTCONN); 18625791Sjulian } 18715885Sjulian } 18815885Sjulian 18925791Sjulian s = splnet(); 19023396Sjulian error = ddp_output( m, so ); 19115885Sjulian if ( addr ) { 19215885Sjulian at_pcbdisconnect( ddp ); 19315885Sjulian } 19425791Sjulian splx(s); 19525791Sjulian return(error); 19625791Sjulian} 19725791Sjulian 19825791Sjulianstatic int 19925791Sjulianddp_abort(struct socket *so) 20025791Sjulian{ 20125791Sjulian struct ddpcb *ddp; 20225791Sjulian int s; 20325791Sjulian 20425791Sjulian ddp = sotoddpcb( so ); 20525791Sjulian if ( ddp == NULL ) { 20625791Sjulian return(EINVAL); 20715885Sjulian } 20815885Sjulian soisdisconnected( so ); 20925791Sjulian s = splnet(); 21015885Sjulian at_pcbdetach( so, ddp ); 21125791Sjulian splx(s); 21225791Sjulian return(0); 21325791Sjulian} 21415885Sjulian 21515885Sjulian 21615885Sjulianstatic void 21728270Swollmanat_sockaddr(struct ddpcb *ddp, struct sockaddr **addr) 21815885Sjulian{ 21928270Swollman *addr = dup_sockaddr((struct sockaddr *)&ddp->ddp_lsat, 0); 22015885Sjulian} 22115885Sjulian 22215885Sjulianstatic int 22383366Sjulianat_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td) 22415885Sjulian{ 22515885Sjulian struct sockaddr_at lsat, *sat; 22615885Sjulian struct at_ifaddr *aa; 22715885Sjulian struct ddpcb *ddpp; 22815885Sjulian 22915885Sjulian if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT ) { /* shouldn't be bound */ 23015885Sjulian return( EINVAL ); 23115885Sjulian } 23215885Sjulian 23328270Swollman if (addr != 0) { /* validate passed address */ 23428270Swollman sat = (struct sockaddr_at *)addr; 23528270Swollman if (sat->sat_family != AF_APPLETALK) { 23628270Swollman return(EAFNOSUPPORT); 23715885Sjulian } 23815885Sjulian 23915885Sjulian if ( sat->sat_addr.s_node != ATADDR_ANYNODE || 24015885Sjulian sat->sat_addr.s_net != ATADDR_ANYNET ) { 24115885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 24215885Sjulian if (( sat->sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) && 24315885Sjulian ( sat->sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node )) { 24415885Sjulian break; 24515885Sjulian } 24615885Sjulian } 24715885Sjulian if ( !aa ) { 24815885Sjulian return( EADDRNOTAVAIL ); 24915885Sjulian } 25015885Sjulian } 25115885Sjulian 25215885Sjulian if ( sat->sat_port != ATADDR_ANYPORT ) { 25315885Sjulian if ( sat->sat_port < ATPORT_FIRST || 25415885Sjulian sat->sat_port >= ATPORT_LAST ) { 25515885Sjulian return( EINVAL ); 25615885Sjulian } 25715885Sjulian if ( sat->sat_port < ATPORT_RESERVED && 25893593Sjhb suser(td) ) { 25915885Sjulian return( EACCES ); 26015885Sjulian } 26115885Sjulian } 26215885Sjulian } else { 26315885Sjulian bzero( (caddr_t)&lsat, sizeof( struct sockaddr_at )); 26415885Sjulian lsat.sat_len = sizeof(struct sockaddr_at); 26515885Sjulian lsat.sat_addr.s_node = ATADDR_ANYNODE; 26615885Sjulian lsat.sat_addr.s_net = ATADDR_ANYNET; 26715885Sjulian lsat.sat_family = AF_APPLETALK; 26815885Sjulian sat = &lsat; 26915885Sjulian } 27015885Sjulian 27115885Sjulian if ( sat->sat_addr.s_node == ATADDR_ANYNODE && 27215885Sjulian sat->sat_addr.s_net == ATADDR_ANYNET ) { 27315885Sjulian if ( at_ifaddr == NULL ) { 27415885Sjulian return( EADDRNOTAVAIL ); 27515885Sjulian } 27615885Sjulian sat->sat_addr = AA_SAT( at_ifaddr )->sat_addr; 27715885Sjulian } 27815885Sjulian ddp->ddp_lsat = *sat; 27915885Sjulian 28015885Sjulian /* 28115885Sjulian * Choose port. 28215885Sjulian */ 28315885Sjulian if ( sat->sat_port == ATADDR_ANYPORT ) { 28415885Sjulian for ( sat->sat_port = ATPORT_RESERVED; 28515885Sjulian sat->sat_port < ATPORT_LAST; sat->sat_port++ ) { 28615885Sjulian if ( ddp_ports[ sat->sat_port - 1 ] == 0 ) { 28715885Sjulian break; 28815885Sjulian } 28915885Sjulian } 29015885Sjulian if ( sat->sat_port == ATPORT_LAST ) { 29115885Sjulian return( EADDRNOTAVAIL ); 29215885Sjulian } 29315885Sjulian ddp->ddp_lsat.sat_port = sat->sat_port; 29415885Sjulian ddp_ports[ sat->sat_port - 1 ] = ddp; 29515885Sjulian } else { 29615885Sjulian for ( ddpp = ddp_ports[ sat->sat_port - 1 ]; ddpp; 29715885Sjulian ddpp = ddpp->ddp_pnext ) { 29815885Sjulian if ( ddpp->ddp_lsat.sat_addr.s_net == sat->sat_addr.s_net && 29915885Sjulian ddpp->ddp_lsat.sat_addr.s_node == sat->sat_addr.s_node ) { 30015885Sjulian break; 30115885Sjulian } 30215885Sjulian } 30315885Sjulian if ( ddpp != NULL ) { 30415885Sjulian return( EADDRINUSE ); 30515885Sjulian } 30615885Sjulian ddp->ddp_pnext = ddp_ports[ sat->sat_port - 1 ]; 30715885Sjulian ddp_ports[ sat->sat_port - 1 ] = ddp; 30815885Sjulian if ( ddp->ddp_pnext ) { 30915885Sjulian ddp->ddp_pnext->ddp_pprev = ddp; 31015885Sjulian } 31115885Sjulian } 31215885Sjulian 31315885Sjulian return( 0 ); 31415885Sjulian} 31515885Sjulian 31615885Sjulianstatic int 31783366Sjulianat_pcbconnect(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td) 31815885Sjulian{ 31928270Swollman struct sockaddr_at *sat = (struct sockaddr_at *)addr; 32015885Sjulian struct route *ro; 32115885Sjulian struct at_ifaddr *aa = 0; 32215885Sjulian struct ifnet *ifp; 32315885Sjulian u_short hintnet = 0, net; 32415885Sjulian 32528270Swollman if (sat->sat_family != AF_APPLETALK) { 32628270Swollman return(EAFNOSUPPORT); 32715885Sjulian } 32815885Sjulian 32915885Sjulian /* 33015885Sjulian * Under phase 2, network 0 means "the network". We take "the 33115885Sjulian * network" to mean the network the control block is bound to. 33215885Sjulian * If the control block is not bound, there is an error. 33315885Sjulian */ 33415885Sjulian if ( sat->sat_addr.s_net == ATADDR_ANYNET 33515885Sjulian && sat->sat_addr.s_node != ATADDR_ANYNODE ) { 33615885Sjulian if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) { 33715885Sjulian return( EADDRNOTAVAIL ); 33815885Sjulian } 33915885Sjulian hintnet = ddp->ddp_lsat.sat_addr.s_net; 34015885Sjulian } 34115885Sjulian 34215885Sjulian ro = &ddp->ddp_route; 34315885Sjulian /* 34415885Sjulian * If we've got an old route for this pcb, check that it is valid. 34515885Sjulian * If we've changed our address, we may have an old "good looking" 34615885Sjulian * route here. Attempt to detect it. 34715885Sjulian */ 34815885Sjulian if ( ro->ro_rt ) { 34915885Sjulian if ( hintnet ) { 35015885Sjulian net = hintnet; 35115885Sjulian } else { 35215885Sjulian net = sat->sat_addr.s_net; 35315885Sjulian } 35415885Sjulian aa = 0; 35543305Sdillon if ((ifp = ro->ro_rt->rt_ifp) != NULL) { 35615885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 35715885Sjulian if ( aa->aa_ifp == ifp && 35815885Sjulian ntohs( net ) >= ntohs( aa->aa_firstnet ) && 35915885Sjulian ntohs( net ) <= ntohs( aa->aa_lastnet )) { 36015885Sjulian break; 36115885Sjulian } 36215885Sjulian } 36315885Sjulian } 36415885Sjulian if ( aa == NULL || ( satosat( &ro->ro_dst )->sat_addr.s_net != 36515885Sjulian ( hintnet ? hintnet : sat->sat_addr.s_net ) || 36615885Sjulian satosat( &ro->ro_dst )->sat_addr.s_node != 36715885Sjulian sat->sat_addr.s_node )) { 36815885Sjulian RTFREE( ro->ro_rt ); 36915885Sjulian ro->ro_rt = (struct rtentry *)0; 37015885Sjulian } 37115885Sjulian } 37215885Sjulian 37315885Sjulian /* 37415885Sjulian * If we've got no route for this interface, try to find one. 37515885Sjulian */ 37615885Sjulian if ( ro->ro_rt == (struct rtentry *)0 || 37715885Sjulian ro->ro_rt->rt_ifp == (struct ifnet *)0 ) { 37815885Sjulian ro->ro_dst.sa_len = sizeof( struct sockaddr_at ); 37915885Sjulian ro->ro_dst.sa_family = AF_APPLETALK; 38015885Sjulian if ( hintnet ) { 38115885Sjulian satosat( &ro->ro_dst )->sat_addr.s_net = hintnet; 38215885Sjulian } else { 38315885Sjulian satosat( &ro->ro_dst )->sat_addr.s_net = sat->sat_addr.s_net; 38415885Sjulian } 38515885Sjulian satosat( &ro->ro_dst )->sat_addr.s_node = sat->sat_addr.s_node; 38615885Sjulian rtalloc( ro ); 38715885Sjulian } 38815885Sjulian 38915885Sjulian /* 39015885Sjulian * Make sure any route that we have has a valid interface. 39115885Sjulian */ 39215885Sjulian aa = 0; 39315885Sjulian if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) { 39415885Sjulian for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 39515885Sjulian if ( aa->aa_ifp == ifp ) { 39615885Sjulian break; 39715885Sjulian } 39815885Sjulian } 39915885Sjulian } 40015885Sjulian if ( aa == 0 ) { 40115885Sjulian return( ENETUNREACH ); 40215885Sjulian } 40315885Sjulian 40415885Sjulian ddp->ddp_fsat = *sat; 40515885Sjulian if ( ddp->ddp_lsat.sat_port == ATADDR_ANYPORT ) { 40683366Sjulian return(at_pcbsetaddr(ddp, (struct sockaddr *)0, td)); 40715885Sjulian } 40815885Sjulian return( 0 ); 40915885Sjulian} 41015885Sjulian 41115885Sjulianstatic void 41215885Sjulianat_pcbdisconnect( struct ddpcb *ddp ) 41315885Sjulian{ 41415885Sjulian ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET; 41515885Sjulian ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE; 41615885Sjulian ddp->ddp_fsat.sat_port = ATADDR_ANYPORT; 41715885Sjulian} 41815885Sjulian 41915885Sjulianstatic int 42015885Sjulianat_pcballoc( struct socket *so ) 42115885Sjulian{ 42228270Swollman struct ddpcb *ddp; 42315885Sjulian 424111119Simp MALLOC(ddp, struct ddpcb *, sizeof *ddp, M_PCB, M_WAITOK | M_ZERO); 42528270Swollman ddp->ddp_lsat.sat_port = ATADDR_ANYPORT; 42615885Sjulian 42728270Swollman ddp->ddp_next = ddpcb; 42828270Swollman ddp->ddp_prev = NULL; 42928270Swollman ddp->ddp_pprev = NULL; 43028270Swollman ddp->ddp_pnext = NULL; 43128270Swollman if (ddpcb) { 43228270Swollman ddpcb->ddp_prev = ddp; 43328270Swollman } 43428270Swollman ddpcb = ddp; 43515885Sjulian 43628270Swollman ddp->ddp_socket = so; 43728270Swollman so->so_pcb = (caddr_t)ddp; 43828270Swollman return(0); 43915885Sjulian} 44015885Sjulian 44115885Sjulianstatic void 44215885Sjulianat_pcbdetach( struct socket *so, struct ddpcb *ddp) 44315885Sjulian{ 44415885Sjulian soisdisconnected( so ); 44515885Sjulian so->so_pcb = 0; 44686487Sdillon sotryfree(so); 44715885Sjulian 44815885Sjulian /* remove ddp from ddp_ports list */ 44915885Sjulian if ( ddp->ddp_lsat.sat_port != ATADDR_ANYPORT && 45015885Sjulian ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] != NULL ) { 45115885Sjulian if ( ddp->ddp_pprev != NULL ) { 45215885Sjulian ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext; 45315885Sjulian } else { 45415885Sjulian ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] = ddp->ddp_pnext; 45515885Sjulian } 45615885Sjulian if ( ddp->ddp_pnext != NULL ) { 45715885Sjulian ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev; 45815885Sjulian } 45915885Sjulian } 46015885Sjulian 46115885Sjulian if ( ddp->ddp_route.ro_rt ) { 46215885Sjulian rtfree( ddp->ddp_route.ro_rt ); 46315885Sjulian } 46415885Sjulian 46515885Sjulian if ( ddp->ddp_prev ) { 46615885Sjulian ddp->ddp_prev->ddp_next = ddp->ddp_next; 46715885Sjulian } else { 46815885Sjulian ddpcb = ddp->ddp_next; 46915885Sjulian } 47015885Sjulian if ( ddp->ddp_next ) { 47115885Sjulian ddp->ddp_next->ddp_prev = ddp->ddp_prev; 47215885Sjulian } 47328270Swollman FREE(ddp, M_PCB); 47415885Sjulian} 47515885Sjulian 47615885Sjulian/* 47715885Sjulian * For the moment, this just find the pcb with the correct local address. 47815885Sjulian * In the future, this will actually do some real searching, so we can use 47915885Sjulian * the sender's address to do de-multiplexing on a single port to many 48015885Sjulian * sockets (pcbs). 48115885Sjulian */ 48215885Sjulianstruct ddpcb * 48315885Sjulianddp_search( struct sockaddr_at *from, struct sockaddr_at *to, 48415885Sjulian struct at_ifaddr *aa) 48515885Sjulian{ 48615885Sjulian struct ddpcb *ddp; 48715885Sjulian 48815885Sjulian /* 48915885Sjulian * Check for bad ports. 49015885Sjulian */ 49115885Sjulian if ( to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST ) { 49215885Sjulian return( NULL ); 49315885Sjulian } 49415885Sjulian 49515885Sjulian /* 49615885Sjulian * Make sure the local address matches the sent address. What about 49715885Sjulian * the interface? 49815885Sjulian */ 49915885Sjulian for ( ddp = ddp_ports[ to->sat_port - 1 ]; ddp; ddp = ddp->ddp_pnext ) { 50015885Sjulian /* XXX should we handle 0.YY? */ 50115885Sjulian 50215885Sjulian /* XXXX.YY to socket on destination interface */ 50315885Sjulian if ( to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net && 50415885Sjulian to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node ) { 50515885Sjulian break; 50615885Sjulian } 50715885Sjulian 50815885Sjulian /* 0.255 to socket on receiving interface */ 50915885Sjulian if ( to->sat_addr.s_node == ATADDR_BCAST && ( to->sat_addr.s_net == 0 || 51015885Sjulian to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net ) && 51115885Sjulian ddp->ddp_lsat.sat_addr.s_net == AA_SAT( aa )->sat_addr.s_net ) { 51215885Sjulian break; 51315885Sjulian } 51415885Sjulian 51515885Sjulian /* XXXX.0 to socket on destination interface */ 51615885Sjulian if ( to->sat_addr.s_net == aa->aa_firstnet && 51715885Sjulian to->sat_addr.s_node == 0 && 51815885Sjulian ntohs( ddp->ddp_lsat.sat_addr.s_net ) >= 51915885Sjulian ntohs( aa->aa_firstnet ) && 52015885Sjulian ntohs( ddp->ddp_lsat.sat_addr.s_net ) <= 52115885Sjulian ntohs( aa->aa_lastnet )) { 52215885Sjulian break; 52315885Sjulian } 52415885Sjulian } 52515885Sjulian return( ddp ); 52615885Sjulian} 52725791Sjulianstatic int 52828270Swollmanat_setpeeraddr(struct socket *so, struct sockaddr **nam) 52925791Sjulian{ 53025791Sjulian return(EOPNOTSUPP); 53125791Sjulian} 53215885Sjulian 53325791Sjulianstatic int 53428270Swollmanat_setsockaddr(struct socket *so, struct sockaddr **nam) 53525791Sjulian{ 53625791Sjulian struct ddpcb *ddp; 53741591Sarchie 53825791Sjulian ddp = sotoddpcb( so ); 53925791Sjulian if ( ddp == NULL ) { 54025791Sjulian return( EINVAL); 54125791Sjulian } 54225791Sjulian at_sockaddr( ddp, nam ); 54325791Sjulian return(0); 54425791Sjulian} 54525791Sjulian 54615885Sjulianvoid 547111888Sjlemonddp_init(void) 54815885Sjulian{ 549111888Sjlemon 550111888Sjlemon atintrq1.ifq_maxlen = IFQ_MAXLEN; 551111888Sjlemon atintrq2.ifq_maxlen = IFQ_MAXLEN; 552111888Sjlemon aarpintrq.ifq_maxlen = IFQ_MAXLEN; 553111888Sjlemon mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF); 554111888Sjlemon mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF); 555111888Sjlemon mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF); 556111888Sjlemon netisr_register(NETISR_ATALK1, at1intr, &atintrq1); 557111888Sjlemon netisr_register(NETISR_ATALK2, at2intr, &atintrq2); 558111888Sjlemon netisr_register(NETISR_AARP, aarpintr, &aarpintrq); 55915885Sjulian} 56015885Sjulian 56117254Sjulian#if 0 56215885Sjulianstatic void 56315885Sjulianddp_clean(void ) 56415885Sjulian{ 56515885Sjulian struct ddpcb *ddp; 56615885Sjulian 56715885Sjulian for ( ddp = ddpcb; ddp; ddp = ddp->ddp_next ) { 56815885Sjulian at_pcbdetach( ddp->ddp_socket, ddp ); 56915885Sjulian } 57015885Sjulian} 57117254Sjulian#endif 57225791Sjulian 57325791Sjulianstruct pr_usrreqs ddp_usrreqs = { 57425791Sjulian ddp_abort, 57525791Sjulian pru_accept_notsupp, 57625791Sjulian ddp_attach, 57725791Sjulian ddp_bind, 57825791Sjulian ddp_connect, 57925791Sjulian pru_connect2_notsupp, 58025791Sjulian at_control, 58125791Sjulian ddp_detach, 58225791Sjulian ddp_disconnect, 58325791Sjulian pru_listen_notsupp, 58425791Sjulian at_setpeeraddr, 58525791Sjulian pru_rcvd_notsupp, 58625791Sjulian pru_rcvoob_notsupp, 58725791Sjulian ddp_send, 58825791Sjulian pru_sense_null, 58925791Sjulian ddp_shutdown, 59025791Sjulian at_setsockaddr, 59125791Sjulian sosend, 59225791Sjulian soreceive, 59329366Speter sopoll 59425791Sjulian}; 595