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);