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