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