59 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 60}; 61 62u_char at_org_code[ 3 ] = { 63 0x08, 0x00, 0x07, 64}; 65u_char aarp_org_code[ 3 ] = { 66 0x00, 0x00, 0x00, 67}; 68 69static struct callout_handle aarptimer_ch = 70 CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch); 71 72static void 73aarptimer(void *ignored) 74{ 75 struct aarptab *aat; 76 int i, s; 77 78 aarptimer_ch = timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz ); 79 aat = aarptab; 80 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) { 81 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM )) 82 continue; 83 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ? 84 AARPT_KILLC : AARPT_KILLI )) 85 continue; 86 s = splimp(); 87 aarptfree( aat ); 88 splx( s ); 89 } 90} 91 92/* 93 * search through the network addresses to find one that includes 94 * the given network.. remember to take netranges into 95 * consideration. 96 */ 97struct at_ifaddr * 98at_ifawithnet(struct sockaddr_at *sat ) 99{ 100 struct at_ifaddr *aa; 101 struct sockaddr_at *sat2; 102 103 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 104 sat2 = &(aa->aa_addr); 105 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { 106 break; 107 } 108 if( (aa->aa_flags & AFA_PHASE2 ) 109 && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) 110 && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) { 111 break; 112 } 113 } 114 return( aa ); 115} 116 117static void 118aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat ) 119{ 120 struct mbuf *m; 121 struct ether_header *eh; 122 struct ether_aarp *ea; 123 struct at_ifaddr *aa; 124 struct llc *llc; 125 struct sockaddr sa; 126 127 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 128 return; 129 } 130 m->m_len = sizeof( *ea ); 131 m->m_pkthdr.len = sizeof( *ea ); 132 MH_ALIGN( m, sizeof( *ea )); 133 134 ea = mtod( m, struct ether_aarp *); 135 bzero((caddr_t)ea, sizeof( *ea )); 136 137 ea->aarp_hrd = htons( AARPHRD_ETHER ); 138 ea->aarp_pro = htons( ETHERTYPE_AT ); 139 ea->aarp_hln = sizeof( ea->aarp_sha ); 140 ea->aarp_pln = sizeof( ea->aarp_spu ); 141 ea->aarp_op = htons( AARPOP_REQUEST ); 142 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 143 sizeof( ea->aarp_sha )); 144 145 /* 146 * We need to check whether the output ethernet type should 147 * be phase 1 or 2. We have the interface that we'll be sending 148 * the aarp out. We need to find an AppleTalk network on that 149 * interface with the same address as we're looking for. If the 150 * net is phase 2, generate an 802.2 and SNAP header. 151 */ 152 if ((aa = at_ifawithnet( sat )) == NULL) { 153 m_freem( m ); 154 return; 155 } 156 157 eh = (struct ether_header *)sa.sa_data; 158 159 if ( aa->aa_flags & AFA_PHASE2 ) { 160 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 161 sizeof( eh->ether_dhost )); 162 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp)); 163 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 164 llc = mtod( m, struct llc *); 165 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 166 llc->llc_control = LLC_UI; 167 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 168 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 169 170 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 171 sizeof( ea->aarp_spnet )); 172 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet, 173 sizeof( ea->aarp_tpnet )); 174 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node; 175 ea->aarp_tpnode = sat->sat_addr.s_node; 176 } else { 177 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 178 sizeof( eh->ether_dhost )); 179 eh->ether_type = htons( ETHERTYPE_AARP ); 180 181 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 182 ea->aarp_tpa = sat->sat_addr.s_node; 183 } 184 185#ifdef NETATALKDEBUG 186 printf("aarp: sending request for %u.%u\n", 187 ntohs(AA_SAT( aa )->sat_addr.s_net), 188 AA_SAT( aa )->sat_addr.s_node); 189#endif /* NETATALKDEBUG */ 190 191 sa.sa_len = sizeof( struct sockaddr ); 192 sa.sa_family = AF_UNSPEC; 193 (*ac->ac_if.if_output)(&ac->ac_if, 194 m, &sa, NULL); /* XXX NULL should be routing information */ 195} 196 197int 198aarpresolve( ac, m, destsat, desten ) 199 struct arpcom *ac; 200 struct mbuf *m; 201 struct sockaddr_at *destsat; 202 u_char *desten; 203{ 204 struct at_ifaddr *aa; 205 struct aarptab *aat; 206 int s; 207 208 if ( at_broadcast( destsat )) { 209 m->m_flags |= M_BCAST; 210 if ((aa = at_ifawithnet( destsat )) == NULL) { 211 m_freem( m ); 212 return( 0 ); 213 } 214 if ( aa->aa_flags & AFA_PHASE2 ) { 215 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 216 sizeof( atmulticastaddr )); 217 } else { 218 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 219 sizeof( etherbroadcastaddr )); 220 } 221 return( 1 ); 222 } 223 224 s = splimp(); 225 AARPTAB_LOOK( aat, destsat->sat_addr ); 226 if ( aat == 0 ) { /* No entry */ 227 aat = aarptnew( &destsat->sat_addr ); 228 if ( aat == 0 ) { 229 panic( "aarpresolve: no free entry" ); 230 } 231 aat->aat_hold = m; 232 aarpwhohas( ac, destsat ); 233 splx( s ); 234 return( 0 ); 235 } 236 /* found an entry */ 237 aat->aat_timer = 0; 238 if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */ 239 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten, 240 sizeof( aat->aat_enaddr )); 241 splx( s ); 242 return( 1 ); 243 } 244 /* entry has not completed */ 245 if ( aat->aat_hold ) { 246 m_freem( aat->aat_hold ); 247 } 248 aat->aat_hold = m; 249 aarpwhohas( ac, destsat ); 250 splx( s ); 251 return( 0 ); 252} 253 254void 255aarpinput( ac, m ) 256 struct arpcom *ac; 257 struct mbuf *m; 258{ 259 struct arphdr *ar; 260 261 if ( ac->ac_if.if_flags & IFF_NOARP ) 262 goto out; 263 264 if ( m->m_len < sizeof( struct arphdr )) { 265 goto out; 266 } 267 268 ar = mtod( m, struct arphdr *); 269 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 270 goto out; 271 } 272 273 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln + 274 2 * ar->ar_pln ) { 275 goto out; 276 } 277 278 switch( ntohs( ar->ar_pro )) { 279 case ETHERTYPE_AT : 280 at_aarpinput( ac, m ); 281 return; 282 283 default: 284 break; 285 } 286 287out: 288 m_freem( m ); 289} 290 291static void 292at_aarpinput( struct arpcom *ac, struct mbuf *m) 293{ 294 struct ether_aarp *ea; 295 struct at_ifaddr *aa; 296 struct aarptab *aat; 297 struct ether_header *eh; 298 struct llc *llc; 299 struct sockaddr_at sat; 300 struct sockaddr sa; 301 struct at_addr spa, tpa, ma; 302 int op; 303 u_short net; 304 305 ea = mtod( m, struct ether_aarp *); 306 307 /* Check to see if from my hardware address */ 308 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 309 sizeof( ac->ac_enaddr ))) { 310 m_freem( m ); 311 return; 312 } 313 314 op = ntohs( ea->aarp_op ); 315 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 316 317 if ( net != 0 ) { /* should be ATADDR_ANYNET? */ 318 sat.sat_len = sizeof(struct sockaddr_at); 319 sat.sat_family = AF_APPLETALK; 320 sat.sat_addr.s_net = net; 321 if ((aa = at_ifawithnet( &sat )) == NULL) { 322 m_freem( m ); 323 return; 324 } 325 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); 326 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net )); 327 } else { 328 /* 329 * Since we don't know the net, we just look for the first 330 * phase 1 address on the interface. 331 */ 332 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa; 333 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 334 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 335 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 336 break; 337 } 338 } 339 if ( aa == NULL ) { 340 m_freem( m ); 341 return; 342 } 343 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net; 344 } 345 346 spa.s_node = ea->aarp_spnode; 347 tpa.s_node = ea->aarp_tpnode; 348 ma.s_net = AA_SAT( aa )->sat_addr.s_net; 349 ma.s_node = AA_SAT( aa )->sat_addr.s_node; 350 351 /* 352 * This looks like it's from us. 353 */ 354 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) { 355 if ( aa->aa_flags & AFA_PROBING ) { 356 /* 357 * We're probing, someone either responded to our probe, or 358 * probed for the same address we'd like to use. Change the 359 * address we're probing for. 360 */ 361 untimeout( aarpprobe, ac, aa->aa_ch ); 362 wakeup( aa ); 363 m_freem( m ); 364 return; 365 } else if ( op != AARPOP_PROBE ) { 366 /* 367 * This is not a probe, and we're not probing. This means 368 * that someone's saying they have the same source address 369 * as the one we're using. Get upset... 370 */ 371 log( LOG_ERR, 372 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n", 373 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ], 374 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]); 375 m_freem( m ); 376 return; 377 } 378 } 379 380 AARPTAB_LOOK( aat, spa ); 381 if ( aat ) { 382 if ( op == AARPOP_PROBE ) { 383 /* 384 * Someone's probing for spa, dealocate the one we've got, 385 * so that if the prober keeps the address, we'll be able 386 * to arp for him. 387 */ 388 aarptfree( aat ); 389 m_freem( m ); 390 return; 391 } 392 393 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 394 sizeof( ea->aarp_sha )); 395 aat->aat_flags |= ATF_COM; 396 if ( aat->aat_hold ) { 397 sat.sat_len = sizeof(struct sockaddr_at); 398 sat.sat_family = AF_APPLETALK; 399 sat.sat_addr = spa; 400 (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold, 401 (struct sockaddr *)&sat, NULL); /* XXX */ 402 aat->aat_hold = 0; 403 } 404 } 405 406 if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node 407 && op != AARPOP_PROBE ) { 408 if ( aat = aarptnew( &spa )) { 409 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 410 sizeof( ea->aarp_sha )); 411 aat->aat_flags |= ATF_COM; 412 } 413 } 414 415 /* 416 * Don't respond to responses, and never respond if we're 417 * still probing. 418 */ 419 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 420 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 421 m_freem( m ); 422 return; 423 } 424 425 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 426 sizeof( ea->aarp_sha )); 427 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 428 sizeof( ea->aarp_sha )); 429 430 /* XXX */ 431 eh = (struct ether_header *)sa.sa_data; 432 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 433 sizeof( eh->ether_dhost )); 434 435 if ( aa->aa_flags & AFA_PHASE2 ) { 436 eh->ether_type = htons( sizeof( struct llc ) + 437 sizeof( struct ether_aarp )); 438 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 439 if ( m == NULL ) { 440 return; 441 } 442 llc = mtod( m, struct llc *); 443 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 444 llc->llc_control = LLC_UI; 445 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 446 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 447 448 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 449 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 450 } else { 451 eh->ether_type = htons( ETHERTYPE_AARP ); 452 } 453 454 ea->aarp_tpnode = ea->aarp_spnode; 455 ea->aarp_spnode = ma.s_node; 456 ea->aarp_op = htons( AARPOP_RESPONSE ); 457 458 sa.sa_len = sizeof( struct sockaddr ); 459 sa.sa_family = AF_UNSPEC; 460 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */ 461 return; 462} 463 464static void 465aarptfree( struct aarptab *aat) 466{ 467 468 if ( aat->aat_hold ) 469 m_freem( aat->aat_hold ); 470 aat->aat_hold = 0; 471 aat->aat_timer = aat->aat_flags = 0; 472 aat->aat_ataddr.s_net = 0; 473 aat->aat_ataddr.s_node = 0; 474} 475 476 struct aarptab * 477aarptnew( addr ) 478 struct at_addr *addr; 479{ 480 int n; 481 int oldest = -1; 482 struct aarptab *aat, *aato = NULL; 483 static int first = 1; 484 485 if ( first ) { 486 first = 0; 487 aarptimer_ch = timeout( aarptimer, (caddr_t)0, hz ); 488 } 489 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ]; 490 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) { 491 if ( aat->aat_flags == 0 ) 492 goto out; 493 if ( aat->aat_flags & ATF_PERM ) 494 continue; 495 if ((int) aat->aat_timer > oldest ) { 496 oldest = aat->aat_timer; 497 aato = aat; 498 } 499 } 500 if ( aato == NULL ) 501 return( NULL ); 502 aat = aato; 503 aarptfree( aat ); 504out: 505 aat->aat_ataddr = *addr; 506 aat->aat_flags = ATF_INUSE; 507 return( aat ); 508} 509 510 511void 512aarpprobe( void *arg ) 513{ 514 struct arpcom *ac = arg; 515 struct mbuf *m; 516 struct ether_header *eh; 517 struct ether_aarp *ea; 518 struct at_ifaddr *aa; 519 struct llc *llc; 520 struct sockaddr sa; 521 522 /* 523 * We need to check whether the output ethernet type should 524 * be phase 1 or 2. We have the interface that we'll be sending 525 * the aarp out. We need to find an AppleTalk network on that 526 * interface with the same address as we're looking for. If the 527 * net is phase 2, generate an 802.2 and SNAP header. 528 */ 529 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa; 530 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 531 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 532 ( aa->aa_flags & AFA_PROBING )) { 533 break; 534 } 535 } 536 if ( aa == NULL ) { /* serious error XXX */ 537 printf( "aarpprobe why did this happen?!\n" ); 538 return; 539 } 540 541 if ( aa->aa_probcnt <= 0 ) { 542 aa->aa_flags &= ~AFA_PROBING; 543 wakeup( aa ); 544 return; 545 } else { 546 aa->aa_ch = timeout( aarpprobe, (caddr_t)ac, hz / 5 ); 547 } 548 549 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 550 return; 551 } 552 m->m_len = sizeof( *ea ); 553 m->m_pkthdr.len = sizeof( *ea ); 554 MH_ALIGN( m, sizeof( *ea )); 555 556 ea = mtod( m, struct ether_aarp *); 557 bzero((caddr_t)ea, sizeof( *ea )); 558 559 ea->aarp_hrd = htons( AARPHRD_ETHER ); 560 ea->aarp_pro = htons( ETHERTYPE_AT ); 561 ea->aarp_hln = sizeof( ea->aarp_sha ); 562 ea->aarp_pln = sizeof( ea->aarp_spu ); 563 ea->aarp_op = htons( AARPOP_PROBE ); 564 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 565 sizeof( ea->aarp_sha )); 566 567 eh = (struct ether_header *)sa.sa_data; 568 569 if ( aa->aa_flags & AFA_PHASE2 ) { 570 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 571 sizeof( eh->ether_dhost )); 572 eh->ether_type = htons( sizeof( struct llc ) + 573 sizeof( struct ether_aarp )); 574 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 575 llc = mtod( m, struct llc *); 576 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 577 llc->llc_control = LLC_UI; 578 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 579 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 580 581 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 582 sizeof( ea->aarp_spnet )); 583 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet, 584 sizeof( ea->aarp_tpnet )); 585 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node; 586 } else { 587 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 588 sizeof( eh->ether_dhost )); 589 eh->ether_type = htons( ETHERTYPE_AARP ); 590 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node; 591 } 592 593#ifdef NETATALKDEBUG 594 printf("aarp: sending probe for %u.%u\n", 595 ntohs(AA_SAT( aa )->sat_addr.s_net), 596 AA_SAT( aa )->sat_addr.s_node); 597#endif /* NETATALKDEBUG */ 598 599 sa.sa_len = sizeof( struct sockaddr ); 600 sa.sa_family = AF_UNSPEC; 601 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */ 602 aa->aa_probcnt--; 603} 604 605void 606aarp_clean(void) 607{ 608 struct aarptab *aat; 609 int i; 610 611 untimeout( aarptimer, 0, aarptimer_ch ); 612 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) { 613 if ( aat->aat_hold ) { 614 m_freem( aat->aat_hold ); 615 } 616 } 617}
| 59 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 60}; 61 62u_char at_org_code[ 3 ] = { 63 0x08, 0x00, 0x07, 64}; 65u_char aarp_org_code[ 3 ] = { 66 0x00, 0x00, 0x00, 67}; 68 69static struct callout_handle aarptimer_ch = 70 CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch); 71 72static void 73aarptimer(void *ignored) 74{ 75 struct aarptab *aat; 76 int i, s; 77 78 aarptimer_ch = timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz ); 79 aat = aarptab; 80 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) { 81 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM )) 82 continue; 83 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ? 84 AARPT_KILLC : AARPT_KILLI )) 85 continue; 86 s = splimp(); 87 aarptfree( aat ); 88 splx( s ); 89 } 90} 91 92/* 93 * search through the network addresses to find one that includes 94 * the given network.. remember to take netranges into 95 * consideration. 96 */ 97struct at_ifaddr * 98at_ifawithnet(struct sockaddr_at *sat ) 99{ 100 struct at_ifaddr *aa; 101 struct sockaddr_at *sat2; 102 103 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 104 sat2 = &(aa->aa_addr); 105 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { 106 break; 107 } 108 if( (aa->aa_flags & AFA_PHASE2 ) 109 && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) 110 && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) { 111 break; 112 } 113 } 114 return( aa ); 115} 116 117static void 118aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat ) 119{ 120 struct mbuf *m; 121 struct ether_header *eh; 122 struct ether_aarp *ea; 123 struct at_ifaddr *aa; 124 struct llc *llc; 125 struct sockaddr sa; 126 127 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 128 return; 129 } 130 m->m_len = sizeof( *ea ); 131 m->m_pkthdr.len = sizeof( *ea ); 132 MH_ALIGN( m, sizeof( *ea )); 133 134 ea = mtod( m, struct ether_aarp *); 135 bzero((caddr_t)ea, sizeof( *ea )); 136 137 ea->aarp_hrd = htons( AARPHRD_ETHER ); 138 ea->aarp_pro = htons( ETHERTYPE_AT ); 139 ea->aarp_hln = sizeof( ea->aarp_sha ); 140 ea->aarp_pln = sizeof( ea->aarp_spu ); 141 ea->aarp_op = htons( AARPOP_REQUEST ); 142 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 143 sizeof( ea->aarp_sha )); 144 145 /* 146 * We need to check whether the output ethernet type should 147 * be phase 1 or 2. We have the interface that we'll be sending 148 * the aarp out. We need to find an AppleTalk network on that 149 * interface with the same address as we're looking for. If the 150 * net is phase 2, generate an 802.2 and SNAP header. 151 */ 152 if ((aa = at_ifawithnet( sat )) == NULL) { 153 m_freem( m ); 154 return; 155 } 156 157 eh = (struct ether_header *)sa.sa_data; 158 159 if ( aa->aa_flags & AFA_PHASE2 ) { 160 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 161 sizeof( eh->ether_dhost )); 162 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp)); 163 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 164 llc = mtod( m, struct llc *); 165 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 166 llc->llc_control = LLC_UI; 167 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 168 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 169 170 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 171 sizeof( ea->aarp_spnet )); 172 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet, 173 sizeof( ea->aarp_tpnet )); 174 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node; 175 ea->aarp_tpnode = sat->sat_addr.s_node; 176 } else { 177 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 178 sizeof( eh->ether_dhost )); 179 eh->ether_type = htons( ETHERTYPE_AARP ); 180 181 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 182 ea->aarp_tpa = sat->sat_addr.s_node; 183 } 184 185#ifdef NETATALKDEBUG 186 printf("aarp: sending request for %u.%u\n", 187 ntohs(AA_SAT( aa )->sat_addr.s_net), 188 AA_SAT( aa )->sat_addr.s_node); 189#endif /* NETATALKDEBUG */ 190 191 sa.sa_len = sizeof( struct sockaddr ); 192 sa.sa_family = AF_UNSPEC; 193 (*ac->ac_if.if_output)(&ac->ac_if, 194 m, &sa, NULL); /* XXX NULL should be routing information */ 195} 196 197int 198aarpresolve( ac, m, destsat, desten ) 199 struct arpcom *ac; 200 struct mbuf *m; 201 struct sockaddr_at *destsat; 202 u_char *desten; 203{ 204 struct at_ifaddr *aa; 205 struct aarptab *aat; 206 int s; 207 208 if ( at_broadcast( destsat )) { 209 m->m_flags |= M_BCAST; 210 if ((aa = at_ifawithnet( destsat )) == NULL) { 211 m_freem( m ); 212 return( 0 ); 213 } 214 if ( aa->aa_flags & AFA_PHASE2 ) { 215 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 216 sizeof( atmulticastaddr )); 217 } else { 218 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 219 sizeof( etherbroadcastaddr )); 220 } 221 return( 1 ); 222 } 223 224 s = splimp(); 225 AARPTAB_LOOK( aat, destsat->sat_addr ); 226 if ( aat == 0 ) { /* No entry */ 227 aat = aarptnew( &destsat->sat_addr ); 228 if ( aat == 0 ) { 229 panic( "aarpresolve: no free entry" ); 230 } 231 aat->aat_hold = m; 232 aarpwhohas( ac, destsat ); 233 splx( s ); 234 return( 0 ); 235 } 236 /* found an entry */ 237 aat->aat_timer = 0; 238 if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */ 239 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten, 240 sizeof( aat->aat_enaddr )); 241 splx( s ); 242 return( 1 ); 243 } 244 /* entry has not completed */ 245 if ( aat->aat_hold ) { 246 m_freem( aat->aat_hold ); 247 } 248 aat->aat_hold = m; 249 aarpwhohas( ac, destsat ); 250 splx( s ); 251 return( 0 ); 252} 253 254void 255aarpinput( ac, m ) 256 struct arpcom *ac; 257 struct mbuf *m; 258{ 259 struct arphdr *ar; 260 261 if ( ac->ac_if.if_flags & IFF_NOARP ) 262 goto out; 263 264 if ( m->m_len < sizeof( struct arphdr )) { 265 goto out; 266 } 267 268 ar = mtod( m, struct arphdr *); 269 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 270 goto out; 271 } 272 273 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln + 274 2 * ar->ar_pln ) { 275 goto out; 276 } 277 278 switch( ntohs( ar->ar_pro )) { 279 case ETHERTYPE_AT : 280 at_aarpinput( ac, m ); 281 return; 282 283 default: 284 break; 285 } 286 287out: 288 m_freem( m ); 289} 290 291static void 292at_aarpinput( struct arpcom *ac, struct mbuf *m) 293{ 294 struct ether_aarp *ea; 295 struct at_ifaddr *aa; 296 struct aarptab *aat; 297 struct ether_header *eh; 298 struct llc *llc; 299 struct sockaddr_at sat; 300 struct sockaddr sa; 301 struct at_addr spa, tpa, ma; 302 int op; 303 u_short net; 304 305 ea = mtod( m, struct ether_aarp *); 306 307 /* Check to see if from my hardware address */ 308 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 309 sizeof( ac->ac_enaddr ))) { 310 m_freem( m ); 311 return; 312 } 313 314 op = ntohs( ea->aarp_op ); 315 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 316 317 if ( net != 0 ) { /* should be ATADDR_ANYNET? */ 318 sat.sat_len = sizeof(struct sockaddr_at); 319 sat.sat_family = AF_APPLETALK; 320 sat.sat_addr.s_net = net; 321 if ((aa = at_ifawithnet( &sat )) == NULL) { 322 m_freem( m ); 323 return; 324 } 325 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); 326 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net )); 327 } else { 328 /* 329 * Since we don't know the net, we just look for the first 330 * phase 1 address on the interface. 331 */ 332 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa; 333 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 334 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 335 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 336 break; 337 } 338 } 339 if ( aa == NULL ) { 340 m_freem( m ); 341 return; 342 } 343 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net; 344 } 345 346 spa.s_node = ea->aarp_spnode; 347 tpa.s_node = ea->aarp_tpnode; 348 ma.s_net = AA_SAT( aa )->sat_addr.s_net; 349 ma.s_node = AA_SAT( aa )->sat_addr.s_node; 350 351 /* 352 * This looks like it's from us. 353 */ 354 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) { 355 if ( aa->aa_flags & AFA_PROBING ) { 356 /* 357 * We're probing, someone either responded to our probe, or 358 * probed for the same address we'd like to use. Change the 359 * address we're probing for. 360 */ 361 untimeout( aarpprobe, ac, aa->aa_ch ); 362 wakeup( aa ); 363 m_freem( m ); 364 return; 365 } else if ( op != AARPOP_PROBE ) { 366 /* 367 * This is not a probe, and we're not probing. This means 368 * that someone's saying they have the same source address 369 * as the one we're using. Get upset... 370 */ 371 log( LOG_ERR, 372 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n", 373 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ], 374 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]); 375 m_freem( m ); 376 return; 377 } 378 } 379 380 AARPTAB_LOOK( aat, spa ); 381 if ( aat ) { 382 if ( op == AARPOP_PROBE ) { 383 /* 384 * Someone's probing for spa, dealocate the one we've got, 385 * so that if the prober keeps the address, we'll be able 386 * to arp for him. 387 */ 388 aarptfree( aat ); 389 m_freem( m ); 390 return; 391 } 392 393 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 394 sizeof( ea->aarp_sha )); 395 aat->aat_flags |= ATF_COM; 396 if ( aat->aat_hold ) { 397 sat.sat_len = sizeof(struct sockaddr_at); 398 sat.sat_family = AF_APPLETALK; 399 sat.sat_addr = spa; 400 (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold, 401 (struct sockaddr *)&sat, NULL); /* XXX */ 402 aat->aat_hold = 0; 403 } 404 } 405 406 if ( aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node 407 && op != AARPOP_PROBE ) { 408 if ( aat = aarptnew( &spa )) { 409 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 410 sizeof( ea->aarp_sha )); 411 aat->aat_flags |= ATF_COM; 412 } 413 } 414 415 /* 416 * Don't respond to responses, and never respond if we're 417 * still probing. 418 */ 419 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 420 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 421 m_freem( m ); 422 return; 423 } 424 425 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 426 sizeof( ea->aarp_sha )); 427 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 428 sizeof( ea->aarp_sha )); 429 430 /* XXX */ 431 eh = (struct ether_header *)sa.sa_data; 432 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 433 sizeof( eh->ether_dhost )); 434 435 if ( aa->aa_flags & AFA_PHASE2 ) { 436 eh->ether_type = htons( sizeof( struct llc ) + 437 sizeof( struct ether_aarp )); 438 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 439 if ( m == NULL ) { 440 return; 441 } 442 llc = mtod( m, struct llc *); 443 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 444 llc->llc_control = LLC_UI; 445 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 446 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 447 448 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 449 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 450 } else { 451 eh->ether_type = htons( ETHERTYPE_AARP ); 452 } 453 454 ea->aarp_tpnode = ea->aarp_spnode; 455 ea->aarp_spnode = ma.s_node; 456 ea->aarp_op = htons( AARPOP_RESPONSE ); 457 458 sa.sa_len = sizeof( struct sockaddr ); 459 sa.sa_family = AF_UNSPEC; 460 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */ 461 return; 462} 463 464static void 465aarptfree( struct aarptab *aat) 466{ 467 468 if ( aat->aat_hold ) 469 m_freem( aat->aat_hold ); 470 aat->aat_hold = 0; 471 aat->aat_timer = aat->aat_flags = 0; 472 aat->aat_ataddr.s_net = 0; 473 aat->aat_ataddr.s_node = 0; 474} 475 476 struct aarptab * 477aarptnew( addr ) 478 struct at_addr *addr; 479{ 480 int n; 481 int oldest = -1; 482 struct aarptab *aat, *aato = NULL; 483 static int first = 1; 484 485 if ( first ) { 486 first = 0; 487 aarptimer_ch = timeout( aarptimer, (caddr_t)0, hz ); 488 } 489 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ]; 490 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) { 491 if ( aat->aat_flags == 0 ) 492 goto out; 493 if ( aat->aat_flags & ATF_PERM ) 494 continue; 495 if ((int) aat->aat_timer > oldest ) { 496 oldest = aat->aat_timer; 497 aato = aat; 498 } 499 } 500 if ( aato == NULL ) 501 return( NULL ); 502 aat = aato; 503 aarptfree( aat ); 504out: 505 aat->aat_ataddr = *addr; 506 aat->aat_flags = ATF_INUSE; 507 return( aat ); 508} 509 510 511void 512aarpprobe( void *arg ) 513{ 514 struct arpcom *ac = arg; 515 struct mbuf *m; 516 struct ether_header *eh; 517 struct ether_aarp *ea; 518 struct at_ifaddr *aa; 519 struct llc *llc; 520 struct sockaddr sa; 521 522 /* 523 * We need to check whether the output ethernet type should 524 * be phase 1 or 2. We have the interface that we'll be sending 525 * the aarp out. We need to find an AppleTalk network on that 526 * interface with the same address as we're looking for. If the 527 * net is phase 2, generate an 802.2 and SNAP header. 528 */ 529 for (aa = (struct at_ifaddr *)ac->ac_if.if_addrhead.tqh_first; aa; 530 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 531 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 532 ( aa->aa_flags & AFA_PROBING )) { 533 break; 534 } 535 } 536 if ( aa == NULL ) { /* serious error XXX */ 537 printf( "aarpprobe why did this happen?!\n" ); 538 return; 539 } 540 541 if ( aa->aa_probcnt <= 0 ) { 542 aa->aa_flags &= ~AFA_PROBING; 543 wakeup( aa ); 544 return; 545 } else { 546 aa->aa_ch = timeout( aarpprobe, (caddr_t)ac, hz / 5 ); 547 } 548 549 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 550 return; 551 } 552 m->m_len = sizeof( *ea ); 553 m->m_pkthdr.len = sizeof( *ea ); 554 MH_ALIGN( m, sizeof( *ea )); 555 556 ea = mtod( m, struct ether_aarp *); 557 bzero((caddr_t)ea, sizeof( *ea )); 558 559 ea->aarp_hrd = htons( AARPHRD_ETHER ); 560 ea->aarp_pro = htons( ETHERTYPE_AT ); 561 ea->aarp_hln = sizeof( ea->aarp_sha ); 562 ea->aarp_pln = sizeof( ea->aarp_spu ); 563 ea->aarp_op = htons( AARPOP_PROBE ); 564 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 565 sizeof( ea->aarp_sha )); 566 567 eh = (struct ether_header *)sa.sa_data; 568 569 if ( aa->aa_flags & AFA_PHASE2 ) { 570 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 571 sizeof( eh->ether_dhost )); 572 eh->ether_type = htons( sizeof( struct llc ) + 573 sizeof( struct ether_aarp )); 574 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 575 llc = mtod( m, struct llc *); 576 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 577 llc->llc_control = LLC_UI; 578 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 579 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 580 581 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 582 sizeof( ea->aarp_spnet )); 583 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet, 584 sizeof( ea->aarp_tpnet )); 585 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node; 586 } else { 587 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 588 sizeof( eh->ether_dhost )); 589 eh->ether_type = htons( ETHERTYPE_AARP ); 590 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node; 591 } 592 593#ifdef NETATALKDEBUG 594 printf("aarp: sending probe for %u.%u\n", 595 ntohs(AA_SAT( aa )->sat_addr.s_net), 596 AA_SAT( aa )->sat_addr.s_node); 597#endif /* NETATALKDEBUG */ 598 599 sa.sa_len = sizeof( struct sockaddr ); 600 sa.sa_family = AF_UNSPEC; 601 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */ 602 aa->aa_probcnt--; 603} 604 605void 606aarp_clean(void) 607{ 608 struct aarptab *aat; 609 int i; 610 611 untimeout( aarptimer, 0, aarptimer_ch ); 612 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) { 613 if ( aat->aat_hold ) { 614 m_freem( aat->aat_hold ); 615 } 616 } 617}
|