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