1 /* $NetBSD: aarp.c,v 1.8 2001/11/15 09:48:26 lukem 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.8 2001/11/15 09:48:26 lukem 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 static void 103 aarptimer(ignored) 104 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 struct sockaddr_at *sat; 131 struct ifnet *ifp; 132 { 133 struct ifaddr *ifa; 134 struct sockaddr_at *sat2; 135 struct netrange *nr; 136 137 for (ifa = ifp->if_addrlist.tqh_first; ifa; 138 ifa = ifa->ifa_list.tqe_next) { 139 if (ifa->ifa_addr->sa_family != AF_APPLETALK) 140 continue; 141 142 sat2 = satosat(ifa->ifa_addr); 143 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 144 break; 145 146 nr = (struct netrange *) (sat2->sat_zero); 147 if ((nr->nr_phase == 2) 148 && (nr->nr_firstnet <= sat->sat_addr.s_net) 149 && (nr->nr_lastnet >= sat->sat_addr.s_net)) 150 break; 151 } 152 return ifa; 153 } 154 155 static void 156 aarpwhohas(ifp, sat) 157 struct ifnet *ifp; 158 struct sockaddr_at *sat; 159 { 160 struct mbuf *m; 161 struct ether_header *eh; 162 struct ether_aarp *ea; 163 struct at_ifaddr *aa; 164 struct llc *llc; 165 struct sockaddr sa; 166 167 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 168 return; 169 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(LLADDR(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_WAIT); 202 llc = mtod(m, struct llc *); 203 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 204 llc->llc_control = LLC_UI; 205 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 206 llc->llc_ether_type = htons(ETHERTYPE_AARP); 207 208 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 209 sizeof(ea->aarp_spnet)); 210 bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet, 211 sizeof(ea->aarp_tpnet)); 212 ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node; 213 ea->aarp_tpnode = sat->sat_addr.s_node; 214 } else { 215 bcopy(etherbroadcastaddr, eh->ether_dhost, 216 sizeof(eh->ether_dhost)); 217 eh->ether_type = htons(ETHERTYPE_AARP); 218 219 ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node; 220 ea->aarp_tpa = sat->sat_addr.s_node; 221 } 222 223 #ifdef NETATALKDEBUG 224 printf("aarp: sending request via %u.%u seaking %u.%u\n", 225 ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node, 226 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); 227 #endif /* NETATALKDEBUG */ 228 229 sa.sa_len = sizeof(struct sockaddr); 230 sa.sa_family = AF_UNSPEC; 231 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX NULL should be routing */ 232 /* information */ 233 } 234 235 int 236 aarpresolve(ifp, m, destsat, desten) 237 struct ifnet *ifp; 238 struct mbuf *m; 239 struct sockaddr_at *destsat; 240 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 aarptab *aat; 332 struct ether_header *eh; 333 struct llc *llc; 334 struct sockaddr_at sat; 335 struct sockaddr sa; 336 struct at_addr spa, tpa, ma; 337 int op; 338 u_int16_t net; 339 340 ea = mtod(m, struct ether_aarp *); 341 342 /* Check to see if from my hardware address */ 343 if (!bcmp(ea->aarp_sha, LLADDR(ifp->if_sadl), sizeof(ea->aarp_sha))) { 344 m_freem(m); 345 return; 346 } 347 op = ntohs(ea->aarp_op); 348 bcopy(ea->aarp_tpnet, &net, sizeof(net)); 349 350 if (net != 0) { /* should be ATADDR_ANYNET? */ 351 sat.sat_len = sizeof(struct sockaddr_at); 352 sat.sat_family = AF_APPLETALK; 353 sat.sat_addr.s_net = net; 354 aa = (struct at_ifaddr *) at_ifawithnet(&sat, ifp); 355 if (aa == NULL) { 356 m_freem(m); 357 return; 358 } 359 bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net)); 360 bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net)); 361 } else { 362 /* 363 * Since we don't know the net, we just look for the first 364 * phase 1 address on the interface. 365 */ 366 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 367 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 368 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 369 (aa->aa_flags & AFA_PHASE2) == 0) 370 break; 371 } 372 if (aa == NULL) { 373 m_freem(m); 374 return; 375 } 376 tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net; 377 } 378 379 spa.s_node = ea->aarp_spnode; 380 tpa.s_node = ea->aarp_tpnode; 381 ma.s_net = AA_SAT(aa)->sat_addr.s_net; 382 ma.s_node = AA_SAT(aa)->sat_addr.s_node; 383 384 /* 385 * This looks like it's from us. 386 */ 387 if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) { 388 if (aa->aa_flags & AFA_PROBING) { 389 /* 390 * We're probing, someone either responded to our 391 * probe, or probed for the same address we'd like 392 * to use. Change the address we're probing for. 393 */ 394 callout_stop(&aa->aa_probe_ch); 395 wakeup(aa); 396 m_freem(m); 397 return; 398 } else if (op != AARPOP_PROBE) { 399 /* 400 * This is not a probe, and we're not probing. 401 * This means that someone's saying they have the same 402 * source address as the one we're using. Get upset... 403 */ 404 log(LOG_ERR, "aarp: duplicate AT address!! %s\n", 405 ether_sprintf(ea->aarp_sha)); 406 m_freem(m); 407 return; 408 } 409 } 410 AARPTAB_LOOK(aat, spa); 411 if (aat) { 412 if (op == AARPOP_PROBE) { 413 /* 414 * Someone's probing for spa, dealocate the one we've 415 * got, so that if the prober keeps the address, we'll 416 * be able to arp for him. 417 */ 418 aarptfree(aat); 419 m_freem(m); 420 return; 421 } 422 bcopy(ea->aarp_sha, aat->aat_enaddr, sizeof(ea->aarp_sha)); 423 aat->aat_flags |= ATF_COM; 424 if (aat->aat_hold) { 425 sat.sat_len = sizeof(struct sockaddr_at); 426 sat.sat_family = AF_APPLETALK; 427 sat.sat_addr = spa; 428 (*ifp->if_output)(ifp, aat->aat_hold, 429 (struct sockaddr *) & sat, NULL); /* XXX */ 430 aat->aat_hold = 0; 431 } 432 } 433 if (aat == 0 && tpa.s_net == ma.s_net && tpa.s_node == ma.s_node 434 && op != AARPOP_PROBE) { 435 if ((aat = aarptnew(&spa)) != NULL) { 436 bcopy(ea->aarp_sha, aat->aat_enaddr, 437 sizeof(ea->aarp_sha)); 438 aat->aat_flags |= ATF_COM; 439 } 440 } 441 /* 442 * Don't respond to responses, and never respond if we're 443 * still probing. 444 */ 445 if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 446 op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) { 447 m_freem(m); 448 return; 449 } 450 bcopy(ea->aarp_sha, ea->aarp_tha, sizeof(ea->aarp_sha)); 451 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 452 453 /* XXX */ 454 eh = (struct ether_header *) sa.sa_data; 455 bcopy(ea->aarp_tha, eh->ether_dhost, sizeof(eh->ether_dhost)); 456 457 if (aa->aa_flags & AFA_PHASE2) { 458 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 459 if (m == NULL) 460 return; 461 462 llc = mtod(m, struct llc *); 463 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 464 llc->llc_control = LLC_UI; 465 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 466 llc->llc_ether_type = htons(ETHERTYPE_AARP); 467 468 bcopy(ea->aarp_spnet, ea->aarp_tpnet, sizeof(ea->aarp_tpnet)); 469 bcopy(&ma.s_net, ea->aarp_spnet, sizeof(ea->aarp_spnet)); 470 eh->ether_type = 0; /* if_output will treat as 802 */ 471 } else { 472 eh->ether_type = htons(ETHERTYPE_AARP); 473 } 474 475 ea->aarp_tpnode = ea->aarp_spnode; 476 ea->aarp_spnode = ma.s_node; 477 ea->aarp_op = htons(AARPOP_RESPONSE); 478 479 sa.sa_len = sizeof(struct sockaddr); 480 sa.sa_family = AF_UNSPEC; 481 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */ 482 return; 483 } 484 485 static void 486 aarptfree(aat) 487 struct aarptab *aat; 488 { 489 490 if (aat->aat_hold) 491 m_freem(aat->aat_hold); 492 aat->aat_hold = 0; 493 aat->aat_timer = aat->aat_flags = 0; 494 aat->aat_ataddr.s_net = 0; 495 aat->aat_ataddr.s_node = 0; 496 } 497 498 static struct aarptab * 499 aarptnew(addr) 500 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); 510 callout_reset(&aarptimer_callout, hz, aarptimer, NULL); 511 } 512 aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ]; 513 for (n = 0; n < AARPTAB_BSIZ; n++, aat++) { 514 if (aat->aat_flags == 0) 515 goto out; 516 if (aat->aat_flags & ATF_PERM) 517 continue; 518 if ((int) aat->aat_timer > oldest) { 519 oldest = aat->aat_timer; 520 aato = aat; 521 } 522 } 523 if (aato == NULL) 524 return (NULL); 525 aat = aato; 526 aarptfree(aat); 527 out: 528 aat->aat_ataddr = *addr; 529 aat->aat_flags = ATF_INUSE; 530 return (aat); 531 } 532 533 534 void 535 aarpprobe(arp) 536 void *arp; 537 { 538 struct mbuf *m; 539 struct ether_header *eh; 540 struct ether_aarp *ea; 541 struct at_ifaddr *aa; 542 struct llc *llc; 543 struct sockaddr sa; 544 struct ifnet *ifp = arp; 545 546 /* 547 * We need to check whether the output ethernet type should 548 * be phase 1 or 2. We have the interface that we'll be sending 549 * the aarp out. We need to find an AppleTalk network on that 550 * interface with the same address as we're looking for. If the 551 * net is phase 2, generate an 802.2 and SNAP header. 552 */ 553 for (aa = (struct at_ifaddr *) ifp->if_addrlist.tqh_first; aa; 554 aa = (struct at_ifaddr *) aa->aa_ifa.ifa_list.tqe_next) { 555 if (AA_SAT(aa)->sat_family == AF_APPLETALK && 556 (aa->aa_flags & AFA_PROBING)) 557 break; 558 } 559 if (aa == NULL) { /* serious error XXX */ 560 printf("aarpprobe why did this happen?!\n"); 561 return; 562 } 563 if (aa->aa_probcnt <= 0) { 564 aa->aa_flags &= ~AFA_PROBING; 565 wakeup(aa); 566 return; 567 } else { 568 callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp); 569 } 570 571 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) { 572 return; 573 } 574 m->m_len = sizeof(*ea); 575 m->m_pkthdr.len = sizeof(*ea); 576 MH_ALIGN(m, sizeof(*ea)); 577 578 ea = mtod(m, struct ether_aarp *); 579 bzero(ea, sizeof(*ea)); 580 581 ea->aarp_hrd = htons(AARPHRD_ETHER); 582 ea->aarp_pro = htons(ETHERTYPE_ATALK); 583 ea->aarp_hln = sizeof(ea->aarp_sha); 584 ea->aarp_pln = sizeof(ea->aarp_spu); 585 ea->aarp_op = htons(AARPOP_PROBE); 586 bcopy(LLADDR(ifp->if_sadl), ea->aarp_sha, sizeof(ea->aarp_sha)); 587 588 eh = (struct ether_header *) sa.sa_data; 589 590 if (aa->aa_flags & AFA_PHASE2) { 591 bcopy(atmulticastaddr, eh->ether_dhost, 592 sizeof(eh->ether_dhost)); 593 eh->ether_type = 0; /* if_output will treat as 802 */ 594 M_PREPEND(m, sizeof(struct llc), M_WAIT); 595 llc = mtod(m, struct llc *); 596 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 597 llc->llc_control = LLC_UI; 598 bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code)); 599 llc->llc_ether_type = htons(ETHERTYPE_AARP); 600 601 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet, 602 sizeof(ea->aarp_spnet)); 603 bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet, 604 sizeof(ea->aarp_tpnet)); 605 ea->aarp_spnode = ea->aarp_tpnode = 606 AA_SAT(aa)->sat_addr.s_node; 607 } else { 608 bcopy(etherbroadcastaddr, eh->ether_dhost, 609 sizeof(eh->ether_dhost)); 610 eh->ether_type = htons(ETHERTYPE_AARP); 611 ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node; 612 } 613 614 #ifdef NETATALKDEBUG 615 printf("aarp: sending probe for %u.%u\n", 616 ntohs(AA_SAT(aa)->sat_addr.s_net), 617 AA_SAT(aa)->sat_addr.s_node); 618 #endif /* NETATALKDEBUG */ 619 620 sa.sa_len = sizeof(struct sockaddr); 621 sa.sa_family = AF_UNSPEC; 622 (*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */ 623 aa->aa_probcnt--; 624 } 625 626 void 627 aarp_clean() 628 { 629 struct aarptab *aat; 630 int i; 631 632 callout_stop(&aarptimer_callout); 633 for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) 634 if (aat->aat_hold) 635 m_freem(aat->aat_hold); 636 } 637