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