xref: /netbsd-src/sys/netatalk/aarp.c (revision 481d3881954fd794ca5f2d880b68c53a5db8620e)
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@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
aarptimer(void * ignored)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 *
at_ifawithnet(const struct sockaddr_at * sat,struct ifnet * ifp)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
aarpwhohas(struct ifnet * ifp,const struct sockaddr_at * sat)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
aarpresolve(struct ifnet * ifp,struct mbuf * m,const struct sockaddr_at * destsat,u_char * desten)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
aarpinput(struct ifnet * ifp,struct mbuf * m)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
at_aarpinput(struct ifnet * ifp,struct mbuf * m)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
aarptfree(struct aarptab * aat)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 *
aarptnew(const struct at_addr * addr)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
aarpprobe(void * arp)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