1 /* $OpenBSD: if_ethersubr.c,v 1.270 2021/02/06 13:15:37 bluhm 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 /* 231 * If broadcasting on a simplex interface, loopback a copy. 232 * The checksum must be calculated in software. Keep the 233 * condition in sync with in_ifcap_cksum(). 234 */ 235 if (ISSET(m->m_flags, M_BCAST) && 236 ISSET(ifp->if_flags, IFF_SIMPLEX) && 237 !m->m_pkthdr.pf.routed) { 238 struct mbuf *mcopy; 239 240 /* XXX Should we input an unencrypted IPsec packet? */ 241 mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT); 242 if (mcopy != NULL) 243 if_input_local(ifp, mcopy, af); 244 } 245 break; 246 #ifdef INET6 247 case AF_INET6: 248 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 249 if (error) 250 return (error); 251 eh->ether_type = htons(ETHERTYPE_IPV6); 252 break; 253 #endif 254 #ifdef MPLS 255 case AF_MPLS: 256 if (rt == NULL) 257 senderr(EHOSTUNREACH); 258 259 if (!ISSET(ifp->if_xflags, IFXF_MPLS)) 260 senderr(ENETUNREACH); 261 262 dst = ISSET(rt->rt_flags, RTF_GATEWAY) ? 263 rt->rt_gateway : rt_key(rt); 264 265 switch (dst->sa_family) { 266 case AF_LINK: 267 if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost)) 268 senderr(EHOSTUNREACH); 269 memcpy(eh->ether_dhost, LLADDR(satosdl(dst)), 270 sizeof(eh->ether_dhost)); 271 break; 272 #ifdef INET6 273 case AF_INET6: 274 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 275 if (error) 276 return (error); 277 break; 278 #endif 279 case AF_INET: 280 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); 281 if (error) 282 return (error); 283 break; 284 default: 285 senderr(EHOSTUNREACH); 286 } 287 /* XXX handling for simplex devices in case of M/BCAST ?? */ 288 if (m->m_flags & (M_BCAST | M_MCAST)) 289 eh->ether_type = htons(ETHERTYPE_MPLS_MCAST); 290 else 291 eh->ether_type = htons(ETHERTYPE_MPLS); 292 break; 293 #endif /* MPLS */ 294 case pseudo_AF_HDRCMPLT: 295 /* take the whole header from the sa */ 296 memcpy(eh, dst->sa_data, sizeof(*eh)); 297 return (0); 298 299 case AF_UNSPEC: 300 /* take the dst and type from the sa, but get src below */ 301 memcpy(eh, dst->sa_data, sizeof(*eh)); 302 break; 303 304 default: 305 printf("%s: can't handle af%d\n", ifp->if_xname, af); 306 senderr(EAFNOSUPPORT); 307 } 308 309 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost)); 310 311 return (0); 312 313 bad: 314 m_freem(m); 315 return (error); 316 } 317 318 struct mbuf* 319 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 320 struct rtentry *rt, int *errorp) 321 { 322 struct ether_header eh; 323 int error; 324 325 error = ether_resolve(ifp, m, dst, rt, &eh); 326 switch (error) { 327 case 0: 328 break; 329 case EAGAIN: 330 error = 0; 331 default: 332 *errorp = error; 333 return (NULL); 334 } 335 336 m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT); 337 if (m == NULL) { 338 *errorp = ENOBUFS; 339 return (NULL); 340 } 341 342 m_adj(m, ETHER_ALIGN); 343 memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh)); 344 345 return (m); 346 } 347 348 int 349 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 350 struct rtentry *rt) 351 { 352 int error; 353 354 m = ether_encap(ifp, m, dst, rt, &error); 355 if (m == NULL) 356 return (error); 357 358 return (if_enqueue(ifp, m)); 359 } 360 361 /* 362 * Process a received Ethernet packet. 363 * 364 * Ethernet input has several "phases" of filtering packets to 365 * support virtual/pseudo interfaces before actual layer 3 protocol 366 * handling. 367 * 368 * First phase: 369 * 370 * The first phase supports drivers that aggregate multiple Ethernet 371 * ports into a single logical interface, ie, aggr(4) and trunk(4). 372 * These drivers intercept packets by swapping out the if_input handler 373 * on the "port" interfaces to steal the packets before they get here 374 * to ether_input(). 375 */ 376 void 377 ether_input(struct ifnet *ifp, struct mbuf *m) 378 { 379 struct ether_header *eh; 380 void (*input)(struct ifnet *, struct mbuf *); 381 u_int16_t etype; 382 struct arpcom *ac; 383 const struct ether_brport *eb; 384 unsigned int sdelim = 0; 385 386 /* Drop short frames */ 387 if (m->m_len < ETHER_HDR_LEN) 388 goto dropanyway; 389 390 /* 391 * Second phase: service delimited packet filtering. 392 * 393 * Let vlan(4) and svlan(4) look at "service delimited" 394 * packets. If a virtual interface does not exist to take 395 * those packets, they're returned to ether_input() so a 396 * bridge can have a go at forwarding them. 397 */ 398 399 eh = mtod(m, struct ether_header *); 400 etype = ntohs(eh->ether_type); 401 402 if (ISSET(m->m_flags, M_VLANTAG) || 403 etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) { 404 #if NVLAN > 0 405 m = vlan_input(ifp, m); 406 if (m == NULL) 407 return; 408 #endif /* NVLAN > 0 */ 409 410 sdelim = 1; 411 } 412 413 /* 414 * Third phase: bridge processing. 415 * 416 * Give the packet to a bridge interface, ie, bridge(4), 417 * switch(4), or tpmr(4), if it is configured. A bridge 418 * may take the packet and forward it to another port, or it 419 * may return it here to ether_input() to support local 420 * delivery to this port. 421 */ 422 423 ac = (struct arpcom *)ifp; 424 425 smr_read_enter(); 426 eb = SMR_PTR_GET(&ac->ac_brport); 427 if (eb != NULL) { 428 m = (*eb->eb_input)(ifp, m, eb->eb_port); 429 if (m == NULL) { 430 smr_read_leave(); 431 return; 432 } 433 } 434 smr_read_leave(); 435 436 /* 437 * Fourth phase: drop service delimited packets. 438 * 439 * If the packet has a tag, and a bridge didn't want it, 440 * it's not for this port. 441 */ 442 443 if (sdelim) 444 goto dropanyway; 445 446 /* 447 * Fifth phase: destination address check. 448 * 449 * Is the packet specifically addressed to this port? 450 */ 451 452 eh = mtod(m, struct ether_header *); 453 if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) { 454 #if NCARP > 0 455 /* 456 * If it's not for this port, it could be for carp(4). 457 */ 458 if (ifp->if_type != IFT_CARP && 459 !SRPL_EMPTY_LOCKED(&ifp->if_carp)) { 460 m = carp_input(ifp, m); 461 if (m == NULL) 462 return; 463 464 eh = mtod(m, struct ether_header *); 465 } 466 #endif 467 468 /* 469 * If not, it must be multicast or broadcast to go further. 470 */ 471 if (!ETHER_IS_MULTICAST(eh->ether_dhost)) 472 goto dropanyway; 473 474 /* 475 * If this is not a simplex interface, drop the packet 476 * if it came from us. 477 */ 478 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 479 if (memcmp(ac->ac_enaddr, eh->ether_shost, 480 ETHER_ADDR_LEN) == 0) 481 goto dropanyway; 482 } 483 484 if (ETHER_IS_BROADCAST(eh->ether_dhost)) 485 m->m_flags |= M_BCAST; 486 else 487 m->m_flags |= M_MCAST; 488 ifp->if_imcasts++; 489 } 490 491 /* 492 * Sixth phase: protocol demux. 493 * 494 * At this point it is known that the packet is destined 495 * for layer 3 protocol handling on the local port. 496 */ 497 498 switch (etype) { 499 case ETHERTYPE_IP: 500 input = ipv4_input; 501 break; 502 503 case ETHERTYPE_ARP: 504 if (ifp->if_flags & IFF_NOARP) 505 goto dropanyway; 506 input = arpinput; 507 break; 508 509 case ETHERTYPE_REVARP: 510 if (ifp->if_flags & IFF_NOARP) 511 goto dropanyway; 512 input = revarpinput; 513 break; 514 515 #ifdef INET6 516 /* 517 * Schedule IPv6 software interrupt for incoming IPv6 packet. 518 */ 519 case ETHERTYPE_IPV6: 520 input = ipv6_input; 521 break; 522 #endif /* INET6 */ 523 #if NPPPOE > 0 || defined(PIPEX) 524 case ETHERTYPE_PPPOEDISC: 525 case ETHERTYPE_PPPOE: 526 if (m->m_flags & (M_MCAST | M_BCAST)) 527 goto dropanyway; 528 #ifdef PIPEX 529 if (pipex_enable) { 530 struct pipex_session *session; 531 532 if ((session = pipex_pppoe_lookup_session(m)) != NULL) { 533 pipex_pppoe_input(m, session); 534 return; 535 } 536 } 537 #endif 538 if (etype == ETHERTYPE_PPPOEDISC) 539 pppoe_disc_input(m); 540 else 541 pppoe_data_input(m); 542 return; 543 #endif 544 #ifdef MPLS 545 case ETHERTYPE_MPLS: 546 case ETHERTYPE_MPLS_MCAST: 547 input = mpls_input; 548 break; 549 #endif 550 #if NBPE > 0 551 case ETHERTYPE_PBB: 552 bpe_input(ifp, m); 553 return; 554 #endif 555 default: 556 goto dropanyway; 557 } 558 559 m_adj(m, sizeof(*eh)); 560 (*input)(ifp, m); 561 return; 562 dropanyway: 563 m_freem(m); 564 return; 565 } 566 567 int 568 ether_brport_isset(struct ifnet *ifp) 569 { 570 struct arpcom *ac = (struct arpcom *)ifp; 571 572 KERNEL_ASSERT_LOCKED(); 573 if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL) 574 return (EBUSY); 575 576 return (0); 577 } 578 579 void 580 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb) 581 { 582 struct arpcom *ac = (struct arpcom *)ifp; 583 584 KERNEL_ASSERT_LOCKED(); 585 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL, 586 "%s setting an already set brport", ifp->if_xname); 587 588 SMR_PTR_SET_LOCKED(&ac->ac_brport, eb); 589 } 590 591 void 592 ether_brport_clr(struct ifnet *ifp) 593 { 594 struct arpcom *ac = (struct arpcom *)ifp; 595 596 KERNEL_ASSERT_LOCKED(); 597 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL, 598 "%s clearing an already clear brport", ifp->if_xname); 599 600 SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL); 601 } 602 603 const struct ether_brport * 604 ether_brport_get(struct ifnet *ifp) 605 { 606 struct arpcom *ac = (struct arpcom *)ifp; 607 SMR_ASSERT_CRITICAL(); 608 return (SMR_PTR_GET(&ac->ac_brport)); 609 } 610 611 const struct ether_brport * 612 ether_brport_get_locked(struct ifnet *ifp) 613 { 614 struct arpcom *ac = (struct arpcom *)ifp; 615 KERNEL_ASSERT_LOCKED(); 616 return (SMR_PTR_GET_LOCKED(&ac->ac_brport)); 617 } 618 619 /* 620 * Convert Ethernet address to printable (loggable) representation. 621 */ 622 static char digits[] = "0123456789abcdef"; 623 char * 624 ether_sprintf(u_char *ap) 625 { 626 int i; 627 static char etherbuf[ETHER_ADDR_LEN * 3]; 628 char *cp = etherbuf; 629 630 for (i = 0; i < ETHER_ADDR_LEN; i++) { 631 *cp++ = digits[*ap >> 4]; 632 *cp++ = digits[*ap++ & 0xf]; 633 *cp++ = ':'; 634 } 635 *--cp = 0; 636 return (etherbuf); 637 } 638 639 /* 640 * Generate a (hopefully) acceptable MAC address, if asked. 641 */ 642 void 643 ether_fakeaddr(struct ifnet *ifp) 644 { 645 static int unit; 646 int rng = arc4random(); 647 648 /* Non-multicast; locally administered address */ 649 ((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe; 650 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1; 651 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xba; 652 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf); 653 ((struct arpcom *)ifp)->ac_enaddr[4] = rng; 654 ((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8; 655 } 656 657 /* 658 * Perform common duties while attaching to interface list 659 */ 660 void 661 ether_ifattach(struct ifnet *ifp) 662 { 663 struct arpcom *ac = (struct arpcom *)ifp; 664 665 /* 666 * Any interface which provides a MAC address which is obviously 667 * invalid gets whacked, so that users will notice. 668 */ 669 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) 670 ether_fakeaddr(ifp); 671 672 ifp->if_type = IFT_ETHER; 673 ifp->if_addrlen = ETHER_ADDR_LEN; 674 ifp->if_hdrlen = ETHER_HDR_LEN; 675 ifp->if_mtu = ETHERMTU; 676 ifp->if_input = ether_input; 677 if (ifp->if_output == NULL) 678 ifp->if_output = ether_output; 679 ifp->if_rtrequest = ether_rtrequest; 680 681 if (ifp->if_hardmtu == 0) 682 ifp->if_hardmtu = ETHERMTU; 683 684 if_alloc_sadl(ifp); 685 memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen); 686 LIST_INIT(&ac->ac_multiaddrs); 687 #if NBPFILTER > 0 688 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN); 689 #endif 690 } 691 692 void 693 ether_ifdetach(struct ifnet *ifp) 694 { 695 struct arpcom *ac = (struct arpcom *)ifp; 696 struct ether_multi *enm; 697 698 /* Undo pseudo-driver changes. */ 699 if_deactivate(ifp); 700 701 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 702 enm != NULL; 703 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 704 LIST_REMOVE(enm, enm_list); 705 free(enm, M_IFMADDR, sizeof *enm); 706 } 707 } 708 709 #if 0 710 /* 711 * This is for reference. We have table-driven versions of the 712 * crc32 generators, which are faster than the double-loop. 713 */ 714 u_int32_t __pure 715 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 716 { 717 u_int32_t c, carry; 718 size_t i, j; 719 720 for (i = 0; i < len; i++) { 721 c = buf[i]; 722 for (j = 0; j < 8; j++) { 723 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); 724 crc >>= 1; 725 c >>= 1; 726 if (carry) 727 crc = (crc ^ ETHER_CRC_POLY_LE); 728 } 729 } 730 731 return (crc); 732 } 733 734 u_int32_t __pure 735 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 736 { 737 u_int32_t c, carry; 738 size_t i, j; 739 740 for (i = 0; i < len; i++) { 741 c = buf[i]; 742 for (j = 0; j < 8; j++) { 743 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); 744 crc <<= 1; 745 c >>= 1; 746 if (carry) 747 crc = (crc ^ ETHER_CRC_POLY_BE) | carry; 748 } 749 } 750 751 return (crc); 752 } 753 #else 754 u_int32_t __pure 755 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len) 756 { 757 static const u_int32_t crctab[] = { 758 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 759 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 760 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 761 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 762 }; 763 size_t i; 764 765 for (i = 0; i < len; i++) { 766 crc ^= buf[i]; 767 crc = (crc >> 4) ^ crctab[crc & 0xf]; 768 crc = (crc >> 4) ^ crctab[crc & 0xf]; 769 } 770 771 return (crc); 772 } 773 774 u_int32_t __pure 775 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len) 776 { 777 static const u_int8_t rev[] = { 778 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 779 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf 780 }; 781 static const u_int32_t crctab[] = { 782 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 783 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 784 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 785 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd 786 }; 787 size_t i; 788 u_int8_t data; 789 790 for (i = 0; i < len; i++) { 791 data = buf[i]; 792 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]]; 793 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]]; 794 } 795 796 return (crc); 797 } 798 #endif 799 800 u_int32_t 801 ether_crc32_le(const u_int8_t *buf, size_t len) 802 { 803 return ether_crc32_le_update(0xffffffff, buf, len); 804 } 805 806 u_int32_t 807 ether_crc32_be(const u_int8_t *buf, size_t len) 808 { 809 return ether_crc32_be_update(0xffffffff, buf, len); 810 } 811 812 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] = 813 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 814 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] = 815 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 816 817 #ifdef INET6 818 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] = 819 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 820 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] = 821 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 822 #endif 823 824 /* 825 * Convert a sockaddr into an Ethernet address or range of Ethernet 826 * addresses. 827 */ 828 int 829 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN], 830 u_int8_t addrhi[ETHER_ADDR_LEN]) 831 { 832 struct sockaddr_in *sin; 833 #ifdef INET6 834 struct sockaddr_in6 *sin6; 835 #endif /* INET6 */ 836 837 switch (sa->sa_family) { 838 839 case AF_UNSPEC: 840 memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN); 841 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 842 break; 843 844 case AF_INET: 845 sin = satosin(sa); 846 if (sin->sin_addr.s_addr == INADDR_ANY) { 847 /* 848 * An IP address of INADDR_ANY means listen to 849 * or stop listening to all of the Ethernet 850 * multicast addresses used for IP. 851 * (This is for the sake of IP multicast routers.) 852 */ 853 memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN); 854 memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN); 855 } else { 856 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 857 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 858 } 859 break; 860 #ifdef INET6 861 case AF_INET6: 862 sin6 = satosin6(sa); 863 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 864 /* 865 * An IP6 address of 0 means listen to or stop 866 * listening to all of the Ethernet multicast 867 * address used for IP6. 868 * 869 * (This might not be healthy, given IPv6's reliance on 870 * multicast for things like neighbor discovery. 871 * Perhaps initializing all-nodes, solicited nodes, and 872 * possibly all-routers for this interface afterwards 873 * is not a bad idea.) 874 */ 875 876 memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN); 877 memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN); 878 } else { 879 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 880 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 881 } 882 break; 883 #endif 884 885 default: 886 return (EAFNOSUPPORT); 887 } 888 return (0); 889 } 890 891 /* 892 * Add an Ethernet multicast address or range of addresses to the list for a 893 * given interface. 894 */ 895 int 896 ether_addmulti(struct ifreq *ifr, struct arpcom *ac) 897 { 898 struct ether_multi *enm; 899 u_char addrlo[ETHER_ADDR_LEN]; 900 u_char addrhi[ETHER_ADDR_LEN]; 901 int s = splnet(), error; 902 903 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 904 if (error != 0) { 905 splx(s); 906 return (error); 907 } 908 909 /* 910 * Verify that we have valid Ethernet multicast addresses. 911 */ 912 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 913 splx(s); 914 return (EINVAL); 915 } 916 /* 917 * See if the address range is already in the list. 918 */ 919 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 920 if (enm != NULL) { 921 /* 922 * Found it; just increment the reference count. 923 */ 924 ++enm->enm_refcount; 925 splx(s); 926 return (0); 927 } 928 /* 929 * New address or range; malloc a new multicast record 930 * and link it into the interface's multicast list. 931 */ 932 enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 933 if (enm == NULL) { 934 splx(s); 935 return (ENOBUFS); 936 } 937 memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN); 938 memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN); 939 enm->enm_refcount = 1; 940 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 941 ac->ac_multicnt++; 942 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 943 ac->ac_multirangecnt++; 944 splx(s); 945 /* 946 * Return ENETRESET to inform the driver that the list has changed 947 * and its reception filter should be adjusted accordingly. 948 */ 949 return (ENETRESET); 950 } 951 952 /* 953 * Delete a multicast address record. 954 */ 955 int 956 ether_delmulti(struct ifreq *ifr, struct arpcom *ac) 957 { 958 struct ether_multi *enm; 959 u_char addrlo[ETHER_ADDR_LEN]; 960 u_char addrhi[ETHER_ADDR_LEN]; 961 int s = splnet(), error; 962 963 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 964 if (error != 0) { 965 splx(s); 966 return (error); 967 } 968 969 /* 970 * Look up the address in our list. 971 */ 972 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 973 if (enm == NULL) { 974 splx(s); 975 return (ENXIO); 976 } 977 if (--enm->enm_refcount != 0) { 978 /* 979 * Still some claims to this record. 980 */ 981 splx(s); 982 return (0); 983 } 984 /* 985 * No remaining claims to this record; unlink and free it. 986 */ 987 LIST_REMOVE(enm, enm_list); 988 free(enm, M_IFMADDR, sizeof *enm); 989 ac->ac_multicnt--; 990 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 991 ac->ac_multirangecnt--; 992 splx(s); 993 /* 994 * Return ENETRESET to inform the driver that the list has changed 995 * and its reception filter should be adjusted accordingly. 996 */ 997 return (ENETRESET); 998 } 999