• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.0/sys/netatalk/
1/*
2 * $Id: aarp.c,v 1.3 2002-01-03 17:49:39 sibaz Exp $
3 *
4 * Copyright (c) 1990,1991 Regents of The University of Michigan.
5 * All Rights Reserved.
6 */
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif /* HAVE_CONFIG_H */
11
12#include <sys/types.h>
13#include <sys/socket.h>
14#include <syslog.h>
15#include <sys/param.h>
16#include <sys/mbuf.h>
17#include <sys/time.h>
18#ifndef _IBMR2
19#include <sys/kernel.h>
20#endif /* _IBMR2 */
21#include <net/if.h>
22#include <net/route.h>
23#include <net/af.h>
24#include <netinet/in.h>
25#undef s_net
26#include <netinet/if_ether.h>
27#ifdef _IBMR2
28#include <netinet/in_netarp.h>
29#include <net/spl.h>
30#include <sys/errno.h>
31#include <sys/err_rec.h>
32#endif /* _IBMR2 */
33
34#include "at.h"
35#include "at_var.h"
36#include "aarp.h"
37#include "ddp_var.h"
38#include "endian.h"
39#include "phase2.h"
40
41#ifdef GATEWAY
42#define AARPTAB_BSIZ	16
43#define AARPTAB_NB	37
44#else /* GATEWAY */
45#define AARPTAB_BSIZ	9
46#define AARPTAB_NB	19
47#endif /* GATEWAY */
48#define AARPTAB_SIZE	(AARPTAB_BSIZ * AARPTAB_NB)
49struct aarptab		aarptab[AARPTAB_SIZE];
50int			aarptab_size = AARPTAB_SIZE;
51
52#define AARPTAB_HASH(a) \
53    ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
54
55#define AARPTAB_LOOK(aat,addr) { \
56    int		n; \
57    aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
58    for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \
59	if ( aat->aat_ataddr.s_net == (addr).s_net && \
60	     aat->aat_ataddr.s_node == (addr).s_node ) \
61	    break; \
62	if ( n >= AARPTAB_BSIZ ) \
63	    aat = 0; \
64}
65
66#define AARPT_AGE	(60 * 1)
67#define AARPT_KILLC	20
68#define AARPT_KILLI	3
69
70#ifdef sun
71extern struct ether_addr	etherbroadcastaddr;
72#else /* sun */
73extern u_char			etherbroadcastaddr[6];
74#endif /* sun */
75
76u_char	atmulticastaddr[ 6 ] = {
77    0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
78};
79
80u_char	at_org_code[ 3 ] = {
81    0x08, 0x00, 0x07,
82};
83u_char	aarp_org_code[ 3 ] = {
84    0x00, 0x00, 0x00,
85};
86
87aarptimer()
88{
89    struct aarptab	*aat;
90    int			i, s;
91
92    timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz );
93    aat = aarptab;
94    for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) {
95	if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM ))
96	    continue;
97	if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ?
98		AARPT_KILLC : AARPT_KILLI ))
99	    continue;
100	s = splimp();
101	aarptfree( aat );
102	splx( s );
103    }
104}
105
106struct ifaddr *
107at_ifawithnet( sat, ifa )
108    struct sockaddr_at	*sat;
109    struct ifaddr	*ifa;
110{
111    struct at_ifaddr	*aa;
112
113    for (; ifa; ifa = ifa->ifa_next ) {
114#ifdef BSD4_4
115	if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) {
116	    continue;
117	}
118	if ( satosat( ifa->ifa_addr )->sat_addr.s_net ==
119		sat->sat_addr.s_net ) {
120	    break;
121	}
122#else /* BSD4_4 */
123	if ( ifa->ifa_addr.sa_family != AF_APPLETALK ) {
124	    continue;
125	}
126	aa = (struct at_ifaddr *)ifa;
127	if ( ntohs( sat->sat_addr.s_net ) >= ntohs( aa->aa_firstnet ) &&
128		ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet )) {
129	    break;
130	}
131#endif /* BSD4_4 */
132    }
133    return( ifa );
134}
135
136aarpwhohas( ac, sat )
137    struct arpcom	*ac;
138    struct sockaddr_at	*sat;
139{
140    struct mbuf		*m;
141    struct ether_header	*eh;
142    struct ether_aarp	*ea;
143    struct at_ifaddr	*aa;
144    struct llc		*llc;
145    struct sockaddr	sa;
146
147#ifdef BSD4_4
148    if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
149	return;
150    }
151    m->m_len = sizeof( *ea );
152    m->m_pkthdr.len = sizeof( *ea );
153    MH_ALIGN( m, sizeof( *ea ));
154#else /* BSD4_4 */
155    if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
156	return;
157    }
158    m->m_len = sizeof( *ea );
159    m->m_off = MMAXOFF - sizeof( *ea );
160#endif /* BSD4_4 */
161
162    ea = mtod( m, struct ether_aarp *);
163    bzero((caddr_t)ea, sizeof( *ea ));
164
165    ea->aarp_hrd = htons( AARPHRD_ETHER );
166    ea->aarp_pro = htons( ETHERTYPE_AT );
167    ea->aarp_hln = sizeof( ea->aarp_sha );
168    ea->aarp_pln = sizeof( ea->aarp_spu );
169    ea->aarp_op = htons( AARPOP_REQUEST );
170#ifdef sun
171    bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
172	    sizeof( ea->aarp_sha ));
173#else /* sun */
174    bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
175	    sizeof( ea->aarp_sha ));
176#endif /* sun */
177
178    /*
179     * We need to check whether the output ethernet type should
180     * be phase 1 or 2. We have the interface that we'll be sending
181     * the aarp out. We need to find an AppleTalk network on that
182     * interface with the same address as we're looking for. If the
183     * net is phase 2, generate an 802.2 and SNAP header.
184     */
185    if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist ))
186	    == NULL ) {
187	m_freem( m );
188	return;
189    }
190
191    eh = (struct ether_header *)sa.sa_data;
192
193    if ( aa->aa_flags & AFA_PHASE2 ) {
194#ifdef sun
195	bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
196		sizeof( eh->ether_dhost ));
197#else /* sun */
198	bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
199		sizeof( eh->ether_dhost ));
200#endif /* sun */
201#if defined( sun ) && defined( i386 )
202	eh->ether_type = htons( sizeof( struct llc ) +
203		sizeof( struct ether_aarp ));
204#else /* sun && i386 */
205	eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
206#endif /* sun && i386 */
207#ifdef BSD4_4
208	M_PREPEND( m, sizeof( struct llc ), M_WAIT );
209#else /* BSD4_4 */
210	m->m_len += sizeof( struct llc );
211	m->m_off -= sizeof( struct llc );
212#endif /* BSD4_4 */
213	llc = mtod( m, struct llc *);
214	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
215	llc->llc_control = LLC_UI;
216	bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
217	llc->llc_ether_type = htons( ETHERTYPE_AARP );
218
219
220	bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
221		sizeof( ea->aarp_spnet ));
222	ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node;
223	bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet,
224		sizeof( ea->aarp_tpnet ));
225	ea->aarp_tpnode = sat->sat_addr.s_node;
226    } else {
227#ifdef sun
228	bcopy((caddr_t)&etherbroadcastaddr, (caddr_t)&eh->ether_dhost,
229		sizeof( eh->ether_dhost ));
230#else /* sun */
231	bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
232		sizeof( eh->ether_dhost ));
233#endif /* sun */
234#if defined( sun ) && defined( i386 )
235	eh->ether_type = htons( ETHERTYPE_AARP );
236#else /* sun && i386 */
237	eh->ether_type = ETHERTYPE_AARP;
238#endif /* sun && i386 */
239
240	ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node;
241	ea->aarp_tpa = sat->sat_addr.s_node;
242    }
243
244#ifdef BSD4_4
245    sa.sa_len = sizeof( struct sockaddr );
246#endif /* BSD4_4 */
247    sa.sa_family = AF_UNSPEC;
248    (*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
249}
250
251aarpresolve( ac, m, destsat, desten )
252    struct arpcom	*ac;
253    struct mbuf		*m;
254    struct sockaddr_at	*destsat;
255#ifdef sun
256    struct ether_addr	*desten;
257#else /* sun */
258    u_char		*desten;
259#endif /* sun */
260{
261    struct at_ifaddr	*aa;
262    struct ifaddr	ifa;
263    struct aarptab	*aat;
264    int			s;
265
266    if ( at_broadcast( destsat )) {
267	if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat,
268		((struct ifnet *)ac)->if_addrlist )) == NULL ) {
269	    m_freem( m );
270	    return( 0 );
271	}
272	if ( aa->aa_flags & AFA_PHASE2 ) {
273	    bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten,
274		    sizeof( atmulticastaddr ));
275	} else {
276#ifdef sun
277	    bcopy( (caddr_t)&etherbroadcastaddr, (caddr_t)desten,
278		    sizeof( etherbroadcastaddr ));
279#else /* sun */
280	    bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten,
281		    sizeof( etherbroadcastaddr ));
282#endif /* sun */
283	}
284	return( 1 );
285    }
286
287    s = splimp();
288    AARPTAB_LOOK( aat, destsat->sat_addr );
289    if ( aat == 0 ) {			/* No entry */
290	aat = aarptnew( &destsat->sat_addr );
291	if ( aat == 0 ) {
292	    panic( "aarpresolve: no free entry" );
293	}
294	aat->aat_hold = m;
295	aarpwhohas( ac, destsat );
296	splx( s );
297	return( 0 );
298    }
299    /* found an entry */
300    aat->aat_timer = 0;
301    if ( aat->aat_flags & ATF_COM ) {	/* entry is COMplete */
302	bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten,
303		sizeof( aat->aat_enaddr ));
304	splx( s );
305	return( 1 );
306    }
307    /* entry has not completed */
308    if ( aat->aat_hold ) {
309	m_freem( aat->aat_hold );
310    }
311    aat->aat_hold = m;
312    aarpwhohas( ac, destsat );
313    splx( s );
314    return( 0 );
315}
316
317aarpinput( ac, m )
318    struct arpcom	*ac;
319    struct mbuf		*m;
320{
321    struct arphdr	*ar;
322
323    if ( ac->ac_if.if_flags & IFF_NOARP )
324	goto out;
325
326#ifndef BSD4_4
327    IF_ADJ( m );
328#endif /* BSD4_4 */
329
330    if ( m->m_len < sizeof( struct arphdr )) {
331	goto out;
332    }
333
334    ar = mtod( m, struct arphdr *);
335    if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) {
336	goto out;
337    }
338
339    if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln +
340	    2 * ar->ar_pln ) {
341	goto out;
342    }
343
344    switch( ntohs( ar->ar_pro )) {
345    case ETHERTYPE_AT :
346	at_aarpinput( ac, m );
347	return;
348
349    default:
350	break;
351    }
352
353out:
354    m_freem( m );
355}
356
357
358at_aarpinput( ac, m )
359    struct arpcom	*ac;
360    struct mbuf		*m;
361{
362    struct mbuf		*m0;
363    struct ether_aarp	*ea;
364    struct at_ifaddr	*aa;
365    struct aarptab	*aat;
366    struct ether_header	*eh;
367    struct llc		*llc;
368    struct sockaddr_at	sat;
369    struct sockaddr	sa;
370    struct at_addr	spa, tpa, ma;
371    int			op, s;
372    u_short		net;
373
374    ea = mtod( m, struct ether_aarp *);
375
376    /* Check to see if from my hardware address */
377#ifdef sun
378    if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )&ac->ac_enaddr,
379	    sizeof( ac->ac_enaddr ))) {
380	m_freem( m );
381	return;
382    }
383#else /* sun */
384    if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr,
385	    sizeof( ac->ac_enaddr ))) {
386	m_freem( m );
387	return;
388    }
389#endif /* sun */
390
391    /*
392     * Check if from broadcast address.  This could be a more robust
393     * check, since we could look for multicasts.
394     */
395#ifdef sun
396    if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )&etherbroadcastaddr,
397	    sizeof( etherbroadcastaddr ))) {
398	log( LOG_ERR, "aarp: source is broadcast!\n" );
399	m_freem( m );
400	return;
401    }
402#else /* sun */
403    if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )etherbroadcastaddr,
404	    sizeof( etherbroadcastaddr ))) {
405#ifndef _IBMR2
406#ifdef ultrix
407	mprintf( LOG_ERR,
408#else /* ultrix */
409	log( LOG_ERR,
410#endif /* ultrix */
411		"aarp: source is broadcast!\n" );
412#endif /* ! _IBMR2 */
413	m_freem( m );
414	return;
415    }
416#endif /* sun */
417
418    op = ntohs( ea->aarp_op );
419    bcopy( ea->aarp_tpnet, &net, sizeof( net ));
420
421    if ( net != 0 ) {
422	sat.sat_family = AF_APPLETALK;
423	sat.sat_addr.s_net = net;
424	if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat,
425		ac->ac_if.if_addrlist )) == NULL ) {
426	    m_freem( m );
427	    return;
428	}
429	bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net ));
430	bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net ));
431    } else {
432	/*
433	 * Since we don't know the net, we just look for the first
434	 * phase 1 address on the interface.
435	 */
436	for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist; aa;
437		aa = (struct at_ifaddr *)aa->aa_ifa.ifa_next ) {
438	    if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
439		    ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
440		break;
441	    }
442	}
443	if ( aa == NULL ) {
444	    m_freem( m );
445	    return;
446	}
447	tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net;
448    }
449
450    spa.s_node = ea->aarp_spnode;
451    tpa.s_node = ea->aarp_tpnode;
452    ma.s_net = AA_SAT( aa )->sat_addr.s_net;
453    ma.s_node = AA_SAT( aa )->sat_addr.s_node;
454
455    /*
456     * This looks like it's from us.
457     */
458    if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) {
459	if ( aa->aa_flags & AFA_PROBING ) {
460	    /*
461	     * We're probing, someone either responded to our probe, or
462	     * probed for the same address we'd like to use. Change the
463	     * address we're probing for.
464	     */
465	    untimeout( aarpprobe, ac );
466	    wakeup( aa );
467	    m_freem( m );
468	    return;
469	} else if ( op != AARPOP_PROBE ) {
470	    /*
471	     * This is not a probe, and we're not probing. This means
472	     * that someone's saying they have the same source address
473	     * as the one we're using. Get upset...
474	     */
475#ifndef _IBMR2
476#ifdef ultrix
477	    mprintf( LOG_ERR,
478#else /* ultrix */
479	    log( LOG_ERR,
480#endif /* ultrix */
481		    "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
482		    ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ],
483		    ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]);
484#endif /* ! _IBMR2 */
485	    m_freem( m );
486	    return;
487	}
488    }
489
490    AARPTAB_LOOK( aat, spa );
491    if ( aat ) {
492	if ( op == AARPOP_PROBE ) {
493	    /*
494	     * Someone's probing for spa, dealocate the one we've got,
495	     * so that if the prober keeps the address, we'll be able
496	     * to arp for him.
497	     */
498	    aarptfree( aat );
499	    m_freem( m );
500	    return;
501	}
502
503	bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
504		sizeof( ea->aarp_sha ));
505	aat->aat_flags |= ATF_COM;
506	if ( aat->aat_hold ) {
507#ifdef _IBMR2
508	    /*
509	     * Like in ddp_output(), we can't rely on the if_output
510	     * routine to resolve AF_APPLETALK addresses, on the rs6k.
511	     * So, we fill the destination ethernet address here.
512	     *
513	     * This should really be replaced with something like
514	     * rsif_output(). XXX Will have to be for phase 2.
515	     */
516	     /* XXX maybe fill in the rest of the frame header */
517	    sat.sat_family = AF_UNSPEC;
518	    bcopy( aat->aat_enaddr, (*(struct sockaddr *)&sat).sa_data,
519		    sizeof( aat->aat_enaddr ));
520#else /* _IBMR2 */
521	    sat.sat_family = AF_APPLETALK;
522	    sat.sat_addr = spa;
523#endif /* _IBMR2 */
524	    (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold,
525		    (struct sockaddr *)&sat );
526	    aat->aat_hold = 0;
527	}
528    }
529
530    if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node
531	    && op != AARPOP_PROBE ) {
532	if ( aat = aarptnew( &spa )) {
533	    bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
534		    sizeof( ea->aarp_sha ));
535	    aat->aat_flags |= ATF_COM;
536	}
537    }
538
539    /*
540     * Don't respond to responses, and never respond if we're
541     * still probing.
542     */
543    if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
544	    op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) {
545	m_freem( m );
546	return;
547    }
548
549    bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha,
550	    sizeof( ea->aarp_sha ));
551#ifdef sun
552    bcopy(( caddr_t )&ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
553	    sizeof( ea->aarp_sha ));
554#else /* sun */
555    bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
556	    sizeof( ea->aarp_sha ));
557#endif /* sun */
558
559    eh = (struct ether_header *)sa.sa_data;
560#ifdef sun
561    bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )&eh->ether_dhost,
562	    sizeof( eh->ether_dhost ));
563#else /* sun */
564    bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost,
565	    sizeof( eh->ether_dhost ));
566#endif /* sun */
567
568    if ( aa->aa_flags & AFA_PHASE2 ) {
569#if defined( sun ) && defined( i386 )
570	eh->ether_type = htons( sizeof( struct llc ) +
571		sizeof( struct ether_aarp ));
572#else /* sun && i386 */
573	eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
574#endif /* sun && i386 */
575#ifdef BSD4_4
576	M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT );
577	if ( m == NULL ) {
578	    m_freem( m );
579	    return;
580	}
581#else /* BSD4_4 */
582	MGET( m0, M_DONTWAIT, MT_HEADER );
583	if ( m0 == NULL ) {
584	    m_freem( m );
585	    return;
586	}
587	m0->m_next = m;
588	m = m0;
589	m->m_off = MMAXOFF - sizeof( struct llc );
590	m->m_len = sizeof ( struct llc );
591#endif /* BSD4_4 */
592	llc = mtod( m, struct llc *);
593	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
594	llc->llc_control = LLC_UI;
595	bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
596	llc->llc_ether_type = htons( ETHERTYPE_AARP );
597
598	bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet ));
599	bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet ));
600    } else {
601#if defined( sun ) && defined( i386 )
602	eh->ether_type = htons( ETHERTYPE_AARP );
603#else /* sun && i386 */
604	eh->ether_type = ETHERTYPE_AARP;
605#endif /* sun && i386 */
606    }
607
608    ea->aarp_tpnode = ea->aarp_spnode;
609    ea->aarp_spnode = ma.s_node;
610    ea->aarp_op = htons( AARPOP_RESPONSE );
611
612#ifdef BSD4_4
613    sa.sa_len = sizeof( struct sockaddr );
614#endif /* BSD4_4 */
615    sa.sa_family = AF_UNSPEC;
616    (*ac->ac_if.if_output)( &ac->ac_if, m, &sa );
617    return;
618}
619
620aarptfree( aat )
621    struct aarptab	*aat;
622{
623
624    if ( aat->aat_hold )
625	m_freem( aat->aat_hold );
626    aat->aat_hold = 0;
627    aat->aat_timer = aat->aat_flags = 0;
628    aat->aat_ataddr.s_net = 0;
629    aat->aat_ataddr.s_node = 0;
630}
631
632    struct aarptab *
633aarptnew( addr )
634    struct at_addr	*addr;
635{
636    int			n;
637    int			oldest = -1;
638    struct aarptab	*aat, *aato = NULL;
639    static int		first = 1;
640
641    if ( first ) {
642	first = 0;
643	timeout( aarptimer, (caddr_t)0, hz );
644    }
645    aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ];
646    for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) {
647	if ( aat->aat_flags == 0 )
648	    goto out;
649	if ( aat->aat_flags & ATF_PERM )
650	    continue;
651	if ((int) aat->aat_timer > oldest ) {
652	    oldest = aat->aat_timer;
653	    aato = aat;
654	}
655    }
656    if ( aato == NULL )
657	return( NULL );
658    aat = aato;
659    aarptfree( aat );
660out:
661    aat->aat_ataddr = *addr;
662    aat->aat_flags = ATF_INUSE;
663    return( aat );
664}
665
666aarpprobe( ac )
667    struct arpcom	*ac;
668{
669    struct mbuf		*m;
670    struct ether_header	*eh;
671    struct ether_aarp	*ea;
672    struct at_ifaddr	*aa;
673    struct llc		*llc;
674    struct sockaddr	sa;
675
676    /*
677     * We need to check whether the output ethernet type should
678     * be phase 1 or 2. We have the interface that we'll be sending
679     * the aarp out. We need to find an AppleTalk network on that
680     * interface with the same address as we're looking for. If the
681     * net is phase 2, generate an 802.2 and SNAP header.
682     */
683    for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist; aa;
684	    aa = (struct at_ifaddr *)aa->aa_ifa.ifa_next ) {
685	if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
686		( aa->aa_flags & AFA_PROBING )) {
687	    break;
688	}
689    }
690    if ( aa == NULL ) {		/* serious error XXX */
691	printf( "aarpprobe why did this happen?!\n" );
692	return;
693    }
694
695    if ( aa->aa_probcnt <= 0 ) {
696	aa->aa_flags &= ~AFA_PROBING;
697	wakeup( aa );
698	return;
699    } else {
700	timeout( aarpprobe, (caddr_t)ac, hz / 5 );
701    }
702
703#ifdef BSD4_4
704    if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
705	return;
706    }
707    m->m_len = sizeof( *ea );
708    m->m_pkthdr.len = sizeof( *ea );
709    MH_ALIGN( m, sizeof( *ea ));
710#else /* BSD4_4 */
711    if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
712	return;
713    }
714    m->m_len = sizeof( *ea );
715    m->m_off = MMAXOFF - sizeof( *ea );
716#endif /* BSD4_4 */
717
718    ea = mtod( m, struct ether_aarp *);
719    bzero((caddr_t)ea, sizeof( *ea ));
720
721    ea->aarp_hrd = htons( AARPHRD_ETHER );
722    ea->aarp_pro = htons( ETHERTYPE_AT );
723    ea->aarp_hln = sizeof( ea->aarp_sha );
724    ea->aarp_pln = sizeof( ea->aarp_spu );
725    ea->aarp_op = htons( AARPOP_PROBE );
726#ifdef sun
727    bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
728	    sizeof( ea->aarp_sha ));
729#else /* sun */
730    bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
731	    sizeof( ea->aarp_sha ));
732#endif /* sun */
733
734    eh = (struct ether_header *)sa.sa_data;
735
736    if ( aa->aa_flags & AFA_PHASE2 ) {
737#ifdef sun
738	bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
739		sizeof( eh->ether_dhost ));
740#else /* sun */
741	bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
742		sizeof( eh->ether_dhost ));
743#endif /* sun */
744#if defined( sun ) && defined( i386 )
745	eh->ether_type = htons( sizeof( struct llc ) +
746		sizeof( struct ether_aarp ));
747#else /* sun && i386 */
748	eh->ether_type = sizeof( struct llc ) + sizeof( struct ether_aarp );
749#endif /* sun && i386 */
750#ifdef BSD4_4
751	M_PREPEND( m, sizeof( struct llc ), M_WAIT );
752#else /* BSD4_4 */
753	m->m_len += sizeof( struct llc );
754	m->m_off -= sizeof( struct llc );
755#endif /* BSD4_4 */
756	llc = mtod( m, struct llc *);
757	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
758	llc->llc_control = LLC_UI;
759	bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
760	llc->llc_ether_type = htons( ETHERTYPE_AARP );
761
762	bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
763		sizeof( ea->aarp_spnet ));
764	bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet,
765		sizeof( ea->aarp_tpnet ));
766	ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node;
767    } else {
768#ifdef sun
769	bcopy((caddr_t)&etherbroadcastaddr, (caddr_t)&eh->ether_dhost,
770		sizeof( eh->ether_dhost ));
771#else /* sun */
772	bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
773		sizeof( eh->ether_dhost ));
774#endif /* sun */
775#if defined( sun ) && defined( i386 )
776	eh->ether_type = htons( ETHERTYPE_AARP );
777#else /* sun && i386 */
778	eh->ether_type = ETHERTYPE_AARP;
779#endif /* sun && i386 */
780	ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node;
781    }
782
783#ifdef BSD4_4
784    sa.sa_len = sizeof( struct sockaddr );
785#endif /* BSD4_4 */
786    sa.sa_family = AF_UNSPEC;
787    (*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
788    aa->aa_probcnt--;
789}
790
791aarp_clean()
792{
793    struct aarptab	*aat;
794    int			i;
795
796    untimeout( aarptimer, 0 );
797    for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) {
798	if ( aat->aat_hold ) {
799	    m_freem( aat->aat_hold );
800	}
801    }
802}
803