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