Okay, that one is just a little too strong.  It won't allow
a FreeBSD token-ring station to arp-reply to an ethernet station
on the other side of a "broken" translational bridge.  This one
will.

Larry Lile
l...@stdio.com

On Wed, 14 Apr 1999, Larry Lile wrote:

> 
> The problem Mr. Pallfreeman was seeing are related to how I was
> building the arp-reply based on the sources arp_hrd type.  I never
> expected to see a token-ring arp arrive over an ethernet interface.
> Therefore the arp code was trying to check for and collect the 
> source route that the arp took on its way.  I have modified the
> arp code to go looking for the source-route information only if
> the arp comes from a token-ring station and is received on a 
> token-ring interface.  The arp-reply packet generated is based
> on the type of interface the arp was received on.  I think
> the bridge should have changed the arp_hrd type when it forwarded
> the packet, while it was changing everything else, but I think
> that falls into a religous debate.  Thanks to Mr. Pallfreeman
> for helping me debug this and testing my patch.
> 
> What this means is: you should be able to arp in both directions
> over a token-ring<->ethernet (translational|non-translational) bridge.
> 
> The inherent "brokenness" of translational bridging is left as an
> exercise for the reader :)
> 
> Here's the patch, if someone would be kind enough to commit it.  It
> seems to have resolved Mr. Pallfreeman's issue and doesn't seem to
> break anything else.
> 
> Larry Lile
> l...@stdio.com
> 
*** if_ether.c.orig     Mon Mar  8 13:22:41 1999
--- if_ether.c  Wed Apr 14 14:43:41 1999
***************
*** 559,566 ****
                (void)memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
                sdl->sdl_alen = sizeof(ea->arp_sha);
                  sdl->sdl_rcf = NULL;
!               /* Save source routing information for Token-ring interfaces, 
if available */
!               if (ea->arp_hrd == htons(ARPHRD_IEEE802)) {
                        th = (struct iso88025_header *)m->m_pkthdr.header;
                        if ((th->iso88025_shost[0] & 0x80) && (((ntohs(th->rcf) 
& 0x1f00) >> 8) > 2)) {
                                sdl->sdl_rcf = ntohs(th->rcf) & 0x0080 ? 
--- 559,568 ----
                (void)memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
                sdl->sdl_alen = sizeof(ea->arp_sha);
                  sdl->sdl_rcf = NULL;
!               /* If we receive an arp from a token-ring station over a 
token-ring nic
!                * then try to save the source routing info.
!                */
!               if (ac->ac_if.if_type == IFT_ISO88025) {
                        th = (struct iso88025_header *)m->m_pkthdr.header;
                        if ((th->iso88025_shost[0] & 0x80) && (((ntohs(th->rcf) 
& 0x1f00) >> 8) > 2)) {
                                sdl->sdl_rcf = ntohs(th->rcf) & 0x0080 ? 
***************
*** 577,582 ****
--- 579,586 ----
                        }
                        th->rcf = sdl->sdl_rcf;
                        
+               } else {
+                       sdl->sdl_rcf = NULL;
                }
                if (rt->rt_expire)
                        rt->rt_expire = time_second + arpt_keep;
***************
*** 646,653 ****
        (void)memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
        ea->arp_op = htons(ARPOP_REPLY);
        ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
!       switch (ntohs(ea->arp_hrd)) {
!       case ARPHRD_IEEE802:
                /* Re-arrange the source/dest address */
                memcpy(th->iso88025_dhost, th->iso88025_shost, 
sizeof(th->iso88025_dhost));
                memcpy(th->iso88025_shost, ac->ac_enaddr, 
sizeof(th->iso88025_shost));
--- 650,657 ----
        (void)memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
        ea->arp_op = htons(ARPOP_REPLY);
        ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
!       switch (ac->ac_if.if_type) {
!       case IFT_ISO88025:
                /* Re-arrange the source/dest address */
                memcpy(th->iso88025_dhost, th->iso88025_shost, 
sizeof(th->iso88025_dhost));
                memcpy(th->iso88025_shost, ac->ac_enaddr, 
sizeof(th->iso88025_shost));
***************
*** 662,668 ****
                sa.sa_data[(sizeof(th->iso88025_dhost) * 2)] = 0x10;
                sa.sa_data[(sizeof(th->iso88025_dhost) * 2) + 1] = 0x40;
                break;
!       case ARPHRD_ETHER:
                eh = (struct ether_header *)sa.sa_data;
                (void)memcpy(eh->ether_dhost, ea->arp_tha, 
sizeof(eh->ether_dhost));
                eh->ether_type = htons(ETHERTYPE_ARP);
--- 666,672 ----
                sa.sa_data[(sizeof(th->iso88025_dhost) * 2)] = 0x10;
                sa.sa_data[(sizeof(th->iso88025_dhost) * 2) + 1] = 0x40;
                break;
!       case IFT_ETHER:
                eh = (struct ether_header *)sa.sa_data;
                (void)memcpy(eh->ether_dhost, ea->arp_tha, 
sizeof(eh->ether_dhost));
                eh->ether_type = htons(ETHERTYPE_ARP);

Reply via email to