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