1/* 2 * $Id: aarp.c,v 1.3 2002-01-03 17:49:39 sibaz Exp $ 3 * 4 * Copyright (c) 1990,1991 Regents of The University of Michigan. 5 * All Rights Reserved. 6 */ 7 8#ifdef HAVE_CONFIG_H 9#include "config.h" 10#endif /* HAVE_CONFIG_H */ 11 12#include <sys/types.h> 13#include <sys/socket.h> 14#include <syslog.h> 15#include <sys/param.h> 16#include <sys/mbuf.h> 17#include <sys/time.h> 18#ifndef _IBMR2 19#include <sys/kernel.h> 20#endif /* _IBMR2 */ 21#include <net/if.h> 22#include <net/route.h> 23#include <net/af.h> 24#include <netinet/in.h> 25#undef s_net 26#include <netinet/if_ether.h> 27#ifdef _IBMR2 28#include <netinet/in_netarp.h> 29#include <net/spl.h> 30#include <sys/errno.h> 31#include <sys/err_rec.h> 32#endif /* _IBMR2 */ 33 34#include "at.h" 35#include "at_var.h" 36#include "aarp.h" 37#include "ddp_var.h" 38#include "endian.h" 39#include "phase2.h" 40 41#ifdef GATEWAY 42#define AARPTAB_BSIZ 16 43#define AARPTAB_NB 37 44#else /* GATEWAY */ 45#define AARPTAB_BSIZ 9 46#define AARPTAB_NB 19 47#endif /* GATEWAY */ 48#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 49struct aarptab aarptab[AARPTAB_SIZE]; 50int aarptab_size = AARPTAB_SIZE; 51 52#define AARPTAB_HASH(a) \ 53 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 54 55#define AARPTAB_LOOK(aat,addr) { \ 56 int n; \ 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 ) \ 61 break; \ 62 if ( n >= AARPTAB_BSIZ ) \ 63 aat = 0; \ 64} 65 66#define AARPT_AGE (60 * 1) 67#define AARPT_KILLC 20 68#define AARPT_KILLI 3 69 70#ifdef sun 71extern struct ether_addr etherbroadcastaddr; 72#else /* sun */ 73extern u_char etherbroadcastaddr[6]; 74#endif /* sun */ 75 76u_char atmulticastaddr[ 6 ] = { 77 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 78}; 79 80u_char at_org_code[ 3 ] = { 81 0x08, 0x00, 0x07, 82}; 83u_char aarp_org_code[ 3 ] = { 84 0x00, 0x00, 0x00, 85}; 86 87aarptimer() 88{ 89 struct aarptab *aat; 90 int i, s; 91 92 timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz ); 93 aat = aarptab; 94 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) { 95 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM )) 96 continue; 97 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ? 98 AARPT_KILLC : AARPT_KILLI )) 99 continue; 100 s = splimp(); 101 aarptfree( aat ); 102 splx( s ); 103 } 104} 105 106struct ifaddr * 107at_ifawithnet( sat, ifa ) 108 struct sockaddr_at *sat; 109 struct ifaddr *ifa; 110{ 111 struct at_ifaddr *aa; 112 113 for (; ifa; ifa = ifa->ifa_next ) { 114#ifdef BSD4_4 115 if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) { 116 continue; 117 } 118 if ( satosat( ifa->ifa_addr )->sat_addr.s_net == 119 sat->sat_addr.s_net ) { 120 break; 121 } 122#else /* BSD4_4 */ 123 if ( ifa->ifa_addr.sa_family != AF_APPLETALK ) { 124 continue; 125 } 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 )) { 129 break; 130 } 131#endif /* BSD4_4 */ 132 } 133 return( ifa ); 134} 135 136aarpwhohas( ac, sat ) 137 struct arpcom *ac; 138 struct sockaddr_at *sat; 139{ 140 struct mbuf *m; 141 struct ether_header *eh; 142 struct ether_aarp *ea; 143 struct at_ifaddr *aa; 144 struct llc *llc; 145 struct sockaddr sa; 146 147#ifdef BSD4_4 148 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 149 return; 150 } 151 m->m_len = sizeof( *ea ); 152 m->m_pkthdr.len = sizeof( *ea ); 153 MH_ALIGN( m, sizeof( *ea )); 154#else /* BSD4_4 */ 155 if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) { 156 return; 157 } 158 m->m_len = sizeof( *ea ); 159 m->m_off = MMAXOFF - sizeof( *ea ); 160#endif /* BSD4_4 */ 161 162 ea = mtod( m, struct ether_aarp *); 163 bzero((caddr_t)ea, sizeof( *ea )); 164 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 ); 170#ifdef sun 171 bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha, 172 sizeof( ea->aarp_sha )); 173#else /* sun */ 174 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 175 sizeof( ea->aarp_sha )); 176#endif /* sun */ 177 178 /* 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. 184 */ 185 if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->ac_if.if_addrlist )) 186 == NULL ) { 187 m_freem( m ); 188 return; 189 } 190 191 eh = (struct ether_header *)sa.sa_data; 192 193 if ( aa->aa_flags & AFA_PHASE2 ) { 194#ifdef sun 195 bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost, 196 sizeof( eh->ether_dhost )); 197#else /* sun */ 198 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 199 sizeof( eh->ether_dhost )); 200#endif /* sun */ 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 */ 207#ifdef BSD4_4 208 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 209#else /* BSD4_4 */ 210 m->m_len += sizeof( struct llc ); 211 m->m_off -= sizeof( struct llc ); 212#endif /* BSD4_4 */ 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 ); 218 219 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; 226 } else { 227#ifdef sun 228 bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost, 229 sizeof( eh->ether_dhost )); 230#else /* sun */ 231 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 232 sizeof( eh->ether_dhost )); 233#endif /* sun */ 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 */ 239 240 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 241 ea->aarp_tpa = sat->sat_addr.s_node; 242 } 243 244#ifdef BSD4_4 245 sa.sa_len = sizeof( struct sockaddr ); 246#endif /* BSD4_4 */ 247 sa.sa_family = AF_UNSPEC; 248 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa ); 249} 250 251aarpresolve( ac, m, destsat, desten ) 252 struct arpcom *ac; 253 struct mbuf *m; 254 struct sockaddr_at *destsat; 255#ifdef sun 256 struct ether_addr *desten; 257#else /* sun */ 258 u_char *desten; 259#endif /* sun */ 260{ 261 struct at_ifaddr *aa; 262 struct ifaddr ifa; 263 struct aarptab *aat; 264 int s; 265 266 if ( at_broadcast( destsat )) { 267 if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat, 268 ((struct ifnet *)ac)->if_addrlist )) == NULL ) { 269 m_freem( m ); 270 return( 0 ); 271 } 272 if ( aa->aa_flags & AFA_PHASE2 ) { 273 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 274 sizeof( atmulticastaddr )); 275 } else { 276#ifdef sun 277 bcopy( (caddr_t)ðerbroadcastaddr, (caddr_t)desten, 278 sizeof( etherbroadcastaddr )); 279#else /* sun */ 280 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 281 sizeof( etherbroadcastaddr )); 282#endif /* sun */ 283 } 284 return( 1 ); 285 } 286 287 s = splimp(); 288 AARPTAB_LOOK( aat, destsat->sat_addr ); 289 if ( aat == 0 ) { /* No entry */ 290 aat = aarptnew( &destsat->sat_addr ); 291 if ( aat == 0 ) { 292 panic( "aarpresolve: no free entry" ); 293 } 294 aat->aat_hold = m; 295 aarpwhohas( ac, destsat ); 296 splx( s ); 297 return( 0 ); 298 } 299 /* found an entry */ 300 aat->aat_timer = 0; 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 )); 304 splx( s ); 305 return( 1 ); 306 } 307 /* entry has not completed */ 308 if ( aat->aat_hold ) { 309 m_freem( aat->aat_hold ); 310 } 311 aat->aat_hold = m; 312 aarpwhohas( ac, destsat ); 313 splx( s ); 314 return( 0 ); 315} 316 317aarpinput( ac, m ) 318 struct arpcom *ac; 319 struct mbuf *m; 320{ 321 struct arphdr *ar; 322 323 if ( ac->ac_if.if_flags & IFF_NOARP ) 324 goto out; 325 326#ifndef BSD4_4 327 IF_ADJ( m ); 328#endif /* BSD4_4 */ 329 330 if ( m->m_len < sizeof( struct arphdr )) { 331 goto out; 332 } 333 334 ar = mtod( m, struct arphdr *); 335 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 336 goto out; 337 } 338 339 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln + 340 2 * ar->ar_pln ) { 341 goto out; 342 } 343 344 switch( ntohs( ar->ar_pro )) { 345 case ETHERTYPE_AT : 346 at_aarpinput( ac, m ); 347 return; 348 349 default: 350 break; 351 } 352 353out: 354 m_freem( m ); 355} 356 357 358at_aarpinput( ac, m ) 359 struct arpcom *ac; 360 struct mbuf *m; 361{ 362 struct mbuf *m0; 363 struct ether_aarp *ea; 364 struct at_ifaddr *aa; 365 struct aarptab *aat; 366 struct ether_header *eh; 367 struct llc *llc; 368 struct sockaddr_at sat; 369 struct sockaddr sa; 370 struct at_addr spa, tpa, ma; 371 int op, s; 372 u_short net; 373 374 ea = mtod( m, struct ether_aarp *); 375 376 /* Check to see if from my hardware address */ 377#ifdef sun 378 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )&ac->ac_enaddr, 379 sizeof( ac->ac_enaddr ))) { 380 m_freem( m ); 381 return; 382 } 383#else /* sun */ 384 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 385 sizeof( ac->ac_enaddr ))) { 386 m_freem( m ); 387 return; 388 } 389#endif /* sun */ 390 391 /* 392 * Check if from broadcast address. This could be a more robust 393 * check, since we could look for multicasts. 394 */ 395#ifdef sun 396 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ðerbroadcastaddr, 397 sizeof( etherbroadcastaddr ))) { 398 log( LOG_ERR, "aarp: source is broadcast!\n" ); 399 m_freem( m ); 400 return; 401 } 402#else /* sun */ 403 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )etherbroadcastaddr, 404 sizeof( etherbroadcastaddr ))) { 405#ifndef _IBMR2 406#ifdef ultrix 407 mprintf( LOG_ERR, 408#else /* ultrix */ 409 log( LOG_ERR, 410#endif /* ultrix */ 411 "aarp: source is broadcast!\n" ); 412#endif /* ! _IBMR2 */ 413 m_freem( m ); 414 return; 415 } 416#endif /* sun */ 417 418 op = ntohs( ea->aarp_op ); 419 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 420 421 if ( net != 0 ) { 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 ) { 426 m_freem( m ); 427 return; 428 } 429 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); 430 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net )); 431 } else { 432 /* 433 * Since we don't know the net, we just look for the first 434 * phase 1 address on the interface. 435 */ 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 ) { 440 break; 441 } 442 } 443 if ( aa == NULL ) { 444 m_freem( m ); 445 return; 446 } 447 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net; 448 } 449 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; 454 455 /* 456 * This looks like it's from us. 457 */ 458 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) { 459 if ( aa->aa_flags & AFA_PROBING ) { 460 /* 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. 464 */ 465 untimeout( aarpprobe, ac ); 466 wakeup( aa ); 467 m_freem( m ); 468 return; 469 } else if ( op != AARPOP_PROBE ) { 470 /* 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... 474 */ 475#ifndef _IBMR2 476#ifdef ultrix 477 mprintf( LOG_ERR, 478#else /* ultrix */ 479 log( LOG_ERR, 480#endif /* ultrix */ 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 */ 485 m_freem( m ); 486 return; 487 } 488 } 489 490 AARPTAB_LOOK( aat, spa ); 491 if ( aat ) { 492 if ( op == AARPOP_PROBE ) { 493 /* 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 496 * to arp for him. 497 */ 498 aarptfree( aat ); 499 m_freem( m ); 500 return; 501 } 502 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 ) { 507#ifdef _IBMR2 508 /* 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. 512 * 513 * This should really be replaced with something like 514 * rsif_output(). XXX Will have to be for phase 2. 515 */ 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 )); 520#else /* _IBMR2 */ 521 sat.sat_family = AF_APPLETALK; 522 sat.sat_addr = spa; 523#endif /* _IBMR2 */ 524 (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold, 525 (struct sockaddr *)&sat ); 526 aat->aat_hold = 0; 527 } 528 } 529 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; 536 } 537 } 538 539 /* 540 * Don't respond to responses, and never respond if we're 541 * still probing. 542 */ 543 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 544 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 545 m_freem( m ); 546 return; 547 } 548 549 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 550 sizeof( ea->aarp_sha )); 551#ifdef sun 552 bcopy(( caddr_t )&ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 553 sizeof( ea->aarp_sha )); 554#else /* sun */ 555 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 556 sizeof( ea->aarp_sha )); 557#endif /* sun */ 558 559 eh = (struct ether_header *)sa.sa_data; 560#ifdef sun 561 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )&eh->ether_dhost, 562 sizeof( eh->ether_dhost )); 563#else /* sun */ 564 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 565 sizeof( eh->ether_dhost )); 566#endif /* sun */ 567 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 */ 575#ifdef BSD4_4 576 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 577 if ( m == NULL ) { 578 m_freem( m ); 579 return; 580 } 581#else /* BSD4_4 */ 582 MGET( m0, M_DONTWAIT, MT_HEADER ); 583 if ( m0 == NULL ) { 584 m_freem( m ); 585 return; 586 } 587 m0->m_next = m; 588 m = m0; 589 m->m_off = MMAXOFF - sizeof( struct llc ); 590 m->m_len = sizeof ( struct llc ); 591#endif /* BSD4_4 */ 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 ); 597 598 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 599 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 600 } else { 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 */ 606 } 607 608 ea->aarp_tpnode = ea->aarp_spnode; 609 ea->aarp_spnode = ma.s_node; 610 ea->aarp_op = htons( AARPOP_RESPONSE ); 611 612#ifdef BSD4_4 613 sa.sa_len = sizeof( struct sockaddr ); 614#endif /* BSD4_4 */ 615 sa.sa_family = AF_UNSPEC; 616 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa ); 617 return; 618} 619 620aarptfree( aat ) 621 struct aarptab *aat; 622{ 623 624 if ( aat->aat_hold ) 625 m_freem( aat->aat_hold ); 626 aat->aat_hold = 0; 627 aat->aat_timer = aat->aat_flags = 0; 628 aat->aat_ataddr.s_net = 0; 629 aat->aat_ataddr.s_node = 0; 630} 631 632 struct aarptab * 633aarptnew( addr ) 634 struct at_addr *addr; 635{ 636 int n; 637 int oldest = -1; 638 struct aarptab *aat, *aato = NULL; 639 static int first = 1; 640 641 if ( first ) { 642 first = 0; 643 timeout( aarptimer, (caddr_t)0, hz ); 644 } 645 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ]; 646 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) { 647 if ( aat->aat_flags == 0 ) 648 goto out; 649 if ( aat->aat_flags & ATF_PERM ) 650 continue; 651 if ((int) aat->aat_timer > oldest ) { 652 oldest = aat->aat_timer; 653 aato = aat; 654 } 655 } 656 if ( aato == NULL ) 657 return( NULL ); 658 aat = aato; 659 aarptfree( aat ); 660out: 661 aat->aat_ataddr = *addr; 662 aat->aat_flags = ATF_INUSE; 663 return( aat ); 664} 665 666aarpprobe( ac ) 667 struct arpcom *ac; 668{ 669 struct mbuf *m; 670 struct ether_header *eh; 671 struct ether_aarp *ea; 672 struct at_ifaddr *aa; 673 struct llc *llc; 674 struct sockaddr sa; 675 676 /* 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. 682 */ 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 )) { 687 break; 688 } 689 } 690 if ( aa == NULL ) { /* serious error XXX */ 691 printf( "aarpprobe why did this happen?!\n" ); 692 return; 693 } 694 695 if ( aa->aa_probcnt <= 0 ) { 696 aa->aa_flags &= ~AFA_PROBING; 697 wakeup( aa ); 698 return; 699 } else { 700 timeout( aarpprobe, (caddr_t)ac, hz / 5 ); 701 } 702 703#ifdef BSD4_4 704 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 705 return; 706 } 707 m->m_len = sizeof( *ea ); 708 m->m_pkthdr.len = sizeof( *ea ); 709 MH_ALIGN( m, sizeof( *ea )); 710#else /* BSD4_4 */ 711 if (( m = m_get( M_DONTWAIT, MT_DATA )) == NULL ) { 712 return; 713 } 714 m->m_len = sizeof( *ea ); 715 m->m_off = MMAXOFF - sizeof( *ea ); 716#endif /* BSD4_4 */ 717 718 ea = mtod( m, struct ether_aarp *); 719 bzero((caddr_t)ea, sizeof( *ea )); 720 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 ); 726#ifdef sun 727 bcopy((caddr_t)&ac->ac_enaddr, (caddr_t)ea->aarp_sha, 728 sizeof( ea->aarp_sha )); 729#else /* sun */ 730 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 731 sizeof( ea->aarp_sha )); 732#endif /* sun */ 733 734 eh = (struct ether_header *)sa.sa_data; 735 736 if ( aa->aa_flags & AFA_PHASE2 ) { 737#ifdef sun 738 bcopy((caddr_t)atmulticastaddr, (caddr_t)&eh->ether_dhost, 739 sizeof( eh->ether_dhost )); 740#else /* sun */ 741 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 742 sizeof( eh->ether_dhost )); 743#endif /* sun */ 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 */ 750#ifdef BSD4_4 751 M_PREPEND( m, sizeof( struct llc ), M_WAIT ); 752#else /* BSD4_4 */ 753 m->m_len += sizeof( struct llc ); 754 m->m_off -= sizeof( struct llc ); 755#endif /* BSD4_4 */ 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 ); 761 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; 767 } else { 768#ifdef sun 769 bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)&eh->ether_dhost, 770 sizeof( eh->ether_dhost )); 771#else /* sun */ 772 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 773 sizeof( eh->ether_dhost )); 774#endif /* sun */ 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; 781 } 782 783#ifdef BSD4_4 784 sa.sa_len = sizeof( struct sockaddr ); 785#endif /* BSD4_4 */ 786 sa.sa_family = AF_UNSPEC; 787 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa ); 788 aa->aa_probcnt--; 789} 790 791aarp_clean() 792{ 793 struct aarptab *aat; 794 int i; 795 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 ); 800 } 801 } 802} 803