2
* $Id: aarp.c,v 1.3 2002/01/03 17:49:39 sibaz Exp $
4
* Copyright (c) 1990,1991 Regents of The University of Michigan.
10
#endif /* HAVE_CONFIG_H */
12
#include <sys/types.h>
13
#include <sys/socket.h>
15
#include <sys/param.h>
19
#include <sys/kernel.h>
22
#include <net/route.h>
24
#include <netinet/in.h>
26
#include <netinet/if_ether.h>
28
#include <netinet/in_netarp.h>
30
#include <sys/errno.h>
31
#include <sys/err_rec.h>
42
#define AARPTAB_BSIZ 16
45
#define AARPTAB_BSIZ 9
48
#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
49
struct aarptab aarptab[AARPTAB_SIZE];
50
int aarptab_size = AARPTAB_SIZE;
52
#define AARPTAB_HASH(a) \
53
((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
55
#define AARPTAB_LOOK(aat,addr) { \
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 ) \
62
if ( n >= AARPTAB_BSIZ ) \
66
#define AARPT_AGE (60 * 1)
67
#define AARPT_KILLC 20
71
extern struct ether_addr etherbroadcastaddr;
73
extern u_char etherbroadcastaddr[6];
76
u_char atmulticastaddr[ 6 ] = {
77
0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
80
u_char at_org_code[ 3 ] = {
83
u_char aarp_org_code[ 3 ] = {
92
timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz );
94
for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) {
95
if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM ))
97
if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ?
98
AARPT_KILLC : AARPT_KILLI ))
107
at_ifawithnet( sat, ifa )
108
struct sockaddr_at *sat;
111
struct at_ifaddr *aa;
113
for (; ifa; ifa = ifa->ifa_next ) {
115
if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) {
118
if ( satosat( ifa->ifa_addr )->sat_addr.s_net ==
119
sat->sat_addr.s_net ) {
123
if ( ifa->ifa_addr.sa_family != AF_APPLETALK ) {
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 )) {
136
aarpwhohas( ac, sat )
138
struct sockaddr_at *sat;
141
struct ether_header *eh;
142
struct ether_aarp *ea;
143
struct at_ifaddr *aa;
148
if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
151
m->m_len = sizeof( *ea );
152
m->m_pkthdr.len = sizeof( *ea );
153
MH_ALIGN( m, sizeof( *ea ));
155
if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
158
m->m_len = sizeof( *ea );
159
m->m_off = MMAXOFF - sizeof( *ea );
162
ea = mtod( m, struct ether_aarp *);
163
bzero((caddr_t)ea, sizeof( *ea ));
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 );
171
bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
172
sizeof( ea->aarp_sha ));
174
bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
175
sizeof( ea->aarp_sha ));
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.
185
if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist ))
191
eh = (struct ether_header *)sa.sa_data;
193
if ( aa->aa_flags & AFA_PHASE2 ) {
195
bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
196
sizeof( eh->ether_dhost ));
198
bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
199
sizeof( eh->ether_dhost ));
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 */
208
M_PREPEND( m, sizeof( struct llc ), M_WAIT );
210
m->m_len += sizeof( struct llc );
211
m->m_off -= sizeof( struct llc );
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 );
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;
228
bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost,
229
sizeof( eh->ether_dhost ));
231
bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
232
sizeof( eh->ether_dhost ));
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 */
240
ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node;
241
ea->aarp_tpa = sat->sat_addr.s_node;
245
sa.sa_len = sizeof( struct sockaddr );
247
sa.sa_family = AF_UNSPEC;
248
(*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
251
aarpresolve( ac, m, destsat, desten )
254
struct sockaddr_at *destsat;
256
struct ether_addr *desten;
261
struct at_ifaddr *aa;
266
if ( at_broadcast( destsat )) {
267
if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat,
268
((struct ifnet *)ac)->if_addrlist )) == NULL ) {
272
if ( aa->aa_flags & AFA_PHASE2 ) {
273
bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten,
274
sizeof( atmulticastaddr ));
277
bcopy( (caddr_t)ðerbroadcastaddr, (caddr_t)desten,
278
sizeof( etherbroadcastaddr ));
280
bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten,
281
sizeof( etherbroadcastaddr ));
288
AARPTAB_LOOK( aat, destsat->sat_addr );
289
if ( aat == 0 ) { /* No entry */
290
aat = aarptnew( &destsat->sat_addr );
292
panic( "aarpresolve: no free entry" );
295
aarpwhohas( ac, destsat );
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 ));
307
/* entry has not completed */
308
if ( aat->aat_hold ) {
309
m_freem( aat->aat_hold );
312
aarpwhohas( ac, destsat );
323
if ( ac->ac_if.if_flags & IFF_NOARP )
330
if ( m->m_len < sizeof( struct arphdr )) {
334
ar = mtod( m, struct arphdr *);
335
if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) {
339
if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln +
344
switch( ntohs( ar->ar_pro )) {
346
at_aarpinput( ac, m );
358
at_aarpinput( ac, m )
363
struct ether_aarp *ea;
364
struct at_ifaddr *aa;
366
struct ether_header *eh;
368
struct sockaddr_at sat;
370
struct at_addr spa, tpa, ma;
374
ea = mtod( m, struct ether_aarp *);
376
/* Check to see if from my hardware address */
378
if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )&ac->ac_enaddr,
379
sizeof( ac->ac_enaddr ))) {
384
if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr,
385
sizeof( ac->ac_enaddr ))) {
392
* Check if from broadcast address. This could be a more robust
393
* check, since we could look for multicasts.
396
if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ðerbroadcastaddr,
397
sizeof( etherbroadcastaddr ))) {
398
log( LOG_ERR, "aarp: source is broadcast!\n" );
403
if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )etherbroadcastaddr,
404
sizeof( etherbroadcastaddr ))) {
411
"aarp: source is broadcast!\n" );
412
#endif /* ! _IBMR2 */
418
op = ntohs( ea->aarp_op );
419
bcopy( ea->aarp_tpnet, &net, sizeof( net ));
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 ) {
429
bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net ));
430
bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net ));
433
* Since we don't know the net, we just look for the first
434
* phase 1 address on the interface.
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 ) {
447
tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net;
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;
456
* This looks like it's from us.
458
if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) {
459
if ( aa->aa_flags & AFA_PROBING ) {
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.
465
untimeout( aarpprobe, ac );
469
} else if ( op != AARPOP_PROBE ) {
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...
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 */
490
AARPTAB_LOOK( aat, spa );
492
if ( op == AARPOP_PROBE ) {
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
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 ) {
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.
513
* This should really be replaced with something like
514
* rsif_output(). XXX Will have to be for phase 2.
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 ));
521
sat.sat_family = AF_APPLETALK;
524
(*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold,
525
(struct sockaddr *)&sat );
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;
540
* Don't respond to responses, and never respond if we're
543
if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
544
op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) {
549
bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha,
550
sizeof( ea->aarp_sha ));
552
bcopy(( caddr_t )&ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
553
sizeof( ea->aarp_sha ));
555
bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
556
sizeof( ea->aarp_sha ));
559
eh = (struct ether_header *)sa.sa_data;
561
bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )&eh->ether_dhost,
562
sizeof( eh->ether_dhost ));
564
bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost,
565
sizeof( eh->ether_dhost ));
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 */
576
M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT );
582
MGET( m0, M_DONTWAIT, MT_HEADER );
589
m->m_off = MMAXOFF - sizeof( struct llc );
590
m->m_len = sizeof ( struct llc );
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 );
598
bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet ));
599
bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet ));
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 */
608
ea->aarp_tpnode = ea->aarp_spnode;
609
ea->aarp_spnode = ma.s_node;
610
ea->aarp_op = htons( AARPOP_RESPONSE );
613
sa.sa_len = sizeof( struct sockaddr );
615
sa.sa_family = AF_UNSPEC;
616
(*ac->ac_if.if_output)( &ac->ac_if, m, &sa );
625
m_freem( aat->aat_hold );
627
aat->aat_timer = aat->aat_flags = 0;
628
aat->aat_ataddr.s_net = 0;
629
aat->aat_ataddr.s_node = 0;
634
struct at_addr *addr;
638
struct aarptab *aat, *aato = NULL;
639
static int first = 1;
643
timeout( aarptimer, (caddr_t)0, hz );
645
aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ];
646
for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) {
647
if ( aat->aat_flags == 0 )
649
if ( aat->aat_flags & ATF_PERM )
651
if ((int) aat->aat_timer > oldest ) {
652
oldest = aat->aat_timer;
661
aat->aat_ataddr = *addr;
662
aat->aat_flags = ATF_INUSE;
670
struct ether_header *eh;
671
struct ether_aarp *ea;
672
struct at_ifaddr *aa;
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.
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 )) {
690
if ( aa == NULL ) { /* serious error XXX */
691
printf( "aarpprobe why did this happen?!\n" );
695
if ( aa->aa_probcnt <= 0 ) {
696
aa->aa_flags &= ~AFA_PROBING;
700
timeout( aarpprobe, (caddr_t)ac, hz / 5 );
704
if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
707
m->m_len = sizeof( *ea );
708
m->m_pkthdr.len = sizeof( *ea );
709
MH_ALIGN( m, sizeof( *ea ));
711
if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) {
714
m->m_len = sizeof( *ea );
715
m->m_off = MMAXOFF - sizeof( *ea );
718
ea = mtod( m, struct ether_aarp *);
719
bzero((caddr_t)ea, sizeof( *ea ));
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 );
727
bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha,
728
sizeof( ea->aarp_sha ));
730
bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
731
sizeof( ea->aarp_sha ));
734
eh = (struct ether_header *)sa.sa_data;
736
if ( aa->aa_flags & AFA_PHASE2 ) {
738
bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost,
739
sizeof( eh->ether_dhost ));
741
bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
742
sizeof( eh->ether_dhost ));
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 */
751
M_PREPEND( m, sizeof( struct llc ), M_WAIT );
753
m->m_len += sizeof( struct llc );
754
m->m_off -= sizeof( struct llc );
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 );
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;
769
bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost,
770
sizeof( eh->ether_dhost ));
772
bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
773
sizeof( eh->ether_dhost ));
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;
784
sa.sa_len = sizeof( struct sockaddr );
786
sa.sa_family = AF_UNSPEC;
787
(*ac->ac_if.if_output)(&ac->ac_if, m, &sa );
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 );