1/* 2 * Copyright (c) 1990,1991 Regents of The University of Michigan. 3 * All Rights Reserved. 4 */ 5 6#include <sys/types.h> 7#include <sys/cdefs.h> 8#include <sys/socket.h> 9#include <sys/syslog.h> 10#include <sys/param.h> |
11#include <machine/endian.h> 12#include <sys/systm.h> 13#include <sys/proc.h> |
14#include <sys/mbuf.h> 15#include <sys/time.h> |
16#include <sys/kernel.h> |
17#include <net/if.h> 18#include <net/route.h> |
19#include <netinet/in.h> 20#undef s_net 21#include <netinet/if_ether.h> |
22 23#include <netatalk/at.h> 24#include <netatalk/at_var.h> 25#include <netatalk/aarp.h> 26#include <netatalk/ddp_var.h> 27#include <netatalk/phase2.h> 28#include <netatalk/at_extern.h> 29 30static void aarptfree( struct aarptab *aat); 31static void at_aarpinput( struct arpcom *ac, struct mbuf *m); 32 |
33#define AARPTAB_BSIZ 9 34#define AARPTAB_NB 19 |
35#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 36struct aarptab aarptab[AARPTAB_SIZE]; 37int aarptab_size = AARPTAB_SIZE; 38 39#define AARPTAB_HASH(a) \ 40 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 41 42#define AARPTAB_LOOK(aat,addr) { \ --- 6 unchanged lines hidden (view full) --- 49 if ( n >= AARPTAB_BSIZ ) \ 50 aat = 0; \ 51} 52 53#define AARPT_AGE (60 * 1) 54#define AARPT_KILLC 20 55#define AARPT_KILLI 3 56 |
57# if !defined( __FreeBSD__ ) 58extern u_char etherbroadcastaddr[6]; 59# endif __FreeBSD__ |
60 61u_char atmulticastaddr[ 6 ] = { 62 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 63}; 64 65u_char at_org_code[ 3 ] = { 66 0x08, 0x00, 0x07, 67}; --- 21 unchanged lines hidden (view full) --- 89 } 90} 91 92struct ifaddr * 93at_ifawithnet( sat, ifa ) 94 struct sockaddr_at *sat; 95 struct ifaddr *ifa; 96{ |
97 98 for (; ifa; ifa = ifa->ifa_next ) { |
99 if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) { 100 continue; 101 } 102 if ( satosat( ifa->ifa_addr )->sat_addr.s_net == 103 sat->sat_addr.s_net ) { 104 break; 105 } |
106 } 107 return( ifa ); 108} 109 110static void 111aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat ) 112{ 113 struct mbuf *m; 114 struct ether_header *eh; 115 struct ether_aarp *ea; 116 struct at_ifaddr *aa; 117 struct llc *llc; 118 struct sockaddr sa; 119 |
120 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 121 return; 122 } 123 m->m_len = sizeof( *ea ); 124 m->m_pkthdr.len = sizeof( *ea ); 125 MH_ALIGN( m, sizeof( *ea )); |
126 127 ea = mtod( m, struct ether_aarp *); 128 bzero((caddr_t)ea, sizeof( *ea )); 129 130 ea->aarp_hrd = htons( AARPHRD_ETHER ); 131 ea->aarp_pro = htons( ETHERTYPE_AT ); 132 ea->aarp_hln = sizeof( ea->aarp_sha ); 133 ea->aarp_pln = sizeof( ea->aarp_spu ); 134 ea->aarp_op = htons( AARPOP_REQUEST ); |
135 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 136 sizeof( ea->aarp_sha )); |
137 138 /* 139 * We need to check whether the output ethernet type should 140 * be phase 1 or 2. We have the interface that we'll be sending 141 * the aarp out. We need to find an AppleTalk network on that 142 * interface with the same address as we're looking for. If the 143 * net is phase 2, generate an 802.2 and SNAP header. 144 */ 145 if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist )) 146 == NULL ) { 147 m_freem( m ); 148 return; 149 } 150 151 eh = (struct ether_header *)sa.sa_data; 152 153 if ( aa->aa_flags & AFA_PHASE2 ) { |
154 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 155 sizeof( eh->ether_dhost )); |
156 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp)); |
157 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); |
158 llc = mtod( m, struct llc *); 159 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 160 llc->llc_control = LLC_UI; 161 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 162 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 163 164 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 165 sizeof( ea->aarp_spnet )); 166 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet, 167 sizeof( ea->aarp_tpnet )); 168 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node; 169 ea->aarp_tpnode = sat->sat_addr.s_node; 170 } else { |
171 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 172 sizeof( eh->ether_dhost )); |
173 eh->ether_type = htons( ETHERTYPE_AARP ); |
174 175 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 176 ea->aarp_tpa = sat->sat_addr.s_node; 177 } 178 179#ifdef NETATALKDEBUG 180 printf("aarp: sending request for %u.%u\n", 181 ntohs(AA_SAT( aa )->sat_addr.s_net), 182 AA_SAT( aa )->sat_addr.s_node); 183#endif NETATALKDEBUG 184 |
185 sa.sa_len = sizeof( struct sockaddr ); |
186 sa.sa_family = AF_UNSPEC; |
187 (*ac->ac_if.if_output)(&ac->ac_if, 188 m, &sa, NULL); /* XXX NULL should be routing information */ |
189} 190 191int 192aarpresolve( ac, m, destsat, desten ) 193 struct arpcom *ac; 194 struct mbuf *m; 195 struct sockaddr_at *destsat; |
196 u_char *desten; |
197{ 198 struct at_ifaddr *aa; |
199 struct aarptab *aat; 200 int s; 201 202 if ( at_broadcast( destsat )) { 203 if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat, 204 ((struct ifnet *)ac)->if_addrlist )) == NULL ) { 205 m_freem( m ); 206 return( 0 ); 207 } 208 if ( aa->aa_flags & AFA_PHASE2 ) { 209 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 210 sizeof( atmulticastaddr )); 211 } else { |
212 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 213 sizeof( etherbroadcastaddr )); |
214 } 215 return( 1 ); 216 } 217 218 s = splimp(); 219 AARPTAB_LOOK( aat, destsat->sat_addr ); 220 if ( aat == 0 ) { /* No entry */ 221 aat = aarptnew( &destsat->sat_addr ); --- 28 unchanged lines hidden (view full) --- 250 struct arpcom *ac; 251 struct mbuf *m; 252{ 253 struct arphdr *ar; 254 255 if ( ac->ac_if.if_flags & IFF_NOARP ) 256 goto out; 257 |
258 if ( m->m_len < sizeof( struct arphdr )) { 259 goto out; 260 } 261 262 ar = mtod( m, struct arphdr *); 263 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 264 goto out; 265 } --- 14 unchanged lines hidden (view full) --- 280 281out: 282 m_freem( m ); 283} 284 285static void 286at_aarpinput( struct arpcom *ac, struct mbuf *m) 287{ |
288 struct ether_aarp *ea; 289 struct at_ifaddr *aa; 290 struct aarptab *aat; 291 struct ether_header *eh; 292 struct llc *llc; 293 struct sockaddr_at sat; 294 struct sockaddr sa; 295 struct at_addr spa, tpa, ma; |
296 int op; |
297 u_short net; 298 299 ea = mtod( m, struct ether_aarp *); 300 301 /* Check to see if from my hardware address */ |
302 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 303 sizeof( ac->ac_enaddr ))) { 304 m_freem( m ); 305 return; 306 } |
307 308 op = ntohs( ea->aarp_op ); 309 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 310 311 if ( net != 0 ) { /* should be ATADDR_ANYNET? */ |
312 sat.sat_len = sizeof(struct sockaddr_at); |
313 sat.sat_family = AF_APPLETALK; 314 sat.sat_addr.s_net = net; 315 if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat, 316 ac->ac_if.if_addrlist )) == NULL ) { 317 m_freem( m ); 318 return; 319 } 320 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); --- 37 unchanged lines hidden (view full) --- 358 m_freem( m ); 359 return; 360 } else if ( op != AARPOP_PROBE ) { 361 /* 362 * This is not a probe, and we're not probing. This means 363 * that someone's saying they have the same source address 364 * as the one we're using. Get upset... 365 */ |
366 log( LOG_ERR, |
367 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n", 368 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ], 369 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]); |
370 m_freem( m ); 371 return; 372 } 373 } 374 375 AARPTAB_LOOK( aat, spa ); 376 if ( aat ) { 377 if ( op == AARPOP_PROBE ) { --- 6 unchanged lines hidden (view full) --- 384 m_freem( m ); 385 return; 386 } 387 388 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 389 sizeof( ea->aarp_sha )); 390 aat->aat_flags |= ATF_COM; 391 if ( aat->aat_hold ) { |
392 sat.sat_len = sizeof(struct sockaddr_at); |
393 sat.sat_family = AF_APPLETALK; 394 sat.sat_addr = spa; |
395 (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold, |
396 (struct sockaddr *)&sat, NULL); /* XXX */ |
397 aat->aat_hold = 0; 398 } 399 } 400 401 if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node 402 && op != AARPOP_PROBE ) { 403 if ( aat = aarptnew( &spa )) { 404 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, --- 9 unchanged lines hidden (view full) --- 414 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 415 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 416 m_freem( m ); 417 return; 418 } 419 420 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 421 sizeof( ea->aarp_sha )); |
422 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 423 sizeof( ea->aarp_sha )); |
424 425 /* XXX */ 426 eh = (struct ether_header *)sa.sa_data; |
427 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 428 sizeof( eh->ether_dhost )); |
429 430 if ( aa->aa_flags & AFA_PHASE2 ) { |
431 eh->ether_type = htons( sizeof( struct llc ) + 432 sizeof( struct ether_aarp )); |
433 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 434 if ( m == NULL ) { 435 return; 436 } |
437 llc = mtod( m, struct llc *); 438 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 439 llc->llc_control = LLC_UI; 440 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 441 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 442 443 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 444 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 445 } else { |
446 eh->ether_type = htons( ETHERTYPE_AARP ); |
447 } 448 449 ea->aarp_tpnode = ea->aarp_spnode; 450 ea->aarp_spnode = ma.s_node; 451 ea->aarp_op = htons( AARPOP_RESPONSE ); 452 |
453 sa.sa_len = sizeof( struct sockaddr ); |
454 sa.sa_family = AF_UNSPEC; |
455 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */ |
456 return; 457} 458 459static void 460aarptfree( struct aarptab *aat) 461{ 462 463 if ( aat->aat_hold ) --- 71 unchanged lines hidden (view full) --- 535 if ( aa->aa_probcnt <= 0 ) { 536 aa->aa_flags &= ~AFA_PROBING; 537 wakeup( aa ); 538 return; 539 } else { 540 timeout( (timeout_func_t)aarpprobe, (caddr_t)ac, hz / 5 ); 541 } 542 |
543 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 544 return; 545 } 546 m->m_len = sizeof( *ea ); 547 m->m_pkthdr.len = sizeof( *ea ); 548 MH_ALIGN( m, sizeof( *ea )); |
549 550 ea = mtod( m, struct ether_aarp *); 551 bzero((caddr_t)ea, sizeof( *ea )); 552 553 ea->aarp_hrd = htons( AARPHRD_ETHER ); 554 ea->aarp_pro = htons( ETHERTYPE_AT ); 555 ea->aarp_hln = sizeof( ea->aarp_sha ); 556 ea->aarp_pln = sizeof( ea->aarp_spu ); 557 ea->aarp_op = htons( AARPOP_PROBE ); |
558 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 559 sizeof( ea->aarp_sha )); |
560 561 eh = (struct ether_header *)sa.sa_data; 562 563 if ( aa->aa_flags & AFA_PHASE2 ) { |
564 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 565 sizeof( eh->ether_dhost )); |
566 eh->ether_type = htons( sizeof( struct llc ) + 567 sizeof( struct ether_aarp )); |
568 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); |
569 llc = mtod( m, struct llc *); 570 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 571 llc->llc_control = LLC_UI; 572 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 573 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 574 575 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 576 sizeof( ea->aarp_spnet )); 577 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet, 578 sizeof( ea->aarp_tpnet )); 579 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node; 580 } else { |
581 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 582 sizeof( eh->ether_dhost )); |
583 eh->ether_type = htons( ETHERTYPE_AARP ); |
584 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node; 585 } 586 587#ifdef NETATALKDEBUG 588 printf("aarp: sending probe for %u.%u\n", 589 ntohs(AA_SAT( aa )->sat_addr.s_net), 590 AA_SAT( aa )->sat_addr.s_node); 591#endif NETATALKDEBUG 592 |
593 sa.sa_len = sizeof( struct sockaddr ); |
594 sa.sa_family = AF_UNSPEC; |
595 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */ |
596 aa->aa_probcnt--; 597} 598 599void 600aarp_clean(void) 601{ 602 struct aarptab *aat; 603 int i; 604 605 untimeout( aarptimer, 0 ); 606 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) { 607 if ( aat->aat_hold ) { 608 m_freem( aat->aat_hold ); 609 } 610 } 611} |