Index: netatalk/aarp.c
===================================================================
RCS file: /cvsroot/src/sys/netatalk/aarp.c,v
retrieving revision 1.35
diff -u -r1.35 aarp.c
--- netatalk/aarp.c	8 May 2011 13:51:31 -0000	1.35
+++ netatalk/aarp.c	10 Jul 2011 14:20:11 -0000
@@ -222,10 +222,18 @@
 		ea->aarp_tpa = sat->sat_addr.s_node;
 	}
 
+	/* If we're talking to ourselves, use the loopback interface. */
+	if(AA_SAT(aa)->sat_addr.s_net == sat->sat_addr.s_net &&
+	   AA_SAT(aa)->sat_addr.s_node == sat->sat_addr.s_node)
+	   ifp = lo0ifp;
+
 #ifdef NETATALKDEBUG
-	printf("aarp: sending request via %u.%u seaking %u.%u\n",
-	    ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node,
-	    ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
+	printf("aarp: sending request via %u.%u through %s seeking %u.%u\n",
+            ntohs(AA_SAT(aa)->sat_addr.s_net),
+            AA_SAT(aa)->sat_addr.s_node,
+	    ifp->if_xname,
+            ntohs(sat->sat_addr.s_net),
+            sat->sat_addr.s_node);
 #endif	/* NETATALKDEBUG */
 
 	sa.sa_len = sizeof(struct sockaddr);
Index: netatalk/ddp_output.c
===================================================================
RCS file: /cvsroot/src/sys/netatalk/ddp_output.c,v
retrieving revision 1.14
diff -u -r1.14 ddp_output.c
--- netatalk/ddp_output.c	6 Apr 2008 18:46:56 -0000	1.14
+++ netatalk/ddp_output.c	10 Jul 2011 14:20:11 -0000
@@ -128,20 +128,43 @@
 	struct elaphdr *elh;
 	struct at_ifaddr *aa = NULL;
 	struct ifnet   *ifp = NULL;
-	u_short         net;
+	uint16_t        net;
+	uint8_t         node;
+	uint8_t         loopback = 0;
 
 	if ((rt = rtcache_validate(ro)) != NULL && (ifp = rt->rt_ifp) != NULL) {
+		const struct sockaddr_at *dst = satocsat(rtcache_getdst(ro));
+		uint16_t dnet = dst->sat_addr.s_net;
+		uint8_t dnode = dst->sat_addr.s_node;
 		net = satosat(rt->rt_gateway)->sat_addr.s_net;
+		node = satosat(rt->rt_gateway)->sat_addr.s_node;
+
 		TAILQ_FOREACH(aa, &at_ifaddr, aa_list) {
-			if (aa->aa_ifp == ifp &&
-			    ntohs(net) >= ntohs(aa->aa_firstnet) &&
+			if (ntohs(net) >= ntohs(aa->aa_firstnet) &&
 			    ntohs(net) <= ntohs(aa->aa_lastnet)) {
+				/* Are we talking to ourselves? */
+				if(dnet == aa->aa_addr.sat_addr.s_net &&
+				   dnode == aa->aa_addr.sat_addr.s_node)
+				{
+					/* If to us, redirect to lo0. */
+					ifp = lo0ifp;
+				}
+				/* Or is it a broadcast? */
+				else if(dnet == aa->aa_addr.sat_addr.s_net &&
+					dnode == 255)
+				{
+					/* If broadcast, loop back a copy. */
+					loopback = 1;
+				}
 				break;
 			}
 		}
 	}
 	if (aa == NULL) {
+		#ifdef NETATALKDEBUG
 		printf("%s: no address found\n", __func__);
+		#endif
+
 		m_freem(m);
 		return EINVAL;
 	}
@@ -184,5 +207,16 @@
 #endif
 
 	/* XXX */
+	if(loopback && rtcache_getdst(ro)->sa_family == AF_APPLETALK)
+	{
+		struct mbuf *copym = m_copypacket(m, M_DONTWAIT);
+		
+		#ifdef NETATALKDEBUG
+		printf("Looping back (not AARP).\n");
+		#endif
+
+		looutput(lo0ifp, copym, rtcache_getdst(ro), NULL);
+	}
+
 	return (*ifp->if_output)(ifp, m, (struct sockaddr *)&gate, NULL);
 }
