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