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