]> arthur.barton.de Git - netatalk.git/blob - sys/netatalk/aarp.c
replaced all #include <sys/syslog.h> with #include <syslog.h>
[netatalk.git] / sys / netatalk / aarp.c
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)
49 struct aarptab          aarptab[AARPTAB_SIZE];
50 int                     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
71 extern struct ether_addr        etherbroadcastaddr;
72 #else /* sun */
73 extern u_char                   etherbroadcastaddr[6];
74 #endif /* sun */
75
76 u_char  atmulticastaddr[ 6 ] = {
77     0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
78 };
79
80 u_char  at_org_code[ 3 ] = {
81     0x08, 0x00, 0x07,
82 };
83 u_char  aarp_org_code[ 3 ] = {
84     0x00, 0x00, 0x00,
85 };
86
87 aarptimer()
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
106 struct ifaddr *
107 at_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
136 aarpwhohas( 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
251 aarpresolve( 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
317 aarpinput( 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
353 out:
354     m_freem( m );
355 }
356
357
358 at_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
620 aarptfree( 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 *
633 aarptnew( 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 );
660 out:
661     aat->aat_ataddr = *addr;
662     aat->aat_flags = ATF_INUSE;
663     return( aat );
664 }
665
666 aarpprobe( 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
791 aarp_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 }