Home | History | Annotate | Line # | Download | only in netatalk
      1 /*	$NetBSD: aarp.c,v 1.47 2024/07/05 04:31:53 rin Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1990,1991 Regents of The University of Michigan.
      5  * All Rights Reserved.
      6  *
      7  * Permission to use, copy, modify, and distribute this software and
      8  * its documentation for any purpose and without fee is hereby granted,
      9  * provided that the above copyright notice appears in all copies and
     10  * that both that copyright notice and this permission notice appear
     11  * in supporting documentation, and that the name of The University
     12  * of Michigan not be used in advertising or publicity pertaining to
     13  * distribution of the software without specific, written prior
     14  * permission. This software is supplied as is without expressed or
     15  * implied warranties of any kind.
     16  *
     17  * This product includes software developed by the University of
     18  * California, Berkeley and its contributors.
     19  *
     20  *	Research Systems Unix Group
     21  *	The University of Michigan
     22  *	c/o Wesley Craig
     23  *	535 W. William Street
     24  *	Ann Arbor, Michigan
     25  *	+1-313-764-2278
     26  *	netatalk (at) umich.edu
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: aarp.c,v 1.47 2024/07/05 04:31:53 rin Exp $");
     31 
     32 #include "opt_mbuftrace.h"
     33 #include "opt_atalk.h"
     34 
     35 #include <sys/param.h>
     36 #include <sys/socket.h>
     37 #include <sys/syslog.h>
     38 #include <sys/systm.h>
     39 #include <sys/callout.h>
     40 #include <sys/proc.h>
     41 #include <sys/mbuf.h>
     42 #include <sys/time.h>
     43 #include <sys/kernel.h>
     44 #include <sys/socketvar.h>
     45 #include <net/if.h>
     46 #include <net/route.h>
     47 #include <net/if_ether.h>
     48 #include <net/if_dl.h>
     49 #include <netinet/in.h>
     50 #undef s_net
     51 
     52 #include <netatalk/at.h>
     53 #include <netatalk/at_var.h>
     54 #include <netatalk/aarp.h>
     55 #include <netatalk/ddp_var.h>
     56 #include <netatalk/phase2.h>
     57 #include <netatalk/at_extern.h>
     58 
     59 static struct aarptab *aarptnew(const struct at_addr *);
     60 static void aarptfree(struct aarptab *);
     61 static void at_aarpinput(struct ifnet *, struct mbuf *);
     62 static void aarptimer(void *);
     63 static void aarpwhohas(struct ifnet *, const struct sockaddr_at *);
     64 
     65 #define AARPTAB_BSIZ	9
     66 #define AARPTAB_NB	19
     67 #define AARPTAB_SIZE	(AARPTAB_BSIZ * AARPTAB_NB)
     68 struct aarptab  aarptab[AARPTAB_SIZE];
     69 
     70 #define AARPTAB_HASH(a) \
     71     ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
     72 
     73 #define AARPTAB_LOOK(aat, addr) { 				\
     74 	int n;							\
     75 								\
     76 	(aat) = &aarptab[AARPTAB_HASH(addr) * AARPTAB_BSIZ];	\
     77 	for (n = 0; n < AARPTAB_BSIZ; n++, (aat)++) {		\
     78 		if ((aat)->aat_ataddr.s_net == (addr).s_net &&	\
     79 	            (aat)->aat_ataddr.s_node == (addr).s_node)	\
     80 			break;					\
     81 	}							\
     82 	if (n >= AARPTAB_BSIZ) {				\
     83 		(aat) = 0;					\
     84 	}							\
     85 }
     86 
     87 #define AARPT_AGE	(60 * 1)
     88 #define AARPT_KILLC	20
     89 #define AARPT_KILLI	3
     90 
     91 const u_char atmulticastaddr[6] = {
     92 	0x09, 0x00, 0x07, 0xff, 0xff, 0xff
     93 };
     94 
     95 const u_char at_org_code[3] = {
     96 	0x08, 0x00, 0x07
     97 };
     98 const u_char aarp_org_code[3] = {
     99 	0x00, 0x00, 0x00
    100 };
    101 
    102 struct callout aarptimer_callout;
    103 #ifdef MBUFTRACE
    104 struct mowner aarp_mowner = MOWNER_INIT("atalk", "arp");
    105 #endif
    106 
    107 /*ARGSUSED*/
    108 static void
    109 aarptimer(void *ignored)
    110 {
    111 	struct aarptab *aat;
    112 	int             i, s;
    113 
    114 	mutex_enter(softnet_lock);
    115 	callout_reset(&aarptimer_callout, AARPT_AGE * hz, aarptimer, NULL);
    116 	aat = aarptab;
    117 	for (i = 0; i < AARPTAB_SIZE; i++, aat++) {
    118 		int killtime = (aat->aat_flags & ATF_COM) ? AARPT_KILLC :
    119 		    AARPT_KILLI;
    120 		if (aat->aat_flags == 0 || (aat->aat_flags & ATF_PERM))
    121 			continue;
    122 		if (++aat->aat_timer < killtime)
    123 			continue;
    124 		s = splnet();
    125 		aarptfree(aat);
    126 		splx(s);
    127 	}
    128 	mutex_exit(softnet_lock);
    129 }
    130 
    131 /*
    132  * search through the network addresses to find one that includes the given
    133  * network.. remember to take netranges into consideration.
    134  */
    135 struct ifaddr *
    136 at_ifawithnet(const struct sockaddr_at *sat, struct ifnet *ifp)
    137 {
    138 	struct ifaddr *ifa;
    139 	struct sockaddr_at *sat2;
    140 	struct netrange *nr;
    141 
    142 	IFADDR_READER_FOREACH(ifa, ifp) {
    143 		if (ifa->ifa_addr->sa_family != AF_APPLETALK)
    144 			continue;
    145 
    146 		sat2 = satosat(ifa->ifa_addr);
    147 		if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
    148 			break;
    149 
    150 		nr = (struct netrange *) (sat2->sat_zero);
    151 		if ((nr->nr_phase == 2)
    152 		    && (ntohs(nr->nr_firstnet) <= ntohs(sat->sat_addr.s_net))
    153 		    && (ntohs(nr->nr_lastnet) >= ntohs(sat->sat_addr.s_net)))
    154 			break;
    155 	}
    156 
    157 	return ifa;
    158 }
    159 
    160 static void
    161 aarpwhohas(struct ifnet *ifp, const struct sockaddr_at *sat)
    162 {
    163 	struct mbuf    *m;
    164 	struct ether_header *eh;
    165 	struct ether_aarp *ea;
    166 	struct at_ifaddr *aa;
    167 	struct llc     *llc;
    168 	struct sockaddr sa;
    169 
    170 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
    171 		return;
    172 
    173 	MCLAIM(m, &aarp_mowner);
    174 	m->m_len = sizeof(*ea);
    175 	m->m_pkthdr.len = sizeof(*ea);
    176 	m_align(m, sizeof(*ea));
    177 
    178 	ea = mtod(m, struct ether_aarp *);
    179 	memset(ea, 0, sizeof(*ea));
    180 
    181 	ea->aarp_hrd = htons(AARPHRD_ETHER);
    182 	ea->aarp_pro = htons(ETHERTYPE_ATALK);
    183 	ea->aarp_hln = sizeof(ea->aarp_sha);
    184 	ea->aarp_pln = sizeof(ea->aarp_spu);
    185 	ea->aarp_op = htons(AARPOP_REQUEST);
    186 	memcpy(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha));
    187 
    188 	/*
    189          * We need to check whether the output ethernet type should
    190          * be phase 1 or 2. We have the interface that we'll be sending
    191          * the aarp out. We need to find an AppleTalk network on that
    192          * interface with the same address as we're looking for. If the
    193          * net is phase 2, generate an 802.2 and SNAP header.
    194          */
    195 	if ((aa = (struct at_ifaddr *) at_ifawithnet(sat, ifp)) == NULL) {
    196 		m_freem(m);
    197 		return;
    198 	}
    199 	eh = (struct ether_header *) sa.sa_data;
    200 
    201 	if (aa->aa_flags & AFA_PHASE2) {
    202 		memcpy(eh->ether_dhost, atmulticastaddr,
    203 		    sizeof(eh->ether_dhost));
    204 		eh->ether_type = 0;	/* if_output will treat as 802 */
    205 		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
    206 		if (!m)
    207 			return;
    208 
    209 		llc = mtod(m, struct llc *);
    210 		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
    211 		llc->llc_control = LLC_UI;
    212 		memcpy(llc->llc_org_code, aarp_org_code, sizeof(aarp_org_code));
    213 		llc->llc_ether_type = htons(ETHERTYPE_AARP);
    214 
    215 		memcpy(ea->aarp_spnet, &AA_SAT(aa)->sat_addr.s_net,
    216 		      sizeof(ea->aarp_spnet));
    217 		memcpy(ea->aarp_tpnet, &sat->sat_addr.s_net,
    218 		      sizeof(ea->aarp_tpnet));
    219 		ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node;
    220 		ea->aarp_tpnode = sat->sat_addr.s_node;
    221 	} else {
    222 		memcpy(eh->ether_dhost, etherbroadcastaddr,
    223 		    sizeof(eh->ether_dhost));
    224 		eh->ether_type = htons(ETHERTYPE_AARP);
    225 
    226 		ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node;
    227 		ea->aarp_tpa = sat->sat_addr.s_node;
    228 	}
    229 
    230 	/* If we are talking to ourselves, use the loopback interface. */
    231 	if (AA_SAT(aa)->sat_addr.s_net == sat->sat_addr.s_net &&
    232 	    AA_SAT(aa)->sat_addr.s_node == sat->sat_addr.s_node)
    233 		ifp = lo0ifp;
    234 
    235 #ifdef NETATALKDEBUG
    236 	printf("aarp: sending request via %u.%u through %s seeking %u.%u\n",
    237 	    ntohs(AA_SAT(aa)->sat_addr.s_net),
    238 	    AA_SAT(aa)->sat_addr.s_node,
    239 	    ifp->if_xname,
    240 	    ntohs(sat->sat_addr.s_net),
    241 	    sat->sat_addr.s_node);
    242 #endif /* NETATALKDEBUG */
    243 
    244 	sa.sa_len = sizeof(struct sockaddr);
    245 	sa.sa_family = AF_UNSPEC;
    246 	if_output_lock(ifp, ifp, m, &sa, NULL);	/* XXX NULL should be routing */
    247 						/* information */
    248 }
    249 
    250 int
    251 aarpresolve(struct ifnet *ifp, struct mbuf *m,
    252     const struct sockaddr_at *destsat, u_char *desten)
    253 {
    254 	struct at_ifaddr *aa;
    255 	struct aarptab *aat;
    256 	int             s;
    257 
    258 	if (at_broadcast(destsat)) {
    259 		struct ifaddr *ifa;
    260 
    261 		s = pserialize_read_enter();
    262 		ifa = at_ifawithnet(destsat, ifp);
    263 		if (ifa == NULL) {
    264 			pserialize_read_exit(s);
    265 			m_freem(m);
    266 			return (0);
    267 		}
    268 		aa = (struct at_ifaddr *)ifa;
    269 
    270 		if (aa->aa_flags & AFA_PHASE2)
    271 			memcpy(desten, atmulticastaddr,
    272 			    sizeof(atmulticastaddr));
    273 		else
    274 			memcpy(desten, etherbroadcastaddr,
    275 			    sizeof(etherbroadcastaddr));
    276 		pserialize_read_exit(s);
    277 		return 1;
    278 	}
    279 	s = splnet();
    280 	AARPTAB_LOOK(aat, destsat->sat_addr);
    281 	if (aat == 0) {		/* No entry */
    282 		aat = aarptnew(&destsat->sat_addr);
    283 		if (aat == 0)
    284 			panic("aarpresolve: no free entry");
    285 
    286 		aat->aat_hold = m;
    287 		aarpwhohas(ifp, destsat);
    288 		splx(s);
    289 		return 0;
    290 	}
    291 
    292 	/* found an entry */
    293 	aat->aat_timer = 0;
    294 	if (aat->aat_flags & ATF_COM) {	/* entry is COMplete */
    295 		memcpy(desten, aat->aat_enaddr, sizeof(aat->aat_enaddr));
    296 		splx(s);
    297 		return 1;
    298 	}
    299 
    300 	/* entry has not completed */
    301 	m_freem(aat->aat_hold);
    302 	aat->aat_hold = m;
    303 	aarpwhohas(ifp, destsat);
    304 	splx(s);
    305 
    306 	return 0;
    307 }
    308 
    309 void
    310 aarpinput(struct ifnet *ifp, struct mbuf *m)
    311 {
    312 	struct arphdr  *ar;
    313 
    314 	if (ifp->if_flags & IFF_NOARP)
    315 		goto out;
    316 
    317 	if (m->m_len < sizeof(struct arphdr))
    318 		goto out;
    319 
    320 	ar = mtod(m, struct arphdr *);
    321 	if (ntohs(ar->ar_hrd) != AARPHRD_ETHER)
    322 		goto out;
    323 
    324 	if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
    325 		goto out;
    326 
    327 	switch (ntohs(ar->ar_pro)) {
    328 	case ETHERTYPE_ATALK:
    329 		at_aarpinput(ifp, m);
    330 		return;
    331 
    332 	default:
    333 		break;
    334 	}
    335 
    336 out:
    337 	m_freem(m);
    338 }
    339 
    340 static void
    341 at_aarpinput(struct ifnet *ifp, struct mbuf *m)
    342 {
    343 	struct ether_aarp *ea;
    344 	struct at_ifaddr *aa;
    345 	struct aarptab *aat;
    346 	struct ether_header *eh;
    347 	struct llc     *llc;
    348 	struct sockaddr_at sat;
    349 	struct sockaddr sa;
    350 	struct at_addr  spa, tpa, ma;
    351 	int             op;
    352 	u_int16_t       net;
    353 	int		s;
    354 	struct psref	psref;
    355 	struct ifaddr *ifa;
    356 
    357 	/* We should also check ar_hln and ar_pln. */
    358 	if ((m = m_pullup(m, sizeof(struct ether_aarp))) == NULL) {
    359 		return;
    360 	}
    361 
    362 	ea = mtod(m, struct ether_aarp *);
    363 
    364 	/* Check to see if from my hardware address */
    365 	if (!memcmp(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha))) {
    366 		m_freem(m);
    367 		return;
    368 	}
    369 	op = ntohs(ea->aarp_op);
    370 	memcpy(&net, ea->aarp_tpnet, sizeof(net));
    371 
    372 	if (net != 0) {		/* should be ATADDR_ANYNET? */
    373 		sat.sat_len = sizeof(struct sockaddr_at);
    374 		sat.sat_family = AF_APPLETALK;
    375 		sat.sat_addr.s_net = net;
    376 
    377 		s = pserialize_read_enter();
    378 		ifa = at_ifawithnet(&sat, ifp);
    379 		if (ifa == NULL) {
    380 			pserialize_read_exit(s);
    381 			m_freem(m);
    382 			return;
    383 		}
    384 		ifa_acquire(ifa, &psref);
    385 		pserialize_read_exit(s);
    386 		aa = (struct at_ifaddr *)ifa;
    387 
    388 		memcpy(&spa.s_net, ea->aarp_spnet, sizeof(spa.s_net));
    389 		memcpy(&tpa.s_net, ea->aarp_tpnet, sizeof(tpa.s_net));
    390 	} else {
    391 		/*
    392 		 * Since we don't know the net, we just look for the first
    393 		 * phase 1 address on the interface.
    394 		 */
    395 		s = pserialize_read_enter();
    396 		IFADDR_READER_FOREACH(ifa, ifp) {
    397 			aa = (struct at_ifaddr *)ifa;
    398 			if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
    399 			    (aa->aa_flags & AFA_PHASE2) == 0) {
    400 				ifa_acquire(ifa, &psref);
    401 				break;
    402 			}
    403 		}
    404 		pserialize_read_exit(s);
    405 
    406 		if (ifa == NULL) {
    407 			m_freem(m);
    408 			return;
    409 		}
    410 		tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net;
    411 	}
    412 
    413 	spa.s_node = ea->aarp_spnode;
    414 	tpa.s_node = ea->aarp_tpnode;
    415 	ma.s_net = AA_SAT(aa)->sat_addr.s_net;
    416 	ma.s_node = AA_SAT(aa)->sat_addr.s_node;
    417 
    418 	/*
    419          * This looks like it's from us.
    420          */
    421 	if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) {
    422 		if (aa->aa_flags & AFA_PROBING) {
    423 			/*
    424 		         * We're probing, someone either responded to our
    425 			 * probe, or probed for the same address we'd like
    426 			 * to use. Change the address we're probing for.
    427 		         */
    428 			callout_stop(&aa->aa_probe_ch);
    429 			wakeup(aa);
    430 			m_freem(m);
    431 			goto out;
    432 		} else if (op != AARPOP_PROBE) {
    433 			/*
    434 		         * This is not a probe, and we're not probing.
    435 			 * This means that someone's saying they have the same
    436 			 * source address as the one we're using. Get upset...
    437 		         */
    438 			log(LOG_ERR, "aarp: duplicate AT address!! %s\n",
    439 			    ether_sprintf(ea->aarp_sha));
    440 			m_freem(m);
    441 			goto out;
    442 		}
    443 	}
    444 	AARPTAB_LOOK(aat, spa);
    445 	if (aat) {
    446 		if (op == AARPOP_PROBE) {
    447 			/*
    448 		         * Someone's probing for spa, deallocate the one we've
    449 			 * got, so that if the prober keeps the address, we'll
    450 			 * be able to arp for him.
    451 		         */
    452 			aarptfree(aat);
    453 			m_freem(m);
    454 			goto out;
    455 		}
    456 		memcpy(aat->aat_enaddr, ea->aarp_sha, sizeof(ea->aarp_sha));
    457 		aat->aat_flags |= ATF_COM;
    458 		if (aat->aat_hold) {
    459 			sat.sat_len = sizeof(struct sockaddr_at);
    460 			sat.sat_family = AF_APPLETALK;
    461 			sat.sat_addr = spa;
    462 			if_output_lock(ifp, ifp, aat->aat_hold,
    463 			    (struct sockaddr *) & sat, NULL);	/* XXX */
    464 			aat->aat_hold = 0;
    465 		}
    466 	}
    467 	if (aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node
    468 	    && op != AARPOP_PROBE) {
    469 		if ((aat = aarptnew(&spa)) != NULL) {
    470 			memcpy(aat->aat_enaddr, ea->aarp_sha,
    471 			    sizeof(ea->aarp_sha));
    472 			aat->aat_flags |= ATF_COM;
    473 		}
    474 	}
    475 	/*
    476          * Don't respond to responses, and never respond if we're
    477          * still probing.
    478          */
    479 	if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
    480 	    op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) {
    481 		m_freem(m);
    482 		goto out;
    483 	}
    484 
    485 	/*
    486 	 * Prepare and send AARP-response.
    487 	 */
    488 	m->m_len = sizeof(*ea);
    489 	m->m_pkthdr.len = sizeof(*ea);
    490 	memcpy(ea->aarp_tha, ea->aarp_sha, sizeof(ea->aarp_sha));
    491 	memcpy(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha));
    492 
    493 	/* XXX */
    494 	eh = (struct ether_header *) sa.sa_data;
    495 	memcpy(eh->ether_dhost, ea->aarp_tha, sizeof(eh->ether_dhost));
    496 
    497 	if (aa->aa_flags & AFA_PHASE2) {
    498 		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
    499 		if (m == NULL)
    500 			goto out;
    501 
    502 		llc = mtod(m, struct llc *);
    503 		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
    504 		llc->llc_control = LLC_UI;
    505 		memcpy(llc->llc_org_code, aarp_org_code, sizeof(aarp_org_code));
    506 		llc->llc_ether_type = htons(ETHERTYPE_AARP);
    507 
    508 		memcpy(ea->aarp_tpnet, ea->aarp_spnet, sizeof(ea->aarp_tpnet));
    509 		memcpy(ea->aarp_spnet, &ma.s_net, sizeof(ea->aarp_spnet));
    510 		eh->ether_type = 0;	/* if_output will treat as 802 */
    511 	} else {
    512 		eh->ether_type = htons(ETHERTYPE_AARP);
    513 	}
    514 
    515 	ea->aarp_tpnode = ea->aarp_spnode;
    516 	ea->aarp_spnode = ma.s_node;
    517 	ea->aarp_op = htons(AARPOP_RESPONSE);
    518 
    519 	sa.sa_len = sizeof(struct sockaddr);
    520 	sa.sa_family = AF_UNSPEC;
    521 	(*ifp->if_output) (ifp, m, &sa, NULL);	/* XXX */
    522 out:
    523 	ifa_release(ifa, &psref);
    524 	return;
    525 }
    526 
    527 static void
    528 aarptfree(struct aarptab *aat)
    529 {
    530 
    531 	m_freem(aat->aat_hold);
    532 	aat->aat_hold = 0;
    533 	aat->aat_timer = aat->aat_flags = 0;
    534 	aat->aat_ataddr.s_net = 0;
    535 	aat->aat_ataddr.s_node = 0;
    536 }
    537 
    538 static struct aarptab *
    539 aarptnew(const struct at_addr *addr)
    540 {
    541 	int             n;
    542 	int             oldest = -1;
    543 	struct aarptab *aat, *aato = NULL;
    544 	static int      first = 1;
    545 
    546 	if (first) {
    547 		first = 0;
    548 		callout_init(&aarptimer_callout, 0);
    549 		callout_reset(&aarptimer_callout, hz, aarptimer, NULL);
    550 	}
    551 	aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ];
    552 	for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {
    553 		if (aat->aat_flags == 0)
    554 			goto out;
    555 		if (aat->aat_flags & ATF_PERM)
    556 			continue;
    557 		if ((int) aat->aat_timer > oldest) {
    558 			oldest = aat->aat_timer;
    559 			aato = aat;
    560 		}
    561 	}
    562 	if (aato == NULL)
    563 		return (NULL);
    564 	aat = aato;
    565 	aarptfree(aat);
    566 out:
    567 	aat->aat_ataddr = *addr;
    568 	aat->aat_flags = ATF_INUSE;
    569 	return (aat);
    570 }
    571 
    572 
    573 void
    574 aarpprobe(void *arp)
    575 {
    576 	struct mbuf    *m;
    577 	struct ether_header *eh;
    578 	struct ether_aarp *ea;
    579 	struct ifaddr *ia;
    580 	struct at_ifaddr *aa;
    581 	struct llc     *llc;
    582 	struct sockaddr sa;
    583 	struct ifnet   *ifp = arp;
    584 
    585 	mutex_enter(softnet_lock);
    586 
    587 	/*
    588          * We need to check whether the output ethernet type should
    589          * be phase 1 or 2. We have the interface that we'll be sending
    590          * the aarp out. We need to find an AppleTalk network on that
    591          * interface with the same address as we're looking for. If the
    592          * net is phase 2, generate an 802.2 and SNAP header.
    593          */
    594 	IFADDR_READER_FOREACH(ia, ifp) {
    595 		aa = (struct at_ifaddr *)ia;
    596 		if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
    597 		    (aa->aa_flags & AFA_PROBING))
    598 			break;
    599 	}
    600 	if (ia == NULL) {	/* serious error XXX */
    601 		printf("aarpprobe why did this happen?!\n");
    602 		mutex_exit(softnet_lock);
    603 		return;
    604 	}
    605 	if (aa->aa_probcnt <= 0) {
    606 		aa->aa_flags &= ~AFA_PROBING;
    607 		wakeup(aa);
    608 		mutex_exit(softnet_lock);
    609 		return;
    610 	} else {
    611 		callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp);
    612 	}
    613 
    614 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) {
    615 		mutex_exit(softnet_lock);
    616 		return;
    617 	}
    618 
    619 	MCLAIM(m, &aarp_mowner);
    620 	m->m_len = sizeof(*ea);
    621 	m->m_pkthdr.len = sizeof(*ea);
    622 	m_align(m, sizeof(*ea));
    623 
    624 	ea = mtod(m, struct ether_aarp *);
    625 	memset(ea, 0, sizeof(*ea));
    626 
    627 	ea->aarp_hrd = htons(AARPHRD_ETHER);
    628 	ea->aarp_pro = htons(ETHERTYPE_ATALK);
    629 	ea->aarp_hln = sizeof(ea->aarp_sha);
    630 	ea->aarp_pln = sizeof(ea->aarp_spu);
    631 	ea->aarp_op = htons(AARPOP_PROBE);
    632 	memcpy(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha));
    633 
    634 	eh = (struct ether_header *) sa.sa_data;
    635 
    636 	if (aa->aa_flags & AFA_PHASE2) {
    637 		memcpy(eh->ether_dhost, atmulticastaddr,
    638 		    sizeof(eh->ether_dhost));
    639 		eh->ether_type = 0;	/* if_output will treat as 802 */
    640 		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
    641 		if (!m) {
    642 			mutex_exit(softnet_lock);
    643 			return;
    644 		}
    645 
    646 		llc = mtod(m, struct llc *);
    647 		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
    648 		llc->llc_control = LLC_UI;
    649 		memcpy(llc->llc_org_code, aarp_org_code, sizeof(aarp_org_code));
    650 		llc->llc_ether_type = htons(ETHERTYPE_AARP);
    651 
    652 		memcpy(ea->aarp_spnet, &AA_SAT(aa)->sat_addr.s_net,
    653 		      sizeof(ea->aarp_spnet));
    654 		memcpy(ea->aarp_tpnet, &AA_SAT(aa)->sat_addr.s_net,
    655 		      sizeof(ea->aarp_tpnet));
    656 		ea->aarp_spnode = ea->aarp_tpnode =
    657 		    AA_SAT(aa)->sat_addr.s_node;
    658 	} else {
    659 		memcpy(eh->ether_dhost, etherbroadcastaddr,
    660 		    sizeof(eh->ether_dhost));
    661 		eh->ether_type = htons(ETHERTYPE_AARP);
    662 		ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
    663 	}
    664 
    665 #ifdef NETATALKDEBUG
    666 	printf("aarp: sending probe for %u.%u\n",
    667 	       ntohs(AA_SAT(aa)->sat_addr.s_net),
    668 	       AA_SAT(aa)->sat_addr.s_node);
    669 #endif	/* NETATALKDEBUG */
    670 
    671 	sa.sa_len = sizeof(struct sockaddr);
    672 	sa.sa_family = AF_UNSPEC;
    673 	(*ifp->if_output) (ifp, m, &sa, NULL);	/* XXX */
    674 	aa->aa_probcnt--;
    675 	mutex_exit(softnet_lock);
    676 }
    677