1 /* $OpenBSD: if_ether.c,v 1.220 2016/07/14 14:01:40 mpi 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. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93 33 */ 34 35 /* 36 * Ethernet address resolution protocol. 37 * TODO: 38 * add "inuse/lock" bit (or ref. count) along with valid bit 39 */ 40 41 #include "carp.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/mbuf.h> 46 #include <sys/socket.h> 47 #include <sys/timeout.h> 48 #include <sys/kernel.h> 49 #include <sys/syslog.h> 50 #include <sys/queue.h> 51 #include <sys/pool.h> 52 53 #include <net/if.h> 54 #include <net/if_var.h> 55 #include <net/if_dl.h> 56 #include <net/route.h> 57 #include <net/if_types.h> 58 #include <net/netisr.h> 59 60 #include <netinet/in.h> 61 #include <netinet/in_var.h> 62 #include <netinet/if_ether.h> 63 #if NCARP > 0 64 #include <netinet/ip_carp.h> 65 #endif 66 67 struct llinfo_arp { 68 LIST_ENTRY(llinfo_arp) la_list; 69 struct rtentry *la_rt; /* backpointer to rtentry */ 70 long la_asked; /* last time we QUERIED */ 71 struct mbuf_list la_ml; /* packet hold queue */ 72 }; 73 #define LA_HOLD_QUEUE 10 74 #define LA_HOLD_TOTAL 100 75 76 /* timer values */ 77 int arpt_prune = (5 * 60); /* walk list every 5 minutes */ 78 int arpt_keep = (20 * 60); /* once resolved, cache for 20 minutes */ 79 int arpt_down = 20; /* once declared down, don't send for 20 secs */ 80 81 void arptfree(struct rtentry *); 82 void arptimer(void *); 83 struct rtentry *arplookup(struct in_addr *, int, int, unsigned int); 84 void in_arpinput(struct ifnet *, struct mbuf *); 85 void in_revarpinput(struct ifnet *, struct mbuf *); 86 int arpcache(struct ifnet *, struct ether_arp *, struct rtentry *); 87 void arpreply(struct ifnet *, struct mbuf *, struct in_addr *, uint8_t *); 88 89 struct niqueue arpinq = NIQUEUE_INITIALIZER(50, NETISR_ARP); 90 91 LIST_HEAD(, llinfo_arp) arp_list; 92 struct pool arp_pool; /* pool for llinfo_arp structures */ 93 int arp_maxtries = 5; 94 int arpinit_done; 95 int la_hold_total; 96 97 #ifdef NFSCLIENT 98 /* revarp state */ 99 struct in_addr revarp_myip, revarp_srvip; 100 int revarp_finished; 101 unsigned int revarp_ifidx; 102 #endif /* NFSCLIENT */ 103 104 /* 105 * Timeout routine. Age arp_tab entries periodically. 106 */ 107 /* ARGSUSED */ 108 void 109 arptimer(void *arg) 110 { 111 struct timeout *to = (struct timeout *)arg; 112 int s; 113 struct llinfo_arp *la, *nla; 114 115 s = splsoftnet(); 116 timeout_add_sec(to, arpt_prune); 117 LIST_FOREACH_SAFE(la, &arp_list, la_list, nla) { 118 struct rtentry *rt = la->la_rt; 119 120 if (rt->rt_expire && rt->rt_expire <= time_uptime) 121 arptfree(rt); /* timer has expired; clear */ 122 } 123 splx(s); 124 } 125 126 void 127 arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt) 128 { 129 struct sockaddr *gate = rt->rt_gateway; 130 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 131 struct ifaddr *ifa; 132 133 if (!arpinit_done) { 134 static struct timeout arptimer_to; 135 136 arpinit_done = 1; 137 pool_init(&arp_pool, sizeof(struct llinfo_arp), 0, 0, 0, "arp", 138 NULL); 139 140 timeout_set(&arptimer_to, arptimer, &arptimer_to); 141 timeout_add_sec(&arptimer_to, 1); 142 } 143 144 if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_BROADCAST|RTF_MULTICAST)) 145 return; 146 147 switch (req) { 148 149 case RTM_ADD: 150 if (rt->rt_flags & RTF_CLONING || 151 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !la)) { 152 /* 153 * Give this route an expiration time, even though 154 * it's a "permanent" route, so that routes cloned 155 * from it do not need their expiration time set. 156 */ 157 rt->rt_expire = time_uptime; 158 if ((rt->rt_flags & RTF_CLONING) != 0) 159 break; 160 } 161 /* 162 * Announce a new entry if requested or warn the user 163 * if another station has this IP address. 164 */ 165 if (rt->rt_flags & (RTF_ANNOUNCE|RTF_LOCAL)) 166 arprequest(ifp, 167 &satosin(rt_key(rt))->sin_addr.s_addr, 168 &satosin(rt_key(rt))->sin_addr.s_addr, 169 (u_char *)LLADDR(satosdl(gate))); 170 /*FALLTHROUGH*/ 171 case RTM_RESOLVE: 172 if (gate->sa_family != AF_LINK || 173 gate->sa_len < sizeof(struct sockaddr_dl)) { 174 log(LOG_DEBUG, "%s: bad gateway value: %s\n", __func__, 175 ifp->if_xname); 176 break; 177 } 178 satosdl(gate)->sdl_type = ifp->if_type; 179 satosdl(gate)->sdl_index = ifp->if_index; 180 if (la != 0) 181 break; /* This happens on a route change */ 182 /* 183 * Case 2: This route may come from cloning, or a manual route 184 * add with a LL address. 185 */ 186 la = pool_get(&arp_pool, PR_NOWAIT | PR_ZERO); 187 rt->rt_llinfo = (caddr_t)la; 188 if (la == NULL) { 189 log(LOG_DEBUG, "%s: pool get failed\n", __func__); 190 break; 191 } 192 193 ml_init(&la->la_ml); 194 la->la_rt = rt; 195 rt->rt_flags |= RTF_LLINFO; 196 LIST_INSERT_HEAD(&arp_list, la, la_list); 197 198 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 199 if ((ifa->ifa_addr->sa_family == AF_INET) && 200 ifatoia(ifa)->ia_addr.sin_addr.s_addr == 201 satosin(rt_key(rt))->sin_addr.s_addr) 202 break; 203 } 204 if (ifa) { 205 KASSERT(ifa == rt->rt_ifa); 206 rt->rt_expire = 0; 207 } 208 break; 209 210 case RTM_DELETE: 211 if (la == NULL) 212 break; 213 LIST_REMOVE(la, la_list); 214 rt->rt_llinfo = NULL; 215 rt->rt_flags &= ~RTF_LLINFO; 216 la_hold_total -= ml_purge(&la->la_ml); 217 pool_put(&arp_pool, la); 218 } 219 } 220 221 /* 222 * Broadcast an ARP request. Caller specifies: 223 * - arp header source ip address 224 * - arp header target ip address 225 * - arp header source ethernet address 226 */ 227 void 228 arprequest(struct ifnet *ifp, u_int32_t *sip, u_int32_t *tip, u_int8_t *enaddr) 229 { 230 struct mbuf *m; 231 struct ether_header *eh; 232 struct ether_arp *ea; 233 struct sockaddr sa; 234 235 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 236 return; 237 m->m_len = sizeof(*ea); 238 m->m_pkthdr.len = sizeof(*ea); 239 m->m_pkthdr.ph_rtableid = ifp->if_rdomain; 240 m->m_pkthdr.pf.prio = ifp->if_llprio; 241 MH_ALIGN(m, sizeof(*ea)); 242 ea = mtod(m, struct ether_arp *); 243 eh = (struct ether_header *)sa.sa_data; 244 memset(ea, 0, sizeof(*ea)); 245 memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)); 246 eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */ 247 ea->arp_hrd = htons(ARPHRD_ETHER); 248 ea->arp_pro = htons(ETHERTYPE_IP); 249 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */ 250 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */ 251 ea->arp_op = htons(ARPOP_REQUEST); 252 memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost)); 253 memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha)); 254 memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa)); 255 memcpy(ea->arp_tpa, tip, sizeof(ea->arp_tpa)); 256 sa.sa_family = pseudo_AF_HDRCMPLT; 257 sa.sa_len = sizeof(sa); 258 m->m_flags |= M_BCAST; 259 ifp->if_output(ifp, m, &sa, NULL); 260 } 261 262 void 263 arpreply(struct ifnet *ifp, struct mbuf *m, struct in_addr *sip, uint8_t *eaddr) 264 { 265 struct ether_header *eh; 266 struct ether_arp *ea; 267 struct sockaddr sa; 268 269 ea = mtod(m, struct ether_arp *); 270 ea->arp_op = htons(ARPOP_REPLY); 271 ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */ 272 273 /* We're replying to a request. */ 274 memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha)); 275 memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa)); 276 277 memcpy(ea->arp_sha, eaddr, sizeof(ea->arp_sha)); 278 memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa)); 279 280 eh = (struct ether_header *)sa.sa_data; 281 memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost)); 282 memcpy(eh->ether_shost, eaddr, sizeof(eh->ether_shost)); 283 eh->ether_type = htons(ETHERTYPE_ARP); 284 sa.sa_family = pseudo_AF_HDRCMPLT; 285 sa.sa_len = sizeof(sa); 286 ifp->if_output(ifp, m, &sa, NULL); 287 } 288 289 /* 290 * Resolve an IP address into an ethernet address. If success, 291 * desten is filled in. If there is no entry in arptab, 292 * set one up and broadcast a request for the IP address. 293 * Hold onto this mbuf and resend it once the address 294 * is finally resolved. A return value of 0 indicates 295 * that desten has been filled in and the packet should be sent 296 * normally; A return value of EAGAIN indicates that the packet 297 * has been taken over here, either now or for later transmission. 298 * Any other return value indicates an error. 299 */ 300 int 301 arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, 302 struct sockaddr *dst, u_char *desten) 303 { 304 struct arpcom *ac = (struct arpcom *)ifp; 305 struct llinfo_arp *la = NULL; 306 struct sockaddr_dl *sdl; 307 struct rtentry *rt = NULL; 308 char addr[INET_ADDRSTRLEN]; 309 int error; 310 311 if (m->m_flags & M_BCAST) { /* broadcast */ 312 memcpy(desten, etherbroadcastaddr, sizeof(etherbroadcastaddr)); 313 return (0); 314 } 315 if (m->m_flags & M_MCAST) { /* multicast */ 316 ETHER_MAP_IP_MULTICAST(&satosin(dst)->sin_addr, desten); 317 return (0); 318 } 319 320 error = rt_checkgate(rt0, &rt); 321 if (error) { 322 m_freem(m); 323 return (error); 324 } 325 326 if (!ISSET(rt->rt_flags, RTF_LLINFO)) { 327 log(LOG_DEBUG, "%s: %s: route contains no arp information\n", 328 __func__, inet_ntop(AF_INET, &satosin(rt_key(rt))->sin_addr, 329 addr, sizeof(addr))); 330 m_freem(m); 331 return (EINVAL); 332 } 333 334 sdl = satosdl(rt->rt_gateway); 335 if (sdl->sdl_alen > 0 && sdl->sdl_alen != ETHER_ADDR_LEN) { 336 log(LOG_DEBUG, "%s: %s: incorrect arp information\n", __func__, 337 inet_ntop(AF_INET, &satosin(dst)->sin_addr, 338 addr, sizeof(addr))); 339 goto bad; 340 } 341 342 /* 343 * Check the address family and length is valid, the address 344 * is resolved; otherwise, try to resolve. 345 */ 346 if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) && 347 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { 348 memcpy(desten, LLADDR(sdl), sdl->sdl_alen); 349 return (0); 350 } 351 352 if (ifp->if_flags & IFF_NOARP) 353 goto bad; 354 355 /* 356 * There is an arptab entry, but no ethernet address 357 * response yet. Insert mbuf in hold queue if below limit 358 * if above the limit free the queue without queuing the new packet. 359 */ 360 la = (struct llinfo_arp *)rt->rt_llinfo; 361 KASSERT(la != NULL); 362 if (la_hold_total < LA_HOLD_TOTAL && la_hold_total < nmbclust / 64) { 363 struct mbuf *mh; 364 365 if (ml_len(&la->la_ml) >= LA_HOLD_QUEUE) { 366 mh = ml_dequeue(&la->la_ml); 367 la_hold_total--; 368 m_freem(mh); 369 } 370 ml_enqueue(&la->la_ml, m); 371 la_hold_total++; 372 } else { 373 la_hold_total -= ml_purge(&la->la_ml); 374 m_freem(m); 375 } 376 377 /* 378 * Re-send the ARP request when appropriate. 379 */ 380 #ifdef DIAGNOSTIC 381 if (rt->rt_expire == 0) { 382 /* This should never happen. (Should it? -gwr) */ 383 printf("%s: unresolved and rt_expire == 0\n", __func__); 384 /* Set expiration time to now (expired). */ 385 rt->rt_expire = time_uptime; 386 } 387 #endif 388 if (rt->rt_expire) { 389 rt->rt_flags &= ~RTF_REJECT; 390 if (la->la_asked == 0 || rt->rt_expire != time_uptime) { 391 rt->rt_expire = time_uptime; 392 if (la->la_asked++ < arp_maxtries) 393 arprequest(ifp, 394 &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr, 395 &satosin(dst)->sin_addr.s_addr, 396 ac->ac_enaddr); 397 else { 398 rt->rt_flags |= RTF_REJECT; 399 rt->rt_expire += arpt_down; 400 la->la_asked = 0; 401 la_hold_total -= ml_purge(&la->la_ml); 402 } 403 } 404 } 405 406 return (EAGAIN); 407 408 bad: 409 m_freem(m); 410 return (EINVAL); 411 } 412 413 /* 414 * Common length and type checks are done here, 415 * then the protocol-specific routine is called. 416 */ 417 void 418 arpinput(struct ifnet *ifp, struct mbuf *m) 419 { 420 struct arphdr *ar; 421 int len; 422 423 #ifdef DIAGNOSTIC 424 if ((m->m_flags & M_PKTHDR) == 0) 425 panic("arpintr"); 426 #endif 427 428 len = sizeof(struct arphdr); 429 if (m->m_len < len && (m = m_pullup(m, len)) == NULL) 430 return; 431 432 ar = mtod(m, struct arphdr *); 433 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER || 434 ntohs(ar->ar_pro) != ETHERTYPE_IP) { 435 m_freem(m); 436 return; 437 } 438 439 len += 2 * (ar->ar_hln + ar->ar_pln); 440 if (m->m_len < len && (m = m_pullup(m, len)) == NULL) 441 return; 442 443 niq_enqueue(&arpinq, m); 444 } 445 446 void 447 arpintr(void) 448 { 449 struct mbuf_list ml; 450 struct mbuf *m; 451 struct ifnet *ifp; 452 453 niq_delist(&arpinq, &ml); 454 455 while ((m = ml_dequeue(&ml)) != NULL) { 456 ifp = if_get(m->m_pkthdr.ph_ifidx); 457 458 if (ifp != NULL) 459 in_arpinput(ifp, m); 460 else 461 m_freem(m); 462 463 if_put(ifp); 464 } 465 } 466 467 /* 468 * ARP for Internet protocols on Ethernet, RFC 826. 469 * In addition, a sanity check is performed on the sender 470 * protocol address, to catch impersonators. 471 */ 472 void 473 in_arpinput(struct ifnet *ifp, struct mbuf *m) 474 { 475 struct ether_arp *ea; 476 struct rtentry *rt = NULL; 477 struct sockaddr_in sin; 478 struct in_addr isaddr, itaddr; 479 char addr[INET_ADDRSTRLEN]; 480 int op, target = 0; 481 unsigned int rdomain; 482 483 rdomain = rtable_l2(m->m_pkthdr.ph_rtableid); 484 485 ea = mtod(m, struct ether_arp *); 486 op = ntohs(ea->arp_op); 487 if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY)) 488 goto out; 489 490 memcpy(&itaddr, ea->arp_tpa, sizeof(itaddr)); 491 memcpy(&isaddr, ea->arp_spa, sizeof(isaddr)); 492 memset(&sin, 0, sizeof(sin)); 493 sin.sin_len = sizeof(sin); 494 sin.sin_family = AF_INET; 495 496 if (ETHER_IS_MULTICAST(&ea->arp_sha[0]) && 497 !memcmp(ea->arp_sha, etherbroadcastaddr, sizeof(ea->arp_sha))) { 498 inet_ntop(AF_INET, &isaddr, addr, sizeof(addr)); 499 log(LOG_ERR, "arp: ether address is broadcast for IP address " 500 "%s!\n", addr); 501 goto out; 502 } 503 504 if (!memcmp(ea->arp_sha, LLADDR(ifp->if_sadl), sizeof(ea->arp_sha))) 505 goto out; /* it's from me, ignore it. */ 506 507 /* Check target against our interface addresses. */ 508 sin.sin_addr = itaddr; 509 rt = rtalloc(sintosa(&sin), 0, rdomain); 510 if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) && 511 rt->rt_ifidx == ifp->if_index) 512 target = 1; 513 rtfree(rt); 514 rt = NULL; 515 516 #if NCARP > 0 517 if (target && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP && 518 !carp_iamatch(ifp)) 519 goto out; 520 #endif 521 522 /* Do we have an ARP cache for the sender? Create if we are target. */ 523 rt = arplookup(&isaddr, target, 0, rdomain); 524 525 /* Check sender against our interface addresses. */ 526 if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) && 527 rt->rt_ifidx == ifp->if_index && isaddr.s_addr != INADDR_ANY) { 528 inet_ntop(AF_INET, &isaddr, addr, sizeof(addr)); 529 log(LOG_ERR, "duplicate IP address %s sent from ethernet " 530 "address %s\n", addr, ether_sprintf(ea->arp_sha)); 531 itaddr = isaddr; 532 } else if (rt != NULL) { 533 int error; 534 535 KERNEL_LOCK(); 536 error = arpcache(ifp, ea, rt); 537 KERNEL_UNLOCK(); 538 if (error) 539 goto out; 540 } 541 542 if (op == ARPOP_REQUEST) { 543 uint8_t *eaddr; 544 545 if (target) { 546 /* We already have all info for the reply */ 547 eaddr = LLADDR(ifp->if_sadl); 548 } else { 549 rtfree(rt); 550 rt = arplookup(&itaddr, 0, SIN_PROXY, rdomain); 551 /* 552 * Protect from possible duplicates, only owner 553 * should respond 554 */ 555 if ((rt == NULL) || (rt->rt_ifidx != ifp->if_index)) 556 goto out; 557 eaddr = LLADDR(satosdl(rt->rt_gateway)); 558 } 559 arpreply(ifp, m, &itaddr, eaddr); 560 rtfree(rt); 561 return; 562 } 563 564 out: 565 rtfree(rt); 566 m_freem(m); 567 } 568 569 int 570 arpcache(struct ifnet *ifp, struct ether_arp *ea, struct rtentry *rt) 571 { 572 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 573 struct sockaddr_dl *sdl = satosdl(rt->rt_gateway); 574 struct in_addr *spa = (struct in_addr *)ea->arp_spa; 575 char addr[INET_ADDRSTRLEN]; 576 struct ifnet *rifp; 577 unsigned int len; 578 int changed = 0; 579 580 KERNEL_ASSERT_LOCKED(); 581 KASSERT(sdl != NULL); 582 583 /* 584 * This can happen if the entry has been deleted by another CPU 585 * after we found it. 586 */ 587 if (la == NULL) 588 return (0); 589 590 if (sdl->sdl_alen > 0) { 591 if (memcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) { 592 if (ISSET(rt->rt_flags, RTF_PERMANENT_ARP|RTF_LOCAL)) { 593 inet_ntop(AF_INET, spa, addr, sizeof(addr)); 594 log(LOG_WARNING, "arp: attempt to overwrite " 595 "permanent entry for %s by %s on %s\n", addr, 596 ether_sprintf(ea->arp_sha), ifp->if_xname); 597 return (-1); 598 } else if (rt->rt_ifidx != ifp->if_index) { 599 #if NCARP > 0 600 if (ifp->if_type != IFT_CARP) 601 #endif 602 { 603 rifp = if_get(rt->rt_ifidx); 604 if (rifp == NULL) 605 return (-1); 606 inet_ntop(AF_INET, spa, addr, 607 sizeof(addr)); 608 log(LOG_WARNING, "arp: attempt to " 609 "overwrite entry for %s on %s by " 610 "%s on %s\n", addr, rifp->if_xname, 611 ether_sprintf(ea->arp_sha), 612 ifp->if_xname); 613 if_put(rifp); 614 } 615 return (-1); 616 } else { 617 inet_ntop(AF_INET, spa, addr, sizeof(addr)); 618 log(LOG_INFO, "arp info overwritten for %s by " 619 "%s on %s\n", addr, 620 ether_sprintf(ea->arp_sha), ifp->if_xname); 621 rt->rt_expire = 1;/* no longer static */ 622 } 623 changed = 1; 624 } 625 } else if (!if_isconnected(ifp, rt->rt_ifidx)) { 626 rifp = if_get(rt->rt_ifidx); 627 if (rifp == NULL) 628 return (-1); 629 inet_ntop(AF_INET, spa, addr, sizeof(addr)); 630 log(LOG_WARNING, "arp: attempt to add entry for %s on %s by %s" 631 " on %s\n", addr, rifp->if_xname, 632 ether_sprintf(ea->arp_sha), ifp->if_xname); 633 if_put(rifp); 634 return (-1); 635 } 636 sdl->sdl_alen = sizeof(ea->arp_sha); 637 memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha)); 638 if (rt->rt_expire) 639 rt->rt_expire = time_uptime + arpt_keep; 640 rt->rt_flags &= ~RTF_REJECT; 641 642 /* Notify userland that an ARP resolution has been done. */ 643 if (la->la_asked || changed) { 644 KERNEL_LOCK(); 645 rt_sendmsg(rt, RTM_RESOLVE, ifp->if_rdomain); 646 KERNEL_UNLOCK(); 647 } 648 649 la->la_asked = 0; 650 while ((len = ml_len(&la->la_ml)) != 0) { 651 struct mbuf *mh; 652 653 mh = ml_dequeue(&la->la_ml); 654 la_hold_total--; 655 656 ifp->if_output(ifp, mh, rt_key(rt), rt); 657 658 if (ml_len(&la->la_ml) == len) { 659 /* mbuf is back in queue. Discard. */ 660 while ((mh = ml_dequeue(&la->la_ml)) != NULL) { 661 la_hold_total--; 662 m_freem(mh); 663 } 664 break; 665 } 666 } 667 668 return (0); 669 } 670 /* 671 * Free an arp entry. 672 */ 673 void 674 arptfree(struct rtentry *rt) 675 { 676 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; 677 struct sockaddr_dl *sdl = satosdl(rt->rt_gateway); 678 struct ifnet *ifp; 679 680 ifp = if_get(rt->rt_ifidx); 681 if ((sdl != NULL) && (sdl->sdl_family == AF_LINK)) { 682 sdl->sdl_alen = 0; 683 la->la_asked = 0; 684 } 685 686 if (!ISSET(rt->rt_flags, RTF_STATIC)) 687 rtdeletemsg(rt, ifp, ifp->if_rdomain); 688 if_put(ifp); 689 } 690 691 /* 692 * Lookup or enter a new address in arptab. 693 */ 694 struct rtentry * 695 arplookup(struct in_addr *inp, int create, int proxy, u_int tableid) 696 { 697 struct rtentry *rt; 698 struct sockaddr_inarp sin; 699 int flags; 700 701 memset(&sin, 0, sizeof(sin)); 702 sin.sin_len = sizeof(sin); 703 sin.sin_family = AF_INET; 704 sin.sin_addr.s_addr = inp->s_addr; 705 sin.sin_other = proxy ? SIN_PROXY : 0; 706 flags = (create) ? RT_RESOLVE : 0; 707 708 rt = rtalloc((struct sockaddr *)&sin, flags, tableid); 709 if (!rtisvalid(rt) || ISSET(rt->rt_flags, RTF_GATEWAY) || 710 !ISSET(rt->rt_flags, RTF_LLINFO) || 711 rt->rt_gateway->sa_family != AF_LINK) { 712 rtfree(rt); 713 return (NULL); 714 } 715 716 if (proxy && !ISSET(rt->rt_flags, RTF_ANNOUNCE)) { 717 struct rtentry *mrt = NULL; 718 #if defined(ART) && !defined(SMALL_KERNEL) 719 mrt = rt; 720 KERNEL_LOCK(); 721 while ((mrt = rtable_mpath_next(mrt)) != NULL) { 722 if (ISSET(mrt->rt_flags, RTF_ANNOUNCE)) { 723 rtref(mrt); 724 break; 725 } 726 } 727 KERNEL_UNLOCK(); 728 #endif /* ART && !SMALL_KERNEL */ 729 rtfree(rt); 730 return (mrt); 731 } 732 733 return (rt); 734 } 735 736 /* 737 * Check whether we do proxy ARP for this address and we point to ourselves. 738 */ 739 int 740 arpproxy(struct in_addr in, unsigned int rtableid) 741 { 742 struct sockaddr_dl *sdl; 743 struct rtentry *rt; 744 struct ifnet *ifp; 745 int found = 0; 746 747 rt = arplookup(&in, 0, SIN_PROXY, rtableid); 748 if (!rtisvalid(rt)) { 749 rtfree(rt); 750 return (0); 751 } 752 753 /* Check that arp information are correct. */ 754 sdl = satosdl(rt->rt_gateway); 755 if (sdl->sdl_alen != ETHER_ADDR_LEN) { 756 rtfree(rt); 757 return (0); 758 } 759 760 ifp = if_get(rt->rt_ifidx); 761 if (ifp == NULL) { 762 rtfree(rt); 763 return (0); 764 } 765 766 if (!memcmp(LLADDR(sdl), LLADDR(ifp->if_sadl), sdl->sdl_alen)) 767 found = 1; 768 769 if_put(ifp); 770 rtfree(rt); 771 return (found); 772 } 773 774 /* 775 * Called from Ethernet interrupt handlers 776 * when ether packet type ETHERTYPE_REVARP 777 * is received. Common length and type checks are done here, 778 * then the protocol-specific routine is called. 779 */ 780 void 781 revarpinput(struct ifnet *ifp, struct mbuf *m) 782 { 783 struct arphdr *ar; 784 785 if (m->m_len < sizeof(struct arphdr)) 786 goto out; 787 ar = mtod(m, struct arphdr *); 788 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 789 goto out; 790 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 791 goto out; 792 switch (ntohs(ar->ar_pro)) { 793 794 case ETHERTYPE_IP: 795 in_revarpinput(ifp, m); 796 return; 797 798 default: 799 break; 800 } 801 out: 802 m_freem(m); 803 } 804 805 /* 806 * RARP for Internet protocols on Ethernet. 807 * Algorithm is that given in RFC 903. 808 * We are only using for bootstrap purposes to get an ip address for one of 809 * our interfaces. Thus we support no user-interface. 810 * 811 * Since the contents of the RARP reply are specific to the interface that 812 * sent the request, this code must ensure that they are properly associated. 813 * 814 * Note: also supports ARP via RARP packets, per the RFC. 815 */ 816 void 817 in_revarpinput(struct ifnet *ifp, struct mbuf *m) 818 { 819 struct ether_arp *ar; 820 int op; 821 822 ar = mtod(m, struct ether_arp *); 823 op = ntohs(ar->arp_op); 824 switch (op) { 825 case ARPOP_REQUEST: 826 case ARPOP_REPLY: /* per RFC */ 827 niq_enqueue(&arpinq, m); 828 return; 829 case ARPOP_REVREPLY: 830 break; 831 case ARPOP_REVREQUEST: /* handled by rarpd(8) */ 832 default: 833 goto out; 834 } 835 #ifdef NFSCLIENT 836 if (revarp_ifidx == 0) 837 goto out; 838 if (revarp_ifidx != m->m_pkthdr.ph_ifidx) /* !same interface */ 839 goto out; 840 if (revarp_finished) 841 goto wake; 842 if (memcmp(ar->arp_tha, LLADDR(ifp->if_sadl), sizeof(ar->arp_tha))) 843 goto out; 844 memcpy(&revarp_srvip, ar->arp_spa, sizeof(revarp_srvip)); 845 memcpy(&revarp_myip, ar->arp_tpa, sizeof(revarp_myip)); 846 revarp_finished = 1; 847 wake: /* Do wakeup every time in case it was missed. */ 848 wakeup((caddr_t)&revarp_myip); 849 #endif /* NFSCLIENT */ 850 851 out: 852 m_freem(m); 853 } 854 855 /* 856 * Send a RARP request for the ip address of the specified interface. 857 * The request should be RFC 903-compliant. 858 */ 859 void 860 revarprequest(struct ifnet *ifp) 861 { 862 struct sockaddr sa; 863 struct mbuf *m; 864 struct ether_header *eh; 865 struct ether_arp *ea; 866 struct arpcom *ac = (struct arpcom *)ifp; 867 868 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 869 return; 870 m->m_len = sizeof(*ea); 871 m->m_pkthdr.len = sizeof(*ea); 872 m->m_pkthdr.pf.prio = ifp->if_llprio; 873 MH_ALIGN(m, sizeof(*ea)); 874 ea = mtod(m, struct ether_arp *); 875 eh = (struct ether_header *)sa.sa_data; 876 memset(ea, 0, sizeof(*ea)); 877 memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)); 878 eh->ether_type = htons(ETHERTYPE_REVARP); 879 ea->arp_hrd = htons(ARPHRD_ETHER); 880 ea->arp_pro = htons(ETHERTYPE_IP); 881 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */ 882 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */ 883 ea->arp_op = htons(ARPOP_REVREQUEST); 884 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(ea->arp_tha)); 885 memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha)); 886 memcpy(ea->arp_tha, ac->ac_enaddr, sizeof(ea->arp_tha)); 887 sa.sa_family = pseudo_AF_HDRCMPLT; 888 sa.sa_len = sizeof(sa); 889 m->m_flags |= M_BCAST; 890 ifp->if_output(ifp, m, &sa, NULL); 891 } 892 893 #ifdef NFSCLIENT 894 /* 895 * RARP for the ip address of the specified interface, but also 896 * save the ip address of the server that sent the answer. 897 * Timeout if no response is received. 898 */ 899 int 900 revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in, 901 struct in_addr *clnt_in) 902 { 903 int result, count = 20; 904 905 if (revarp_finished) 906 return EIO; 907 908 revarp_ifidx = ifp->if_index; 909 while (count--) { 910 revarprequest(ifp); 911 result = tsleep((caddr_t)&revarp_myip, PSOCK, "revarp", hz/2); 912 if (result != EWOULDBLOCK) 913 break; 914 } 915 revarp_ifidx = 0; 916 if (!revarp_finished) 917 return ENETUNREACH; 918 919 memcpy(serv_in, &revarp_srvip, sizeof(*serv_in)); 920 memcpy(clnt_in, &revarp_myip, sizeof(*clnt_in)); 921 return 0; 922 } 923 924 /* For compatibility: only saves interface address. */ 925 int 926 revarpwhoami(struct in_addr *in, struct ifnet *ifp) 927 { 928 struct in_addr server; 929 return (revarpwhoarewe(ifp, &server, in)); 930 } 931 #endif /* NFSCLIENT */ 932