xref: /netbsd-src/sys/netatalk/aarp.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /*	$NetBSD: aarp.c,v 1.46 2023/07/31 01:24:36 dholland 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.46 2023/07/31 01:24:36 dholland 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 	if (aat->aat_hold)
302 		m_freem(aat->aat_hold);
303 	aat->aat_hold = m;
304 	aarpwhohas(ifp, destsat);
305 	splx(s);
306 
307 	return 0;
308 }
309 
310 void
311 aarpinput(struct ifnet *ifp, struct mbuf *m)
312 {
313 	struct arphdr  *ar;
314 
315 	if (ifp->if_flags & IFF_NOARP)
316 		goto out;
317 
318 	if (m->m_len < sizeof(struct arphdr))
319 		goto out;
320 
321 	ar = mtod(m, struct arphdr *);
322 	if (ntohs(ar->ar_hrd) != AARPHRD_ETHER)
323 		goto out;
324 
325 	if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
326 		goto out;
327 
328 	switch (ntohs(ar->ar_pro)) {
329 	case ETHERTYPE_ATALK:
330 		at_aarpinput(ifp, m);
331 		return;
332 
333 	default:
334 		break;
335 	}
336 
337 out:
338 	m_freem(m);
339 }
340 
341 static void
342 at_aarpinput(struct ifnet *ifp, struct mbuf *m)
343 {
344 	struct ether_aarp *ea;
345 	struct at_ifaddr *aa;
346 	struct aarptab *aat;
347 	struct ether_header *eh;
348 	struct llc     *llc;
349 	struct sockaddr_at sat;
350 	struct sockaddr sa;
351 	struct at_addr  spa, tpa, ma;
352 	int             op;
353 	u_int16_t       net;
354 	int		s;
355 	struct psref	psref;
356 	struct ifaddr *ifa;
357 
358 	/* We should also check ar_hln and ar_pln. */
359 	if ((m = m_pullup(m, sizeof(struct ether_aarp))) == NULL) {
360 		return;
361 	}
362 
363 	ea = mtod(m, struct ether_aarp *);
364 
365 	/* Check to see if from my hardware address */
366 	if (!memcmp(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha))) {
367 		m_freem(m);
368 		return;
369 	}
370 	op = ntohs(ea->aarp_op);
371 	memcpy(&net, ea->aarp_tpnet, sizeof(net));
372 
373 	if (net != 0) {		/* should be ATADDR_ANYNET? */
374 		sat.sat_len = sizeof(struct sockaddr_at);
375 		sat.sat_family = AF_APPLETALK;
376 		sat.sat_addr.s_net = net;
377 
378 		s = pserialize_read_enter();
379 		ifa = at_ifawithnet(&sat, ifp);
380 		if (ifa == NULL) {
381 			pserialize_read_exit(s);
382 			m_freem(m);
383 			return;
384 		}
385 		ifa_acquire(ifa, &psref);
386 		pserialize_read_exit(s);
387 		aa = (struct at_ifaddr *)ifa;
388 
389 		memcpy(&spa.s_net, ea->aarp_spnet, sizeof(spa.s_net));
390 		memcpy(&tpa.s_net, ea->aarp_tpnet, sizeof(tpa.s_net));
391 	} else {
392 		/*
393 		 * Since we don't know the net, we just look for the first
394 		 * phase 1 address on the interface.
395 		 */
396 		s = pserialize_read_enter();
397 		IFADDR_READER_FOREACH(ifa, ifp) {
398 			aa = (struct at_ifaddr *)ifa;
399 			if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
400 			    (aa->aa_flags & AFA_PHASE2) == 0) {
401 				ifa_acquire(ifa, &psref);
402 				break;
403 			}
404 		}
405 		pserialize_read_exit(s);
406 
407 		if (ifa == NULL) {
408 			m_freem(m);
409 			return;
410 		}
411 		tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net;
412 	}
413 
414 	spa.s_node = ea->aarp_spnode;
415 	tpa.s_node = ea->aarp_tpnode;
416 	ma.s_net = AA_SAT(aa)->sat_addr.s_net;
417 	ma.s_node = AA_SAT(aa)->sat_addr.s_node;
418 
419 	/*
420          * This looks like it's from us.
421          */
422 	if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) {
423 		if (aa->aa_flags & AFA_PROBING) {
424 			/*
425 		         * We're probing, someone either responded to our
426 			 * probe, or probed for the same address we'd like
427 			 * to use. Change the address we're probing for.
428 		         */
429 			callout_stop(&aa->aa_probe_ch);
430 			wakeup(aa);
431 			m_freem(m);
432 			goto out;
433 		} else if (op != AARPOP_PROBE) {
434 			/*
435 		         * This is not a probe, and we're not probing.
436 			 * This means that someone's saying they have the same
437 			 * source address as the one we're using. Get upset...
438 		         */
439 			log(LOG_ERR, "aarp: duplicate AT address!! %s\n",
440 			    ether_sprintf(ea->aarp_sha));
441 			m_freem(m);
442 			goto out;
443 		}
444 	}
445 	AARPTAB_LOOK(aat, spa);
446 	if (aat) {
447 		if (op == AARPOP_PROBE) {
448 			/*
449 		         * Someone's probing for spa, deallocate the one we've
450 			 * got, so that if the prober keeps the address, we'll
451 			 * be able to arp for him.
452 		         */
453 			aarptfree(aat);
454 			m_freem(m);
455 			goto out;
456 		}
457 		memcpy(aat->aat_enaddr, ea->aarp_sha, sizeof(ea->aarp_sha));
458 		aat->aat_flags |= ATF_COM;
459 		if (aat->aat_hold) {
460 			sat.sat_len = sizeof(struct sockaddr_at);
461 			sat.sat_family = AF_APPLETALK;
462 			sat.sat_addr = spa;
463 			if_output_lock(ifp, ifp, aat->aat_hold,
464 			    (struct sockaddr *) & sat, NULL);	/* XXX */
465 			aat->aat_hold = 0;
466 		}
467 	}
468 	if (aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node
469 	    && op != AARPOP_PROBE) {
470 		if ((aat = aarptnew(&spa)) != NULL) {
471 			memcpy(aat->aat_enaddr, ea->aarp_sha,
472 			    sizeof(ea->aarp_sha));
473 			aat->aat_flags |= ATF_COM;
474 		}
475 	}
476 	/*
477          * Don't respond to responses, and never respond if we're
478          * still probing.
479          */
480 	if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
481 	    op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) {
482 		m_freem(m);
483 		goto out;
484 	}
485 
486 	/*
487 	 * Prepare and send AARP-response.
488 	 */
489 	m->m_len = sizeof(*ea);
490 	m->m_pkthdr.len = sizeof(*ea);
491 	memcpy(ea->aarp_tha, ea->aarp_sha, sizeof(ea->aarp_sha));
492 	memcpy(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha));
493 
494 	/* XXX */
495 	eh = (struct ether_header *) sa.sa_data;
496 	memcpy(eh->ether_dhost, ea->aarp_tha, sizeof(eh->ether_dhost));
497 
498 	if (aa->aa_flags & AFA_PHASE2) {
499 		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
500 		if (m == NULL)
501 			goto out;
502 
503 		llc = mtod(m, struct llc *);
504 		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
505 		llc->llc_control = LLC_UI;
506 		memcpy(llc->llc_org_code, aarp_org_code, sizeof(aarp_org_code));
507 		llc->llc_ether_type = htons(ETHERTYPE_AARP);
508 
509 		memcpy(ea->aarp_tpnet, ea->aarp_spnet, sizeof(ea->aarp_tpnet));
510 		memcpy(ea->aarp_spnet, &ma.s_net, sizeof(ea->aarp_spnet));
511 		eh->ether_type = 0;	/* if_output will treat as 802 */
512 	} else {
513 		eh->ether_type = htons(ETHERTYPE_AARP);
514 	}
515 
516 	ea->aarp_tpnode = ea->aarp_spnode;
517 	ea->aarp_spnode = ma.s_node;
518 	ea->aarp_op = htons(AARPOP_RESPONSE);
519 
520 	sa.sa_len = sizeof(struct sockaddr);
521 	sa.sa_family = AF_UNSPEC;
522 	(*ifp->if_output) (ifp, m, &sa, NULL);	/* XXX */
523 out:
524 	ifa_release(ifa, &psref);
525 	return;
526 }
527 
528 static void
529 aarptfree(struct aarptab *aat)
530 {
531 
532 	if (aat->aat_hold)
533 		m_freem(aat->aat_hold);
534 	aat->aat_hold = 0;
535 	aat->aat_timer = aat->aat_flags = 0;
536 	aat->aat_ataddr.s_net = 0;
537 	aat->aat_ataddr.s_node = 0;
538 }
539 
540 static struct aarptab *
541 aarptnew(const struct at_addr *addr)
542 {
543 	int             n;
544 	int             oldest = -1;
545 	struct aarptab *aat, *aato = NULL;
546 	static int      first = 1;
547 
548 	if (first) {
549 		first = 0;
550 		callout_init(&aarptimer_callout, 0);
551 		callout_reset(&aarptimer_callout, hz, aarptimer, NULL);
552 	}
553 	aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ];
554 	for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {
555 		if (aat->aat_flags == 0)
556 			goto out;
557 		if (aat->aat_flags & ATF_PERM)
558 			continue;
559 		if ((int) aat->aat_timer > oldest) {
560 			oldest = aat->aat_timer;
561 			aato = aat;
562 		}
563 	}
564 	if (aato == NULL)
565 		return (NULL);
566 	aat = aato;
567 	aarptfree(aat);
568 out:
569 	aat->aat_ataddr = *addr;
570 	aat->aat_flags = ATF_INUSE;
571 	return (aat);
572 }
573 
574 
575 void
576 aarpprobe(void *arp)
577 {
578 	struct mbuf    *m;
579 	struct ether_header *eh;
580 	struct ether_aarp *ea;
581 	struct ifaddr *ia;
582 	struct at_ifaddr *aa;
583 	struct llc     *llc;
584 	struct sockaddr sa;
585 	struct ifnet   *ifp = arp;
586 
587 	mutex_enter(softnet_lock);
588 
589 	/*
590          * We need to check whether the output ethernet type should
591          * be phase 1 or 2. We have the interface that we'll be sending
592          * the aarp out. We need to find an AppleTalk network on that
593          * interface with the same address as we're looking for. If the
594          * net is phase 2, generate an 802.2 and SNAP header.
595          */
596 	IFADDR_READER_FOREACH(ia, ifp) {
597 		aa = (struct at_ifaddr *)ia;
598 		if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
599 		    (aa->aa_flags & AFA_PROBING))
600 			break;
601 	}
602 	if (ia == NULL) {	/* serious error XXX */
603 		printf("aarpprobe why did this happen?!\n");
604 		mutex_exit(softnet_lock);
605 		return;
606 	}
607 	if (aa->aa_probcnt <= 0) {
608 		aa->aa_flags &= ~AFA_PROBING;
609 		wakeup(aa);
610 		mutex_exit(softnet_lock);
611 		return;
612 	} else {
613 		callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp);
614 	}
615 
616 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) {
617 		mutex_exit(softnet_lock);
618 		return;
619 	}
620 
621 	MCLAIM(m, &aarp_mowner);
622 	m->m_len = sizeof(*ea);
623 	m->m_pkthdr.len = sizeof(*ea);
624 	m_align(m, sizeof(*ea));
625 
626 	ea = mtod(m, struct ether_aarp *);
627 	memset(ea, 0, sizeof(*ea));
628 
629 	ea->aarp_hrd = htons(AARPHRD_ETHER);
630 	ea->aarp_pro = htons(ETHERTYPE_ATALK);
631 	ea->aarp_hln = sizeof(ea->aarp_sha);
632 	ea->aarp_pln = sizeof(ea->aarp_spu);
633 	ea->aarp_op = htons(AARPOP_PROBE);
634 	memcpy(ea->aarp_sha, CLLADDR(ifp->if_sadl), sizeof(ea->aarp_sha));
635 
636 	eh = (struct ether_header *) sa.sa_data;
637 
638 	if (aa->aa_flags & AFA_PHASE2) {
639 		memcpy(eh->ether_dhost, atmulticastaddr,
640 		    sizeof(eh->ether_dhost));
641 		eh->ether_type = 0;	/* if_output will treat as 802 */
642 		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
643 		if (!m) {
644 			mutex_exit(softnet_lock);
645 			return;
646 		}
647 
648 		llc = mtod(m, struct llc *);
649 		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
650 		llc->llc_control = LLC_UI;
651 		memcpy(llc->llc_org_code, aarp_org_code, sizeof(aarp_org_code));
652 		llc->llc_ether_type = htons(ETHERTYPE_AARP);
653 
654 		memcpy(ea->aarp_spnet, &AA_SAT(aa)->sat_addr.s_net,
655 		      sizeof(ea->aarp_spnet));
656 		memcpy(ea->aarp_tpnet, &AA_SAT(aa)->sat_addr.s_net,
657 		      sizeof(ea->aarp_tpnet));
658 		ea->aarp_spnode = ea->aarp_tpnode =
659 		    AA_SAT(aa)->sat_addr.s_node;
660 	} else {
661 		memcpy(eh->ether_dhost, etherbroadcastaddr,
662 		    sizeof(eh->ether_dhost));
663 		eh->ether_type = htons(ETHERTYPE_AARP);
664 		ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
665 	}
666 
667 #ifdef NETATALKDEBUG
668 	printf("aarp: sending probe for %u.%u\n",
669 	       ntohs(AA_SAT(aa)->sat_addr.s_net),
670 	       AA_SAT(aa)->sat_addr.s_node);
671 #endif	/* NETATALKDEBUG */
672 
673 	sa.sa_len = sizeof(struct sockaddr);
674 	sa.sa_family = AF_UNSPEC;
675 	(*ifp->if_output) (ifp, m, &sa, NULL);	/* XXX */
676 	aa->aa_probcnt--;
677 	mutex_exit(softnet_lock);
678 }
679