Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Apr 1999 13:54:05 -0400 (EDT)
From:      Larry Lile <lile@stdio.com>
To:        ip@mcc.ac.uk
Cc:        current@FreeBSD.ORG
Subject:   Patch to fix [Re: Bad, reliable crash: Julian's "oltr" stuff & ARP]
Message-ID:  <Pine.BSF.4.05.9904141308310.3818-200000@heathers.stdio.com>
In-Reply-To: <199904121605.RAA47641@albatross.mcc.ac.uk>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]

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
lile@stdio.com

[-- Attachment #2 --]
*** 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);
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9904141308310.3818-200000>