1 /* $OpenBSD: if_ether.c,v 1.35 2001/12/08 06:15:15 jason Exp $ */ 2 /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93 37 */ 38 39 /* 40 * Ethernet address resolution protocol. 41 * TODO: 42 * add "inuse/lock" bit (or ref. count) along with valid bit 43 */ 44 45 #ifdef INET 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/mbuf.h> 50 #include <sys/socket.h> 51 #include <sys/kernel.h> 52 #include <sys/syslog.h> 53 #include <sys/proc.h> 54 55 #include <net/if.h> 56 #include <net/if_dl.h> 57 #include <net/route.h> 58 59 #include <netinet/in.h> 60 #include <netinet/in_var.h> 61 #include <netinet/if_ether.h> 62 63 #define SIN(s) ((struct sockaddr_in *)s) 64 #define SDL(s) ((struct sockaddr_dl *)s) 65 #define SRP(s) ((struct sockaddr_inarp *)s) 66 67 /* 68 * ARP trailer negotiation. Trailer protocol is not IP specific, 69 * but ARP request/response use IP addresses. 70 */ 71 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 72 73 /* timer values */ 74 int arpt_prune = (5*60*1); /* walk list every 5 minutes */ 75 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 76 int arpt_down = 20; /* once declared down, don't send for 20 secs */ 77 #define rt_expire rt_rmx.rmx_expire 78 79 void arptfree __P((struct llinfo_arp *)); 80 void arptimer __P((void *)); 81 struct llinfo_arp *arplookup __P((u_int32_t, int, int)); 82 void in_arpinput __P((struct mbuf *)); 83 84 LIST_HEAD(, llinfo_arp) llinfo_arp; 85 struct ifqueue arpintrq = {0, 0, 0, 50}; 86 int arp_inuse, arp_allocated, arp_intimer; 87 int arp_maxtries = 5; 88 int useloopback = 1; /* use loopback interface for local traffic */ 89 int arpinit_done = 0; 90 91 /* revarp state */ 92 static struct in_addr myip, srv_ip; 93 static int myip_initialized = 0; 94 static int revarp_in_progress = 0; 95 struct ifnet *myip_ifp = NULL; 96 97 #ifdef DDB 98 #include <uvm/uvm_extern.h> 99 100 void db_print_sa __P((struct sockaddr *)); 101 void db_print_ifa __P((struct ifaddr *)); 102 void db_print_llinfo __P((caddr_t)); 103 int db_show_radix_node __P((struct radix_node *, void *)); 104 #endif 105 106 /* 107 * Timeout routine. Age arp_tab entries periodically. 108 */ 109 /* ARGSUSED */ 110 void 111 arptimer(arg) 112 void *arg; 113 { 114 struct timeout *to = (struct timeout *)arg; 115 int s; 116 struct llinfo_arp *la, *nla; 117 118 s = splsoftnet(); 119 timeout_add(to, arpt_prune * hz); 120 for (la = llinfo_arp.lh_first; la != 0; la = nla) { 121 register struct rtentry *rt = la->la_rt; 122 123 nla = la->la_list.le_next; 124 if (rt->rt_expire && rt->rt_expire <= time.tv_sec) 125 arptfree(la); /* timer has expired; clear */ 126 } 127 splx(s); 128 } 129 130 /* 131 * Parallel to llc_rtrequest. 132 */ 133 void 134 arp_rtrequest(req, rt, info) 135 int req; 136 register struct rtentry *rt; 137 struct rt_addrinfo *info; 138 { 139 register struct sockaddr *gate = rt->rt_gateway; 140 register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 141 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; 142 143 if (!arpinit_done) { 144 static struct timeout arptimer_to; 145 146 arpinit_done = 1; 147 /* 148 * We generate expiration times from time.tv_sec 149 * so avoid accidently creating permanent routes. 150 */ 151 if (time.tv_sec == 0) { 152 time.tv_sec++; 153 } 154 155 timeout_set(&arptimer_to, arptimer, &arptimer_to); 156 timeout_add(&arptimer_to, hz); 157 } 158 if (rt->rt_flags & RTF_GATEWAY) 159 return; 160 switch (req) { 161 162 case RTM_ADD: 163 /* 164 * XXX: If this is a manually added route to interface 165 * such as older version of routed or gated might provide, 166 * restore cloning bit. 167 */ 168 if ((rt->rt_flags & RTF_HOST) == 0 && 169 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) 170 rt->rt_flags |= RTF_CLONING; 171 if (rt->rt_flags & RTF_CLONING) { 172 /* 173 * Case 1: This route should come from a route to iface. 174 */ 175 rt_setgate(rt, rt_key(rt), 176 (struct sockaddr *)&null_sdl); 177 gate = rt->rt_gateway; 178 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 179 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 180 /* 181 * Give this route an expiration time, even though 182 * it's a "permanent" route, so that routes cloned 183 * from it do not need their expiration time set. 184 */ 185 rt->rt_expire = time.tv_sec; 186 break; 187 } 188 /* Announce a new entry if requested. */ 189 if (rt->rt_flags & RTF_ANNOUNCE) 190 arprequest(rt->rt_ifp, 191 &SIN(rt_key(rt))->sin_addr.s_addr, 192 &SIN(rt_key(rt))->sin_addr.s_addr, 193 (u_char *)LLADDR(SDL(gate))); 194 /*FALLTHROUGH*/ 195 case RTM_RESOLVE: 196 if (gate->sa_family != AF_LINK || 197 gate->sa_len < sizeof(null_sdl)) { 198 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n"); 199 break; 200 } 201 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 202 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 203 if (la != 0) 204 break; /* This happens on a route change */ 205 /* 206 * Case 2: This route may come from cloning, or a manual route 207 * add with a LL address. 208 */ 209 R_Malloc(la, struct llinfo_arp *, sizeof(*la)); 210 rt->rt_llinfo = (caddr_t)la; 211 if (la == 0) { 212 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n"); 213 break; 214 } 215 arp_inuse++, arp_allocated++; 216 Bzero(la, sizeof(*la)); 217 la->la_rt = rt; 218 rt->rt_flags |= RTF_LLINFO; 219 LIST_INSERT_HEAD(&llinfo_arp, la, la_list); 220 if (SIN(rt_key(rt))->sin_addr.s_addr == 221 (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) { 222 /* 223 * This test used to be 224 * if (lo0ifp->if_flags & IFF_UP) 225 * It allowed local traffic to be forced through 226 * the hardware by configuring the loopback down. 227 * However, it causes problems during network 228 * configuration for boards that can't receive 229 * packets they send. It is now necessary to clear 230 * "useloopback" and remove the route to force 231 * traffic out to the hardware. 232 */ 233 rt->rt_expire = 0; 234 Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr, 235 LLADDR(SDL(gate)), 236 SDL(gate)->sdl_alen = ETHER_ADDR_LEN); 237 if (useloopback) 238 rt->rt_ifp = lo0ifp; 239 } 240 break; 241 242 case RTM_DELETE: 243 if (la == 0) 244 break; 245 arp_inuse--; 246 LIST_REMOVE(la, la_list); 247 rt->rt_llinfo = 0; 248 rt->rt_flags &= ~RTF_LLINFO; 249 if (la->la_hold) 250 m_freem(la->la_hold); 251 Free((caddr_t)la); 252 } 253 } 254 255 /* 256 * Broadcast an ARP request. Caller specifies: 257 * - arp header source ip address 258 * - arp header target ip address 259 * - arp header source ethernet address 260 */ 261 void 262 arprequest(ifp, sip, tip, enaddr) 263 register struct ifnet *ifp; 264 register u_int32_t *sip, *tip; 265 register u_int8_t *enaddr; 266 { 267 register struct mbuf *m; 268 register struct ether_header *eh; 269 register struct ether_arp *ea; 270 struct sockaddr sa; 271 272 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 273 return; 274 m->m_len = sizeof(*ea); 275 m->m_pkthdr.len = sizeof(*ea); 276 MH_ALIGN(m, sizeof(*ea)); 277 ea = mtod(m, struct ether_arp *); 278 eh = (struct ether_header *)sa.sa_data; 279 bzero((caddr_t)ea, sizeof (*ea)); 280 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 281 sizeof(eh->ether_dhost)); 282 eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */ 283 ea->arp_hrd = htons(ARPHRD_ETHER); 284 ea->arp_pro = htons(ETHERTYPE_IP); 285 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */ 286 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */ 287 ea->arp_op = htons(ARPOP_REQUEST); 288 bcopy((caddr_t)enaddr, (caddr_t)eh->ether_shost, 289 sizeof(eh->ether_shost)); 290 bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha)); 291 bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa)); 292 bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa)); 293 sa.sa_family = AF_UNSPEC; 294 sa.sa_len = sizeof(sa); 295 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0); 296 } 297 298 /* 299 * Resolve an IP address into an ethernet address. If success, 300 * desten is filled in. If there is no entry in arptab, 301 * set one up and broadcast a request for the IP address. 302 * Hold onto this mbuf and resend it once the address 303 * is finally resolved. A return value of 1 indicates 304 * that desten has been filled in and the packet should be sent 305 * normally; a 0 return indicates that the packet has been 306 * taken over here, either now or for later transmission. 307 */ 308 int 309 arpresolve(ac, rt, m, dst, desten) 310 register struct arpcom *ac; 311 register struct rtentry *rt; 312 struct mbuf *m; 313 register struct sockaddr *dst; 314 register u_char *desten; 315 { 316 register struct llinfo_arp *la; 317 struct sockaddr_dl *sdl; 318 319 if (m->m_flags & M_BCAST) { /* broadcast */ 320 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten, 321 sizeof(etherbroadcastaddr)); 322 return (1); 323 } 324 if (m->m_flags & M_MCAST) { /* multicast */ 325 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten); 326 return (1); 327 } 328 if (rt) 329 la = (struct llinfo_arp *)rt->rt_llinfo; 330 else { 331 if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL) 332 rt = la->la_rt; 333 } 334 if (la == 0 || rt == 0) { 335 log(LOG_DEBUG, "arpresolve: can't allocate llinfo\n"); 336 m_freem(m); 337 return (0); 338 } 339 sdl = SDL(rt->rt_gateway); 340 /* 341 * Check the address family and length is valid, the address 342 * is resolved; otherwise, try to resolve. 343 */ 344 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) && 345 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { 346 bcopy(LLADDR(sdl), desten, sdl->sdl_alen); 347 return 1; 348 } 349 if (((struct ifnet *)ac)->if_flags & IFF_NOARP) 350 return 0; 351 352 /* 353 * There is an arptab entry, but no ethernet address 354 * response yet. Replace the held mbuf with this 355 * latest one. 356 */ 357 if (la->la_hold) 358 m_freem(la->la_hold); 359 la->la_hold = m; 360 /* 361 * Re-send the ARP request when appropriate. 362 */ 363 #ifdef DIAGNOSTIC 364 if (rt->rt_expire == 0) { 365 /* This should never happen. (Should it? -gwr) */ 366 printf("arpresolve: unresolved and rt_expire == 0\n"); 367 /* Set expiration time to now (expired). */ 368 rt->rt_expire = time.tv_sec; 369 } 370 #endif 371 if (rt->rt_expire) { 372 rt->rt_flags &= ~RTF_REJECT; 373 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) { 374 rt->rt_expire = time.tv_sec; 375 if (la->la_asked++ < arp_maxtries) 376 arprequest(&ac->ac_if, 377 &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr), 378 &(SIN(dst)->sin_addr.s_addr), 379 ac->ac_enaddr); 380 else { 381 rt->rt_flags |= RTF_REJECT; 382 rt->rt_expire += arpt_down; 383 la->la_asked = 0; 384 } 385 } 386 } 387 return (0); 388 } 389 390 /* 391 * Common length and type checks are done here, 392 * then the protocol-specific routine is called. 393 */ 394 void 395 arpintr() 396 { 397 register struct mbuf *m; 398 register struct arphdr *ar; 399 int s, len; 400 401 while (arpintrq.ifq_head) { 402 s = splimp(); 403 IF_DEQUEUE(&arpintrq, m); 404 splx(s); 405 if (m == 0 || (m->m_flags & M_PKTHDR) == 0) 406 panic("arpintr"); 407 408 len = sizeof(struct arphdr); 409 if (m->m_len < len && (m = m_pullup(m, len)) == NULL) 410 continue; 411 412 ar = mtod(m, struct arphdr *); 413 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 414 continue; 415 416 len += 2 * (ar->ar_hln + ar->ar_pln); 417 if (m->m_len < len && (m = m_pullup(m, len)) == NULL) 418 continue; 419 420 switch (ntohs(ar->ar_pro)) { 421 case ETHERTYPE_IP: 422 case ETHERTYPE_IPTRAILERS: 423 in_arpinput(m); 424 continue; 425 } 426 m_freem(m); 427 } 428 } 429 430 /* 431 * ARP for Internet protocols on Ethernet. 432 * Algorithm is that given in RFC 826. 433 * In addition, a sanity check is performed on the sender 434 * protocol address, to catch impersonators. 435 * We no longer handle negotiations for use of trailer protocol: 436 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent 437 * along with IP replies if we wanted trailers sent to us, 438 * and also sent them in response to IP replies. 439 * This allowed either end to announce the desire to receive 440 * trailer packets. 441 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, 442 * but formerly didn't normally send requests. 443 */ 444 void 445 in_arpinput(m) 446 struct mbuf *m; 447 { 448 register struct ether_arp *ea; 449 register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif; 450 struct ether_header *eh; 451 register struct llinfo_arp *la = 0; 452 register struct rtentry *rt; 453 struct in_ifaddr *ia, *maybe_ia = 0; 454 struct sockaddr_dl *sdl; 455 struct sockaddr sa; 456 struct in_addr isaddr, itaddr, myaddr; 457 int op; 458 459 ea = mtod(m, struct ether_arp *); 460 op = ntohs(ea->arp_op); 461 if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY)) 462 goto out; 463 #if notyet 464 if ((op == ARPOP_REPLY) && (m->m_flags & (M_BCAST|M_MCAST))) { 465 log(LOG_ERR, 466 "arp: received reply to broadcast or multicast address\n"); 467 goto out; 468 } 469 #endif 470 bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof(isaddr)); 471 bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof(itaddr)); 472 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { 473 if (ia->ia_ifp == &ac->ac_if || 474 (ia->ia_ifp->if_bridge && 475 ia->ia_ifp->if_bridge == ac->ac_if.if_bridge)) { 476 maybe_ia = ia; 477 if (itaddr.s_addr == ia->ia_addr.sin_addr.s_addr || 478 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) 479 break; 480 } 481 } 482 if (maybe_ia == 0) 483 goto out; 484 myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr; 485 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr, 486 sizeof (ea->arp_sha))) 487 goto out; /* it's from me, ignore it. */ 488 if (ETHER_IS_MULTICAST (&ea->arp_sha[0])) { 489 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr, 490 sizeof (ea->arp_sha))) 491 log(LOG_ERR, 492 "arp: ether address is broadcast for IP address %s!\n", 493 inet_ntoa(isaddr)); 494 else 495 log(LOG_ERR, 496 "arp: ether address is multicast for IP address %s!\n", 497 inet_ntoa(isaddr)); 498 goto out; 499 } 500 if (isaddr.s_addr == myaddr.s_addr) { 501 log(LOG_ERR, 502 "duplicate IP address %s sent from ethernet address %s\n", 503 inet_ntoa(isaddr), ether_sprintf(ea->arp_sha)); 504 itaddr = myaddr; 505 goto reply; 506 } 507 la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0); 508 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { 509 if (sdl->sdl_alen) { 510 if (bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) { 511 if (rt->rt_flags & RTF_PERMANENT_ARP) { 512 log(LOG_WARNING, 513 "arp: attempt to overwrite permanent " 514 "entry for %s by %s on %s\n", 515 inet_ntoa(isaddr), 516 ether_sprintf(ea->arp_sha), 517 ac->ac_if.if_xname); 518 goto out; 519 } else if (rt->rt_ifp != &ac->ac_if) { 520 log(LOG_WARNING, 521 "arp: attempt to overwrite entry for %s " 522 "on %s by %s on %s\n", 523 inet_ntoa(isaddr), rt->rt_ifp->if_xname, 524 ether_sprintf(ea->arp_sha), 525 ac->ac_if.if_xname); 526 goto out; 527 } else { 528 log(LOG_INFO, 529 "arp info overwritten for %s by %s on %s\n", 530 inet_ntoa(isaddr), 531 ether_sprintf(ea->arp_sha), 532 ac->ac_if.if_xname); 533 rt->rt_expire = 1; /* no longer static */ 534 } 535 } 536 } else if (rt->rt_ifp != &ac->ac_if && !(ac->ac_if.if_bridge && 537 (rt->rt_ifp->if_bridge == ac->ac_if.if_bridge))) { 538 log(LOG_WARNING, 539 "arp: attempt to add entry for %s " 540 "on %s by %s on %s\n", 541 inet_ntoa(isaddr), rt->rt_ifp->if_xname, 542 ether_sprintf(ea->arp_sha), 543 ac->ac_if.if_xname); 544 goto out; 545 } 546 bcopy((caddr_t)ea->arp_sha, LLADDR(sdl), 547 sdl->sdl_alen = sizeof(ea->arp_sha)); 548 if (rt->rt_expire) 549 rt->rt_expire = time.tv_sec + arpt_keep; 550 rt->rt_flags &= ~RTF_REJECT; 551 la->la_asked = 0; 552 if (la->la_hold) { 553 (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold, 554 rt_key(rt), rt); 555 la->la_hold = 0; 556 } 557 } 558 reply: 559 if (op != ARPOP_REQUEST) { 560 out: 561 m_freem(m); 562 return; 563 } 564 if (itaddr.s_addr == myaddr.s_addr) { 565 /* I am the target */ 566 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha, 567 sizeof(ea->arp_sha)); 568 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha, 569 sizeof(ea->arp_sha)); 570 } else { 571 la = arplookup(itaddr.s_addr, 0, SIN_PROXY); 572 if (la == 0) 573 goto out; 574 rt = la->la_rt; 575 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha, 576 sizeof(ea->arp_sha)); 577 sdl = SDL(rt->rt_gateway); 578 bcopy(LLADDR(sdl), (caddr_t)ea->arp_sha, sizeof(ea->arp_sha)); 579 } 580 581 bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa)); 582 bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa)); 583 ea->arp_op = htons(ARPOP_REPLY); 584 ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */ 585 eh = (struct ether_header *)sa.sa_data; 586 bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost, 587 sizeof(eh->ether_dhost)); 588 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, 589 sizeof(eh->ether_shost)); 590 eh->ether_type = htons(ETHERTYPE_ARP); 591 sa.sa_family = AF_UNSPEC; 592 sa.sa_len = sizeof(sa); 593 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0); 594 return; 595 } 596 597 /* 598 * Free an arp entry. 599 */ 600 void 601 arptfree(la) 602 register struct llinfo_arp *la; 603 { 604 register struct rtentry *rt = la->la_rt; 605 register struct sockaddr_dl *sdl; 606 607 if (rt == 0) 608 panic("arptfree"); 609 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) && 610 sdl->sdl_family == AF_LINK) { 611 sdl->sdl_alen = 0; 612 la->la_asked = 0; 613 rt->rt_flags &= ~RTF_REJECT; 614 return; 615 } 616 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt), 617 0, (struct rtentry **)0); 618 } 619 620 /* 621 * Lookup or enter a new address in arptab. 622 */ 623 struct llinfo_arp * 624 arplookup(addr, create, proxy) 625 u_int32_t addr; 626 int create, proxy; 627 { 628 register struct rtentry *rt; 629 static struct sockaddr_inarp sin; 630 631 sin.sin_len = sizeof(sin); 632 sin.sin_family = AF_INET; 633 sin.sin_addr.s_addr = addr; 634 sin.sin_other = proxy ? SIN_PROXY : 0; 635 rt = rtalloc1(sintosa(&sin), create); 636 if (rt == 0) 637 return (0); 638 rt->rt_refcnt--; 639 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 || 640 rt->rt_gateway->sa_family != AF_LINK) { 641 if (create) 642 log(LOG_DEBUG, 643 "arplookup: unable to enter address for %s\n", 644 inet_ntoa(sin.sin_addr)); 645 return (0); 646 } 647 return ((struct llinfo_arp *)rt->rt_llinfo); 648 } 649 650 int 651 arpioctl(cmd, data) 652 u_long cmd; 653 caddr_t data; 654 { 655 656 return (EOPNOTSUPP); 657 } 658 659 void 660 arp_ifinit(ac, ifa) 661 struct arpcom *ac; 662 struct ifaddr *ifa; 663 { 664 665 /* Warn the user if another station has this IP address. */ 666 arprequest(&ac->ac_if, 667 &(IA_SIN(ifa)->sin_addr.s_addr), 668 &(IA_SIN(ifa)->sin_addr.s_addr), 669 ac->ac_enaddr); 670 ifa->ifa_rtrequest = arp_rtrequest; 671 ifa->ifa_flags |= RTF_CLONING; 672 } 673 674 /* 675 * Called from Ethernet interrupt handlers 676 * when ether packet type ETHERTYPE_REVARP 677 * is received. Common length and type checks are done here, 678 * then the protocol-specific routine is called. 679 */ 680 void 681 revarpinput(m) 682 struct mbuf *m; 683 { 684 struct arphdr *ar; 685 686 if (m->m_len < sizeof(struct arphdr)) 687 goto out; 688 ar = mtod(m, struct arphdr *); 689 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 690 goto out; 691 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 692 goto out; 693 switch (ntohs(ar->ar_pro)) { 694 695 case ETHERTYPE_IP: 696 case ETHERTYPE_IPTRAILERS: 697 in_revarpinput(m); 698 return; 699 700 default: 701 break; 702 } 703 out: 704 m_freem(m); 705 } 706 707 /* 708 * RARP for Internet protocols on Ethernet. 709 * Algorithm is that given in RFC 903. 710 * We are only using for bootstrap purposes to get an ip address for one of 711 * our interfaces. Thus we support no user-interface. 712 * 713 * Since the contents of the RARP reply are specific to the interface that 714 * sent the request, this code must ensure that they are properly associated. 715 * 716 * Note: also supports ARP via RARP packets, per the RFC. 717 */ 718 void 719 in_revarpinput(m) 720 struct mbuf *m; 721 { 722 struct ifnet *ifp; 723 struct ether_arp *ar; 724 int op; 725 726 ar = mtod(m, struct ether_arp *); 727 op = ntohs(ar->arp_op); 728 switch (op) { 729 case ARPOP_REQUEST: 730 case ARPOP_REPLY: /* per RFC */ 731 in_arpinput(m); 732 return; 733 case ARPOP_REVREPLY: 734 break; 735 case ARPOP_REVREQUEST: /* handled by rarpd(8) */ 736 default: 737 goto out; 738 } 739 if (!revarp_in_progress) 740 goto out; 741 ifp = m->m_pkthdr.rcvif; 742 if (ifp != myip_ifp) /* !same interface */ 743 goto out; 744 if (myip_initialized) 745 goto wake; 746 if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr, 747 sizeof(ar->arp_tha))) 748 goto out; 749 bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip)); 750 bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip)); 751 myip_initialized = 1; 752 wake: /* Do wakeup every time in case it was missed. */ 753 wakeup((caddr_t)&myip); 754 755 out: 756 m_freem(m); 757 } 758 759 /* 760 * Send a RARP request for the ip address of the specified interface. 761 * The request should be RFC 903-compliant. 762 */ 763 void 764 revarprequest(ifp) 765 struct ifnet *ifp; 766 { 767 struct sockaddr sa; 768 struct mbuf *m; 769 struct ether_header *eh; 770 struct ether_arp *ea; 771 struct arpcom *ac = (struct arpcom *)ifp; 772 773 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 774 return; 775 m->m_len = sizeof(*ea); 776 m->m_pkthdr.len = sizeof(*ea); 777 MH_ALIGN(m, sizeof(*ea)); 778 ea = mtod(m, struct ether_arp *); 779 eh = (struct ether_header *)sa.sa_data; 780 bzero((caddr_t)ea, sizeof(*ea)); 781 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 782 sizeof(eh->ether_dhost)); 783 eh->ether_type = htons(ETHERTYPE_REVARP); 784 ea->arp_hrd = htons(ARPHRD_ETHER); 785 ea->arp_pro = htons(ETHERTYPE_IP); 786 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */ 787 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */ 788 ea->arp_op = htons(ARPOP_REVREQUEST); 789 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, 790 sizeof(ea->arp_tha)); 791 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha, 792 sizeof(ea->arp_sha)); 793 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha, 794 sizeof(ea->arp_tha)); 795 sa.sa_family = AF_UNSPEC; 796 sa.sa_len = sizeof(sa); 797 ifp->if_output(ifp, m, &sa, (struct rtentry *)0); 798 } 799 800 /* 801 * RARP for the ip address of the specified interface, but also 802 * save the ip address of the server that sent the answer. 803 * Timeout if no response is received. 804 */ 805 int 806 revarpwhoarewe(ifp, serv_in, clnt_in) 807 struct ifnet *ifp; 808 struct in_addr *serv_in; 809 struct in_addr *clnt_in; 810 { 811 int result, count = 20; 812 813 if (myip_initialized) 814 return EIO; 815 816 myip_ifp = ifp; 817 revarp_in_progress = 1; 818 while (count--) { 819 revarprequest(ifp); 820 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2); 821 if (result != EWOULDBLOCK) 822 break; 823 } 824 revarp_in_progress = 0; 825 if (!myip_initialized) 826 return ENETUNREACH; 827 828 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in)); 829 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in)); 830 return 0; 831 } 832 833 /* For compatibility: only saves interface address. */ 834 int 835 revarpwhoami(in, ifp) 836 struct in_addr *in; 837 struct ifnet *ifp; 838 { 839 struct in_addr server; 840 return (revarpwhoarewe(ifp, &server, in)); 841 } 842 843 844 #ifdef DDB 845 846 #include <machine/db_machdep.h> 847 #include <ddb/db_interface.h> 848 #include <ddb/db_output.h> 849 850 void 851 db_print_sa(sa) 852 struct sockaddr *sa; 853 { 854 int len; 855 u_char *p; 856 857 if (sa == 0) { 858 db_printf("[NULL]"); 859 return; 860 } 861 862 p = (u_char*)sa; 863 len = sa->sa_len; 864 db_printf("["); 865 while (len > 0) { 866 db_printf("%d", *p); 867 p++; 868 len--; 869 if (len) 870 db_printf(","); 871 } 872 db_printf("]\n"); 873 } 874 875 void 876 db_print_ifa(ifa) 877 struct ifaddr *ifa; 878 { 879 if (ifa == 0) 880 return; 881 db_printf(" ifa_addr="); 882 db_print_sa(ifa->ifa_addr); 883 db_printf(" ifa_dsta="); 884 db_print_sa(ifa->ifa_dstaddr); 885 db_printf(" ifa_mask="); 886 db_print_sa(ifa->ifa_netmask); 887 db_printf(" flags=0x%x, refcnt=%d, metric=%d\n", 888 ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric); 889 } 890 891 void 892 db_print_llinfo(li) 893 caddr_t li; 894 { 895 struct llinfo_arp *la; 896 897 if (li == 0) 898 return; 899 la = (struct llinfo_arp *)li; 900 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n", 901 la->la_rt, la->la_hold, la->la_asked); 902 } 903 904 /* 905 * Function to pass to rn_walktree(). 906 * Return non-zero error to abort walk. 907 */ 908 int 909 db_show_radix_node(rn, w) 910 struct radix_node *rn; 911 void *w; 912 { 913 struct rtentry *rt = (struct rtentry *)rn; 914 915 db_printf("rtentry=%p", rt); 916 917 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n", 918 rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire); 919 920 db_printf(" key="); db_print_sa(rt_key(rt)); 921 db_printf(" mask="); db_print_sa(rt_mask(rt)); 922 db_printf(" gw="); db_print_sa(rt->rt_gateway); 923 924 db_printf(" ifp=%p ", rt->rt_ifp); 925 if (rt->rt_ifp) 926 db_printf("(%s)", rt->rt_ifp->if_xname); 927 else 928 db_printf("(NULL)"); 929 930 db_printf(" ifa=%p\n", rt->rt_ifa); 931 db_print_ifa(rt->rt_ifa); 932 933 db_printf(" genmask="); db_print_sa(rt->rt_genmask); 934 935 db_printf(" gwroute=%p llinfo=%p\n", rt->rt_gwroute, rt->rt_llinfo); 936 db_print_llinfo(rt->rt_llinfo); 937 return (0); 938 } 939 940 /* 941 * Function to print all the route trees. 942 * Use this from ddb: "call db_show_arptab" 943 */ 944 int 945 db_show_arptab() 946 { 947 struct radix_node_head *rnh; 948 rnh = rt_tables[AF_INET]; 949 db_printf("Route tree for AF_INET\n"); 950 if (rnh == NULL) { 951 db_printf(" (not initialized)\n"); 952 return (0); 953 } 954 rn_walktree(rnh, db_show_radix_node, NULL); 955 return (0); 956 } 957 #endif 958 #endif /* INET */ 959