2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
5 * $FreeBSD: src/sys/netatalk/aarp.c,v 1.12.2.2 2001/06/23 20:43:09 iedowse Exp $
6 * $DragonFly: src/sys/netproto/atalk/aarp.c,v 1.11 2004/06/02 14:43:02 eirikn Exp $
11 #include <sys/param.h>
12 #include <sys/systm.h>
14 #include <sys/kernel.h>
15 #include <sys/socket.h>
16 #include <sys/syslog.h>
18 #include <sys/thread2.h>
19 #include <sys/msgport2.h>
22 #include <net/netisr.h>
24 #include <netinet/in.h>
26 #include <netinet/if_ether.h>
32 #include "at_extern.h"
34 static void aarptfree( struct aarptab *aat);
35 static void at_aarpinput( struct arpcom *ac, struct mbuf *m);
37 #define AARPTAB_BSIZ 9
39 #define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
40 static struct aarptab aarptab[AARPTAB_SIZE];
42 #define AARPTAB_HASH(a) \
43 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
45 #define AARPTAB_LOOK(aat,addr) { \
47 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
48 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \
49 if ( aat->aat_ataddr.s_net == (addr).s_net && \
50 aat->aat_ataddr.s_node == (addr).s_node ) \
52 if ( n >= AARPTAB_BSIZ ) \
56 #define AARPT_AGE (60 * 1)
57 #define AARPT_KILLC 20
60 # if !defined( __DragonFly__ )
61 extern u_char etherbroadcastaddr[6];
64 static u_char atmulticastaddr[ 6 ] = {
65 0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
68 u_char at_org_code[ 3 ] = {
71 u_char aarp_org_code[ 3 ] = {
75 static struct callout_handle aarptimer_ch =
76 CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch);
79 aarptimer(void *ignored)
84 aarptimer_ch = timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz );
86 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) {
87 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM ))
89 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ?
90 AARPT_KILLC : AARPT_KILLI ))
99 * search through the network addresses to find one that includes
100 * the given network.. remember to take netranges into
104 at_ifawithnet(struct sockaddr_at *sat )
106 struct at_ifaddr *aa;
107 struct sockaddr_at *sat2;
109 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
110 sat2 = &(aa->aa_addr);
111 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) {
114 if( (aa->aa_flags & AFA_PHASE2 )
115 && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net))
116 && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) {
124 aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat )
127 struct ether_header *eh;
128 struct ether_aarp *ea;
129 struct at_ifaddr *aa;
133 if (( m = m_gethdr( MB_DONTWAIT, MT_DATA )) == NULL ) {
136 m->m_len = sizeof( *ea );
137 m->m_pkthdr.len = sizeof( *ea );
138 MH_ALIGN( m, sizeof( *ea ));
140 ea = mtod( m, struct ether_aarp *);
141 bzero((caddr_t)ea, sizeof( *ea ));
143 ea->aarp_hrd = htons( AARPHRD_ETHER );
144 ea->aarp_pro = htons( ETHERTYPE_AT );
145 ea->aarp_hln = sizeof( ea->aarp_sha );
146 ea->aarp_pln = sizeof( ea->aarp_spu );
147 ea->aarp_op = htons( AARPOP_REQUEST );
148 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
149 sizeof( ea->aarp_sha ));
152 * We need to check whether the output ethernet type should
153 * be phase 1 or 2. We have the interface that we'll be sending
154 * the aarp out. We need to find an AppleTalk network on that
155 * interface with the same address as we're looking for. If the
156 * net is phase 2, generate an 802.2 and SNAP header.
158 if ((aa = at_ifawithnet( sat )) == NULL) {
163 eh = (struct ether_header *)sa.sa_data;
165 if ( aa->aa_flags & AFA_PHASE2 ) {
166 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
167 sizeof( eh->ether_dhost ));
168 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp));
169 M_PREPEND( m, sizeof( struct llc ), MB_WAIT );
170 llc = mtod( m, struct llc *);
171 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
172 llc->llc_control = LLC_UI;
173 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
174 llc->llc_ether_type = htons( ETHERTYPE_AARP );
176 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
177 sizeof( ea->aarp_spnet ));
178 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet,
179 sizeof( ea->aarp_tpnet ));
180 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node;
181 ea->aarp_tpnode = sat->sat_addr.s_node;
183 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
184 sizeof( eh->ether_dhost ));
185 eh->ether_type = htons( ETHERTYPE_AARP );
187 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node;
188 ea->aarp_tpa = sat->sat_addr.s_node;
192 printf("aarp: sending request for %u.%u\n",
193 ntohs(AA_SAT( aa )->sat_addr.s_net),
194 AA_SAT( aa )->sat_addr.s_node);
195 #endif /* NETATALKDEBUG */
197 sa.sa_len = sizeof( struct sockaddr );
198 sa.sa_family = AF_UNSPEC;
199 (*ac->ac_if.if_output)(&ac->ac_if,
200 m, &sa, NULL); /* XXX NULL should be routing information */
204 aarpresolve( ac, m, destsat, desten )
207 struct sockaddr_at *destsat;
210 struct at_ifaddr *aa;
214 if ( at_broadcast( destsat )) {
215 m->m_flags |= M_BCAST;
216 if ((aa = at_ifawithnet( destsat )) == NULL) {
220 if ( aa->aa_flags & AFA_PHASE2 ) {
221 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten,
222 sizeof( atmulticastaddr ));
224 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten,
225 sizeof( etherbroadcastaddr ));
231 AARPTAB_LOOK( aat, destsat->sat_addr );
232 if ( aat == 0 ) { /* No entry */
233 aat = aarptnew( &destsat->sat_addr );
235 panic( "aarpresolve: no free entry" );
238 aarpwhohas( ac, destsat );
244 if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */
245 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten,
246 sizeof( aat->aat_enaddr ));
250 /* entry has not completed */
251 if ( aat->aat_hold ) {
252 m_freem( aat->aat_hold );
255 aarpwhohas( ac, destsat );
261 aarpintr(struct netmsg *msg)
263 struct mbuf *m = ((struct netmsg_packet *)msg)->nm_packet;
267 ac = (struct arpcom *)m->m_pkthdr.rcvif;
268 if ( ac->ac_if.if_flags & IFF_NOARP )
271 if ( m->m_len < sizeof( struct arphdr )) {
275 ar = mtod( m, struct arphdr *);
276 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) {
280 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln +
285 switch( ntohs( ar->ar_pro )) {
287 at_aarpinput( ac, m );
297 lwkt_replymsg(&msg->nm_lmsg, 0);
302 at_aarpinput( struct arpcom *ac, struct mbuf *m)
304 struct ether_aarp *ea;
305 struct at_ifaddr *aa;
307 struct ether_header *eh;
309 struct sockaddr_at sat;
311 struct at_addr spa, tpa, ma;
315 ea = mtod( m, struct ether_aarp *);
317 /* Check to see if from my hardware address */
318 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr,
319 sizeof( ac->ac_enaddr ))) {
324 op = ntohs( ea->aarp_op );
325 bcopy( ea->aarp_tpnet, &net, sizeof( net ));
327 if ( net != 0 ) { /* should be ATADDR_ANYNET? */
328 sat.sat_len = sizeof(struct sockaddr_at);
329 sat.sat_family = AF_APPLETALK;
330 sat.sat_addr.s_net = net;
331 if ((aa = at_ifawithnet( &sat )) == NULL) {
335 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net ));
336 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net ));
339 * Since we don't know the net, we just look for the first
340 * phase 1 address on the interface.
342 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa;
343 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
344 if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
345 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
353 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net;
356 spa.s_node = ea->aarp_spnode;
357 tpa.s_node = ea->aarp_tpnode;
358 ma.s_net = AA_SAT( aa )->sat_addr.s_net;
359 ma.s_node = AA_SAT( aa )->sat_addr.s_node;
362 * This looks like it's from us.
364 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) {
365 if ( aa->aa_flags & AFA_PROBING ) {
367 * We're probing, someone either responded to our probe, or
368 * probed for the same address we'd like to use. Change the
369 * address we're probing for.
371 untimeout( aarpprobe, ac, aa->aa_ch );
375 } else if ( op != AARPOP_PROBE ) {
377 * This is not a probe, and we're not probing. This means
378 * that someone's saying they have the same source address
379 * as the one we're using. Get upset...
382 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
383 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ],
384 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]);
390 AARPTAB_LOOK( aat, spa );
392 if ( op == AARPOP_PROBE ) {
394 * Someone's probing for spa, dealocate the one we've got,
395 * so that if the prober keeps the address, we'll be able
403 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
404 sizeof( ea->aarp_sha ));
405 aat->aat_flags |= ATF_COM;
406 if ( aat->aat_hold ) {
407 struct mbuf *mhold = aat->aat_hold;
408 aat->aat_hold = NULL;
409 sat.sat_len = sizeof(struct sockaddr_at);
410 sat.sat_family = AF_APPLETALK;
412 (*ac->ac_if.if_output)( &ac->ac_if, mhold,
413 (struct sockaddr *)&sat, NULL); /* XXX */
415 } else if ((tpa.s_net == ma.s_net)
416 && (tpa.s_node == ma.s_node)
417 && (op != AARPOP_PROBE)
418 && ((aat = aarptnew( &spa )) != NULL)) {
419 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
420 sizeof( ea->aarp_sha ));
421 aat->aat_flags |= ATF_COM;
425 * Don't respond to responses, and never respond if we're
428 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
429 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) {
434 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha,
435 sizeof( ea->aarp_sha ));
436 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
437 sizeof( ea->aarp_sha ));
440 eh = (struct ether_header *)sa.sa_data;
441 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost,
442 sizeof( eh->ether_dhost ));
444 if ( aa->aa_flags & AFA_PHASE2 ) {
445 eh->ether_type = htons( sizeof( struct llc ) +
446 sizeof( struct ether_aarp ));
447 M_PREPEND( m, sizeof( struct llc ), MB_DONTWAIT );
451 llc = mtod( m, struct llc *);
452 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
453 llc->llc_control = LLC_UI;
454 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
455 llc->llc_ether_type = htons( ETHERTYPE_AARP );
457 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet ));
458 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet ));
460 eh->ether_type = htons( ETHERTYPE_AARP );
463 ea->aarp_tpnode = ea->aarp_spnode;
464 ea->aarp_spnode = ma.s_node;
465 ea->aarp_op = htons( AARPOP_RESPONSE );
467 sa.sa_len = sizeof( struct sockaddr );
468 sa.sa_family = AF_UNSPEC;
469 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */
474 aarptfree( struct aarptab *aat)
478 m_freem( aat->aat_hold );
479 aat->aat_hold = NULL;
480 aat->aat_timer = aat->aat_flags = 0;
481 aat->aat_ataddr.s_net = 0;
482 aat->aat_ataddr.s_node = 0;
487 struct at_addr *addr;
491 struct aarptab *aat, *aato = NULL;
492 static int first = 1;
496 aarptimer_ch = timeout( aarptimer, (caddr_t)0, hz );
498 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ];
499 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) {
500 if ( aat->aat_flags == 0 )
502 if ( aat->aat_flags & ATF_PERM )
504 if ((int) aat->aat_timer > oldest ) {
505 oldest = aat->aat_timer;
514 aat->aat_ataddr = *addr;
515 aat->aat_flags = ATF_INUSE;
521 aarpprobe( void *arg )
523 struct arpcom *ac = arg;
525 struct ether_header *eh;
526 struct ether_aarp *ea;
527 struct at_ifaddr *aa;
532 * We need to check whether the output ethernet type should
533 * be phase 1 or 2. We have the interface that we'll be sending
534 * the aarp out. We need to find an AppleTalk network on that
535 * interface with the same address as we're looking for. If the
536 * net is phase 2, generate an 802.2 and SNAP header.
538 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa;
539 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
540 if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
541 ( aa->aa_flags & AFA_PROBING )) {
545 if ( aa == NULL ) { /* serious error XXX */
546 printf( "aarpprobe why did this happen?!\n" );
550 if ( aa->aa_probcnt <= 0 ) {
551 aa->aa_flags &= ~AFA_PROBING;
555 aa->aa_ch = timeout( aarpprobe, (caddr_t)ac, hz / 5 );
558 if (( m = m_gethdr( MB_DONTWAIT, MT_DATA )) == NULL ) {
561 m->m_len = sizeof( *ea );
562 m->m_pkthdr.len = sizeof( *ea );
563 MH_ALIGN( m, sizeof( *ea ));
565 ea = mtod( m, struct ether_aarp *);
566 bzero((caddr_t)ea, sizeof( *ea ));
568 ea->aarp_hrd = htons( AARPHRD_ETHER );
569 ea->aarp_pro = htons( ETHERTYPE_AT );
570 ea->aarp_hln = sizeof( ea->aarp_sha );
571 ea->aarp_pln = sizeof( ea->aarp_spu );
572 ea->aarp_op = htons( AARPOP_PROBE );
573 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
574 sizeof( ea->aarp_sha ));
576 eh = (struct ether_header *)sa.sa_data;
578 if ( aa->aa_flags & AFA_PHASE2 ) {
579 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
580 sizeof( eh->ether_dhost ));
581 eh->ether_type = htons( sizeof( struct llc ) +
582 sizeof( struct ether_aarp ));
583 M_PREPEND( m, sizeof( struct llc ), MB_WAIT );
585 llc = mtod( m, struct llc *);
586 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
587 llc->llc_control = LLC_UI;
588 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
589 llc->llc_ether_type = htons( ETHERTYPE_AARP );
591 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
592 sizeof( ea->aarp_spnet ));
593 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet,
594 sizeof( ea->aarp_tpnet ));
595 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node;
597 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
598 sizeof( eh->ether_dhost ));
599 eh->ether_type = htons( ETHERTYPE_AARP );
600 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node;
604 printf("aarp: sending probe for %u.%u\n",
605 ntohs(AA_SAT( aa )->sat_addr.s_net),
606 AA_SAT( aa )->sat_addr.s_node);
607 #endif /* NETATALKDEBUG */
609 sa.sa_len = sizeof( struct sockaddr );
610 sa.sa_family = AF_UNSPEC;
611 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */
621 untimeout( aarptimer, 0, aarptimer_ch );
622 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) {
623 if ( aat->aat_hold ) {
624 m_freem( aat->aat_hold );
625 aat->aat_hold = NULL;