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     Wed Apr 14 09:54:35 1999
--- if_ether.c  Wed Apr 14 12:50:02 1999
***************
*** 560,567 ****
                (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 ? 
--- 560,569 ----
                (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) && (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 ? 
***************
*** 578,583 ****
--- 580,587 ----
                        }
                        th->rcf = sdl->sdl_rcf;
                        
+               } else {
+                       sdl->sdl_rcf = NULL;
                }
                if (rt->rt_expire)
                        rt->rt_expire = time_second + arpt_keep;
***************
*** 647,654 ****
        (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));
--- 651,658 ----
        (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));
***************
*** 663,669 ****
                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);
--- 667,673 ----
                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