Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Aug 1998 00:43:55 +0200 (CEST)
From:      Stefan Bethke <stb@hanse.de>
To:        Julian Elischer <julian@whistle.com>
Cc:        Parag Patel <parag@cgt.com>, current@FreeBSD.ORG
Subject:   Re: Netatalk name-registering problem with -current
Message-ID:  <Pine.BSF.3.96.980805003231.1544A-100000@transit.hanse.de>
In-Reply-To: <Pine.BSF.3.96.980803224405.10187B-100000@transit.hanse.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 4 Aug 1998, Stefan Bethke wrote:

> On Sat, 1 Aug 1998, Julian Elischer wrote:
> 
> > yes there is a problem with -current and netatalk name registration.
> > 
> > it's on my list of things to look at..
> > there are two suspicious areas..
> 
> I've delved a bit into this and think I've found the problem.
> 
> In net/ether_output, around line 365, if_simloop() is called with a fixed
> LLC header length of ETHER_HDR_LEN, instead of whatever length the header
> has (in case of a SNAP frame [Phase 2], its a LLC header).

There's a second problem: because packets for our own address are handed to
ether_output, an aarpresolve() is tried. As it seems to me, our own MAC
address isn't in the table, so a request goes out and is received by
aarp_input(). aarp_input() however doesn't respond to requests coming from
the address of the interface it was received from; so the packet is never
delivered.

The quick workaround is to call if_simloop() from ddp_output.

The right thing to do would be to integrate AARP into the routing tables
(as for ARP). If I could only figure out how this whole stuff works...

Enought muttering: please test the following patch. At least you can
successfully register, deregister, and query NBPs again; because my oldish
IIcx went up in smoke the last night I have nothing to really test it
against.

--------- snip ----------

Index: src/sys/net/if_ethersubr.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.51
diff -u -r1.51 if_ethersubr.c
--- if_ethersubr.c	1998/06/14 20:58:14	1.51
+++ if_ethersubr.c	1998/08/04 20:13:12
@@ -132,6 +132,7 @@
 	register struct rtentry *rt;
 	register struct ether_header *eh;
 	int off, len = m->m_pkthdr.len, loop_copy = 0;
+	int hlen;	/* link layer header lenght */
 	struct arpcom *ac = (struct arpcom *)ifp;
 
 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
@@ -161,6 +162,7 @@
 			    time_second < rt->rt_rmx.rmx_expire)
 				senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
 	}
+	hlen = ETHER_HDR_LEN;
 	switch (dst->sa_family) {
 #ifdef INET
 	case AF_INET:
@@ -203,6 +205,7 @@
 		llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
 		bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
 		type = htons(m->m_pkthdr.len);
+		hlen = sizeof(struct llc) + ETHER_HDR_LEN;
 	    } else {
 		type = htons(ETHERTYPE_AT);
 	    }
@@ -362,10 +365,10 @@
 		if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
 			struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
 
-			(void) if_simloop(ifp, n, dst, ETHER_HDR_LEN);
+			(void) if_simloop(ifp, n, dst, hlen);
 		} else if (bcmp(eh->ether_dhost,
 		    eh->ether_shost, ETHER_ADDR_LEN) == 0) {
-			(void) if_simloop(ifp, m, dst, ETHER_HDR_LEN);
+			(void) if_simloop(ifp, m, dst, hlen);
 			return(0);	/* XXX */
 		}
 	}
Index: src/sys/netatalk/ddp_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netatalk/ddp_output.c,v
retrieving revision 1.12
diff -u -r1.12 ddp_output.c
--- ddp_output.c	1998/07/13 06:34:02	1.12
+++ ddp_output.c	1998/08/04 22:29:06
@@ -72,6 +72,11 @@
     }
     deh->deh_bytes = htonl( deh->deh_bytes );
 
+#ifdef NETATALK_DEBUG
+    printf ("ddp_output: from %d.%d:%d to %d.%d:%d\n",
+	ntohs(deh->deh_snet), deh->deh_snode, deh->deh_sport,
+	ntohs(deh->deh_dnet), deh->deh_dnode, deh->deh_dport);
+#endif
     return( ddp_route( m, &ddp->ddp_route ));
 }
 
@@ -142,13 +147,24 @@
 	}
     } else {
 	m_freem( m );
-	return( EINVAL );
+#ifdef NETATALK_DEBUG
+	if (ro->ro_rt == NULL)
+	    printf ("ddp_route: no ro_rt.\n");
+	else if (ro->ro_rt->rt_ifa == NULL)
+	    printf ("ddp_route: no ro_rt->rt_ifa\n");
+	else
+	    printf ("ddp_route: no ro_rt->rt_ifa->ifa_ifp\n");
+#endif
+	return( ENETUNREACH );
     }
 
     if ( aa == NULL ) {
-printf( "ddp_route: oops\n" );
+#ifdef NETATALK_DEBUG
+	printf( "ddp_route: no atalk address found for %s%d\n", 
+	    ifp->if_name, ifp->if_unit);
+#endif
 	m_freem( m );
-	return( EINVAL );
+	return( ENETUNREACH );
     }
 
     /*
@@ -189,7 +205,24 @@
     }
     ro->ro_rt->rt_use++;
 
+#ifdef NETATALK_DEBUG
+    printf ("ddp_route: from %d.%d to %d.%d, via %d.%d (%s%d)\n",
+	ntohs(satosat(&aa->aa_addr)->sat_addr.s_net),
+	satosat(&aa->aa_addr)->sat_addr.s_node,
+	ntohs(satosat(&ro->ro_dst)->sat_addr.s_net),
+	satosat(&ro->ro_dst)->sat_addr.s_node,
+	ntohs(gate.sat_addr.s_net),
+	gate.sat_addr.s_node,
+	ifp->if_name, ifp->if_unit);
+#endif
+
+    /* short-circuit the output if we're sending this to ourself */
+    if ((satosat(&aa->aa_addr)->sat_addr.s_net  == satosat(&ro->ro_dst)->sat_addr.s_net) &&
+	(satosat(&aa->aa_addr)->sat_addr.s_node == satosat(&ro->ro_dst)->sat_addr.s_node))
+    {
+	return (if_simloop(ifp, m, (struct sockaddr *)&gate, 0));
+    }
+
     return((*ifp->if_output)( ifp,
 	m, (struct sockaddr *)&gate, NULL)); /* XXX */
 }
-

---------- snip -----------

Cheers,
Stefan

--
Stefan Bethke
Muehlendamm 12            Phone: +49-40-256848, +49-177-3504009
D-22087 Hamburg           <stefan.bethke@hanse.de>
Hamburg, Germany          <stb@freebsd.org>


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



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