1 /* $OpenBSD: if_ethersubr.c,v 1.267 2020/10/01 05:14:10 jsg Exp $ */ 2 /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * 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 project 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 PROJECT 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 PROJECT 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 33 /* 34 * Copyright (c) 1982, 1989, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 62 */ 63 64 /* 65 %%% portions-copyright-nrl-95 66 Portions of this software are Copyright 1995-1998 by Randall Atkinson, 67 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights 68 Reserved. All rights under this copyright have been assigned to the US 69 Naval Research Laboratory (NRL). The NRL Copyright Notice and License 70 Agreement Version 1.1 (January 17, 1995) applies to these portions of the 71 software. 72 You should have received a copy of the license with this software. If you 73 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. 74 */ 75 76 #include "bpfilter.h" 77 78 #include <sys/param.h> 79 #include <sys/systm.h> 80 #include <sys/kernel.h> 81 #include <sys/malloc.h> 82 #include <sys/mbuf.h> 83 #include <sys/protosw.h> 84 #include <sys/socket.h> 85 #include <sys/ioctl.h> 86 #include <sys/errno.h> 87 #include <sys/syslog.h> 88 #include <sys/timeout.h> 89 #include <sys/smr.h> 90 91 #include <net/if.h> 92 #include <net/netisr.h> 93 #include <net/route.h> 94 #include <net/if_llc.h> 95 #include <net/if_dl.h> 96 #include <net/if_media.h> 97 #include <net/if_types.h> 98 99 #include <netinet/in.h> 100 #include <netinet/if_ether.h> 101 #include <netinet/ip_ipsp.h> 102 103 #if NBPFILTER > 0 104 #include <net/bpf.h> 105 #endif 106 107 #include "vlan.h" 108 #if NVLAN > 0 109 #include <net/if_vlan_var.h> 110 #endif 111 112 #include "carp.h" 113 #if NCARP > 0 114 #include <netinet/ip_carp.h> 115 #endif 116 117 #include "pppoe.h" 118 #if NPPPOE > 0 119 #include <net/if_pppoe.h> 120 #endif 121 122 #include "bpe.h" 123 #if NBPE > 0 124 #include <net/if_bpe.h> 125 #endif 126 127 #ifdef INET6 128 #include <netinet6/in6_var.h> 129 #include <netinet6/nd6.h> 130 #endif 131 132 #ifdef PIPEX 133 #include <net/pipex.h> 134 #endif 135 136 #ifdef MPLS 137 #include <netmpls/mpls.h> 138 #endif /* MPLS */ 139 140 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] = 141 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 142 u_int8_t etheranyaddr[ETHER_ADDR_LEN] = 143 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 144 #define senderr(e) { error = (e); goto bad;} 145 146 int 147 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data) 148 { 149 struct ifreq *ifr = (struct ifreq *)data; 150 int error = 0; 151 152 switch (cmd) { 153 case SIOCSIFADDR: 154 break; 155 156 case SIOCSIFMTU: 157 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu) 158 error = EINVAL; 159 else 160 ifp->if_mtu = ifr->ifr_mtu; 161 break; 162 163 case SIOCADDMULTI: 164 case SIOCDELMULTI: 165 if (ifp->if_flags & IFF_MULTICAST) { 166 error = (cmd == SIOCADDMULTI) ? 167 ether_addmulti(ifr, arp) : 168 ether_delmulti(ifr, arp); 169 } else 170 error = ENOTTY; 171 break; 172 173 default: 174 error = ENOTTY; 175 } 176 177 return (error); 178 } 179 180 181 void 182 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt) 183 { 184 if (rt == NULL) 185 return; 186 187 switch (rt_key(rt)->sa_family) { 188 case AF_INET: 189 arp_rtrequest(ifp, req, rt); 190 break; 191 #ifdef INET6 192 case AF_INET6: 193 nd6_rtrequest(ifp, req, rt); 194 break; 195 #endif 196 default: 197 break; 198 } 199 } 200 201 int 202 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 203 struct rtentry *rt, struct ether_header *eh) 204 { 205 struct arpcom *ac = (struct arpcom *)ifp; 206 sa_family_t af = dst->sa_family; 207 int error = 0; 208 209 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 210 senderr(ENETDOWN); 211 212 KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) || 213 af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT); 214 215 #ifdef DIAGNOSTIC 216 if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) { 217 printf("%s: trying to send packet on wrong domain. " 218 "if %d vs. mbuf %d\n", ifp->if_xname, 219 ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid)); 220 } 221 #endif 222 223 switch (af) { 224 case AF_INET: 225 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); 226 if (error) 227 return (error); 228 eh->ether_type = htons(ETHERTYPE_IP); 229 230 /* If broadcasting on a simplex interface, loopback a copy */ 231 if (ISSET(m->m_flags, M_BCAST) && 232 ISSET(ifp->if_flags, IFF_SIMPLEX) && 233 !m->m_pkthdr.pf.routed) { 234 struct mbuf *mcopy; 235 236 /* XXX Should we input an unencrypted IPsec packet? */ 237 mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT); 238 if (mcopy != NULL) 239 if_input_local(ifp, mcopy, af); 240 } 241 break; 242 #ifdef INET6 243 case AF_INET6: 244 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 245 if (error) 246 return (error); 247 eh->ether_type = htons(ETHERTYPE_IPV6); 248 break; 249 #endif 250 #ifdef MPLS 251 case AF_MPLS: 252 if (rt == NULL) 253 senderr(EHOSTUNREACH); 254 255 if (!ISSET(ifp->if_xflags, IFXF_MPLS)) 256 senderr(ENETUNREACH); 257 258 dst = ISSET(rt->rt_flags, RTF_GATEWAY) ? 259 rt->rt_gateway : rt_key(rt); 260 261 switch (dst->sa_family) { 262 case AF_LINK: 263 if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost)) 264 senderr(EHOSTUNREACH); 265 memcpy(eh->ether_dhost, LLADDR(satosdl(dst)), 266 sizeof(eh->ether_dhost)); 267 break; 268 #ifdef INET6 269 case AF_INET6: 270 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 271 if (error) 272 return (error); 273 break; 274 #endif 275 case AF_INET: 276 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); 277 if (error) 278 return (error); 279 break; 280 default: 281 senderr(EHOSTUNREACH); 282 } 283 /* XXX handling for simplex devices in case of M/BCAST ?? */ 284 if (m->m_flags & (M_BCAST | M_MCAST)) 285 eh->ether_type = htons(ETHERTYPE_MPLS_MCAST); 286 else 287 eh->ether_type = htons(ETHERTYPE_MPLS); 288 break; 289 #endif /* MPLS */ 290 case pseudo_AF_HDRCMPLT: 291 /* take the whole header from the sa */ 292 memcpy(eh, dst->sa_data, sizeof(*eh)); 293 return (0); 294 295 case AF_UNSPEC: 296 /* take the dst and type from the sa, but get src below */ 297 memcpy(eh, dst->sa_data, sizeof(*eh)); 298 break; 299 300 default: 301 printf("%s: can't handle af%d\n", ifp->if_xname, af); 302 senderr(EAFNOSUPPORT); 303 } 304 305 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost)); 306 307 return (0); 308 309 bad: 310 m_freem(m); 311 return (error); 312 } 313 314 struct mbuf* 315 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 316 struct rtentry *rt, int *errorp) 317 { 318 struct ether_header eh; 319 int error; 320 321 error = ether_resolve(ifp, m, dst, rt, &eh); 322 switch (error) { 323 case 0: 324 break; 325 case EAGAIN: 326 error = 0; 327 default: 328 *errorp = error; 329 return (NULL); 330 } 331 332 m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT); 333 if (m == NULL) { 334 *errorp = ENOBUFS; 335 return (NULL); 336 } 337 338 m_adj(m, ETHER_ALIGN); 339 memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh)); 340 341 return (m); 342 } 343 344 int 345 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 346 struct rtentry *rt) 347 { 348 int error; 349 350 m = ether_encap(ifp, m, dst, rt, &error); 351 if (m == NULL) 352 return (error); 353 354 return (if_enqueue(ifp, m)); 355 } 356 357 /* 358 * Process a received Ethernet packet. 359 * 360 * Ethernet input has several "phases" of filtering packets to 361 * support virtual/pseudo interfaces before actual layer 3 protocol 362 * handling. 363 * 364 * First phase: 365 * 366 * The first phase supports drivers that aggregate multiple Ethernet 367 * ports into a single logical interface, ie, aggr(4) and trunk(4). 368 * These drivers intercept packets by swapping out the if_input handler 369 * on the "port" interfaces to steal the packets before they get here 370 * to ether_input(). 371 */ 372 void 373 ether_input(struct ifnet *ifp, struct mbuf *m) 374 { 375 struct ether_header *eh; 376 void (*input)(struct ifnet *, struct mbuf *); 377 u_int16_t etype; 378 struct arpcom *ac; 379 const struct ether_brport *eb; 380 unsigned int sdelim = 0; 381 382 /* Drop short frames */ 383 if (m->m_len < ETHER_HDR_LEN) 384 goto dropanyway; 385 386 /* 387 * Second phase: service delimited packet filtering. 388 * 389 * Let vlan(4) and svlan(4) look at "service delimited" 390 * packets. If a virtual interface does not exist to take 391 * those packets, they're returned to ether_input() so a 392 * bridge can have a go at forwarding them. 393 */ 394 395 eh = mtod(m, struct ether_header *); 396 etype = ntohs(eh->ether_type); 397 398 if (ISSET(m->m_flags, M_VLANTAG) || 399 etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) { 400 #if NVLAN > 0 401 m = vlan_input(ifp, m); 402 if (m == NULL) 403 return; 404 #endif /* NVLAN > 0 */ 405 406 sdelim = 1; 407 } 408 409 /* 410 * Third phase: bridge processing. 411 * 412 * Give the packet to a bridge interface, ie, bridge(4), 413 * switch(4), or tpmr(4), if it is configured. A bridge 414 * may take the packet and forward it to another port, or it 415 * may return it here to ether_input() to support local 416 * delivery to this port. 417 */ 418 419 ac = (struct arpcom *)ifp; 420 421 smr_read_enter(); 422 eb = SMR_PTR_GET(&ac->ac_brport); 423 if (eb != NULL) { 424 m = (*eb->eb_input)(ifp, m, eb->eb_port); 425 if (m == NULL) { 426 smr_read_leave(); 427 return; 428 } 429 } 430 smr_read_leave(); 431 432 /* 433 * Fourth phase: drop service delimited packets. 434 * 435 * If the packet has a tag, and a bridge didn't want it, 436 * it's not for this port. 437 */ 438 439 if (sdelim) 440 goto dropanyway; 441 442 /* 443 * Fifth phase: destination address check. 444 * 445 * Is the packet specifically addressed to this port? 446 */ 447 448 eh = mtod(m, struct ether_header *); 449 if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) { 450 #if NCARP > 0 451 /* 452 * If it's not for this port, it could be for carp(4). 453 */ 454 if (ifp->if_type != IFT_CARP && 455 !SRPL_EMPTY_LOCKED(&ifp->if_carp)) { 456 m = carp_input(ifp, m); 457 if (m == NULL) 458 return; 459 460 eh = mtod(m, struct ether_header *); 461 } 462 #endif 463 464 /* 465 * If not, it must be multicast or broadcast to go further. 466 */ 467 if (!ETHER_IS_MULTICAST(eh->ether_dhost)) 468 goto dropanyway; 469 470 /* 471 * If this is not a simplex interface, drop the packet 472 * if it came from us. 473 */ 474 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 475 if (memcmp(ac->ac_enaddr, eh->ether_shost, 476 ETHER_ADDR_LEN) == 0) 477 goto dropanyway; 478 } 479 480 if (ETHER_IS_BROADCAST(eh->ether_dhost)) 481 m->m_flags |= M_BCAST; 482 else 483 m->m_flags |= M_MCAST; 484 ifp->if_imcasts++; 485 } 486 487 /* 488 * Sixth phase: protocol demux. 489 * 490 * At this point it is known that the packet is destined 491 * for layer 3 protocol handling on the local port. 492 */ 493 494 switch (etype) { 495 case ETHERTYPE_IP: 496 input = ipv4_input; 497 break; 498 499 case ETHERTYPE_ARP: 500 if (ifp->if_flags & IFF_NOARP) 501 goto dropanyway; 502 input = arpinput; 503 break; 504 505 case ETHERTYPE_REVARP: 506 if (ifp->if_flags & IFF_NOARP) 507 goto dropanyway; 508 input = revarpinput; 509 break; 510 511 #ifdef INET6 512 /* 513 * Schedule IPv6 software interrupt for incoming IPv6 packet. 514 */ 515 case ETHERTYPE_IPV6: 516 input = ipv6_input; 517 break; 518 #endif /* INET6 */ 519 #if NPPPOE > 0 || defined(PIPEX) 520 case ETHERTYPE_PPPOEDISC: 521 case ETHERTYPE_PPPOE: 522 if (m->m_flags & (M_MCAST | M_BCAST)) 523 goto dropanyway; 524 #ifdef PIPEX 525 if (pipex_enable) { 526 struct pipex_session *session; 527 528 if ((session = pipex_pppoe_lookup_session(m)) != NULL) { 529 pipex_pppoe_input(m, session); 530 return; 531 } 532 } 533 #endif 534 if (etype == ETHERTYPE_PPPOEDISC) 535 niq_enqueue(&pppoediscinq, m); 536 else 537 niq_enqueue(&pppoeinq, m); 538 return; 539 #endif 540 #ifdef MPLS 541 case ETHERTYPE_MPLS: 542 case ETHERTYPE_MPLS_MCAST: 543 input = mpls_input; 544 break; 545 #endif 546 #if NBPE > 0 547 case ETHERTYPE_PBB: 548 bpe_input(ifp, m); 549 return; 550 #endif 551 default: 552 goto dropanyway; 553 } 554 555 m_adj(m, sizeof(*eh)); 556 (*input)(ifp, m); 557 return; 558 dropanyway: 559 m_freem(m); 560 return; 561 } 562 563 int 564 ether_brport_isset(struct ifnet *ifp) 565 { 566 struct arpcom *ac = (struct arpcom *)ifp; 567 568 KERNEL_ASSERT_LOCKED(); 569 if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL) 570 return (EBUSY); 571 572 return (0); 573 } 574 575 void 576 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb) 577 { 578 struct arpcom *ac = (struct arpcom *)ifp; 579 580 KERNEL_ASSERT_LOCKED(); 581 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL, 582 "%s setting an already set brport", ifp->if_xname); 583 584 SMR_PTR_SET_LOCKED(&ac->ac_brport, eb); 585 } 586 587 void 588 ether_brport_clr(struct ifnet *ifp) 589 { 590 struct arpcom *ac = (struct arpcom *)ifp; 591 592 KERNEL_ASSERT_LOCKED(); 593 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL, 594 "%s clearing an already clear brport", ifp->if_xname); 595 596 SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL); 597 } 598 599 const struct ether_brport * 600 ether_brport_get(struct ifnet *ifp) 601 { 602 struct arpcom *ac = (struct arpcom *)ifp; 603 SMR_ASSERT_CRITICAL(); 604 return (SMR_PTR_GET(&ac->ac_brport)); 605 } 606 607 const struct ether_brport * 608 ether_brport_get_locked(struct ifnet *ifp) 609 { 610 struct arpcom *ac = (struct arpcom *)ifp; 611 KERNEL_ASSERT_LOCKED(); 612 return (SMR_PTR_GET_LOCKED(&ac->ac_brport)); 613 } 614 615 /* 616 * Convert Ethernet address to printable (loggable) representation. 617 */ 618 static char digits[] = "0123456789abcdef"; 619 char * 620 ether_sprintf(u_char *ap) 621 { 622 int i; 623 static char etherbuf[ETHER_ADDR_LEN * 3]; 624 char *cp = etherbuf; 625 626 for (i = 0; i < ETHER_ADDR_LEN; i++) { 627 *cp++ = digits[*ap >> 4]; 628 *cp++ = digits[*ap++ & 0xf]; 629 *cp++ = ':'; 630 } 631 *--cp = 0; 632 return (etherbuf); 633 } 634 635 /* 636 * Generate a (hopefully) acceptable MAC address, if asked. 637 */ 638 void 639 ether_fakeaddr(struct ifnet *ifp) 640 { 641 static int unit; 642 int rng = arc4random(); 643 644 /* Non-multicast; locally administered address */ 645 ((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe; 646 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1; 647 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xba; 648 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf); 649 ((struct arpcom *)ifp)->ac_enaddr[4] = rng; 650 ((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8; 651 } 652 653 /* 654 * Perform common duties while attaching to interface list 655 */ 656 void 657 ether_ifattach(struct ifnet *ifp) 658 { 659 struct arpcom *ac = (struct arpcom *)ifp; 660 661 /* 662 * Any interface which provides a MAC address which is obviously 663 * invalid gets whacked, so that users will notice. 664 */ 665 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) 666 ether_fakeaddr(ifp); 667 668 ifp->if_type = IFT_ETHER; 669 ifp->if_addrlen = ETHER_ADDR_LEN; 670 ifp->if_hdrlen = ETHER_HDR_LEN; 671 ifp->if_mtu = ETHERMTU; 672 ifp->if_input = ether_input; 673 if (ifp->if_output == NULL) 674 ifp->if_output = ether_output; 675 ifp->if_rtrequest = ether_rtrequest; 676 677 if (ifp->if_hardmtu == 0) 678 ifp->if_hardmtu = ETHERMTU; 679 680 if_alloc_sadl(ifp); 681 memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen); 682 LIST_INIT(&ac->ac_multiaddrs); 683 #if NBPFILTER > 0 684 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN); 685 #endif 686 } 687 688 void 689 ether_ifdetach(struct ifnet *ifp) 690 { 691 struct arpcom *ac = (struct arpcom *)ifp; 692 struct ether_multi *enm; 693 694 /* Undo pseudo-driver changes. */ 695 if_deactivate(ifp); 696 697 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 698 enm != NULL; 699 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 700 LIST_REMOVE(enm, enm_list); 701 free(enm, M_IFMADDR, sizeof *enm); 702 } 703 } 704 705 #if 0 706 /* 707 * This is for reference. We have table-driven versions of the 708 * crc32 generators, which are faster than the double-loop. 709 */ 710 u_int32_t __pure 711 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 712 { 713 u_int32_t c, carry; 714 size_t i, j; 715 716 for (i = 0; i < len; i++) { 717 c = buf[i]; 718 for (j = 0; j < 8; j++) { 719 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); 720 crc >>= 1; 721 c >>= 1; 722 if (carry) 723 crc = (crc ^ ETHER_CRC_POLY_LE); 724 } 725 } 726 727 return (crc); 728 } 729 730 u_int32_t __pure 731 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 732 { 733 u_int32_t c, carry; 734 size_t i, j; 735 736 for (i = 0; i < len; i++) { 737 c = buf[i]; 738 for (j = 0; j < 8; j++) { 739 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); 740 crc <<= 1; 741 c >>= 1; 742 if (carry) 743 crc = (crc ^ ETHER_CRC_POLY_BE) | carry; 744 } 745 } 746 747 return (crc); 748 } 749 #else 750 u_int32_t __pure 751 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len) 752 { 753 static const u_int32_t crctab[] = { 754 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 755 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 756 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 757 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 758 }; 759 size_t i; 760 761 for (i = 0; i < len; i++) { 762 crc ^= buf[i]; 763 crc = (crc >> 4) ^ crctab[crc & 0xf]; 764 crc = (crc >> 4) ^ crctab[crc & 0xf]; 765 } 766 767 return (crc); 768 } 769 770 u_int32_t __pure 771 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len) 772 { 773 static const u_int8_t rev[] = { 774 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 775 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf 776 }; 777 static const u_int32_t crctab[] = { 778 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 779 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 780 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 781 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd 782 }; 783 size_t i; 784 u_int8_t data; 785 786 for (i = 0; i < len; i++) { 787 data = buf[i]; 788 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]]; 789 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]]; 790 } 791 792 return (crc); 793 } 794 #endif 795 796 u_int32_t 797 ether_crc32_le(const u_int8_t *buf, size_t len) 798 { 799 return ether_crc32_le_update(0xffffffff, buf, len); 800 } 801 802 u_int32_t 803 ether_crc32_be(const u_int8_t *buf, size_t len) 804 { 805 return ether_crc32_be_update(0xffffffff, buf, len); 806 } 807 808 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] = 809 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 810 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] = 811 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 812 813 #ifdef INET6 814 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] = 815 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 816 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] = 817 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 818 #endif 819 820 /* 821 * Convert a sockaddr into an Ethernet address or range of Ethernet 822 * addresses. 823 */ 824 int 825 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN], 826 u_int8_t addrhi[ETHER_ADDR_LEN]) 827 { 828 struct sockaddr_in *sin; 829 #ifdef INET6 830 struct sockaddr_in6 *sin6; 831 #endif /* INET6 */ 832 833 switch (sa->sa_family) { 834 835 case AF_UNSPEC: 836 memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN); 837 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 838 break; 839 840 case AF_INET: 841 sin = satosin(sa); 842 if (sin->sin_addr.s_addr == INADDR_ANY) { 843 /* 844 * An IP address of INADDR_ANY means listen to 845 * or stop listening to all of the Ethernet 846 * multicast addresses used for IP. 847 * (This is for the sake of IP multicast routers.) 848 */ 849 memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN); 850 memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN); 851 } else { 852 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 853 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 854 } 855 break; 856 #ifdef INET6 857 case AF_INET6: 858 sin6 = satosin6(sa); 859 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 860 /* 861 * An IP6 address of 0 means listen to or stop 862 * listening to all of the Ethernet multicast 863 * address used for IP6. 864 * 865 * (This might not be healthy, given IPv6's reliance on 866 * multicast for things like neighbor discovery. 867 * Perhaps initializing all-nodes, solicited nodes, and 868 * possibly all-routers for this interface afterwards 869 * is not a bad idea.) 870 */ 871 872 memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN); 873 memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN); 874 } else { 875 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 876 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 877 } 878 break; 879 #endif 880 881 default: 882 return (EAFNOSUPPORT); 883 } 884 return (0); 885 } 886 887 /* 888 * Add an Ethernet multicast address or range of addresses to the list for a 889 * given interface. 890 */ 891 int 892 ether_addmulti(struct ifreq *ifr, struct arpcom *ac) 893 { 894 struct ether_multi *enm; 895 u_char addrlo[ETHER_ADDR_LEN]; 896 u_char addrhi[ETHER_ADDR_LEN]; 897 int s = splnet(), error; 898 899 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 900 if (error != 0) { 901 splx(s); 902 return (error); 903 } 904 905 /* 906 * Verify that we have valid Ethernet multicast addresses. 907 */ 908 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 909 splx(s); 910 return (EINVAL); 911 } 912 /* 913 * See if the address range is already in the list. 914 */ 915 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 916 if (enm != NULL) { 917 /* 918 * Found it; just increment the reference count. 919 */ 920 ++enm->enm_refcount; 921 splx(s); 922 return (0); 923 } 924 /* 925 * New address or range; malloc a new multicast record 926 * and link it into the interface's multicast list. 927 */ 928 enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 929 if (enm == NULL) { 930 splx(s); 931 return (ENOBUFS); 932 } 933 memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN); 934 memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN); 935 enm->enm_refcount = 1; 936 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 937 ac->ac_multicnt++; 938 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 939 ac->ac_multirangecnt++; 940 splx(s); 941 /* 942 * Return ENETRESET to inform the driver that the list has changed 943 * and its reception filter should be adjusted accordingly. 944 */ 945 return (ENETRESET); 946 } 947 948 /* 949 * Delete a multicast address record. 950 */ 951 int 952 ether_delmulti(struct ifreq *ifr, struct arpcom *ac) 953 { 954 struct ether_multi *enm; 955 u_char addrlo[ETHER_ADDR_LEN]; 956 u_char addrhi[ETHER_ADDR_LEN]; 957 int s = splnet(), error; 958 959 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 960 if (error != 0) { 961 splx(s); 962 return (error); 963 } 964 965 /* 966 * Look up the address in our list. 967 */ 968 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 969 if (enm == NULL) { 970 splx(s); 971 return (ENXIO); 972 } 973 if (--enm->enm_refcount != 0) { 974 /* 975 * Still some claims to this record. 976 */ 977 splx(s); 978 return (0); 979 } 980 /* 981 * No remaining claims to this record; unlink and free it. 982 */ 983 LIST_REMOVE(enm, enm_list); 984 free(enm, M_IFMADDR, sizeof *enm); 985 ac->ac_multicnt--; 986 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 987 ac->ac_multirangecnt--; 988 splx(s); 989 /* 990 * Return ENETRESET to inform the driver that the list has changed 991 * and its reception filter should be adjusted accordingly. 992 */ 993 return (ENETRESET); 994 } 995