1 /* $NetBSD: aarp.c,v 1.14 2003/06/23 11:02:12 martin Exp $ */ 2 3 /* 4 * Copyright (c) 1990,1991 Regents of The University of Michigan. 5 * All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and distribute this software and 8 * its documentation for any purpose and without fee is hereby granted, 9 * provided that the above copyright notice appears in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation, and that the name of The University 12 * of Michigan not be used in advertising or publicity pertaining to 13 * distribution of the software without specific, written prior 14 * permission. This software is supplied as is without expressed or 15 * implied warranties of any kind. 16 * 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 20 * Research Systems Unix Group 21 * The University of Michigan 22 * c/o Wesley Craig 23 * 535 W. William Street 24 * Ann Arbor, Michigan 25 * +1-313-764-2278 26 * netatalk@umich.edu 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: aarp.c,v 1.14 2003/06/23 11:02:12 martin Exp $"); 31 32 #include "opt_mbuftrace.h" 33 34 #include <sys/param.h> 35 #include <sys/socket.h> 36 #include <sys/syslog.h> 37 #include <sys/systm.h> 38 #include <sys/callout.h> 39 #include <sys/proc.h> 40 #include <sys/mbuf.h> 41 #include <sys/time.h> 42 #include <sys/kernel.h> 43 #include <net/if.h> 44 #include <net/route.h> 45 #include <net/if_ether.h> 46 #include <net/if_dl.h> 47 #include <netinet/in.h> 48 #undef s_net 49 50 #include <netatalk/at.h> 51 #include <netatalk/at_var.h> 52 #include <netatalk/aarp.h> 53 #include <netatalk/ddp_var.h> 54 #include <netatalk/phase2.h> 55 #include <netatalk/at_extern.h> 56 57 static struct aarptab *aarptnew __P((struct at_addr *)); 58 static void aarptfree __P((struct aarptab *)); 59 static void at_aarpinput __P((struct ifnet *, struct mbuf *)); 60 static void aarptimer __P((void *)); 61 static void aarpwhohas __P((struct ifnet *, struct sockaddr_at *)); 62 63 #define AARPTAB_BSIZ 9 64 #define AARPTAB_NB 19 65 #define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 66 struct aarptab aarptab[AARPTAB_SIZE]; 67 68 #define AARPTAB_HASH(a) \ 69 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 70 71 #define AARPTAB_LOOK(aat,addr) { \ 72 int n; \ 73 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \ 74 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \ 75 if ( aat->aat_ataddr.s_net == (addr).s_net && \ 76 aat->aat_ataddr.s_node == (addr).s_node ) \ 77 break; \ 78 if ( n >= AARPTAB_BSIZ ) \ 79 aat = 0; \ 80 } 81 82 #define AARPT_AGE (60 * 1) 83 #define AARPT_KILLC 20 84 #define AARPT_KILLI 3 85 86 #if !defined( __FreeBSD__ ) 87 extern u_char etherbroadcastaddr[6]; 88 #endif /* __FreeBSD__ */ 89 90 const u_char atmulticastaddr[6] = { 91 0x09, 0x00, 0x07, 0xff, 0xff, 0xff 92 }; 93 94 const u_char at_org_code[3] = { 95 0x08, 0x00, 0x07 96 }; 97 const u_char aarp_org_code[3] = { 98 0x00, 0x00, 0x00 99 }; 100 101 struct callout aarptimer_callout; 102 #ifdef MBUFTRACE 103 struct mowner aarp_mowner = { "atalk", "arp" }; 104 #endif 105 106 /*ARGSUSED*/ 107 static void 108 aarptimer(ignored) 109 void *ignored; 110 { 111 struct aarptab *aat; 112 int i, s; 113 114 callout_reset(&aarptimer_callout, AARPT_AGE * hz, aarptimer, NULL); 115 aat = aarptab; 116 for (i = 0; i < AARPTAB_SIZE; i++, aat++) { 117 int killtime = (aat->aat_flags & ATF_COM) ? AARPT_KILLC : 118 AARPT_KILLI; 119 if (aat->aat_flags == 0 || (aat->aat_flags & ATF_PERM)) 120 continue; 121 if (++aat->aat_timer < killtime) 122 continue; 123 s = splnet(); 124 aarptfree(aat); 125 splx(s); 126 } 127 } 128 129 /* 130 * search through the network addresses to find one that includes the given 131 * network.. remember to take netranges into consideration. 132 */ 133 struct ifaddr * 134 at_ifawithnet(sat, ifp) 135 struct sockaddr_at *sat; 136 struct ifnet *ifp; 137 { 138 struct ifaddr *ifa; 139 struct sockaddr_at *sat2; 140 struct netrange *nr; 141 142 for (ifa = ifp->if_addrlist.tqh_first; ifa; 143 ifa = ifa->ifa_list.tqe_next) { 144 if (ifa->ifa_addr->sa_family != AF_APPLETALK) 145 continue; 146 147 sat2 = satosat(ifa->ifa_addr); 148 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 149 break; 150 151 nr = (struct netrange *) (sat2->sat_zero); 152 if ((nr->nr_phase == 2) 153 && (nr->nr_firstnet <= sat->sat_addr.s_net) 154 && (nr->nr_lastnet >= sat->sat_addr.s_net)) 155 break; 156 } 157 return ifa; 158 } 159 160 static void 161 aarpwhohas(ifp, sat) 162 struct ifnet *ifp; 163 struct sockaddr_at *sat; 164 { 165 struct mbuf *m; 166 struct ether_header *eh; 167 struct ether_aarp *ea; 168 struct at_ifaddr *aa; 169 struct llc *llc; 170 struct sockaddr sa; 171 172 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 173 return; 174 175 MCLAIM(m, &aarp_mowner); 176 m->m_len = sizeof(*ea); 177 m->m_pkthdr.len = sizeof(*ea); 178 MH_ALIGN(m, sizeof(*ea)); 179 180 ea = mtod(m, struct ether_aarp *); 181 bzero(ea, sizeof(*ea)); 182 183 ea->aarp_hrd = htons(AARPHRD_ETHER); 184 ea->aarp_pro = htons(ETHERTYPE_ATALK); 185 ea->aarp_hln = sizeof(ea->aarp_sha); 186 ea->aarp_pln = sizeof(ea->aarp_spu); 187 ea->aarp_op = htons(AARPOP_REQUEST); 188 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 189 190 /* 191 * We need to check whether the output ethernet type should 192 * be phase 1 or 2. We have the interface that we'll be sending 193 * the aarp out. We need to find an AppleTalk network on that 194 * interface with the same address as we're looking for. If the 195 * net is phase 2, generate an 802.2 and SNAP header. 196 */ 197 if ((aa = (struct at_ifaddr *) at_ifawithnet(sat, ifp)) == NULL) { 198 m_freem(m); 199 return; 200 } 201 eh = (struct ether_header *) sa.sa_data; 202 203 if (aa->aa_flags & AFA_PHASE2) { 204 bcopy(atmulticastaddr, eh->ether_dhost, 205 sizeof(eh->ether_dhost)); 206 eh->ether_type = 0; /* if_output will treat as 802 */ 207 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 208 if (!m) 209 return; 210 211 llc = mtod(m, struct llc *); 212 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 213 llc->llc_control = LLC_UI; 214 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 215 llc->llc_ether_type = htons(ETHERTYPE_AARP); 216 217 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 218 sizeof(ea->aarp_spnet)); 219 bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet, 220 sizeof(ea->aarp_tpnet)); 221 ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node; 222 ea->aarp_tpnode = sat->sat_addr.s_node; 223 } else { 224 bcopy(etherbroadcastaddr, eh->ether_dhost, 225 sizeof(eh->ether_dhost)); 226 eh->ether_type = htons(ETHERTYPE_AARP); 227 228 ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node; 229 ea->aarp_tpa = sat->sat_addr.s_node; 230 } 231 232 #ifdef NETATALKDEBUG 233 printf("aarp: sending request via %u.%u seaking %u.%u\n", 234 ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node, 235 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); 236 #endif /* NETATALKDEBUG */ 237 238 sa.sa_len = sizeof(struct sockaddr); 239 sa.sa_family = AF_UNSPEC; 240 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX NULL should be routing */ 241 /* information */ 242 } 243 244 int 245 aarpresolve(ifp, m, destsat, desten) 246 struct ifnet *ifp; 247 struct mbuf *m; 248 struct sockaddr_at *destsat; 249 u_char *desten; 250 { 251 struct at_ifaddr *aa; 252 struct aarptab *aat; 253 int s; 254 255 if (at_broadcast(destsat)) { 256 aa = (struct at_ifaddr *) at_ifawithnet(destsat, ifp); 257 if (aa == NULL) { 258 m_freem(m); 259 return (0); 260 } 261 if (aa->aa_flags & AFA_PHASE2) 262 bcopy(atmulticastaddr, desten, 263 sizeof(atmulticastaddr)); 264 else 265 bcopy(etherbroadcastaddr, desten, 266 sizeof(etherbroadcastaddr)); 267 return 1; 268 } 269 s = splnet(); 270 AARPTAB_LOOK(aat, destsat->sat_addr); 271 if (aat == 0) { /* No entry */ 272 aat = aarptnew(&destsat->sat_addr); 273 if (aat == 0) 274 panic("aarpresolve: no free entry"); 275 276 aat->aat_hold = m; 277 aarpwhohas(ifp, destsat); 278 splx(s); 279 return 0; 280 } 281 282 /* found an entry */ 283 aat->aat_timer = 0; 284 if (aat->aat_flags & ATF_COM) { /* entry is COMplete */ 285 bcopy(aat->aat_enaddr, desten, sizeof(aat->aat_enaddr)); 286 splx(s); 287 return 1; 288 } 289 290 /* entry has not completed */ 291 if (aat->aat_hold) 292 m_freem(aat->aat_hold); 293 aat->aat_hold = m; 294 aarpwhohas(ifp, destsat); 295 splx(s); 296 297 return 0; 298 } 299 300 void 301 aarpinput(ifp, m) 302 struct ifnet *ifp; 303 struct mbuf *m; 304 { 305 struct arphdr *ar; 306 307 if (ifp->if_flags & IFF_NOARP) 308 goto out; 309 310 if (m->m_len < sizeof(struct arphdr)) 311 goto out; 312 313 ar = mtod(m, struct arphdr *); 314 if (ntohs(ar->ar_hrd) != AARPHRD_ETHER) 315 goto out; 316 317 if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln) 318 goto out; 319 320 switch (ntohs(ar->ar_pro)) { 321 case ETHERTYPE_ATALK: 322 at_aarpinput(ifp, m); 323 return; 324 325 default: 326 break; 327 } 328 329 out: 330 m_freem(m); 331 } 332 333 static void 334 at_aarpinput(ifp, m) 335 struct ifnet *ifp; 336 struct mbuf *m; 337 { 338 struct ether_aarp *ea; 339 struct at_ifaddr *aa; 340 struct aarptab *aat; 341 struct ether_header *eh; 342 struct llc *llc; 343 struct sockaddr_at sat; 344 struct sockaddr sa; 345 struct at_addr spa, tpa, ma; 346 int op; 347 u_int16_t net; 348 349 ea = mtod(m, struct ether_aarp *); 350 351 /* Check to see if from my hardware address */ 352 if (!bcmp(ea->aarp_sha, LLADDR(ifp->if_sadl), sizeof(ea->aarp_sha))) { 353 m_freem(m); 354 return; 355 } 356 op = ntohs(ea->aarp_op); 357 bcopy(ea->aarp_tpnet, &net, sizeof(net)); 358 359 if (net != 0) { /* should be ATADDR_ANYNET? */ 360 sat.sat_len = sizeof(struct sockaddr_at); 361 sat.sat_family = AF_APPLETALK; 362 sat.sat_addr.s_net = net; 363 aa = (struct at_ifaddr *) at_ifawithnet(&sat, ifp); 364 if (aa == NULL) { 365 m_freem(m); 366 return; 367 } 368 bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net)); 369 bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net)); 370 } else { 371 /* 372 * Since we don't know the net, we just look for the first 373 * phase 1 address on the interface. 374 */ 375 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 376 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 377 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 378 (aa->aa_flags & AFA_PHASE2) == 0) 379 break; 380 } 381 if (aa == NULL) { 382 m_freem(m); 383 return; 384 } 385 tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net; 386 } 387 388 spa.s_node = ea->aarp_spnode; 389 tpa.s_node = ea->aarp_tpnode; 390 ma.s_net = AA_SAT(aa)->sat_addr.s_net; 391 ma.s_node = AA_SAT(aa)->sat_addr.s_node; 392 393 /* 394 * This looks like it's from us. 395 */ 396 if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) { 397 if (aa->aa_flags & AFA_PROBING) { 398 /* 399 * We're probing, someone either responded to our 400 * probe, or probed for the same address we'd like 401 * to use. Change the address we're probing for. 402 */ 403 callout_stop(&aa->aa_probe_ch); 404 wakeup(aa); 405 m_freem(m); 406 return; 407 } else if (op != AARPOP_PROBE) { 408 /* 409 * This is not a probe, and we're not probing. 410 * This means that someone's saying they have the same 411 * source address as the one we're using. Get upset... 412 */ 413 log(LOG_ERR, "aarp: duplicate AT address!! %s\n", 414 ether_sprintf(ea->aarp_sha)); 415 m_freem(m); 416 return; 417 } 418 } 419 AARPTAB_LOOK(aat, spa); 420 if (aat) { 421 if (op == AARPOP_PROBE) { 422 /* 423 * Someone's probing for spa, deallocate the one we've 424 * got, so that if the prober keeps the address, we'll 425 * be able to arp for him. 426 */ 427 aarptfree(aat); 428 m_freem(m); 429 return; 430 } 431 bcopy(ea->aarp_sha, aat->aat_enaddr, sizeof(ea->aarp_sha)); 432 aat->aat_flags |= ATF_COM; 433 if (aat->aat_hold) { 434 sat.sat_len = sizeof(struct sockaddr_at); 435 sat.sat_family = AF_APPLETALK; 436 sat.sat_addr = spa; 437 (*ifp->if_output)(ifp, aat->aat_hold, 438 (struct sockaddr *) & sat, NULL); /* XXX */ 439 aat->aat_hold = 0; 440 } 441 } 442 if (aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node 443 && op != AARPOP_PROBE) { 444 if ((aat = aarptnew(&spa)) != NULL) { 445 bcopy(ea->aarp_sha, aat->aat_enaddr, 446 sizeof(ea->aarp_sha)); 447 aat->aat_flags |= ATF_COM; 448 } 449 } 450 /* 451 * Don't respond to responses, and never respond if we're 452 * still probing. 453 */ 454 if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 455 op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) { 456 m_freem(m); 457 return; 458 } 459 bcopy(ea->aarp_sha, ea->aarp_tha, sizeof(ea->aarp_sha)); 460 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 461 462 /* XXX */ 463 eh = (struct ether_header *) sa.sa_data; 464 bcopy(ea->aarp_tha, eh->ether_dhost, sizeof(eh->ether_dhost)); 465 466 if (aa->aa_flags & AFA_PHASE2) { 467 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 468 if (m == NULL) 469 return; 470 471 llc = mtod(m, struct llc *); 472 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 473 llc->llc_control = LLC_UI; 474 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 475 llc->llc_ether_type = htons(ETHERTYPE_AARP); 476 477 bcopy(ea->aarp_spnet, ea->aarp_tpnet, sizeof(ea->aarp_tpnet)); 478 bcopy(&ma.s_net, ea->aarp_spnet, sizeof(ea->aarp_spnet)); 479 eh->ether_type = 0; /* if_output will treat as 802 */ 480 } else { 481 eh->ether_type = htons(ETHERTYPE_AARP); 482 } 483 484 ea->aarp_tpnode = ea->aarp_spnode; 485 ea->aarp_spnode = ma.s_node; 486 ea->aarp_op = htons(AARPOP_RESPONSE); 487 488 sa.sa_len = sizeof(struct sockaddr); 489 sa.sa_family = AF_UNSPEC; 490 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */ 491 return; 492 } 493 494 static void 495 aarptfree(aat) 496 struct aarptab *aat; 497 { 498 499 if (aat->aat_hold) 500 m_freem(aat->aat_hold); 501 aat->aat_hold = 0; 502 aat->aat_timer = aat->aat_flags = 0; 503 aat->aat_ataddr.s_net = 0; 504 aat->aat_ataddr.s_node = 0; 505 } 506 507 static struct aarptab * 508 aarptnew(addr) 509 struct at_addr *addr; 510 { 511 int n; 512 int oldest = -1; 513 struct aarptab *aat, *aato = NULL; 514 static int first = 1; 515 516 if (first) { 517 first = 0; 518 callout_init(&aarptimer_callout); 519 callout_reset(&aarptimer_callout, hz, aarptimer, NULL); 520 MOWNER_ATTACH(&aarp_mowner); 521 } 522 aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ]; 523 for (n = 0; n < AARPTAB_BSIZ; n++, aat++) { 524 if (aat->aat_flags == 0) 525 goto out; 526 if (aat->aat_flags & ATF_PERM) 527 continue; 528 if ((int) aat->aat_timer > oldest) { 529 oldest = aat->aat_timer; 530 aato = aat; 531 } 532 } 533 if (aato == NULL) 534 return (NULL); 535 aat = aato; 536 aarptfree(aat); 537 out: 538 aat->aat_ataddr = *addr; 539 aat->aat_flags = ATF_INUSE; 540 return (aat); 541 } 542 543 544 void 545 aarpprobe(arp) 546 void *arp; 547 { 548 struct mbuf *m; 549 struct ether_header *eh; 550 struct ether_aarp *ea; 551 struct at_ifaddr *aa; 552 struct llc *llc; 553 struct sockaddr sa; 554 struct ifnet *ifp = arp; 555 556 /* 557 * We need to check whether the output ethernet type should 558 * be phase 1 or 2. We have the interface that we'll be sending 559 * the aarp out. We need to find an AppleTalk network on that 560 * interface with the same address as we're looking for. If the 561 * net is phase 2, generate an 802.2 and SNAP header. 562 */ 563 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 564 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 565 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 566 (aa->aa_flags & AFA_PROBING)) 567 break; 568 } 569 if (aa == NULL) { /* serious error XXX */ 570 printf("aarpprobe why did this happen?!\n"); 571 return; 572 } 573 if (aa->aa_probcnt <= 0) { 574 aa->aa_flags &= ~AFA_PROBING; 575 wakeup(aa); 576 return; 577 } else { 578 callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp); 579 } 580 581 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 582 return; 583 584 MCLAIM(m, &aarp_mowner); 585 m->m_len = sizeof(*ea); 586 m->m_pkthdr.len = sizeof(*ea); 587 MH_ALIGN(m, sizeof(*ea)); 588 589 ea = mtod(m, struct ether_aarp *); 590 bzero(ea, sizeof(*ea)); 591 592 ea->aarp_hrd = htons(AARPHRD_ETHER); 593 ea->aarp_pro = htons(ETHERTYPE_ATALK); 594 ea->aarp_hln = sizeof(ea->aarp_sha); 595 ea->aarp_pln = sizeof(ea->aarp_spu); 596 ea->aarp_op = htons(AARPOP_PROBE); 597 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 598 599 eh = (struct ether_header *) sa.sa_data; 600 601 if (aa->aa_flags & AFA_PHASE2) { 602 bcopy(atmulticastaddr, eh->ether_dhost, 603 sizeof(eh->ether_dhost)); 604 eh->ether_type = 0; /* if_output will treat as 802 */ 605 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 606 if (!m) 607 return; 608 609 llc = mtod(m, struct llc *); 610 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 611 llc->llc_control = LLC_UI; 612 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 613 llc->llc_ether_type = htons(ETHERTYPE_AARP); 614 615 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 616 sizeof(ea->aarp_spnet)); 617 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet, 618 sizeof(ea->aarp_tpnet)); 619 ea->aarp_spnode = ea->aarp_tpnode = 620 AA_SAT(aa)->sat_addr.s_node; 621 } else { 622 bcopy(etherbroadcastaddr, eh->ether_dhost, 623 sizeof(eh->ether_dhost)); 624 eh->ether_type = htons(ETHERTYPE_AARP); 625 ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node; 626 } 627 628 #ifdef NETATALKDEBUG 629 printf("aarp: sending probe for %u.%u\n", 630 ntohs(AA_SAT(aa)->sat_addr.s_net), 631 AA_SAT(aa)->sat_addr.s_node); 632 #endif /* NETATALKDEBUG */ 633 634 sa.sa_len = sizeof(struct sockaddr); 635 sa.sa_family = AF_UNSPEC; 636 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */ 637 aa->aa_probcnt--; 638 } 639 640 void 641 aarp_clean() 642 { 643 struct aarptab *aat; 644 int i; 645 646 callout_stop(&aarptimer_callout); 647 for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) 648 if (aat->aat_hold) 649 m_freem(aat->aat_hold); 650 } 651