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