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