1 /* $NetBSD: aarp.c,v 1.9 2002/10/22 21:58:33 perry 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.9 2002/10/22 21:58:33 perry Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/socket.h> 34 #include <sys/syslog.h> 35 #include <sys/systm.h> 36 #include <sys/callout.h> 37 #include <sys/proc.h> 38 #include <sys/mbuf.h> 39 #include <sys/time.h> 40 #include <sys/kernel.h> 41 #include <net/if.h> 42 #include <net/route.h> 43 #include <net/if_ether.h> 44 #include <net/if_dl.h> 45 #include <netinet/in.h> 46 #undef s_net 47 48 #include <netatalk/at.h> 49 #include <netatalk/at_var.h> 50 #include <netatalk/aarp.h> 51 #include <netatalk/ddp_var.h> 52 #include <netatalk/phase2.h> 53 #include <netatalk/at_extern.h> 54 55 static struct aarptab *aarptnew __P((struct at_addr *)); 56 static void aarptfree __P((struct aarptab *)); 57 static void at_aarpinput __P((struct ifnet *, struct mbuf *)); 58 static void aarptimer __P((void *)); 59 static void aarpwhohas __P((struct ifnet *, struct sockaddr_at *)); 60 61 #define AARPTAB_BSIZ 9 62 #define AARPTAB_NB 19 63 #define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 64 struct aarptab aarptab[AARPTAB_SIZE]; 65 int aarptab_size = AARPTAB_SIZE; 66 67 #define AARPTAB_HASH(a) \ 68 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 69 70 #define AARPTAB_LOOK(aat,addr) { \ 71 int n; \ 72 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \ 73 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \ 74 if ( aat->aat_ataddr.s_net == (addr).s_net && \ 75 aat->aat_ataddr.s_node == (addr).s_node ) \ 76 break; \ 77 if ( n >= AARPTAB_BSIZ ) \ 78 aat = 0; \ 79 } 80 81 #define AARPT_AGE (60 * 1) 82 #define AARPT_KILLC 20 83 #define AARPT_KILLI 3 84 85 #if !defined( __FreeBSD__ ) 86 extern u_char etherbroadcastaddr[6]; 87 #endif /* __FreeBSD__ */ 88 89 u_char atmulticastaddr[6] = { 90 0x09, 0x00, 0x07, 0xff, 0xff, 0xff 91 }; 92 93 u_char at_org_code[3] = { 94 0x08, 0x00, 0x07 95 }; 96 u_char aarp_org_code[3] = { 97 0x00, 0x00, 0x00 98 }; 99 100 struct callout aarptimer_callout; 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 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 && (nr->nr_firstnet <= sat->sat_addr.s_net) 150 && (nr->nr_lastnet >= 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 m->m_len = sizeof(*ea); 172 m->m_pkthdr.len = sizeof(*ea); 173 MH_ALIGN(m, sizeof(*ea)); 174 175 ea = mtod(m, struct ether_aarp *); 176 bzero(ea, sizeof(*ea)); 177 178 ea->aarp_hrd = htons(AARPHRD_ETHER); 179 ea->aarp_pro = htons(ETHERTYPE_ATALK); 180 ea->aarp_hln = sizeof(ea->aarp_sha); 181 ea->aarp_pln = sizeof(ea->aarp_spu); 182 ea->aarp_op = htons(AARPOP_REQUEST); 183 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 184 185 /* 186 * We need to check whether the output ethernet type should 187 * be phase 1 or 2. We have the interface that we'll be sending 188 * the aarp out. We need to find an AppleTalk network on that 189 * interface with the same address as we're looking for. If the 190 * net is phase 2, generate an 802.2 and SNAP header. 191 */ 192 if ((aa = (struct at_ifaddr *) at_ifawithnet(sat, ifp)) == NULL) { 193 m_freem(m); 194 return; 195 } 196 eh = (struct ether_header *) sa.sa_data; 197 198 if (aa->aa_flags & AFA_PHASE2) { 199 bcopy(atmulticastaddr, eh->ether_dhost, 200 sizeof(eh->ether_dhost)); 201 eh->ether_type = 0; /* if_output will treat as 802 */ 202 M_PREPEND(m, sizeof(struct llc), M_WAIT); 203 llc = mtod(m, struct llc *); 204 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 205 llc->llc_control = LLC_UI; 206 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 207 llc->llc_ether_type = htons(ETHERTYPE_AARP); 208 209 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 210 sizeof(ea->aarp_spnet)); 211 bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet, 212 sizeof(ea->aarp_tpnet)); 213 ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node; 214 ea->aarp_tpnode = sat->sat_addr.s_node; 215 } else { 216 bcopy(etherbroadcastaddr, eh->ether_dhost, 217 sizeof(eh->ether_dhost)); 218 eh->ether_type = htons(ETHERTYPE_AARP); 219 220 ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node; 221 ea->aarp_tpa = sat->sat_addr.s_node; 222 } 223 224 #ifdef NETATALKDEBUG 225 printf("aarp: sending request via %u.%u seaking %u.%u\n", 226 ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node, 227 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); 228 #endif /* NETATALKDEBUG */ 229 230 sa.sa_len = sizeof(struct sockaddr); 231 sa.sa_family = AF_UNSPEC; 232 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX NULL should be routing */ 233 /* information */ 234 } 235 236 int 237 aarpresolve(ifp, m, destsat, desten) 238 struct ifnet *ifp; 239 struct mbuf *m; 240 struct sockaddr_at *destsat; 241 u_char *desten; 242 { 243 struct at_ifaddr *aa; 244 struct aarptab *aat; 245 int s; 246 247 if (at_broadcast(destsat)) { 248 aa = (struct at_ifaddr *) at_ifawithnet(destsat, ifp); 249 if (aa == NULL) { 250 m_freem(m); 251 return (0); 252 } 253 if (aa->aa_flags & AFA_PHASE2) 254 bcopy(atmulticastaddr, desten, 255 sizeof(atmulticastaddr)); 256 else 257 bcopy(etherbroadcastaddr, desten, 258 sizeof(etherbroadcastaddr)); 259 return 1; 260 } 261 s = splnet(); 262 AARPTAB_LOOK(aat, destsat->sat_addr); 263 if (aat == 0) { /* No entry */ 264 aat = aarptnew(&destsat->sat_addr); 265 if (aat == 0) 266 panic("aarpresolve: no free entry"); 267 268 aat->aat_hold = m; 269 aarpwhohas(ifp, destsat); 270 splx(s); 271 return 0; 272 } 273 274 /* found an entry */ 275 aat->aat_timer = 0; 276 if (aat->aat_flags & ATF_COM) { /* entry is COMplete */ 277 bcopy(aat->aat_enaddr, desten, sizeof(aat->aat_enaddr)); 278 splx(s); 279 return 1; 280 } 281 282 /* entry has not completed */ 283 if (aat->aat_hold) 284 m_freem(aat->aat_hold); 285 aat->aat_hold = m; 286 aarpwhohas(ifp, destsat); 287 splx(s); 288 289 return 0; 290 } 291 292 void 293 aarpinput(ifp, m) 294 struct ifnet *ifp; 295 struct mbuf *m; 296 { 297 struct arphdr *ar; 298 299 if (ifp->if_flags & IFF_NOARP) 300 goto out; 301 302 if (m->m_len < sizeof(struct arphdr)) 303 goto out; 304 305 ar = mtod(m, struct arphdr *); 306 if (ntohs(ar->ar_hrd) != AARPHRD_ETHER) 307 goto out; 308 309 if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln) 310 goto out; 311 312 switch (ntohs(ar->ar_pro)) { 313 case ETHERTYPE_ATALK: 314 at_aarpinput(ifp, m); 315 return; 316 317 default: 318 break; 319 } 320 321 out: 322 m_freem(m); 323 } 324 325 static void 326 at_aarpinput(ifp, m) 327 struct ifnet *ifp; 328 struct mbuf *m; 329 { 330 struct ether_aarp *ea; 331 struct at_ifaddr *aa; 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, LLADDR(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 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 368 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 369 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 370 (aa->aa_flags & AFA_PHASE2) == 0) 371 break; 372 } 373 if (aa == 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, dealocate 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(LLADDR(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(addr) 501 struct at_addr *addr; 502 { 503 int n; 504 int oldest = -1; 505 struct aarptab *aat, *aato = NULL; 506 static int first = 1; 507 508 if (first) { 509 first = 0; 510 callout_init(&aarptimer_callout); 511 callout_reset(&aarptimer_callout, hz, aarptimer, NULL); 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 at_ifaddr *aa; 543 struct llc *llc; 544 struct sockaddr sa; 545 struct ifnet *ifp = arp; 546 547 /* 548 * We need to check whether the output ethernet type should 549 * be phase 1 or 2. We have the interface that we'll be sending 550 * the aarp out. We need to find an AppleTalk network on that 551 * interface with the same address as we're looking for. If the 552 * net is phase 2, generate an 802.2 and SNAP header. 553 */ 554 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 555 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 556 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 557 (aa->aa_flags & AFA_PROBING)) 558 break; 559 } 560 if (aa == NULL) { /* serious error XXX */ 561 printf("aarpprobe why did this happen?!\n"); 562 return; 563 } 564 if (aa->aa_probcnt <= 0) { 565 aa->aa_flags &= ~AFA_PROBING; 566 wakeup(aa); 567 return; 568 } else { 569 callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp); 570 } 571 572 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) { 573 return; 574 } 575 m->m_len = sizeof(*ea); 576 m->m_pkthdr.len = sizeof(*ea); 577 MH_ALIGN(m, sizeof(*ea)); 578 579 ea = mtod(m, struct ether_aarp *); 580 bzero(ea, sizeof(*ea)); 581 582 ea->aarp_hrd = htons(AARPHRD_ETHER); 583 ea->aarp_pro = htons(ETHERTYPE_ATALK); 584 ea->aarp_hln = sizeof(ea->aarp_sha); 585 ea->aarp_pln = sizeof(ea->aarp_spu); 586 ea->aarp_op = htons(AARPOP_PROBE); 587 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 588 589 eh = (struct ether_header *) sa.sa_data; 590 591 if (aa->aa_flags & AFA_PHASE2) { 592 bcopy(atmulticastaddr, eh->ether_dhost, 593 sizeof(eh->ether_dhost)); 594 eh->ether_type = 0; /* if_output will treat as 802 */ 595 M_PREPEND(m, sizeof(struct llc), M_WAIT); 596 llc = mtod(m, struct llc *); 597 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 598 llc->llc_control = LLC_UI; 599 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 600 llc->llc_ether_type = htons(ETHERTYPE_AARP); 601 602 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 603 sizeof(ea->aarp_spnet)); 604 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet, 605 sizeof(ea->aarp_tpnet)); 606 ea->aarp_spnode = ea->aarp_tpnode = 607 AA_SAT(aa)->sat_addr.s_node; 608 } else { 609 bcopy(etherbroadcastaddr, eh->ether_dhost, 610 sizeof(eh->ether_dhost)); 611 eh->ether_type = htons(ETHERTYPE_AARP); 612 ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node; 613 } 614 615 #ifdef NETATALKDEBUG 616 printf("aarp: sending probe for %u.%u\n", 617 ntohs(AA_SAT(aa)->sat_addr.s_net), 618 AA_SAT(aa)->sat_addr.s_node); 619 #endif /* NETATALKDEBUG */ 620 621 sa.sa_len = sizeof(struct sockaddr); 622 sa.sa_family = AF_UNSPEC; 623 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */ 624 aa->aa_probcnt--; 625 } 626 627 void 628 aarp_clean() 629 { 630 struct aarptab *aat; 631 int i; 632 633 callout_stop(&aarptimer_callout); 634 for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) 635 if (aat->aat_hold) 636 m_freem(aat->aat_hold); 637 } 638