1 /* $NetBSD: if_arp.c,v 1.103 2005/02/26 22:45:12 perry 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. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 69 */ 70 71 /* 72 * Ethernet address resolution protocol. 73 * TODO: 74 * add "inuse/lock" bit (or ref. count) along with valid bit 75 */ 76 77 #include <sys/cdefs.h> 78 __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.103 2005/02/26 22:45:12 perry Exp $"); 79 80 #include "opt_ddb.h" 81 #include "opt_inet.h" 82 83 #ifdef INET 84 85 #include "bridge.h" 86 87 #include <sys/param.h> 88 #include <sys/systm.h> 89 #include <sys/callout.h> 90 #include <sys/malloc.h> 91 #include <sys/mbuf.h> 92 #include <sys/socket.h> 93 #include <sys/time.h> 94 #include <sys/kernel.h> 95 #include <sys/errno.h> 96 #include <sys/ioctl.h> 97 #include <sys/syslog.h> 98 #include <sys/proc.h> 99 #include <sys/protosw.h> 100 #include <sys/domain.h> 101 #include <sys/sysctl.h> 102 103 #include <net/ethertypes.h> 104 #include <net/if.h> 105 #include <net/if_dl.h> 106 #include <net/if_token.h> 107 #include <net/if_types.h> 108 #include <net/route.h> 109 110 #include <netinet/in.h> 111 #include <netinet/in_systm.h> 112 #include <netinet/in_var.h> 113 #include <netinet/ip.h> 114 #include <netinet/if_inarp.h> 115 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 126 #define SIN(s) ((struct sockaddr_in *)s) 127 #define SDL(s) ((struct sockaddr_dl *)s) 128 #define SRP(s) ((struct sockaddr_inarp *)s) 129 130 /* 131 * ARP trailer negotiation. Trailer protocol is not IP specific, 132 * but ARP request/response use IP addresses. 133 */ 134 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 135 136 /* timer values */ 137 int arpt_prune = (5*60*1); /* walk list every 5 minutes */ 138 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 139 int arpt_down = 20; /* once declared down, don't send for 20 secs */ 140 int arpt_refresh = (5*60); /* time left before refreshing */ 141 #define rt_expire rt_rmx.rmx_expire 142 #define rt_pksent rt_rmx.rmx_pksent 143 144 static void arprequest(struct ifnet *, 145 struct in_addr *, struct in_addr *, u_int8_t *); 146 static void arptfree(struct llinfo_arp *); 147 static void arptimer(void *); 148 static struct llinfo_arp *arplookup(struct mbuf *, struct in_addr *, 149 int, int); 150 static void in_arpinput(struct mbuf *); 151 152 LIST_HEAD(, llinfo_arp) llinfo_arp; 153 struct ifqueue arpintrq = {0, 0, 0, 50}; 154 int arp_inuse, arp_allocated, arp_intimer; 155 int arp_maxtries = 5; 156 int useloopback = 1; /* use loopback interface for local traffic */ 157 int arpinit_done = 0; 158 159 struct arpstat arpstat; 160 struct callout arptimer_ch; 161 162 163 /* revarp state */ 164 static struct in_addr myip, srv_ip; 165 static int myip_initialized = 0; 166 static int revarp_in_progress = 0; 167 static struct ifnet *myip_ifp = NULL; 168 169 #ifdef DDB 170 static void db_print_sa(const struct sockaddr *); 171 static void db_print_ifa(struct ifaddr *); 172 static void db_print_llinfo(caddr_t); 173 static int db_show_radix_node(struct radix_node *, void *); 174 #endif 175 176 /* 177 * this should be elsewhere. 178 */ 179 180 static char * 181 lla_snprintf(u_int8_t *, int); 182 183 static char * 184 lla_snprintf(u_int8_t *adrp, int len) 185 { 186 #define NUMBUFS 3 187 static char buf[NUMBUFS][16*3]; 188 static int bnum = 0; 189 static const char hexdigits[] = { 190 '0','1','2','3','4','5','6','7', 191 '8','9','a','b','c','d','e','f' 192 }; 193 194 int i; 195 char *p; 196 197 p = buf[bnum]; 198 199 *p++ = hexdigits[(*adrp)>>4]; 200 *p++ = hexdigits[(*adrp++)&0xf]; 201 202 for (i=1; i<len && i<16; i++) { 203 *p++ = ':'; 204 *p++ = hexdigits[(*adrp)>>4]; 205 *p++ = hexdigits[(*adrp++)&0xf]; 206 } 207 208 *p = 0; 209 p = buf[bnum]; 210 bnum = (bnum + 1) % NUMBUFS; 211 return p; 212 } 213 214 DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */ 215 216 const struct protosw arpsw[] = { 217 { 0, &arpdomain, 0, 0, 218 0, 0, 0, 0, 219 0, 220 0, 0, 0, arp_drain, 221 } 222 }; 223 224 225 struct domain arpdomain = 226 { PF_ARP, "arp", 0, 0, 0, 227 arpsw, &arpsw[sizeof(arpsw)/sizeof(arpsw[0])] 228 }; 229 230 /* 231 * ARP table locking. 232 * 233 * to prevent lossage vs. the arp_drain routine (which may be called at 234 * any time, including in a device driver context), we do two things: 235 * 236 * 1) manipulation of la->la_hold is done at splnet() (for all of 237 * about two instructions). 238 * 239 * 2) manipulation of the arp table's linked list is done under the 240 * protection of the ARP_LOCK; if arp_drain() or arptimer is called 241 * while the arp table is locked, we punt and try again later. 242 */ 243 244 static int arp_locked; 245 static __inline int arp_lock_try(int); 246 static __inline void arp_unlock(void); 247 248 static __inline int 249 arp_lock_try(int recurse) 250 { 251 int s; 252 253 /* 254 * Use splvm() -- we're blocking things that would cause 255 * mbuf allocation. 256 */ 257 s = splvm(); 258 if (!recurse && arp_locked) { 259 splx(s); 260 return (0); 261 } 262 arp_locked++; 263 splx(s); 264 return (1); 265 } 266 267 static __inline void 268 arp_unlock(void) 269 { 270 int s; 271 272 s = splvm(); 273 arp_locked--; 274 splx(s); 275 } 276 277 #ifdef DIAGNOSTIC 278 #define ARP_LOCK(recurse) \ 279 do { \ 280 if (arp_lock_try(recurse) == 0) { \ 281 printf("%s:%d: arp already locked\n", __FILE__, __LINE__); \ 282 panic("arp_lock"); \ 283 } \ 284 } while (/*CONSTCOND*/ 0) 285 #define ARP_LOCK_CHECK() \ 286 do { \ 287 if (arp_locked == 0) { \ 288 printf("%s:%d: arp lock not held\n", __FILE__, __LINE__); \ 289 panic("arp lock check"); \ 290 } \ 291 } while (/*CONSTCOND*/ 0) 292 #else 293 #define ARP_LOCK(x) (void) arp_lock_try(x) 294 #define ARP_LOCK_CHECK() /* nothing */ 295 #endif 296 297 #define ARP_UNLOCK() arp_unlock() 298 299 /* 300 * ARP protocol drain routine. Called when memory is in short supply. 301 * Called at splvm(); 302 */ 303 304 void 305 arp_drain(void) 306 { 307 struct llinfo_arp *la, *nla; 308 int count = 0; 309 struct mbuf *mold; 310 311 if (arp_lock_try(0) == 0) { 312 printf("arp_drain: locked; punting\n"); 313 return; 314 } 315 316 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) { 317 nla = LIST_NEXT(la, la_list); 318 319 mold = la->la_hold; 320 la->la_hold = 0; 321 322 if (mold) { 323 m_freem(mold); 324 count++; 325 } 326 } 327 ARP_UNLOCK(); 328 arpstat.as_dfrdropped += count; 329 } 330 331 332 /* 333 * Timeout routine. Age arp_tab entries periodically. 334 */ 335 /* ARGSUSED */ 336 static void 337 arptimer(void *arg) 338 { 339 int s; 340 struct llinfo_arp *la, *nla; 341 342 s = splsoftnet(); 343 344 if (arp_lock_try(0) == 0) { 345 /* get it later.. */ 346 splx(s); 347 return; 348 } 349 350 callout_reset(&arptimer_ch, arpt_prune * hz, arptimer, NULL); 351 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) { 352 struct rtentry *rt = la->la_rt; 353 354 nla = LIST_NEXT(la, la_list); 355 if (rt->rt_expire == 0) 356 continue; 357 if ((rt->rt_expire - time.tv_sec) < arpt_refresh && 358 rt->rt_pksent > (time.tv_sec - arpt_keep)) { 359 /* 360 * If the entry has been used during since last 361 * refresh, try to renew it before deleting. 362 */ 363 arprequest(rt->rt_ifp, 364 &SIN(rt->rt_ifa->ifa_addr)->sin_addr, 365 &SIN(rt_key(rt))->sin_addr, 366 LLADDR(rt->rt_ifp->if_sadl)); 367 } else if (rt->rt_expire <= time.tv_sec) 368 arptfree(la); /* timer has expired; clear */ 369 } 370 371 ARP_UNLOCK(); 372 373 splx(s); 374 } 375 376 /* 377 * Parallel to llc_rtrequest. 378 */ 379 void 380 arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info) 381 { 382 struct sockaddr *gate = rt->rt_gateway; 383 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 384 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; 385 size_t allocsize; 386 struct mbuf *mold; 387 int s; 388 struct in_ifaddr *ia; 389 struct ifaddr *ifa; 390 391 if (!arpinit_done) { 392 arpinit_done = 1; 393 /* 394 * We generate expiration times from time.tv_sec 395 * so avoid accidently creating permanent routes. 396 */ 397 if (time.tv_sec == 0) { 398 time.tv_sec++; 399 } 400 callout_init(&arptimer_ch); 401 callout_reset(&arptimer_ch, hz, arptimer, NULL); 402 } 403 404 if ((rt->rt_flags & RTF_GATEWAY) != 0) { 405 if (req != RTM_ADD) 406 return; 407 408 /* 409 * linklayers with particular link MTU limitation. 410 */ 411 switch(rt->rt_ifp->if_type) { 412 #if NFDDI > 0 413 case IFT_FDDI: 414 if (rt->rt_ifp->if_mtu > FDDIIPMTU) 415 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 416 break; 417 #endif 418 #if NARC > 0 419 case IFT_ARCNET: 420 { 421 int arcipifmtu; 422 423 if (rt->rt_ifp->if_flags & IFF_LINK0) 424 arcipifmtu = arc_ipmtu; 425 else 426 arcipifmtu = ARCMTU; 427 if (rt->rt_ifp->if_mtu > arcipifmtu) 428 rt->rt_rmx.rmx_mtu = arcipifmtu; 429 break; 430 } 431 #endif 432 } 433 return; 434 } 435 436 ARP_LOCK(1); /* we may already be locked here. */ 437 438 switch (req) { 439 440 case RTM_ADD: 441 /* 442 * XXX: If this is a manually added route to interface 443 * such as older version of routed or gated might provide, 444 * restore cloning bit. 445 */ 446 if ((rt->rt_flags & RTF_HOST) == 0 && 447 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) 448 rt->rt_flags |= RTF_CLONING; 449 if (rt->rt_flags & RTF_CLONING) { 450 /* 451 * Case 1: This route should come from a route to iface. 452 */ 453 rt_setgate(rt, rt_key(rt), 454 (struct sockaddr *)&null_sdl); 455 gate = rt->rt_gateway; 456 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 457 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 458 /* 459 * Give this route an expiration time, even though 460 * it's a "permanent" route, so that routes cloned 461 * from it do not need their expiration time set. 462 */ 463 rt->rt_expire = time.tv_sec; 464 /* 465 * linklayers with particular link MTU limitation. 466 */ 467 switch (rt->rt_ifp->if_type) { 468 #if NFDDI > 0 469 case IFT_FDDI: 470 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 471 (rt->rt_rmx.rmx_mtu > FDDIIPMTU || 472 (rt->rt_rmx.rmx_mtu == 0 && 473 rt->rt_ifp->if_mtu > FDDIIPMTU))) 474 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 475 break; 476 #endif 477 #if NARC > 0 478 case IFT_ARCNET: 479 { 480 int arcipifmtu; 481 if (rt->rt_ifp->if_flags & IFF_LINK0) 482 arcipifmtu = arc_ipmtu; 483 else 484 arcipifmtu = ARCMTU; 485 486 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 487 (rt->rt_rmx.rmx_mtu > arcipifmtu || 488 (rt->rt_rmx.rmx_mtu == 0 && 489 rt->rt_ifp->if_mtu > arcipifmtu))) 490 rt->rt_rmx.rmx_mtu = arcipifmtu; 491 break; 492 } 493 #endif 494 } 495 break; 496 } 497 /* Announce a new entry if requested. */ 498 if (rt->rt_flags & RTF_ANNOUNCE) 499 arprequest(rt->rt_ifp, 500 &SIN(rt_key(rt))->sin_addr, 501 &SIN(rt_key(rt))->sin_addr, 502 (u_char *)LLADDR(SDL(gate))); 503 /*FALLTHROUGH*/ 504 case RTM_RESOLVE: 505 if (gate->sa_family != AF_LINK || 506 gate->sa_len < sizeof(null_sdl)) { 507 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n"); 508 break; 509 } 510 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 511 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 512 if (la != 0) 513 break; /* This happens on a route change */ 514 /* 515 * Case 2: This route may come from cloning, or a manual route 516 * add with a LL address. 517 */ 518 switch (SDL(gate)->sdl_type) { 519 #if NTOKEN > 0 520 case IFT_ISO88025: 521 allocsize = sizeof(*la) + sizeof(struct token_rif); 522 break; 523 #endif /* NTOKEN > 0 */ 524 default: 525 allocsize = sizeof(*la); 526 } 527 R_Malloc(la, struct llinfo_arp *, allocsize); 528 rt->rt_llinfo = (caddr_t)la; 529 if (la == 0) { 530 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n"); 531 break; 532 } 533 arp_inuse++, arp_allocated++; 534 Bzero(la, allocsize); 535 la->la_rt = rt; 536 rt->rt_flags |= RTF_LLINFO; 537 LIST_INSERT_HEAD(&llinfo_arp, la, la_list); 538 539 INADDR_TO_IA(SIN(rt_key(rt))->sin_addr, ia); 540 while (ia && ia->ia_ifp != rt->rt_ifp) 541 NEXT_IA_WITH_SAME_ADDR(ia); 542 if (ia) { 543 /* 544 * This test used to be 545 * if (lo0ifp->if_flags & IFF_UP) 546 * It allowed local traffic to be forced through 547 * the hardware by configuring the loopback down. 548 * However, it causes problems during network 549 * configuration for boards that can't receive 550 * packets they send. It is now necessary to clear 551 * "useloopback" and remove the route to force 552 * traffic out to the hardware. 553 * 554 * In 4.4BSD, the above "if" statement checked 555 * rt->rt_ifa against rt_key(rt). It was changed 556 * to the current form so that we can provide a 557 * better support for multiple IPv4 addresses on a 558 * interface. 559 */ 560 rt->rt_expire = 0; 561 Bcopy(LLADDR(rt->rt_ifp->if_sadl), 562 LLADDR(SDL(gate)), 563 SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen); 564 if (useloopback) 565 rt->rt_ifp = lo0ifp; 566 /* 567 * make sure to set rt->rt_ifa to the interface 568 * address we are using, otherwise we will have trouble 569 * with source address selection. 570 */ 571 ifa = &ia->ia_ifa; 572 if (ifa != rt->rt_ifa) { 573 IFAFREE(rt->rt_ifa); 574 IFAREF(ifa); 575 rt->rt_ifa = ifa; 576 } 577 } 578 break; 579 580 case RTM_DELETE: 581 if (la == 0) 582 break; 583 arp_inuse--; 584 LIST_REMOVE(la, la_list); 585 rt->rt_llinfo = 0; 586 rt->rt_flags &= ~RTF_LLINFO; 587 588 s = splnet(); 589 mold = la->la_hold; 590 la->la_hold = 0; 591 splx(s); 592 593 if (mold) 594 m_freem(mold); 595 596 Free((caddr_t)la); 597 } 598 ARP_UNLOCK(); 599 } 600 601 /* 602 * Broadcast an ARP request. Caller specifies: 603 * - arp header source ip address 604 * - arp header target ip address 605 * - arp header source ethernet address 606 */ 607 static void 608 arprequest(struct ifnet *ifp, 609 struct in_addr *sip, struct in_addr *tip, u_int8_t *enaddr) 610 { 611 struct mbuf *m; 612 struct arphdr *ah; 613 struct sockaddr sa; 614 615 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 616 return; 617 MCLAIM(m, &arpdomain.dom_mowner); 618 switch (ifp->if_type) { 619 case IFT_IEEE1394: 620 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 621 ifp->if_addrlen; 622 break; 623 default: 624 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 625 2 * ifp->if_addrlen; 626 break; 627 } 628 m->m_pkthdr.len = m->m_len; 629 MH_ALIGN(m, m->m_len); 630 ah = mtod(m, struct arphdr *); 631 bzero((caddr_t)ah, m->m_len); 632 switch (ifp->if_type) { 633 case IFT_IEEE1394: /* RFC2734 */ 634 /* fill it now for ar_tpa computation */ 635 ah->ar_hrd = htons(ARPHRD_IEEE1394); 636 break; 637 default: 638 /* ifp->if_output will fill ar_hrd */ 639 break; 640 } 641 ah->ar_pro = htons(ETHERTYPE_IP); 642 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 643 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 644 ah->ar_op = htons(ARPOP_REQUEST); 645 bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln); 646 bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln); 647 bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln); 648 sa.sa_family = AF_ARP; 649 sa.sa_len = 2; 650 m->m_flags |= M_BCAST; 651 arpstat.as_sndtotal++; 652 arpstat.as_sndrequest++; 653 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 654 } 655 656 /* 657 * Resolve an IP address into an ethernet address. If success, 658 * desten is filled in. If there is no entry in arptab, 659 * set one up and broadcast a request for the IP address. 660 * Hold onto this mbuf and resend it once the address 661 * is finally resolved. A return value of 1 indicates 662 * that desten has been filled in and the packet should be sent 663 * normally; a 0 return indicates that the packet has been 664 * taken over here, either now or for later transmission. 665 */ 666 int 667 arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m, 668 struct sockaddr *dst, u_char *desten) 669 { 670 struct llinfo_arp *la; 671 struct sockaddr_dl *sdl; 672 struct mbuf *mold; 673 int s; 674 675 if (rt) 676 la = (struct llinfo_arp *)rt->rt_llinfo; 677 else { 678 if ((la = arplookup(m, &SIN(dst)->sin_addr, 1, 0)) != NULL) 679 rt = la->la_rt; 680 } 681 if (la == 0 || rt == 0) { 682 arpstat.as_allocfail++; 683 log(LOG_DEBUG, 684 "arpresolve: can't allocate llinfo on %s for %s\n", 685 ifp->if_xname, in_fmtaddr(SIN(dst)->sin_addr)); 686 m_freem(m); 687 return (0); 688 } 689 sdl = SDL(rt->rt_gateway); 690 /* 691 * Check the address family and length is valid, the address 692 * is resolved; otherwise, try to resolve. 693 */ 694 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) && 695 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { 696 bcopy(LLADDR(sdl), desten, 697 min(sdl->sdl_alen, ifp->if_addrlen)); 698 rt->rt_pksent = time.tv_sec; /* Time for last pkt sent */ 699 return 1; 700 } 701 /* 702 * There is an arptab entry, but no ethernet address 703 * response yet. Replace the held mbuf with this 704 * latest one. 705 */ 706 707 arpstat.as_dfrtotal++; 708 s = splnet(); 709 mold = la->la_hold; 710 la->la_hold = m; 711 splx(s); 712 713 if (mold) { 714 arpstat.as_dfrdropped++; 715 m_freem(mold); 716 } 717 718 /* 719 * Re-send the ARP request when appropriate. 720 */ 721 #ifdef DIAGNOSTIC 722 if (rt->rt_expire == 0) { 723 /* This should never happen. (Should it? -gwr) */ 724 printf("arpresolve: unresolved and rt_expire == 0\n"); 725 /* Set expiration time to now (expired). */ 726 rt->rt_expire = time.tv_sec; 727 } 728 #endif 729 if (rt->rt_expire) { 730 rt->rt_flags &= ~RTF_REJECT; 731 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) { 732 rt->rt_expire = time.tv_sec; 733 if (la->la_asked++ < arp_maxtries) 734 arprequest(ifp, 735 &SIN(rt->rt_ifa->ifa_addr)->sin_addr, 736 &SIN(dst)->sin_addr, 737 LLADDR(ifp->if_sadl)); 738 else { 739 rt->rt_flags |= RTF_REJECT; 740 rt->rt_expire += arpt_down; 741 la->la_asked = 0; 742 } 743 } 744 } 745 return (0); 746 } 747 748 /* 749 * Common length and type checks are done here, 750 * then the protocol-specific routine is called. 751 */ 752 void 753 arpintr(void) 754 { 755 struct mbuf *m; 756 struct arphdr *ar; 757 int s; 758 int arplen; 759 760 while (arpintrq.ifq_head) { 761 s = splnet(); 762 IF_DEQUEUE(&arpintrq, m); 763 splx(s); 764 if (m == 0 || (m->m_flags & M_PKTHDR) == 0) 765 panic("arpintr"); 766 767 MCLAIM(m, &arpdomain.dom_mowner); 768 arpstat.as_rcvtotal++; 769 770 /* 771 * First, make sure we have at least struct arphdr. 772 */ 773 if (m->m_len < sizeof(struct arphdr) || 774 (ar = mtod(m, struct arphdr *)) == NULL) 775 goto badlen; 776 777 switch (m->m_pkthdr.rcvif->if_type) { 778 case IFT_IEEE1394: 779 arplen = sizeof(struct arphdr) + 780 ar->ar_hln + 2 * ar->ar_pln; 781 break; 782 default: 783 arplen = sizeof(struct arphdr) + 784 2 * ar->ar_hln + 2 * ar->ar_pln; 785 break; 786 } 787 788 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */ 789 m->m_len >= arplen) 790 switch (ntohs(ar->ar_pro)) { 791 case ETHERTYPE_IP: 792 case ETHERTYPE_IPTRAILERS: 793 in_arpinput(m); 794 continue; 795 default: 796 arpstat.as_rcvbadproto++; 797 } 798 else { 799 badlen: 800 arpstat.as_rcvbadlen++; 801 } 802 m_freem(m); 803 } 804 } 805 806 /* 807 * ARP for Internet protocols on 10 Mb/s Ethernet. 808 * Algorithm is that given in RFC 826. 809 * In addition, a sanity check is performed on the sender 810 * protocol address, to catch impersonators. 811 * We no longer handle negotiations for use of trailer protocol: 812 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent 813 * along with IP replies if we wanted trailers sent to us, 814 * and also sent them in response to IP replies. 815 * This allowed either end to announce the desire to receive 816 * trailer packets. 817 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, 818 * but formerly didn't normally send requests. 819 */ 820 static void 821 in_arpinput(struct mbuf *m) 822 { 823 struct arphdr *ah; 824 struct ifnet *ifp = m->m_pkthdr.rcvif; 825 struct llinfo_arp *la = 0; 826 struct rtentry *rt; 827 struct in_ifaddr *ia; 828 #if NBRIDGE > 0 829 struct in_ifaddr *bridge_ia = NULL; 830 #endif 831 struct sockaddr_dl *sdl; 832 struct sockaddr sa; 833 struct in_addr isaddr, itaddr, myaddr; 834 int op; 835 struct mbuf *mold; 836 int s; 837 838 ah = mtod(m, struct arphdr *); 839 op = ntohs(ah->ar_op); 840 841 /* 842 * Fix up ah->ar_hrd if necessary, before using ar_tha() or 843 * ar_tpa(). 844 */ 845 switch (ifp->if_type) { 846 case IFT_IEEE1394: 847 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394) 848 ; 849 else { 850 /* XXX this is to make sure we compute ar_tha right */ 851 /* XXX check ar_hrd more strictly? */ 852 ah->ar_hrd = htons(ARPHRD_IEEE1394); 853 } 854 break; 855 default: 856 /* XXX check ar_hrd? */ 857 break; 858 } 859 860 bcopy((caddr_t)ar_spa(ah), (caddr_t)&isaddr, sizeof (isaddr)); 861 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&itaddr, sizeof (itaddr)); 862 863 if (m->m_flags & (M_BCAST|M_MCAST)) 864 arpstat.as_rcvmcast++; 865 866 /* 867 * If the target IP address is zero, ignore the packet. 868 * This prevents the code below from tring to answer 869 * when we are using IP address zero (booting). 870 */ 871 if (in_nullhost(itaddr)) { 872 arpstat.as_rcvzerotpa++; 873 goto out; 874 } 875 876 /* 877 * If the source IP address is zero, this is most likely a 878 * confused host trying to use IP address zero. (Windoze?) 879 * XXX: Should we bother trying to reply to these? 880 */ 881 if (in_nullhost(isaddr)) { 882 arpstat.as_rcvzerospa++; 883 goto out; 884 } 885 886 /* 887 * Search for a matching interface address 888 * or any address on the interface to use 889 * as a dummy address in the rest of this function 890 */ 891 INADDR_TO_IA(itaddr, ia); 892 while (ia != NULL) { 893 if (ia->ia_ifp == m->m_pkthdr.rcvif) 894 break; 895 896 #if NBRIDGE > 0 897 /* 898 * If the interface we received the packet on 899 * is part of a bridge, check to see if we need 900 * to "bridge" the packet to ourselves at this 901 * layer. Note we still prefer a perfect match, 902 * but allow this weaker match if necessary. 903 */ 904 if (m->m_pkthdr.rcvif->if_bridge != NULL && 905 m->m_pkthdr.rcvif->if_bridge == ia->ia_ifp->if_bridge) 906 bridge_ia = ia; 907 #endif /* NBRIDGE > 0 */ 908 909 NEXT_IA_WITH_SAME_ADDR(ia); 910 } 911 912 #if NBRIDGE > 0 913 if (ia == NULL && bridge_ia != NULL) { 914 ia = bridge_ia; 915 ifp = bridge_ia->ia_ifp; 916 } 917 #endif 918 919 if (ia == NULL) { 920 INADDR_TO_IA(isaddr, ia); 921 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif) 922 NEXT_IA_WITH_SAME_ADDR(ia); 923 924 if (ia == NULL) { 925 IFP_TO_IA(ifp, ia); 926 if (ia == NULL) { 927 arpstat.as_rcvnoint++; 928 goto out; 929 } 930 } 931 } 932 933 myaddr = ia->ia_addr.sin_addr; 934 935 /* XXX checks for bridge case? */ 936 if (!bcmp((caddr_t)ar_sha(ah), LLADDR(ifp->if_sadl), 937 ifp->if_addrlen)) { 938 arpstat.as_rcvlocalsha++; 939 goto out; /* it's from me, ignore it. */ 940 } 941 942 /* XXX checks for bridge case? */ 943 if (!bcmp((caddr_t)ar_sha(ah), (caddr_t)ifp->if_broadcastaddr, 944 ifp->if_addrlen)) { 945 arpstat.as_rcvbcastsha++; 946 log(LOG_ERR, 947 "%s: arp: link address is broadcast for IP address %s!\n", 948 ifp->if_xname, in_fmtaddr(isaddr)); 949 goto out; 950 } 951 952 if (in_hosteq(isaddr, myaddr)) { 953 arpstat.as_rcvlocalspa++; 954 log(LOG_ERR, 955 "duplicate IP address %s sent from link address %s\n", 956 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); 957 itaddr = myaddr; 958 goto reply; 959 } 960 la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0); 961 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { 962 if (sdl->sdl_alen && 963 bcmp((caddr_t)ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) { 964 if (rt->rt_flags & RTF_STATIC) { 965 arpstat.as_rcvoverperm++; 966 log(LOG_INFO, 967 "%s tried to overwrite permanent arp info" 968 " for %s\n", 969 lla_snprintf(ar_sha(ah), ah->ar_hln), 970 in_fmtaddr(isaddr)); 971 goto out; 972 } else if (rt->rt_ifp != ifp) { 973 arpstat.as_rcvoverint++; 974 log(LOG_INFO, 975 "%s on %s tried to overwrite " 976 "arp info for %s on %s\n", 977 lla_snprintf(ar_sha(ah), ah->ar_hln), 978 ifp->if_xname, in_fmtaddr(isaddr), 979 rt->rt_ifp->if_xname); 980 goto out; 981 } else { 982 arpstat.as_rcvover++; 983 log(LOG_INFO, 984 "arp info overwritten for %s by %s\n", 985 in_fmtaddr(isaddr), 986 lla_snprintf(ar_sha(ah), ah->ar_hln)); 987 } 988 } 989 /* 990 * sanity check for the address length. 991 * XXX this does not work for protocols with variable address 992 * length. -is 993 */ 994 if (sdl->sdl_alen && 995 sdl->sdl_alen != ah->ar_hln) { 996 arpstat.as_rcvlenchg++; 997 log(LOG_WARNING, 998 "arp from %s: new addr len %d, was %d", 999 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); 1000 } 1001 if (ifp->if_addrlen != ah->ar_hln) { 1002 arpstat.as_rcvbadlen++; 1003 log(LOG_WARNING, 1004 "arp from %s: addr len: new %d, i/f %d (ignored)", 1005 in_fmtaddr(isaddr), ah->ar_hln, 1006 ifp->if_addrlen); 1007 goto reply; 1008 } 1009 #if NTOKEN > 0 1010 /* 1011 * XXX uses m_data and assumes the complete answer including 1012 * XXX token-ring headers is in the same buf 1013 */ 1014 if (ifp->if_type == IFT_ISO88025) { 1015 struct token_header *trh; 1016 1017 trh = (struct token_header *)M_TRHSTART(m); 1018 if (trh->token_shost[0] & TOKEN_RI_PRESENT) { 1019 struct token_rif *rif; 1020 size_t riflen; 1021 1022 rif = TOKEN_RIF(trh); 1023 riflen = (ntohs(rif->tr_rcf) & 1024 TOKEN_RCF_LEN_MASK) >> 8; 1025 1026 if (riflen > 2 && 1027 riflen < sizeof(struct token_rif) && 1028 (riflen & 1) == 0) { 1029 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION); 1030 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK); 1031 bcopy(rif, TOKEN_RIF(la), riflen); 1032 } 1033 } 1034 } 1035 #endif /* NTOKEN > 0 */ 1036 bcopy((caddr_t)ar_sha(ah), LLADDR(sdl), 1037 sdl->sdl_alen = ah->ar_hln); 1038 if (rt->rt_expire) 1039 rt->rt_expire = time.tv_sec + arpt_keep; 1040 rt->rt_flags &= ~RTF_REJECT; 1041 la->la_asked = 0; 1042 1043 s = splnet(); 1044 mold = la->la_hold; 1045 la->la_hold = 0; 1046 splx(s); 1047 1048 if (mold) { 1049 arpstat.as_dfrsent++; 1050 (*ifp->if_output)(ifp, mold, rt_key(rt), rt); 1051 } 1052 } 1053 reply: 1054 if (op != ARPOP_REQUEST) { 1055 if (op == ARPOP_REPLY) 1056 arpstat.as_rcvreply++; 1057 out: 1058 m_freem(m); 1059 return; 1060 } 1061 arpstat.as_rcvrequest++; 1062 if (in_hosteq(itaddr, myaddr)) { 1063 /* I am the target */ 1064 if (ar_tha(ah)) 1065 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), 1066 ah->ar_hln); 1067 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln); 1068 } else { 1069 la = arplookup(m, &itaddr, 0, SIN_PROXY); 1070 if (la == 0) 1071 goto out; 1072 rt = la->la_rt; 1073 if (ar_tha(ah)) 1074 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), 1075 ah->ar_hln); 1076 sdl = SDL(rt->rt_gateway); 1077 bcopy(LLADDR(sdl), (caddr_t)ar_sha(ah), ah->ar_hln); 1078 } 1079 1080 bcopy((caddr_t)ar_spa(ah), (caddr_t)ar_tpa(ah), ah->ar_pln); 1081 bcopy((caddr_t)&itaddr, (caddr_t)ar_spa(ah), ah->ar_pln); 1082 ah->ar_op = htons(ARPOP_REPLY); 1083 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */ 1084 switch (ifp->if_type) { 1085 case IFT_IEEE1394: 1086 /* 1087 * ieee1394 arp reply is broadcast 1088 */ 1089 m->m_flags &= ~M_MCAST; 1090 m->m_flags |= M_BCAST; 1091 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln; 1092 break; 1093 1094 default: 1095 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */ 1096 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); 1097 break; 1098 } 1099 m->m_pkthdr.len = m->m_len; 1100 sa.sa_family = AF_ARP; 1101 sa.sa_len = 2; 1102 arpstat.as_sndtotal++; 1103 arpstat.as_sndreply++; 1104 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 1105 return; 1106 } 1107 1108 /* 1109 * Free an arp entry. 1110 */ 1111 static void arptfree(struct llinfo_arp *la) 1112 { 1113 struct rtentry *rt = la->la_rt; 1114 struct sockaddr_dl *sdl; 1115 1116 ARP_LOCK_CHECK(); 1117 1118 if (rt == 0) 1119 panic("arptfree"); 1120 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) && 1121 sdl->sdl_family == AF_LINK) { 1122 sdl->sdl_alen = 0; 1123 la->la_asked = 0; 1124 rt->rt_flags &= ~RTF_REJECT; 1125 return; 1126 } 1127 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt), 1128 0, (struct rtentry **)0); 1129 } 1130 1131 /* 1132 * Lookup or enter a new address in arptab. 1133 */ 1134 static struct llinfo_arp * 1135 arplookup(struct mbuf *m, struct in_addr *addr, int create, int proxy) 1136 { 1137 struct arphdr *ah; 1138 struct ifnet *ifp = m->m_pkthdr.rcvif; 1139 struct rtentry *rt; 1140 static struct sockaddr_inarp sin; 1141 const char *why = 0; 1142 1143 ah = mtod(m, struct arphdr *); 1144 sin.sin_len = sizeof(sin); 1145 sin.sin_family = AF_INET; 1146 sin.sin_addr = *addr; 1147 sin.sin_other = proxy ? SIN_PROXY : 0; 1148 rt = rtalloc1(sintosa(&sin), create); 1149 if (rt == 0) 1150 return (0); 1151 rt->rt_refcnt--; 1152 1153 if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) == RTF_LLINFO && 1154 rt->rt_gateway->sa_family == AF_LINK) 1155 return ((struct llinfo_arp *)rt->rt_llinfo); 1156 1157 1158 1159 if (create) { 1160 if (rt->rt_flags & RTF_GATEWAY) 1161 why = "host is not on local network"; 1162 else if ((rt->rt_flags & RTF_LLINFO) == 0) { 1163 arpstat.as_allocfail++; 1164 why = "could not allocate llinfo"; 1165 } else 1166 why = "gateway route is not ours"; 1167 log(LOG_DEBUG, "arplookup: unable to enter address" 1168 " for %s@%s on %s (%s)\n", 1169 in_fmtaddr(*addr), lla_snprintf(ar_sha(ah), ah->ar_hln), 1170 (ifp) ? ifp->if_xname : 0, why); 1171 if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_CLONED) != 0) { 1172 rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt), 1173 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); 1174 } 1175 } 1176 return (0); 1177 } 1178 1179 int 1180 arpioctl(u_long cmd, caddr_t data) 1181 { 1182 1183 return (EOPNOTSUPP); 1184 } 1185 1186 void 1187 arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa) 1188 { 1189 struct in_addr *ip; 1190 1191 /* 1192 * Warn the user if another station has this IP address, 1193 * but only if the interface IP address is not zero. 1194 */ 1195 ip = &IA_SIN(ifa)->sin_addr; 1196 if (!in_nullhost(*ip)) 1197 arprequest(ifp, ip, ip, LLADDR(ifp->if_sadl)); 1198 1199 ifa->ifa_rtrequest = arp_rtrequest; 1200 ifa->ifa_flags |= RTF_CLONING; 1201 } 1202 1203 /* 1204 * Called from 10 Mb/s Ethernet interrupt handlers 1205 * when ether packet type ETHERTYPE_REVARP 1206 * is received. Common length and type checks are done here, 1207 * then the protocol-specific routine is called. 1208 */ 1209 void 1210 revarpinput(struct mbuf *m) 1211 { 1212 struct arphdr *ar; 1213 1214 if (m->m_len < sizeof(struct arphdr)) 1215 goto out; 1216 ar = mtod(m, struct arphdr *); 1217 #if 0 /* XXX I don't think we need this... and it will prevent other LL */ 1218 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 1219 goto out; 1220 #endif 1221 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 1222 goto out; 1223 switch (ntohs(ar->ar_pro)) { 1224 case ETHERTYPE_IP: 1225 case ETHERTYPE_IPTRAILERS: 1226 in_revarpinput(m); 1227 return; 1228 1229 default: 1230 break; 1231 } 1232 out: 1233 m_freem(m); 1234 } 1235 1236 /* 1237 * RARP for Internet protocols on 10 Mb/s Ethernet. 1238 * Algorithm is that given in RFC 903. 1239 * We are only using for bootstrap purposes to get an ip address for one of 1240 * our interfaces. Thus we support no user-interface. 1241 * 1242 * Since the contents of the RARP reply are specific to the interface that 1243 * sent the request, this code must ensure that they are properly associated. 1244 * 1245 * Note: also supports ARP via RARP packets, per the RFC. 1246 */ 1247 void 1248 in_revarpinput(struct mbuf *m) 1249 { 1250 struct ifnet *ifp; 1251 struct arphdr *ah; 1252 int op; 1253 1254 ah = mtod(m, struct arphdr *); 1255 op = ntohs(ah->ar_op); 1256 1257 switch (m->m_pkthdr.rcvif->if_type) { 1258 case IFT_IEEE1394: 1259 /* ARP without target hardware address is not supported */ 1260 goto out; 1261 default: 1262 break; 1263 } 1264 1265 switch (op) { 1266 case ARPOP_REQUEST: 1267 case ARPOP_REPLY: /* per RFC */ 1268 in_arpinput(m); 1269 return; 1270 case ARPOP_REVREPLY: 1271 break; 1272 case ARPOP_REVREQUEST: /* handled by rarpd(8) */ 1273 default: 1274 goto out; 1275 } 1276 if (!revarp_in_progress) 1277 goto out; 1278 ifp = m->m_pkthdr.rcvif; 1279 if (ifp != myip_ifp) /* !same interface */ 1280 goto out; 1281 if (myip_initialized) 1282 goto wake; 1283 if (bcmp(ar_tha(ah), LLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen)) 1284 goto out; 1285 bcopy((caddr_t)ar_spa(ah), (caddr_t)&srv_ip, sizeof(srv_ip)); 1286 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&myip, sizeof(myip)); 1287 myip_initialized = 1; 1288 wake: /* Do wakeup every time in case it was missed. */ 1289 wakeup((caddr_t)&myip); 1290 1291 out: 1292 m_freem(m); 1293 } 1294 1295 /* 1296 * Send a RARP request for the ip address of the specified interface. 1297 * The request should be RFC 903-compliant. 1298 */ 1299 void 1300 revarprequest(struct ifnet *ifp) 1301 { 1302 struct sockaddr sa; 1303 struct mbuf *m; 1304 struct arphdr *ah; 1305 1306 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 1307 return; 1308 MCLAIM(m, &arpdomain.dom_mowner); 1309 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) + 1310 2*ifp->if_addrlen; 1311 m->m_pkthdr.len = m->m_len; 1312 MH_ALIGN(m, m->m_len); 1313 ah = mtod(m, struct arphdr *); 1314 bzero((caddr_t)ah, m->m_len); 1315 ah->ar_pro = htons(ETHERTYPE_IP); 1316 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 1317 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 1318 ah->ar_op = htons(ARPOP_REVREQUEST); 1319 1320 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln); 1321 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_tha(ah), ah->ar_hln); 1322 1323 sa.sa_family = AF_ARP; 1324 sa.sa_len = 2; 1325 m->m_flags |= M_BCAST; 1326 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 1327 1328 } 1329 1330 /* 1331 * RARP for the ip address of the specified interface, but also 1332 * save the ip address of the server that sent the answer. 1333 * Timeout if no response is received. 1334 */ 1335 int 1336 revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in, 1337 struct in_addr *clnt_in) 1338 { 1339 int result, count = 20; 1340 1341 myip_initialized = 0; 1342 myip_ifp = ifp; 1343 1344 revarp_in_progress = 1; 1345 while (count--) { 1346 revarprequest(ifp); 1347 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2); 1348 if (result != EWOULDBLOCK) 1349 break; 1350 } 1351 revarp_in_progress = 0; 1352 1353 if (!myip_initialized) 1354 return ENETUNREACH; 1355 1356 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in)); 1357 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in)); 1358 return 0; 1359 } 1360 1361 1362 1363 #ifdef DDB 1364 1365 #include <machine/db_machdep.h> 1366 #include <ddb/db_interface.h> 1367 #include <ddb/db_output.h> 1368 1369 static void 1370 db_print_sa(const struct sockaddr *sa) 1371 { 1372 int len; 1373 u_char *p; 1374 1375 if (sa == 0) { 1376 db_printf("[NULL]"); 1377 return; 1378 } 1379 1380 p = (u_char*)sa; 1381 len = sa->sa_len; 1382 db_printf("["); 1383 while (len > 0) { 1384 db_printf("%d", *p); 1385 p++; len--; 1386 if (len) db_printf(","); 1387 } 1388 db_printf("]\n"); 1389 } 1390 1391 static void 1392 db_print_ifa(struct ifaddr *ifa) 1393 { 1394 if (ifa == 0) 1395 return; 1396 db_printf(" ifa_addr="); 1397 db_print_sa(ifa->ifa_addr); 1398 db_printf(" ifa_dsta="); 1399 db_print_sa(ifa->ifa_dstaddr); 1400 db_printf(" ifa_mask="); 1401 db_print_sa(ifa->ifa_netmask); 1402 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n", 1403 ifa->ifa_flags, 1404 ifa->ifa_refcnt, 1405 ifa->ifa_metric); 1406 } 1407 1408 static void 1409 db_print_llinfo(caddr_t li) 1410 { 1411 struct llinfo_arp *la; 1412 1413 if (li == 0) 1414 return; 1415 la = (struct llinfo_arp *)li; 1416 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n", 1417 la->la_rt, la->la_hold, la->la_asked); 1418 } 1419 1420 /* 1421 * Function to pass to rn_walktree(). 1422 * Return non-zero error to abort walk. 1423 */ 1424 static int 1425 db_show_radix_node(struct radix_node *rn, void *w) 1426 { 1427 struct rtentry *rt = (struct rtentry *)rn; 1428 1429 db_printf("rtentry=%p", rt); 1430 1431 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n", 1432 rt->rt_flags, rt->rt_refcnt, 1433 rt->rt_use, rt->rt_expire); 1434 1435 db_printf(" key="); db_print_sa(rt_key(rt)); 1436 db_printf(" mask="); db_print_sa(rt_mask(rt)); 1437 db_printf(" gw="); db_print_sa(rt->rt_gateway); 1438 1439 db_printf(" ifp=%p ", rt->rt_ifp); 1440 if (rt->rt_ifp) 1441 db_printf("(%s)", rt->rt_ifp->if_xname); 1442 else 1443 db_printf("(NULL)"); 1444 1445 db_printf(" ifa=%p\n", rt->rt_ifa); 1446 db_print_ifa(rt->rt_ifa); 1447 1448 db_printf(" genmask="); db_print_sa(rt->rt_genmask); 1449 1450 db_printf(" gwroute=%p llinfo=%p\n", 1451 rt->rt_gwroute, rt->rt_llinfo); 1452 db_print_llinfo(rt->rt_llinfo); 1453 1454 return (0); 1455 } 1456 1457 /* 1458 * Function to print all the route trees. 1459 * Use this from ddb: "show arptab" 1460 */ 1461 void 1462 db_show_arptab(db_expr_t addr, int have_addr, db_expr_t count, char *modif) 1463 { 1464 struct radix_node_head *rnh; 1465 rnh = rt_tables[AF_INET]; 1466 db_printf("Route tree for AF_INET\n"); 1467 if (rnh == NULL) { 1468 db_printf(" (not initialized)\n"); 1469 return; 1470 } 1471 rn_walktree(rnh, db_show_radix_node, NULL); 1472 return; 1473 } 1474 #endif 1475 1476 SYSCTL_SETUP(sysctl_net_inet_arp_setup, "sysctl net.inet.arp subtree setup") 1477 { 1478 struct sysctlnode *node; 1479 1480 sysctl_createv(clog, 0, NULL, NULL, 1481 CTLFLAG_PERMANENT, 1482 CTLTYPE_NODE, "net", NULL, 1483 NULL, 0, NULL, 0, 1484 CTL_NET, CTL_EOL); 1485 sysctl_createv(clog, 0, NULL, NULL, 1486 CTLFLAG_PERMANENT, 1487 CTLTYPE_NODE, "inet", NULL, 1488 NULL, 0, NULL, 0, 1489 CTL_NET, PF_INET, CTL_EOL); 1490 sysctl_createv(clog, 0, NULL, &node, 1491 CTLFLAG_PERMANENT, 1492 CTLTYPE_NODE, "arp", 1493 SYSCTL_DESCR("Address Resolution Protocol"), 1494 NULL, 0, NULL, 0, 1495 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL); 1496 1497 sysctl_createv(clog, 0, NULL, NULL, 1498 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1499 CTLTYPE_INT, "prune", 1500 SYSCTL_DESCR("ARP cache pruning interval"), 1501 NULL, 0, &arpt_prune, 0, 1502 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 1503 1504 sysctl_createv(clog, 0, NULL, NULL, 1505 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1506 CTLTYPE_INT, "keep", 1507 SYSCTL_DESCR("Valid ARP entry lifetime"), 1508 NULL, 0, &arpt_keep, 0, 1509 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 1510 1511 sysctl_createv(clog, 0, NULL, NULL, 1512 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1513 CTLTYPE_INT, "down", 1514 SYSCTL_DESCR("Failed ARP entry lifetime"), 1515 NULL, 0, &arpt_down, 0, 1516 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 1517 1518 sysctl_createv(clog, 0, NULL, NULL, 1519 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1520 CTLTYPE_INT, "refresh", 1521 SYSCTL_DESCR("ARP entry refresh interval"), 1522 NULL, 0, &arpt_refresh, 0, 1523 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 1524 } 1525 1526 #endif /* INET */ 1527