Index: net/if_ethersubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.26.2.3 diff -c -r1.26.2.3 if_ethersubr.c *** if_ethersubr.c 1997/09/30 12:29:00 1.26.2.3 --- if_ethersubr.c 1997/10/28 08:14:06 *************** *** 194,214 **** #endif #ifdef NETATALK case AF_APPLETALK: ! if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { #ifdef NETATALKDEBUG ! extern char *prsockaddr(struct sockaddr *); ! printf("aarpresolv: failed for %s\n", prsockaddr(dst)); #endif NETATALKDEBUG ! return (0); ! } ! /* ! * ifaddr is the first thing in at_ifaddr ! */ ! if ((aa = (struct at_ifaddr *)at_ifawithnet( ! (struct sockaddr_at *)dst, ifp->if_addrlist)) ! == 0) ! goto bad; ! /* * In the phase 2 case, we need to prepend an mbuf for the llc header. * Since we must preserve the value of m, which is passed to us by --- 194,239 ---- #endif #ifdef NETATALK case AF_APPLETALK: ! { ! struct sockaddr_at *sat = (struct sockaddr_at *)dst; ! ! /* ! * super hack.. ! * Most of this loopback code should move into the appletalk ! * code, but it's here for now.. remember to move it! [JRE] ! * This may not get the same interface we started with ! * fix asap. XXX ! */ ! aa = at_ifawithnet( sat ); ! if (aa == NULL) { ! goto bad; ! } ! if( aa->aa_ifa.ifa_ifp != ifp ) { ! (*aa->aa_ifa.ifa_ifp->if_output)(aa->aa_ifa.ifa_ifp, ! m,dst,rt); ! } ! if (((sat->sat_addr.s_net == ATADDR_ANYNET) ! && (sat->sat_addr.s_node == ATADDR_ANYNODE)) ! || ((sat->sat_addr.s_net == aa->aa_addr.sat_addr.s_net ) ! && (sat->sat_addr.s_node == aa->aa_addr.sat_addr.s_node))) { ! (void) looutput(ifp, m, dst, rt); ! return(0); ! } ! ! if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { #ifdef NETATALKDEBUG ! extern char *prsockaddr(struct sockaddr *); ! printf("aarpresolv: failed for %s\n", prsockaddr(dst)); #endif NETATALKDEBUG ! return (0); ! } ! ! /* ! * If broadcasting on a simplex interface, loopback a copy ! */ ! if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) ! mcopy = m_copy(m, 0, (int)M_COPYALL); ! } /* * In the phase 2 case, we need to prepend an mbuf for the llc header. * Since we must preserve the value of m, which is passed to us by Index: netatalk/aarp.c =================================================================== RCS file: /home/ncvs/src/sys/netatalk/aarp.c,v retrieving revision 1.3 diff -c -r1.3 aarp.c *** aarp.c 1996/08/29 23:16:29 1.3 --- aarp.c 1997/10/28 08:14:07 *************** *** 94,123 **** * the given network.. remember to take netranges into * consideration. */ ! struct ifaddr * ! at_ifawithnet( sat, ifa ) ! struct sockaddr_at *sat; ! struct ifaddr *ifa; { struct sockaddr_at *sat2; - struct netrange *nr; ! for (; ifa; ifa = ifa->ifa_next ) { ! if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) { ! continue; ! } ! sat2 = satosat( ifa->ifa_addr ); ! if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { ! break; } ! nr = (struct netrange *)(sat2->sat_zero); ! if( (nr->nr_phase == 2 ) ! && (nr->nr_firstnet <= sat->sat_addr.s_net) ! && (nr->nr_lastnet >= sat->sat_addr.s_net)) { ! break; ! } ! } ! return( ifa ); } static void --- 94,117 ---- * the given network.. remember to take netranges into * consideration. */ ! struct at_ifaddr * ! at_ifawithnet(struct sockaddr_at *sat ) { + struct at_ifaddr *aa; struct sockaddr_at *sat2; ! for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { ! sat2 = &(aa->aa_addr); ! if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { ! break; ! } ! if( (aa->aa_flags & AFA_PHASE2 ) ! && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) ! && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) { ! break; ! } } ! return( aa ); } static void *************** *** 155,162 **** * interface with the same address as we're looking for. If the * net is phase 2, generate an 802.2 and SNAP header. */ ! if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist )) ! == NULL ) { m_freem( m ); return; } --- 149,155 ---- * interface with the same address as we're looking for. If the * net is phase 2, generate an 802.2 and SNAP header. */ ! if (( aa = at_ifawithnet( sat )) == NULL ) { m_freem( m ); return; } *************** *** 213,220 **** int s; if ( at_broadcast( destsat )) { ! if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat, ! ((struct ifnet *)ac)->if_addrlist )) == NULL ) { m_freem( m ); return( 0 ); } --- 206,213 ---- int s; if ( at_broadcast( destsat )) { ! m->m_flags |= M_BCAST; ! if (( aa = at_ifawithnet( destsat )) == NULL ) { m_freem( m ); return( 0 ); } *************** *** 325,332 **** sat.sat_len = sizeof(struct sockaddr_at); sat.sat_family = AF_APPLETALK; sat.sat_addr.s_net = net; ! if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat, ! ac->ac_if.if_addrlist )) == NULL ) { m_freem( m ); return; } --- 318,324 ---- sat.sat_len = sizeof(struct sockaddr_at); sat.sat_family = AF_APPLETALK; sat.sat_addr.s_net = net; ! if (( aa = at_ifawithnet( &sat )) == NULL ) { m_freem( m ); return; } Index: netatalk/at_control.c =================================================================== RCS file: /home/ncvs/src/sys/netatalk/at_control.c,v retrieving revision 1.11.2.1 diff -c -r1.11.2.1 at_control.c *** at_control.c 1997/10/05 21:41:06 1.11.2.1 --- at_control.c 1997/10/28 08:14:07 *************** *** 882,891 **** */ if ((addr->sat_addr.s_net == gw->sat_addr.s_net) || ((addr->sat_range.r_netrange.nr_lastnet) ! && (gw->sat_addr.s_net ! >= addr->sat_range.r_netrange.nr_firstnet ) ! && (gw->sat_addr.s_net ! <= addr->sat_range.r_netrange.nr_lastnet ))) { return 1; } break; --- 882,891 ---- */ if ((addr->sat_addr.s_net == gw->sat_addr.s_net) || ((addr->sat_range.r_netrange.nr_lastnet) ! && (ntohs(gw->sat_addr.s_net) ! >= ntohs(addr->sat_range.r_netrange.nr_firstnet )) ! && (ntohs(gw->sat_addr.s_net) ! <= ntohs(addr->sat_range.r_netrange.nr_lastnet )))) { return 1; } break; Index: netatalk/at_extern.h =================================================================== RCS file: /home/ncvs/src/sys/netatalk/at_extern.h,v retrieving revision 1.1 diff -c -r1.1 at_extern.h *** at_extern.h 1996/05/24 01:35:23 1.1 --- at_extern.h 1997/10/28 08:14:07 *************** *** 24,31 **** struct mbuf *addr, struct mbuf *rights)); extern void ddp_init __P((void )); ! extern struct ifaddr *at_ifawithnet __P((struct sockaddr_at *, ! struct ifaddr *)); #ifdef _NETATALK_DDP_VAR_H_ extern int ddp_output __P(( struct ddpcb *ddp, struct mbuf *m)); #endif --- 24,30 ---- struct mbuf *addr, struct mbuf *rights)); extern void ddp_init __P((void )); ! extern struct at_ifaddr *at_ifawithnet __P((struct sockaddr_at *)); #ifdef _NETATALK_DDP_VAR_H_ extern int ddp_output __P(( struct ddpcb *ddp, struct mbuf *m)); #endif Index: netatalk/ddp_input.c =================================================================== RCS file: /home/ncvs/src/sys/netatalk/ddp_input.c,v retrieving revision 1.3 diff -c -r1.3 ddp_input.c *** ddp_input.c 1996/09/10 08:23:11 1.3 --- ddp_input.c 1997/10/28 08:14:08 *************** *** 41,46 **** --- 41,49 ---- struct at_ifaddr *aa; int s; + /* + * First pull off all the phase 2 packets. + */ for (;;) { s = splimp(); *************** *** 53,71 **** } ifp = m->m_pkthdr.rcvif; - for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { - if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) { - break; - } - } - if ( aa == NULL ) { /* ifp not an appletalk interface */ - m_freem( m ); - continue; - } - ddp_input( m, ifp, (struct elaphdr *)NULL, 2 ); } for (;;) { s = splimp(); --- 56,67 ---- } ifp = m->m_pkthdr.rcvif; ddp_input( m, ifp, (struct elaphdr *)NULL, 2 ); } + /* + * Then pull off all the phase 1 packets. + */ for (;;) { s = splimp(); *************** *** 78,92 **** } ifp = m->m_pkthdr.rcvif; - for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { - if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { - break; - } - } - if ( aa == NULL ) { /* ifp not an appletalk interface */ - m_freem( m ); - continue; - } if ( m->m_len < SZ_ELAPHDR && (( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) { --- 74,79 ---- *************** *** 94,99 **** --- 81,89 ---- continue; } + /* + * this seems a little dubios, but I don't know phase 1 so leave it. + */ elhp = mtod( m, struct elaphdr *); m_adj( m, SZ_ELAPHDR ); *************** *** 127,133 **** --- 117,130 ---- u_short cksum = 0; bzero( (caddr_t)&from, sizeof( struct sockaddr_at )); + bzero( (caddr_t)&to, sizeof( struct sockaddr_at )); if ( elh ) { + /* + * Extract the information in the short header. + * netowrk information is defaulted to ATADDR_ANYNET + * and node information comes from the elh info. + * We must be phase 1. + */ ddpstat.ddps_short++; if ( m->m_len < sizeof( struct ddpshdr ) && *************** *** 148,165 **** from.sat_addr.s_node = elh->el_snode; from.sat_port = ddps.dsh_sport; for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { ! if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 && ! ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node || ! to.sat_addr.s_node == ATADDR_BCAST )) { break; } } if ( aa == NULL ) { m_freem( m ); return; } } else { ddpstat.ddps_long++; if ( m->m_len < sizeof( struct ddpehdr ) && --- 145,176 ---- from.sat_addr.s_node = elh->el_snode; from.sat_port = ddps.dsh_sport; + /* + * Make sure that we point to the phase1 ifaddr info + * and that it's valid for this packet. + */ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { ! if ( (aa->aa_ifp == ifp) ! && ( (aa->aa_flags & AFA_PHASE2) == 0) ! && ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node) ! || (to.sat_addr.s_node == ATADDR_BCAST))) { break; } } + /* + * maybe we got a broadcast not meant for us.. ditch it. + */ if ( aa == NULL ) { m_freem( m ); return; } } else { + /* + * There was no 'elh' passed on. This could still be + * either phase1 or phase2. + * We have a long header, but we may be running on a pahse 1 net. + * Extract out all the info regarding this packet's src & dst. + */ ddpstat.ddps_long++; if ( m->m_len < sizeof( struct ddpehdr ) && *************** *** 185,190 **** --- 196,213 ---- to.sat_port = ddpe.deh_dport; if ( to.sat_addr.s_net == ATADDR_ANYNET ) { + /* + * The TO address doesn't specify a net, + * So by definition it's for this net. + * Try find ifaddr info with the right phase, + * the right interface, and either to our node, a bradcast, + * or looped back (though that SHOULD be covered in the other + * cases). + * + * XXX If we have multiple interfaces, then the first with + * this node number will match (which may NOT be what we want, + * but it's probably safe in 99.999% of cases. + */ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) { continue; *************** *** 192,218 **** if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { continue; } ! if ( aa->aa_ifp == ifp && ! ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node || ! to.sat_addr.s_node == ATADDR_BCAST || ! ( ifp->if_flags & IFF_LOOPBACK ))) { break; } } } else { for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { if ( to.sat_addr.s_net == aa->aa_firstnet && to.sat_addr.s_node == 0 ) { break; } ! if (( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ) || ! ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )) && ! ( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 ) || ! ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe ))) { continue; } ! if ( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node && ! to.sat_addr.s_node != ATADDR_BCAST ) { continue; } break; --- 215,261 ---- if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { continue; } ! if ( (aa->aa_ifp == ifp) ! && ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node) ! || (to.sat_addr.s_node == ATADDR_BCAST) ! || (ifp->if_flags & IFF_LOOPBACK))) { break; } } } else { + /* + * A destination network was given. We just try to find + * which ifaddr info matches it. + */ for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { + /* + * This is a kludge. Accept packets that are + * for any router on a local netrange. + */ if ( to.sat_addr.s_net == aa->aa_firstnet && to.sat_addr.s_node == 0 ) { break; } ! /* ! * Don't use ifaddr info for which we are totally outside the ! * netrange, and it's not a startup packet. ! * Startup packets are always implicitly allowed on to ! * the next test. ! */ ! if ((( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet )) ! || (ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet ))) ! && (( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 )) ! || (ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe )))) { continue; } ! ! /* ! * Don't record a match either if we just don't have a match ! * in the node address. This can have if the interface ! * is in promiscuous mode for example. ! */ ! if (( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node) ! && (to.sat_addr.s_node != ATADDR_BCAST) ) { continue; } break; *************** *** 236,278 **** } /* ! * XXX Should we deliver broadcasts locally, also, or rely on the ! * link layer to give us a copy? For the moment, the latter. */ ! if ( aa == NULL || ( to.sat_addr.s_node == ATADDR_BCAST && ! aa->aa_ifp != ifp && ( ifp->if_flags & IFF_LOOPBACK ) == 0 )) { if ( ddp_forward == 0 ) { m_freem( m ); return; } ! if ( forwro.ro_rt && ( satosat( &forwro.ro_dst )->sat_addr.s_net != ! to.sat_addr.s_net || ! satosat( &forwro.ro_dst )->sat_addr.s_node != ! to.sat_addr.s_node )) { RTFREE( forwro.ro_rt ); forwro.ro_rt = (struct rtentry *)0; } ! if ( forwro.ro_rt == (struct rtentry *)0 || ! forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) { forwro.ro_dst.sa_len = sizeof( struct sockaddr_at ); forwro.ro_dst.sa_family = AF_APPLETALK; ! satosat( &forwro.ro_dst )->sat_addr.s_net = to.sat_addr.s_net; ! satosat( &forwro.ro_dst )->sat_addr.s_node = to.sat_addr.s_node; ! rtalloc( &forwro ); } ! if ( to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net && ! ddpe.deh_hops == DDP_MAXHOPS ) { m_freem( m ); return; } ! if ( ddp_firewall && ! ( forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp != ifp )) { m_freem( m ); return; } ddpe.deh_hops++; ddpe.deh_bytes = htonl( ddpe.deh_bytes ); bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_short )); /* XXX deh? */ --- 279,353 ---- } /* ! * If it aint for a net on any of our interfaces, ! * or it IS for a net on a different interface than it came in on, ! * (and it is not looped back) then consider if we shoulf forward it. ! * As we a re not really a router this is a bit cheaky, but it may be ! * useful some day. */ ! if ( (aa == NULL) ! || ( (to.sat_addr.s_node == ATADDR_BCAST) ! && (aa->aa_ifp != ifp) ! && (( ifp->if_flags & IFF_LOOPBACK ) == 0 ))) { ! /* ! * If we've explicitly disabled it, don't route anything ! */ if ( ddp_forward == 0 ) { m_freem( m ); return; } ! /* ! * If the cached forwarding route is still valid, use it. ! */ ! if ( forwro.ro_rt ! && ( satosat(&forwro.ro_dst)->sat_addr.s_net != to.sat_addr.s_net ! || satosat(&forwro.ro_dst)->sat_addr.s_node != to.sat_addr.s_node )) { RTFREE( forwro.ro_rt ); forwro.ro_rt = (struct rtentry *)0; } ! ! /* ! * If we don't have a cached one (any more) or it's useless, ! * Then get a new route. ! * XXX this could cause a 'route leak'. check this! ! */ ! if ( forwro.ro_rt == (struct rtentry *)0 ! || forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) { forwro.ro_dst.sa_len = sizeof( struct sockaddr_at ); forwro.ro_dst.sa_family = AF_APPLETALK; ! satosat(&forwro.ro_dst)->sat_addr.s_net = to.sat_addr.s_net; ! satosat(&forwro.ro_dst)->sat_addr.s_node = to.sat_addr.s_node; ! rtalloc(&forwro); } ! /* ! * If it's not going to get there on this hop, and it's ! * already done too many hops, then throw it away. ! */ ! if ( (to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net) ! && (ddpe.deh_hops == DDP_MAXHOPS) ) { m_freem( m ); return; } ! /* ! * A ddp router might use the same interface ! * to forward the packet, which this would not effect. ! * Don't allow packets to cross from one interface to another however. ! */ ! if ( ddp_firewall ! && ( (forwro.ro_rt == NULL) ! || (forwro.ro_rt->rt_ifp != ifp))) { m_freem( m ); return; } + /* + * Adjust the header. + * If it was a short header then it would have not gotten here, + * so we can assume there is room to drop the header in. + * XXX what about promiscuous mode, etc... + */ ddpe.deh_hops++; ddpe.deh_bytes = htonl( ddpe.deh_bytes ); bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_short )); /* XXX deh? */ *************** *** 284,292 **** --- 359,374 ---- return; } + /* + * It was for us, and we have an ifaddr to use with it. + */ from.sat_len = sizeof( struct sockaddr_at ); from.sat_family = AF_APPLETALK; + /* + * We are no longer interested in the link layer. + * so cut it off. + */ if ( elh ) { m_adj( m, sizeof( struct ddpshdr )); } else { *************** *** 298,318 **** --- 380,415 ---- m_adj( m, sizeof( struct ddpehdr )); } + /* + * Search for ddp protocol control blocks that match these + * addresses. + */ if (( ddp = ddp_search( &from, &to, aa )) == NULL ) { m_freem( m ); return; } + /* + * If we found one, deliver th epacket to the socket + */ if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr *)&from, m, (struct mbuf *)0 ) == 0 ) { + /* + * If the socket is full (or similar error) dump the packet. + */ ddpstat.ddps_nosockspace++; m_freem( m ); return; } + /* + * And wake up whatever might be waiting for it + */ sorwakeup( ddp->ddp_socket ); } #if 0 + /* As if we haven't got enough of this sort of think floating + around the kernel :) */ #define BPXLEN 48 #define BPALEN 16 Index: netatalk/ddp_output.c =================================================================== RCS file: /home/ncvs/src/sys/netatalk/ddp_output.c,v retrieving revision 1.3.2.1 diff -c -r1.3.2.1 ddp_output.c *** ddp_output.c 1997/10/05 21:41:06 1.3.2.1 --- ddp_output.c 1997/10/28 08:14:08 *************** *** 128,138 **** if ( (ro->ro_rt != NULL) && ( ro->ro_rt->rt_ifa ) && ( ifp = ro->ro_rt->rt_ifa->ifa_ifp )) { ! net = satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net; for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { if (((net == 0) || (aa->aa_ifp == ifp)) && ! ntohs( net ) >= ntohs( aa->aa_firstnet ) && ! ntohs( net ) <= ntohs( aa->aa_lastnet )) { break; } } --- 128,138 ---- if ( (ro->ro_rt != NULL) && ( ro->ro_rt->rt_ifa ) && ( ifp = ro->ro_rt->rt_ifa->ifa_ifp )) { ! net = ntohs(satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net); for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { if (((net == 0) || (aa->aa_ifp == ifp)) && ! net >= ntohs( aa->aa_firstnet ) && ! net <= ntohs( aa->aa_lastnet )) { break; } }