This source file includes following definitions.
- aarptimer
- at_ifawithnet
- aarpwhohas
- aarpresolve
- aarpinput
- at_aarpinput
- aarptfree
- aarptnew
- aarpprobe
- aarp_clean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/kernel.h>
57 #include <sys/malloc.h>
58 #include <sys/mbuf.h>
59 #include <sys/protosw.h>
60 #include <sys/socket.h>
61 #include <sys/ioctl.h>
62 #include <sys/errno.h>
63 #include <sys/syslog.h>
64 #include <sys/proc.h>
65 #include <sys/timeout.h>
66
67 #include <net/if.h>
68 #include <net/route.h>
69 #include <netinet/in.h>
70 #undef s_net
71 #include <netinet/if_ether.h>
72 #include <net/if_llc.h>
73
74 #include <machine/endian.h>
75
76 #include <netatalk/at.h>
77 #include <netatalk/at_var.h>
78 #include <netatalk/aarp.h>
79 #include <netatalk/ddp_var.h>
80 #include <netatalk/phase2.h>
81 #include <netatalk/at_extern.h>
82
83 static void aarptimer(void *);
84 struct ifaddr *at_ifawithnet(struct sockaddr_at *, struct ifaddr *);
85 static void aarpwhohas(struct arpcom *, struct sockaddr_at *);
86 int aarpresolve(struct arpcom *, struct mbuf *,
87 struct sockaddr_at *, u_int8_t *);
88 void aarpinput(struct arpcom *, struct mbuf *);
89 static void at_aarpinput(struct arpcom *, struct mbuf *);
90 static void aarptfree(struct aarptab *);
91 struct aarptab *aarptnew(struct at_addr *);
92 void aarpprobe(void *);
93 void aarp_clean(void);
94
95 #ifdef GATEWAY
96 #define AARPTAB_BSIZ 16
97 #define AARPTAB_NB 37
98 #else
99 #define AARPTAB_BSIZ 9
100 #define AARPTAB_NB 19
101 #endif
102
103 #define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
104 struct aarptab aarptab[AARPTAB_SIZE];
105 int aarptab_size = AARPTAB_SIZE;
106
107 struct timeout aarpprobe_timeout;
108 struct timeout aarptimer_timeout;
109
110 #define AARPTAB_HASH(a) \
111 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB )
112
113 #define AARPTAB_LOOK(aat,addr) { \
114 int n; \
115 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
116 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \
117 if ( aat->aat_ataddr.s_net == (addr).s_net && \
118 aat->aat_ataddr.s_node == (addr).s_node ) \
119 break; \
120 if ( n >= AARPTAB_BSIZ ) \
121 aat = 0; \
122 }
123
124 #define AARPT_AGE (60 * 1)
125 #define AARPT_KILLC 20
126 #define AARPT_KILLI 3
127
128 u_int8_t atmulticastaddr[ 6 ] = {
129 0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
130 };
131
132 u_int8_t at_org_code[ 3 ] = {
133 0x08, 0x00, 0x07,
134 };
135 u_int8_t aarp_org_code[ 3 ] = {
136 0x00, 0x00, 0x00,
137 };
138
139
140 static void
141 aarptimer(v)
142 void *v;
143 {
144 struct aarptab *aat;
145 int i, s;
146
147 timeout_add(&aarptimer_timeout, AARPT_AGE * hz);
148 aat = aarptab;
149 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) {
150 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM ))
151 continue;
152 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ?
153 AARPT_KILLC : AARPT_KILLI ))
154 continue;
155 s = splnet();
156 aarptfree( aat );
157 splx( s );
158 }
159 }
160
161 struct ifaddr *
162 at_ifawithnet( sat, ifa )
163 struct sockaddr_at *sat;
164 struct ifaddr *ifa;
165 {
166 struct sockaddr_at *sat2;
167 struct netrange *nr;
168
169 for (; ifa; ifa = ifa->ifa_list.tqe_next ) {
170 if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) {
171 continue;
172 }
173 sat2 = satosat( ifa->ifa_addr );
174 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) {
175 break;
176 }
177 nr = (struct netrange *)(sat2->sat_zero);
178 if( (nr->nr_phase == 2 )
179 && (ntohs(nr->nr_firstnet) <= ntohs(sat->sat_addr.s_net))
180 && (ntohs(nr->nr_lastnet) >= ntohs(sat->sat_addr.s_net))) {
181 break;
182 }
183 }
184 return( ifa );
185 }
186
187 static void
188 aarpwhohas( ac, sat )
189 struct arpcom *ac;
190 struct sockaddr_at *sat;
191 {
192 struct mbuf *m;
193 struct ether_header *eh;
194 struct ether_aarp *ea;
195 struct at_ifaddr *aa;
196 struct llc *llc;
197 struct sockaddr sa;
198
199 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
200 return;
201 }
202 m->m_len = sizeof( *ea );
203 m->m_pkthdr.len = sizeof( *ea );
204 MH_ALIGN( m, sizeof( *ea ));
205
206 ea = mtod( m, struct ether_aarp *);
207 bzero((caddr_t)ea, sizeof( *ea ));
208
209 ea->aarp_hrd = htons( AARPHRD_ETHER );
210 ea->aarp_pro = htons( ETHERTYPE_AT );
211 ea->aarp_hln = sizeof( ea->aarp_sha );
212 ea->aarp_pln = sizeof( ea->aarp_spu );
213 ea->aarp_op = htons( AARPOP_REQUEST );
214 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
215 sizeof( ea->aarp_sha ));
216
217
218
219
220
221
222
223
224 if (( aa = (struct at_ifaddr *)
225 at_ifawithnet( sat, ac->ac_if.if_addrlist.tqh_first )) == NULL ) {
226 m_freem( m );
227 return;
228 }
229
230 eh = (struct ether_header *)sa.sa_data;
231
232 if ( aa->aa_flags & AFA_PHASE2 ) {
233 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
234 sizeof( eh->ether_dhost ));
235 eh->ether_type = htons(AT_LLC_SIZE + sizeof(struct ether_aarp));
236 M_PREPEND( m, AT_LLC_SIZE, M_DONTWAIT );
237 if (!m)
238 return;
239
240 llc = mtod( m, struct llc *);
241 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
242 llc->llc_control = LLC_UI;
243 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
244 llc->llc_ether_type = htons( ETHERTYPE_AARP );
245
246 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
247 sizeof( ea->aarp_spnet ));
248 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node;
249 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet,
250 sizeof( ea->aarp_tpnet ));
251 ea->aarp_tpnode = sat->sat_addr.s_node;
252 } else {
253 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
254 sizeof( eh->ether_dhost ));
255 eh->ether_type = htons( ETHERTYPE_AARP );
256
257 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node;
258 ea->aarp_tpa = sat->sat_addr.s_node;
259 }
260
261 sa.sa_len = sizeof( struct sockaddr );
262 sa.sa_family = AF_UNSPEC;
263
264 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa , NULL);
265 }
266
267 int
268 aarpresolve( ac, m, destsat, desten )
269 struct arpcom *ac;
270 struct mbuf *m;
271 struct sockaddr_at *destsat;
272 u_int8_t *desten;
273 {
274 struct at_ifaddr *aa;
275 struct aarptab *aat;
276 int s;
277
278 if ( at_broadcast( destsat )) {
279 if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat,
280 ((struct ifnet *)ac)->if_addrlist.tqh_first )) == NULL ) {
281 m_freem( m );
282 return( 0 );
283 }
284 if ( aa->aa_flags & AFA_PHASE2 ) {
285 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten,
286 sizeof( atmulticastaddr ));
287 } else {
288 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten,
289 sizeof( etherbroadcastaddr ));
290 }
291 return( 1 );
292 }
293
294 s = splnet();
295 AARPTAB_LOOK( aat, destsat->sat_addr );
296 if ( aat == 0 ) {
297 aat = aarptnew( &destsat->sat_addr );
298 if ( aat == 0 ) {
299 panic( "aarpresolve: no free entry" );
300 }
301 aat->aat_hold = m;
302 aarpwhohas( ac, destsat );
303 splx( s );
304 return( 0 );
305 }
306
307 aat->aat_timer = 0;
308 if ( aat->aat_flags & ATF_COM ) {
309 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten,
310 sizeof( aat->aat_enaddr ));
311 splx( s );
312 return( 1 );
313 }
314
315 if ( aat->aat_hold ) {
316 m_freem( aat->aat_hold );
317 }
318 aat->aat_hold = m;
319 aarpwhohas( ac, destsat );
320 splx( s );
321 return( 0 );
322 }
323
324 void
325 aarpinput( ac, m )
326 struct arpcom *ac;
327 struct mbuf *m;
328 {
329 struct arphdr *ar;
330
331 if ( ac->ac_if.if_flags & IFF_NOARP )
332 goto out;
333
334 if ( m->m_len < sizeof( struct arphdr )) {
335 goto out;
336 }
337
338 ar = mtod( m, struct arphdr *);
339 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) {
340 goto out;
341 }
342
343 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln +
344 2 * ar->ar_pln ) {
345 goto out;
346 }
347
348 switch( ntohs( ar->ar_pro )) {
349 case ETHERTYPE_AT :
350 at_aarpinput( ac, m );
351 return;
352
353 default:
354 break;
355 }
356
357 out:
358 m_freem( m );
359 }
360
361
362 static void
363 at_aarpinput( ac, m )
364 struct arpcom *ac;
365 struct mbuf *m;
366 {
367 struct ether_aarp *ea;
368 struct at_ifaddr *aa;
369 struct aarptab *aat;
370 struct ether_header *eh;
371 struct llc *llc;
372 struct sockaddr_at sat;
373 struct sockaddr sa;
374 struct at_addr spa, tpa, ma;
375 int op;
376 u_int16_t net;
377
378 ea = mtod( m, struct ether_aarp *);
379
380
381 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr,
382 sizeof( ac->ac_enaddr ))) {
383 m_freem( m );
384 return;
385 }
386
387
388
389
390
391 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )etherbroadcastaddr,
392 sizeof( etherbroadcastaddr ))) {
393 log( LOG_ERR,
394 "aarp: source is broadcast!\n" );
395 m_freem( m );
396 return;
397 }
398
399 op = ntohs( ea->aarp_op );
400 bcopy( ea->aarp_tpnet, &net, sizeof( net ));
401
402 if ( net != 0 ) {
403 sat.sat_len = sizeof(struct sockaddr_at);
404 sat.sat_family = AF_APPLETALK;
405 sat.sat_addr.s_net = net;
406 if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat,
407 ac->ac_if.if_addrlist.tqh_first )) == NULL ) {
408 m_freem( m );
409 return;
410 }
411 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net ));
412 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net ));
413 } else {
414
415
416
417
418 for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist.tqh_first; aa;
419 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_list.tqe_next ) {
420 if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
421 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
422 break;
423 }
424 }
425 if ( aa == NULL ) {
426 m_freem( m );
427 return;
428 }
429 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net;
430 }
431
432 spa.s_node = ea->aarp_spnode;
433 tpa.s_node = ea->aarp_tpnode;
434 ma.s_net = AA_SAT( aa )->sat_addr.s_net;
435 ma.s_node = AA_SAT( aa )->sat_addr.s_node;
436
437
438
439
440 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) {
441 if ( aa->aa_flags & AFA_PROBING ) {
442
443
444
445
446
447 timeout_del(&aarpprobe_timeout);
448 wakeup( aa );
449 m_freem( m );
450 return;
451 } else if ( op != AARPOP_PROBE ) {
452
453
454
455
456
457
458 log( LOG_ERR,
459 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
460 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ],
461 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]);
462 m_freem( m );
463 return;
464 }
465 }
466
467 AARPTAB_LOOK( aat, spa );
468 if ( aat ) {
469 if ( op == AARPOP_PROBE ) {
470
471
472
473
474
475 aarptfree( aat );
476 m_freem( m );
477 return;
478 }
479
480 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
481 sizeof( ea->aarp_sha ));
482 aat->aat_flags |= ATF_COM;
483 if ( aat->aat_hold ) {
484 sat.sat_len = sizeof(struct sockaddr_at);
485 sat.sat_family = AF_APPLETALK;
486 sat.sat_addr = spa;
487
488 (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold,
489 (struct sockaddr *)&sat, NULL );
490 aat->aat_hold = 0;
491 }
492 }
493
494 if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node
495 && op != AARPOP_PROBE ) {
496 if ( (aat = aarptnew( &spa ))) {
497 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr,
498 sizeof( ea->aarp_sha ));
499 aat->aat_flags |= ATF_COM;
500 }
501 }
502
503
504
505
506
507 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
508 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) {
509 m_freem( m );
510 return;
511 }
512
513 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha,
514 sizeof( ea->aarp_sha ));
515 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha,
516 sizeof( ea->aarp_sha ));
517
518
519 eh = (struct ether_header *)sa.sa_data;
520 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost,
521 sizeof( eh->ether_dhost ));
522
523 if ( aa->aa_flags & AFA_PHASE2 ) {
524 eh->ether_type = htons( AT_LLC_SIZE +
525 sizeof( struct ether_aarp ));
526 M_PREPEND( m, AT_LLC_SIZE, M_DONTWAIT );
527 if ( m == NULL ) {
528 return;
529 }
530 llc = mtod( m, struct llc *);
531 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
532 llc->llc_control = LLC_UI;
533 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
534 llc->llc_ether_type = htons( ETHERTYPE_AARP );
535
536 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet ));
537 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet ));
538 } else {
539 eh->ether_type = htons( ETHERTYPE_AARP );
540 }
541
542 ea->aarp_tpnode = ea->aarp_spnode;
543 ea->aarp_spnode = ma.s_node;
544 ea->aarp_op = htons( AARPOP_RESPONSE );
545
546 sa.sa_len = sizeof( struct sockaddr );
547 sa.sa_family = AF_UNSPEC;
548
549 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL );
550 return;
551 }
552
553 static void
554 aarptfree( aat )
555 struct aarptab *aat;
556 {
557
558 if ( aat->aat_hold )
559 m_freem( aat->aat_hold );
560 aat->aat_hold = 0;
561 aat->aat_timer = aat->aat_flags = 0;
562 aat->aat_ataddr.s_net = 0;
563 aat->aat_ataddr.s_node = 0;
564 }
565
566 struct aarptab *
567 aarptnew( addr )
568 struct at_addr *addr;
569 {
570 int n;
571 int oldest = -1;
572 struct aarptab *aat, *aato = NULL;
573 static int first = 1;
574
575 if ( first ) {
576 first = 0;
577 timeout_set(&aarptimer_timeout, aarptimer, NULL);
578 timeout_add(&aarptimer_timeout, hz);
579 }
580 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ];
581 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) {
582 if ( aat->aat_flags == 0 )
583 goto out;
584 if ( aat->aat_flags & ATF_PERM )
585 continue;
586 if ((int) aat->aat_timer > oldest ) {
587 oldest = aat->aat_timer;
588 aato = aat;
589 }
590 }
591 if ( aato == NULL )
592 return( NULL );
593 aat = aato;
594 aarptfree( aat );
595 out:
596 aat->aat_ataddr = *addr;
597 aat->aat_flags = ATF_INUSE;
598 return( aat );
599 }
600
601 void
602 aarpprobe( arg )
603 void *arg;
604 {
605 struct arpcom *ac = (struct arpcom *) arg;
606 struct mbuf *m;
607 struct ether_header *eh;
608 struct ether_aarp *ea;
609 struct at_ifaddr *aa;
610 struct llc *llc;
611 struct sockaddr sa;
612
613
614
615
616
617
618
619
620 for ( aa = (struct at_ifaddr *)ac->ac_if.if_addrlist.tqh_first; aa;
621 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_list.tqe_next) {
622 if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
623 ( aa->aa_flags & AFA_PROBING )) {
624 break;
625 }
626 }
627 if ( aa == NULL ) {
628 printf( "aarpprobe why did this happen?!\n" );
629 return;
630 }
631
632 if ( aa->aa_probcnt <= 0 ) {
633 aa->aa_flags &= ~AFA_PROBING;
634 wakeup( aa );
635 return;
636 } else {
637 timeout_set(&aarpprobe_timeout, aarpprobe, ac);
638 timeout_add(&aarpprobe_timeout, hz / 5);
639 }
640
641 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) {
642 return;
643 }
644 m->m_len = sizeof( *ea );
645 m->m_pkthdr.len = sizeof( *ea );
646 MH_ALIGN( m, sizeof( *ea ));
647
648 ea = mtod( m, struct ether_aarp *);
649 bzero((caddr_t)ea, sizeof( *ea ));
650
651 ea->aarp_hrd = htons( AARPHRD_ETHER );
652 ea->aarp_pro = htons( ETHERTYPE_AT );
653 ea->aarp_hln = sizeof( ea->aarp_sha );
654 ea->aarp_pln = sizeof( ea->aarp_spu );
655 ea->aarp_op = htons( AARPOP_PROBE );
656 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha,
657 sizeof( ea->aarp_sha ));
658
659 eh = (struct ether_header *)sa.sa_data;
660
661 if ( aa->aa_flags & AFA_PHASE2 ) {
662 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost,
663 sizeof( eh->ether_dhost ));
664 eh->ether_type = htons( AT_LLC_SIZE +
665 sizeof( struct ether_aarp ));
666 M_PREPEND( m, AT_LLC_SIZE, M_DONTWAIT );
667 if (!m)
668 return;
669
670 llc = mtod( m, struct llc *);
671 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
672 llc->llc_control = LLC_UI;
673 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code ));
674 llc->llc_ether_type = htons( ETHERTYPE_AARP );
675
676 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet,
677 sizeof( ea->aarp_spnet ));
678 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet,
679 sizeof( ea->aarp_tpnet ));
680 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node;
681 } else {
682 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
683 sizeof( eh->ether_dhost ));
684 eh->ether_type = htons( ETHERTYPE_AARP );
685 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node;
686 }
687
688 sa.sa_len = sizeof( struct sockaddr );
689 sa.sa_family = AF_UNSPEC;
690
691 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL );
692 aa->aa_probcnt--;
693 }
694
695 void
696 aarp_clean(void)
697 {
698 struct aarptab *aat;
699 int i;
700
701 timeout_del(&aarptimer_timeout);
702 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) {
703 if ( aat->aat_hold ) {
704 m_freem( aat->aat_hold );
705 }
706 }
707 }