1 /* $NetBSD: if_arp.c,v 1.69 2000/05/20 03:08:42 jhawk Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Public Access Networks Corporation ("Panix"). It was developed under 9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1982, 1986, 1988, 1993 42 * The Regents of the University of California. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by the University of 55 * California, Berkeley and its contributors. 56 * 4. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 73 */ 74 75 /* 76 * Ethernet address resolution protocol. 77 * TODO: 78 * add "inuse/lock" bit (or ref. count) along with valid bit 79 */ 80 81 #include "opt_ddb.h" 82 #include "opt_inet.h" 83 84 #ifdef INET 85 86 #include <sys/param.h> 87 #include <sys/systm.h> 88 #include <sys/callout.h> 89 #include <sys/malloc.h> 90 #include <sys/mbuf.h> 91 #include <sys/socket.h> 92 #include <sys/time.h> 93 #include <sys/kernel.h> 94 #include <sys/errno.h> 95 #include <sys/ioctl.h> 96 #include <sys/syslog.h> 97 #include <sys/proc.h> 98 #include <sys/protosw.h> 99 #include <sys/domain.h> 100 101 #include <net/ethertypes.h> 102 #include <net/if.h> 103 #include <net/if_dl.h> 104 #include <net/if_token.h> 105 #include <net/if_types.h> 106 #include <net/route.h> 107 108 109 #include <netinet/in.h> 110 #include <netinet/in_systm.h> 111 #include <netinet/in_var.h> 112 #include <netinet/ip.h> 113 #include <netinet/if_inarp.h> 114 115 #include "loop.h" 116 #include "arc.h" 117 #if NARC > 0 118 #include <net/if_arc.h> 119 #endif 120 #include "fddi.h" 121 #if NFDDI > 0 122 #include <net/if_fddi.h> 123 #endif 124 #include "token.h" 125 #include "token.h" 126 127 #define SIN(s) ((struct sockaddr_in *)s) 128 #define SDL(s) ((struct sockaddr_dl *)s) 129 #define SRP(s) ((struct sockaddr_inarp *)s) 130 131 /* 132 * ARP trailer negotiation. Trailer protocol is not IP specific, 133 * but ARP request/response use IP addresses. 134 */ 135 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 136 137 /* timer values */ 138 int arpt_prune = (5*60*1); /* walk list every 5 minutes */ 139 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 140 int arpt_down = 20; /* once declared down, don't send for 20 secs */ 141 #define rt_expire rt_rmx.rmx_expire 142 143 static void arprequest __P((struct ifnet *, 144 struct in_addr *, struct in_addr *, u_int8_t *)); 145 static void arptfree __P((struct llinfo_arp *)); 146 static void arptimer __P((void *)); 147 static struct llinfo_arp *arplookup __P((struct in_addr *, int, int)); 148 static void in_arpinput __P((struct mbuf *)); 149 150 #if NLOOP > 0 151 extern struct ifnet loif[NLOOP]; 152 #endif 153 LIST_HEAD(, llinfo_arp) llinfo_arp; 154 struct ifqueue arpintrq = {0, 0, 0, 50}; 155 int arp_inuse, arp_allocated, arp_intimer; 156 int arp_maxtries = 5; 157 int useloopback = 1; /* use loopback interface for local traffic */ 158 int arpinit_done = 0; 159 160 struct callout arptimer_ch; 161 162 /* revarp state */ 163 static struct in_addr myip, srv_ip; 164 static int myip_initialized = 0; 165 static int revarp_in_progress = 0; 166 static struct ifnet *myip_ifp = NULL; 167 168 #ifdef DDB 169 static void db_print_sa __P((struct sockaddr *)); 170 static void db_print_ifa __P((struct ifaddr *)); 171 static void db_print_llinfo __P((caddr_t)); 172 static int db_show_radix_node __P((struct radix_node *, void *)); 173 #endif 174 175 /* 176 * this should be elsewhere. 177 */ 178 179 static char * 180 lla_snprintf __P((u_int8_t *, int)); 181 182 static char * 183 lla_snprintf(adrp, len) 184 u_int8_t *adrp; 185 int len; 186 { 187 static char buf[16*3]; 188 static const char hexdigits[] = { 189 '0','1','2','3','4','5','6','7', 190 '8','9','a','b','c','d','e','f' 191 }; 192 193 int i; 194 char *p; 195 196 p = buf; 197 198 *p++ = hexdigits[(*adrp)>>4]; 199 *p++ = hexdigits[(*adrp++)&0xf]; 200 201 for (i=1; i<len && i<16; i++) { 202 *p++ = ':'; 203 *p++ = hexdigits[(*adrp)>>4]; 204 *p++ = hexdigits[(*adrp++)&0xf]; 205 } 206 207 *p = 0; 208 return buf; 209 } 210 211 struct protosw arpsw[] = { 212 { 0, 0, 0, 0, 213 0, 0, 0, 0, 214 0, 215 0, 0, 0, arp_drain, 216 } 217 }; 218 219 220 struct domain arpdomain = 221 { PF_ARP, "arp", 0, 0, 0, 222 arpsw, &arpsw[sizeof(arpsw)/sizeof(arpsw[0])] 223 }; 224 225 /* 226 * ARP table locking. 227 * 228 * to prevent lossage vs. the arp_drain routine (which may be called at 229 * any time, including in a device driver context), we do two things: 230 * 231 * 1) manipulation of la->la_hold is done at splimp() (for all of 232 * about two instructions). 233 * 234 * 2) manipulation of the arp table's linked list is done under the 235 * protection of the ARP_LOCK; if arp_drain() or arptimer is called 236 * while the arp table is locked, we punt and try again later. 237 */ 238 239 int arp_locked; 240 241 static __inline int arp_lock_try __P((int)); 242 static __inline void arp_unlock __P((void)); 243 244 static __inline int 245 arp_lock_try(int recurse) 246 { 247 int s; 248 249 s = splimp(); 250 if (!recurse && arp_locked) { 251 splx(s); 252 return (0); 253 } 254 arp_locked++; 255 splx(s); 256 return (1); 257 } 258 259 static __inline void 260 arp_unlock() 261 { 262 int s; 263 264 s = splimp(); 265 arp_locked--; 266 splx(s); 267 } 268 269 #ifdef DIAGNOSTIC 270 #define ARP_LOCK(recurse) \ 271 do { \ 272 if (arp_lock_try(recurse) == 0) { \ 273 printf("%s:%d: arp already locked\n", __FILE__, __LINE__); \ 274 panic("arp_lock"); \ 275 } \ 276 } while (0) 277 #define ARP_LOCK_CHECK() \ 278 do { \ 279 if (arp_locked == 0) { \ 280 printf("%s:%d: arp lock not held\n", __FILE__, __LINE__); \ 281 panic("arp lock check"); \ 282 } \ 283 } while (0) 284 #else 285 #define ARP_LOCK(x) (void) arp_lock_try(x) 286 #define ARP_LOCK_CHECK() /* nothing */ 287 #endif 288 289 #define ARP_UNLOCK() arp_unlock() 290 291 /* 292 * ARP protocol drain routine. Called when memory is in short supply. 293 * Called at splimp(); 294 */ 295 296 void 297 arp_drain() 298 { 299 struct llinfo_arp *la, *nla; 300 int count = 0; 301 struct mbuf *mold; 302 303 if (arp_lock_try(0) == 0) { 304 printf("arp_drain: locked; punting\n"); 305 return; 306 } 307 308 for (la = llinfo_arp.lh_first; la != 0; la = nla) { 309 nla = la->la_list.le_next; 310 311 mold = la->la_hold; 312 la->la_hold = 0; 313 314 if (mold) { 315 m_freem(mold); 316 count++; 317 } 318 } 319 ARP_UNLOCK(); 320 } 321 322 323 /* 324 * Timeout routine. Age arp_tab entries periodically. 325 */ 326 /* ARGSUSED */ 327 static void 328 arptimer(arg) 329 void *arg; 330 { 331 int s; 332 struct llinfo_arp *la, *nla; 333 334 s = splsoftnet(); 335 336 if (arp_lock_try(0) == 0) { 337 /* get it later.. */ 338 splx(s); 339 return; 340 } 341 342 callout_reset(&arptimer_ch, arpt_prune * hz, arptimer, NULL); 343 for (la = llinfo_arp.lh_first; la != 0; la = nla) { 344 struct rtentry *rt = la->la_rt; 345 346 nla = la->la_list.le_next; 347 if (rt->rt_expire && rt->rt_expire <= time.tv_sec) 348 arptfree(la); /* timer has expired; clear */ 349 } 350 351 ARP_UNLOCK(); 352 353 splx(s); 354 } 355 356 /* 357 * Parallel to llc_rtrequest. 358 */ 359 void 360 arp_rtrequest(req, rt, sa) 361 int req; 362 struct rtentry *rt; 363 struct sockaddr *sa; 364 { 365 struct sockaddr *gate = rt->rt_gateway; 366 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 367 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; 368 size_t allocsize; 369 struct mbuf *mold; 370 int s; 371 372 if (!arpinit_done) { 373 arpinit_done = 1; 374 /* 375 * We generate expiration times from time.tv_sec 376 * so avoid accidently creating permanent routes. 377 */ 378 if (time.tv_sec == 0) { 379 time.tv_sec++; 380 } 381 callout_init(&arptimer_ch); 382 callout_reset(&arptimer_ch, hz, arptimer, NULL); 383 } 384 if (rt->rt_flags & RTF_GATEWAY) 385 return; 386 387 ARP_LOCK(1); /* we may already be locked here. */ 388 389 switch (req) { 390 391 case RTM_ADD: 392 /* 393 * XXX: If this is a manually added route to interface 394 * such as older version of routed or gated might provide, 395 * restore cloning bit. 396 */ 397 if ((rt->rt_flags & RTF_HOST) == 0 && 398 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) 399 rt->rt_flags |= RTF_CLONING; 400 if (rt->rt_flags & RTF_CLONING) { 401 /* 402 * Case 1: This route should come from a route to iface. 403 */ 404 rt_setgate(rt, rt_key(rt), 405 (struct sockaddr *)&null_sdl); 406 gate = rt->rt_gateway; 407 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 408 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 409 /* 410 * Give this route an expiration time, even though 411 * it's a "permanent" route, so that routes cloned 412 * from it do not need their expiration time set. 413 */ 414 rt->rt_expire = time.tv_sec; 415 #if NFDDI > 0 416 if (rt->rt_ifp->if_type == IFT_FDDI 417 && (rt->rt_rmx.rmx_mtu > FDDIIPMTU 418 || (rt->rt_rmx.rmx_mtu == 0 419 && rt->rt_ifp->if_mtu > FDDIIPMTU))) { 420 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 421 } 422 #endif 423 #if NARC > 0 424 if (rt->rt_ifp->if_type == IFT_ARCNET) { 425 int arcipifmtu; 426 427 if (rt->rt_ifp->if_flags & IFF_LINK0) 428 arcipifmtu = arc_ipmtu; 429 else 430 arcipifmtu = ARCMTU; 431 432 if (rt->rt_rmx.rmx_mtu > arcipifmtu || 433 (rt->rt_rmx.rmx_mtu == 0 && 434 rt->rt_ifp->if_mtu > arcipifmtu)) 435 436 rt->rt_rmx.rmx_mtu = arcipifmtu; 437 } 438 #endif 439 break; 440 } 441 /* Announce a new entry if requested. */ 442 if (rt->rt_flags & RTF_ANNOUNCE) 443 arprequest(rt->rt_ifp, 444 &SIN(rt_key(rt))->sin_addr, 445 &SIN(rt_key(rt))->sin_addr, 446 (u_char *)LLADDR(SDL(gate))); 447 /*FALLTHROUGH*/ 448 case RTM_RESOLVE: 449 if (gate->sa_family != AF_LINK || 450 gate->sa_len < sizeof(null_sdl)) { 451 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n"); 452 break; 453 } 454 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 455 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 456 if (la != 0) 457 break; /* This happens on a route change */ 458 /* 459 * Case 2: This route may come from cloning, or a manual route 460 * add with a LL address. 461 */ 462 switch (SDL(gate)->sdl_type) { 463 #if NTOKEN > 0 464 case IFT_ISO88025: 465 allocsize = sizeof(*la) + sizeof(struct token_rif); 466 break; 467 #endif /* NTOKEN > 0 */ 468 default: 469 allocsize = sizeof(*la); 470 } 471 R_Malloc(la, struct llinfo_arp *, allocsize); 472 rt->rt_llinfo = (caddr_t)la; 473 if (la == 0) { 474 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n"); 475 break; 476 } 477 arp_inuse++, arp_allocated++; 478 Bzero(la, allocsize); 479 la->la_rt = rt; 480 rt->rt_flags |= RTF_LLINFO; 481 LIST_INSERT_HEAD(&llinfo_arp, la, la_list); 482 if (in_hosteq(SIN(rt_key(rt))->sin_addr, 483 (IA_SIN(rt->rt_ifa))->sin_addr)) { 484 /* 485 * This test used to be 486 * if (loif.if_flags & IFF_UP) 487 * It allowed local traffic to be forced through 488 * the hardware by configuring the loopback down. 489 * However, it causes problems during network 490 * configuration for boards that can't receive 491 * packets they send. It is now necessary to clear 492 * "useloopback" and remove the route to force 493 * traffic out to the hardware. 494 */ 495 rt->rt_expire = 0; 496 Bcopy(LLADDR(rt->rt_ifp->if_sadl), 497 LLADDR(SDL(gate)), 498 SDL(gate)->sdl_alen = 499 rt->rt_ifp->if_data.ifi_addrlen); 500 #if NLOOP > 0 501 if (useloopback) 502 rt->rt_ifp = &loif[0]; 503 #endif 504 } 505 break; 506 507 case RTM_DELETE: 508 if (la == 0) 509 break; 510 arp_inuse--; 511 LIST_REMOVE(la, la_list); 512 rt->rt_llinfo = 0; 513 rt->rt_flags &= ~RTF_LLINFO; 514 515 s = splimp(); 516 mold = la->la_hold; 517 la->la_hold = 0; 518 splx(s); 519 520 if (mold) 521 m_freem(mold); 522 523 Free((caddr_t)la); 524 } 525 ARP_UNLOCK(); 526 } 527 528 /* 529 * Broadcast an ARP request. Caller specifies: 530 * - arp header source ip address 531 * - arp header target ip address 532 * - arp header source ethernet address 533 */ 534 static void 535 arprequest(ifp, sip, tip, enaddr) 536 struct ifnet *ifp; 537 struct in_addr *sip, *tip; 538 u_int8_t *enaddr; 539 { 540 struct mbuf *m; 541 struct arphdr *ah; 542 struct sockaddr sa; 543 544 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 545 return; 546 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) + 547 2*ifp->if_data.ifi_addrlen; 548 m->m_pkthdr.len = m->m_len; 549 MH_ALIGN(m, m->m_len); 550 ah = mtod(m, struct arphdr *); 551 bzero((caddr_t)ah, m->m_len); 552 ah->ar_pro = htons(ETHERTYPE_IP); 553 ah->ar_hln = ifp->if_data.ifi_addrlen; /* hardware address length */ 554 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 555 ah->ar_op = htons(ARPOP_REQUEST); 556 bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln); 557 bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln); 558 bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln); 559 sa.sa_family = AF_ARP; 560 sa.sa_len = 2; 561 m->m_flags |= M_BCAST; 562 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 563 } 564 565 /* 566 * Resolve an IP address into an ethernet address. If success, 567 * desten is filled in. If there is no entry in arptab, 568 * set one up and broadcast a request for the IP address. 569 * Hold onto this mbuf and resend it once the address 570 * is finally resolved. A return value of 1 indicates 571 * that desten has been filled in and the packet should be sent 572 * normally; a 0 return indicates that the packet has been 573 * taken over here, either now or for later transmission. 574 */ 575 int 576 arpresolve(ifp, rt, m, dst, desten) 577 struct ifnet *ifp; 578 struct rtentry *rt; 579 struct mbuf *m; 580 struct sockaddr *dst; 581 u_char *desten; 582 { 583 struct llinfo_arp *la; 584 struct sockaddr_dl *sdl; 585 struct mbuf *mold; 586 int s; 587 588 if (rt) 589 la = (struct llinfo_arp *)rt->rt_llinfo; 590 else { 591 if ((la = arplookup(&SIN(dst)->sin_addr, 1, 0)) != NULL) 592 rt = la->la_rt; 593 } 594 if (la == 0 || rt == 0) { 595 log(LOG_DEBUG, "arpresolve: can't allocate llinfo\n"); 596 m_freem(m); 597 return (0); 598 } 599 sdl = SDL(rt->rt_gateway); 600 /* 601 * Check the address family and length is valid, the address 602 * is resolved; otherwise, try to resolve. 603 */ 604 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) && 605 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { 606 bcopy(LLADDR(sdl), desten, 607 min(sdl->sdl_alen, ifp->if_data.ifi_addrlen)); 608 return 1; 609 } 610 /* 611 * There is an arptab entry, but no ethernet address 612 * response yet. Replace the held mbuf with this 613 * latest one. 614 */ 615 616 s = splimp(); 617 mold = la->la_hold; 618 la->la_hold = m; 619 splx(s); 620 621 if (mold) 622 m_freem(mold); 623 624 625 /* 626 * Re-send the ARP request when appropriate. 627 */ 628 #ifdef DIAGNOSTIC 629 if (rt->rt_expire == 0) { 630 /* This should never happen. (Should it? -gwr) */ 631 printf("arpresolve: unresolved and rt_expire == 0\n"); 632 /* Set expiration time to now (expired). */ 633 rt->rt_expire = time.tv_sec; 634 } 635 #endif 636 if (rt->rt_expire) { 637 rt->rt_flags &= ~RTF_REJECT; 638 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) { 639 rt->rt_expire = time.tv_sec; 640 if (la->la_asked++ < arp_maxtries) 641 arprequest(ifp, 642 &SIN(rt->rt_ifa->ifa_addr)->sin_addr, 643 &SIN(dst)->sin_addr, 644 LLADDR(ifp->if_sadl)); 645 else { 646 rt->rt_flags |= RTF_REJECT; 647 rt->rt_expire += arpt_down; 648 la->la_asked = 0; 649 } 650 } 651 } 652 return (0); 653 } 654 655 /* 656 * Common length and type checks are done here, 657 * then the protocol-specific routine is called. 658 */ 659 void 660 arpintr() 661 { 662 struct mbuf *m; 663 struct arphdr *ar; 664 int s; 665 666 while (arpintrq.ifq_head) { 667 s = splimp(); 668 IF_DEQUEUE(&arpintrq, m); 669 splx(s); 670 if (m == 0 || (m->m_flags & M_PKTHDR) == 0) 671 panic("arpintr"); 672 673 if (m->m_len >= sizeof(struct arphdr) && 674 (ar = mtod(m, struct arphdr *)) && 675 /* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */ 676 m->m_len >= 677 sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 678 switch (ntohs(ar->ar_pro)) { 679 680 case ETHERTYPE_IP: 681 case ETHERTYPE_IPTRAILERS: 682 in_arpinput(m); 683 continue; 684 } 685 m_freem(m); 686 } 687 } 688 689 /* 690 * ARP for Internet protocols on 10 Mb/s Ethernet. 691 * Algorithm is that given in RFC 826. 692 * In addition, a sanity check is performed on the sender 693 * protocol address, to catch impersonators. 694 * We no longer handle negotiations for use of trailer protocol: 695 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent 696 * along with IP replies if we wanted trailers sent to us, 697 * and also sent them in response to IP replies. 698 * This allowed either end to announce the desire to receive 699 * trailer packets. 700 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, 701 * but formerly didn't normally send requests. 702 */ 703 static void 704 in_arpinput(m) 705 struct mbuf *m; 706 { 707 struct arphdr *ah; 708 struct ifnet *ifp = m->m_pkthdr.rcvif; 709 struct llinfo_arp *la = 0; 710 struct rtentry *rt; 711 struct in_ifaddr *ia; 712 struct sockaddr_dl *sdl; 713 struct sockaddr sa; 714 struct in_addr isaddr, itaddr, myaddr; 715 int op; 716 struct mbuf *mold; 717 int s; 718 719 720 ah = mtod(m, struct arphdr *); 721 op = ntohs(ah->ar_op); 722 bcopy((caddr_t)ar_spa(ah), (caddr_t)&isaddr, sizeof (isaddr)); 723 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&itaddr, sizeof (itaddr)); 724 725 /* 726 * If the target IP address is zero, ignore the packet. 727 * This prevents the code below from tring to answer 728 * when we are using IP address zero (booting). 729 */ 730 if (in_nullhost(itaddr)) 731 goto out; 732 733 /* 734 * If the source IP address is zero, this is most likely a 735 * confused host trying to use IP address zero. (Windoze?) 736 * XXX: Should we bother trying to reply to these? 737 */ 738 if (in_nullhost(isaddr)) 739 goto out; 740 741 /* 742 * Search for a matching interface address 743 * or any address on the interface to use 744 * as a dummy address in the rest of this function 745 */ 746 INADDR_TO_IA(itaddr, ia); 747 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif) 748 NEXT_IA_WITH_SAME_ADDR(ia); 749 750 if (ia == NULL) { 751 INADDR_TO_IA(isaddr, ia); 752 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif) 753 NEXT_IA_WITH_SAME_ADDR(ia); 754 755 if (ia == NULL) { 756 IFP_TO_IA(ifp, ia); 757 if (ia == NULL) 758 goto out; 759 } 760 } 761 762 myaddr = ia->ia_addr.sin_addr; 763 764 if (!bcmp((caddr_t)ar_sha(ah), LLADDR(ifp->if_sadl), 765 ifp->if_data.ifi_addrlen)) 766 goto out; /* it's from me, ignore it. */ 767 768 if (!bcmp((caddr_t)ar_sha(ah), (caddr_t)ifp->if_broadcastaddr, 769 ifp->if_data.ifi_addrlen)) { 770 log(LOG_ERR, 771 "%s: arp: link address is broadcast for IP address %s!\n", 772 ifp->if_xname, in_fmtaddr(isaddr)); 773 goto out; 774 } 775 776 if (in_hosteq(isaddr, myaddr)) { 777 log(LOG_ERR, 778 "duplicate IP address %s sent from link address %s\n", 779 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); 780 itaddr = myaddr; 781 goto reply; 782 } 783 la = arplookup(&isaddr, in_hosteq(itaddr, myaddr), 0); 784 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { 785 if (sdl->sdl_alen && 786 bcmp((caddr_t)ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) { 787 if (rt->rt_flags & RTF_STATIC) { 788 log(LOG_INFO, 789 "%s tried to overwrite permanent arp info" 790 " for %s\n", 791 lla_snprintf(ar_sha(ah), ah->ar_hln), 792 in_fmtaddr(isaddr)); 793 goto out; 794 } else if (rt->rt_ifp != ifp) { 795 log(LOG_INFO, 796 "%s on %s tried to overwrite " 797 "arp info for %s on %s\n", 798 lla_snprintf(ar_sha(ah), ah->ar_hln), 799 ifp->if_xname, in_fmtaddr(isaddr), 800 rt->rt_ifp->if_xname); 801 goto out; 802 } else { 803 log(LOG_INFO, 804 "arp info overwritten for %s by %s\n", 805 in_fmtaddr(isaddr), 806 lla_snprintf(ar_sha(ah), ah->ar_hln)); 807 } 808 } 809 /* 810 * sanity check for the address length. 811 * XXX this does not work for protocols with variable address 812 * length. -is 813 */ 814 if (sdl->sdl_alen && 815 sdl->sdl_alen != ah->ar_hln) { 816 log(LOG_WARNING, 817 "arp from %s: new addr len %d, was %d", 818 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); 819 } 820 if (ifp->if_data.ifi_addrlen != ah->ar_hln) { 821 log(LOG_WARNING, 822 "arp from %s: addr len: new %d, i/f %d (ignored)", 823 in_fmtaddr(isaddr), ah->ar_hln, 824 ifp->if_data.ifi_addrlen); 825 goto reply; 826 } 827 #if NTOKEN > 0 828 /* 829 * XXX uses m_data and assumes the complete answer including 830 * XXX token-ring headers is in the same buf 831 */ 832 if (ifp->if_type == IFT_ISO88025) { 833 struct token_header *trh; 834 835 trh = (struct token_header *)M_TRHSTART(m); 836 if (trh->token_shost[0] & TOKEN_RI_PRESENT) { 837 struct token_rif *rif; 838 size_t riflen; 839 840 rif = TOKEN_RIF(trh); 841 riflen = (ntohs(rif->tr_rcf) & 842 TOKEN_RCF_LEN_MASK) >> 8; 843 844 if (riflen > 2 && 845 riflen < sizeof(struct token_rif) && 846 (riflen & 1) == 0) { 847 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION); 848 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK); 849 bcopy(rif, TOKEN_RIF(la), riflen); 850 } 851 } 852 } 853 #endif /* NTOKEN > 0 */ 854 bcopy((caddr_t)ar_sha(ah), LLADDR(sdl), 855 sdl->sdl_alen = ah->ar_hln); 856 if (rt->rt_expire) 857 rt->rt_expire = time.tv_sec + arpt_keep; 858 rt->rt_flags &= ~RTF_REJECT; 859 la->la_asked = 0; 860 861 s = splimp(); 862 mold = la->la_hold; 863 la->la_hold = 0; 864 splx(s); 865 866 if (mold) 867 (*ifp->if_output)(ifp, mold, rt_key(rt), rt); 868 } 869 reply: 870 if (op != ARPOP_REQUEST) { 871 out: 872 m_freem(m); 873 return; 874 } 875 if (in_hosteq(itaddr, myaddr)) { 876 /* I am the target */ 877 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), ah->ar_hln); 878 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln); 879 } else { 880 la = arplookup(&itaddr, 0, SIN_PROXY); 881 if (la == 0) 882 goto out; 883 rt = la->la_rt; 884 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), ah->ar_hln); 885 sdl = SDL(rt->rt_gateway); 886 bcopy(LLADDR(sdl), (caddr_t)ar_sha(ah), ah->ar_hln); 887 } 888 889 bcopy((caddr_t)ar_spa(ah), (caddr_t)ar_tpa(ah), ah->ar_pln); 890 bcopy((caddr_t)&itaddr, (caddr_t)ar_spa(ah), ah->ar_pln); 891 ah->ar_op = htons(ARPOP_REPLY); 892 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */ 893 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */ 894 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); 895 m->m_pkthdr.len = m->m_len; 896 sa.sa_family = AF_ARP; 897 sa.sa_len = 2; 898 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 899 return; 900 } 901 902 /* 903 * Free an arp entry. 904 */ 905 static void 906 arptfree(la) 907 struct llinfo_arp *la; 908 { 909 struct rtentry *rt = la->la_rt; 910 struct sockaddr_dl *sdl; 911 912 ARP_LOCK_CHECK(); 913 914 if (rt == 0) 915 panic("arptfree"); 916 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) && 917 sdl->sdl_family == AF_LINK) { 918 sdl->sdl_alen = 0; 919 la->la_asked = 0; 920 rt->rt_flags &= ~RTF_REJECT; 921 return; 922 } 923 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt), 924 0, (struct rtentry **)0); 925 } 926 927 /* 928 * Lookup or enter a new address in arptab. 929 */ 930 static struct llinfo_arp * 931 arplookup(addr, create, proxy) 932 struct in_addr *addr; 933 int create, proxy; 934 { 935 struct rtentry *rt; 936 static struct sockaddr_inarp sin; 937 const char *why = 0; 938 939 sin.sin_len = sizeof(sin); 940 sin.sin_family = AF_INET; 941 sin.sin_addr = *addr; 942 sin.sin_other = proxy ? SIN_PROXY : 0; 943 rt = rtalloc1(sintosa(&sin), create); 944 if (rt == 0) 945 return (0); 946 rt->rt_refcnt--; 947 948 if (rt->rt_flags & RTF_GATEWAY) 949 why = "host is not on local network"; 950 else if ((rt->rt_flags & RTF_LLINFO) == 0) 951 why = "could not allocate llinfo"; 952 else if (rt->rt_gateway->sa_family != AF_LINK) 953 why = "gateway route is not ours"; 954 else 955 return ((struct llinfo_arp *)rt->rt_llinfo); 956 957 if (create) 958 log(LOG_DEBUG, "arplookup: unable to enter address" 959 " for %s (%s)\n", 960 in_fmtaddr(*addr), why); 961 return (0); 962 } 963 964 int 965 arpioctl(cmd, data) 966 u_long cmd; 967 caddr_t data; 968 { 969 970 return (EOPNOTSUPP); 971 } 972 973 void 974 arp_ifinit(ifp, ifa) 975 struct ifnet *ifp; 976 struct ifaddr *ifa; 977 { 978 struct in_addr *ip; 979 980 /* 981 * Warn the user if another station has this IP address, 982 * but only if the interface IP address is not zero. 983 */ 984 ip = &IA_SIN(ifa)->sin_addr; 985 if (!in_nullhost(*ip)) 986 arprequest(ifp, ip, ip, LLADDR(ifp->if_sadl)); 987 988 ifa->ifa_rtrequest = arp_rtrequest; 989 ifa->ifa_flags |= RTF_CLONING; 990 } 991 992 /* 993 * Called from 10 Mb/s Ethernet interrupt handlers 994 * when ether packet type ETHERTYPE_REVARP 995 * is received. Common length and type checks are done here, 996 * then the protocol-specific routine is called. 997 */ 998 void 999 revarpinput(m) 1000 struct mbuf *m; 1001 { 1002 struct arphdr *ar; 1003 1004 if (m->m_len < sizeof(struct arphdr)) 1005 goto out; 1006 ar = mtod(m, struct arphdr *); 1007 #if 0 /* XXX I don't think we need this... and it will prevent other LL */ 1008 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 1009 goto out; 1010 #endif 1011 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 1012 goto out; 1013 switch (ntohs(ar->ar_pro)) { 1014 1015 case ETHERTYPE_IP: 1016 case ETHERTYPE_IPTRAILERS: 1017 in_revarpinput(m); 1018 return; 1019 1020 default: 1021 break; 1022 } 1023 out: 1024 m_freem(m); 1025 } 1026 1027 /* 1028 * RARP for Internet protocols on 10 Mb/s Ethernet. 1029 * Algorithm is that given in RFC 903. 1030 * We are only using for bootstrap purposes to get an ip address for one of 1031 * our interfaces. Thus we support no user-interface. 1032 * 1033 * Since the contents of the RARP reply are specific to the interface that 1034 * sent the request, this code must ensure that they are properly associated. 1035 * 1036 * Note: also supports ARP via RARP packets, per the RFC. 1037 */ 1038 void 1039 in_revarpinput(m) 1040 struct mbuf *m; 1041 { 1042 struct ifnet *ifp; 1043 struct arphdr *ah; 1044 int op; 1045 1046 ah = mtod(m, struct arphdr *); 1047 op = ntohs(ah->ar_op); 1048 switch (op) { 1049 case ARPOP_REQUEST: 1050 case ARPOP_REPLY: /* per RFC */ 1051 in_arpinput(m); 1052 return; 1053 case ARPOP_REVREPLY: 1054 break; 1055 case ARPOP_REVREQUEST: /* handled by rarpd(8) */ 1056 default: 1057 goto out; 1058 } 1059 if (!revarp_in_progress) 1060 goto out; 1061 ifp = m->m_pkthdr.rcvif; 1062 if (ifp != myip_ifp) /* !same interface */ 1063 goto out; 1064 if (myip_initialized) 1065 goto wake; 1066 if (bcmp(ar_tha(ah), LLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen)) 1067 goto out; 1068 bcopy((caddr_t)ar_spa(ah), (caddr_t)&srv_ip, sizeof(srv_ip)); 1069 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&myip, sizeof(myip)); 1070 myip_initialized = 1; 1071 wake: /* Do wakeup every time in case it was missed. */ 1072 wakeup((caddr_t)&myip); 1073 1074 out: 1075 m_freem(m); 1076 } 1077 1078 /* 1079 * Send a RARP request for the ip address of the specified interface. 1080 * The request should be RFC 903-compliant. 1081 */ 1082 void 1083 revarprequest(ifp) 1084 struct ifnet *ifp; 1085 { 1086 struct sockaddr sa; 1087 struct mbuf *m; 1088 struct arphdr *ah; 1089 1090 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 1091 return; 1092 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) + 1093 2*ifp->if_data.ifi_addrlen; 1094 m->m_pkthdr.len = m->m_len; 1095 MH_ALIGN(m, m->m_len); 1096 ah = mtod(m, struct arphdr *); 1097 bzero((caddr_t)ah, m->m_len); 1098 ah->ar_pro = htons(ETHERTYPE_IP); 1099 ah->ar_hln = ifp->if_data.ifi_addrlen; /* hardware address length */ 1100 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 1101 ah->ar_op = htons(ARPOP_REVREQUEST); 1102 1103 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln); 1104 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_tha(ah), ah->ar_hln); 1105 1106 sa.sa_family = AF_ARP; 1107 sa.sa_len = 2; 1108 m->m_flags |= M_BCAST; 1109 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 1110 1111 } 1112 1113 /* 1114 * RARP for the ip address of the specified interface, but also 1115 * save the ip address of the server that sent the answer. 1116 * Timeout if no response is received. 1117 */ 1118 int 1119 revarpwhoarewe(ifp, serv_in, clnt_in) 1120 struct ifnet *ifp; 1121 struct in_addr *serv_in; 1122 struct in_addr *clnt_in; 1123 { 1124 int result, count = 20; 1125 1126 myip_initialized = 0; 1127 myip_ifp = ifp; 1128 1129 revarp_in_progress = 1; 1130 while (count--) { 1131 revarprequest(ifp); 1132 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2); 1133 if (result != EWOULDBLOCK) 1134 break; 1135 } 1136 revarp_in_progress = 0; 1137 1138 if (!myip_initialized) 1139 return ENETUNREACH; 1140 1141 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in)); 1142 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in)); 1143 return 0; 1144 } 1145 1146 1147 1148 #ifdef DDB 1149 1150 #include <machine/db_machdep.h> 1151 #include <ddb/db_interface.h> 1152 #include <ddb/db_output.h> 1153 static void 1154 db_print_sa(sa) 1155 struct sockaddr *sa; 1156 { 1157 int len; 1158 u_char *p; 1159 1160 if (sa == 0) { 1161 db_printf("[NULL]"); 1162 return; 1163 } 1164 1165 p = (u_char*)sa; 1166 len = sa->sa_len; 1167 db_printf("["); 1168 while (len > 0) { 1169 db_printf("%d", *p); 1170 p++; len--; 1171 if (len) db_printf(","); 1172 } 1173 db_printf("]\n"); 1174 } 1175 static void 1176 db_print_ifa(ifa) 1177 struct ifaddr *ifa; 1178 { 1179 if (ifa == 0) 1180 return; 1181 db_printf(" ifa_addr="); 1182 db_print_sa(ifa->ifa_addr); 1183 db_printf(" ifa_dsta="); 1184 db_print_sa(ifa->ifa_dstaddr); 1185 db_printf(" ifa_mask="); 1186 db_print_sa(ifa->ifa_netmask); 1187 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n", 1188 ifa->ifa_flags, 1189 ifa->ifa_refcnt, 1190 ifa->ifa_metric); 1191 } 1192 static void 1193 db_print_llinfo(li) 1194 caddr_t li; 1195 { 1196 struct llinfo_arp *la; 1197 1198 if (li == 0) 1199 return; 1200 la = (struct llinfo_arp *)li; 1201 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n", 1202 la->la_rt, la->la_hold, la->la_asked); 1203 } 1204 /* 1205 * Function to pass to rn_walktree(). 1206 * Return non-zero error to abort walk. 1207 */ 1208 static int 1209 db_show_radix_node(rn, w) 1210 struct radix_node *rn; 1211 void *w; 1212 { 1213 struct rtentry *rt = (struct rtentry *)rn; 1214 1215 db_printf("rtentry=%p", rt); 1216 1217 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n", 1218 rt->rt_flags, rt->rt_refcnt, 1219 rt->rt_use, rt->rt_expire); 1220 1221 db_printf(" key="); db_print_sa(rt_key(rt)); 1222 db_printf(" mask="); db_print_sa(rt_mask(rt)); 1223 db_printf(" gw="); db_print_sa(rt->rt_gateway); 1224 1225 db_printf(" ifp=%p ", rt->rt_ifp); 1226 if (rt->rt_ifp) 1227 db_printf("(%s)", rt->rt_ifp->if_xname); 1228 else 1229 db_printf("(NULL)"); 1230 1231 db_printf(" ifa=%p\n", rt->rt_ifa); 1232 db_print_ifa(rt->rt_ifa); 1233 1234 db_printf(" genmask="); db_print_sa(rt->rt_genmask); 1235 1236 db_printf(" gwroute=%p llinfo=%p\n", 1237 rt->rt_gwroute, rt->rt_llinfo); 1238 db_print_llinfo(rt->rt_llinfo); 1239 1240 return (0); 1241 } 1242 /* 1243 * Function to print all the route trees. 1244 * Use this from ddb: "show arptab" 1245 */ 1246 void 1247 db_show_arptab(addr, have_addr, count, modif) 1248 db_expr_t addr; 1249 int have_addr; 1250 db_expr_t count; 1251 char * modif; 1252 { 1253 struct radix_node_head *rnh; 1254 rnh = rt_tables[AF_INET]; 1255 db_printf("Route tree for AF_INET\n"); 1256 if (rnh == NULL) { 1257 db_printf(" (not initialized)\n"); 1258 return; 1259 } 1260 rn_walktree(rnh, db_show_radix_node, NULL); 1261 return; 1262 } 1263 #endif 1264 #endif /* INET */ 1265 1266