1 /* $OpenBSD: if_ethersubr.c,v 1.257 2018/12/26 18:32:38 denis 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 90 #include <net/if.h> 91 #include <net/netisr.h> 92 #include <net/route.h> 93 #include <net/if_llc.h> 94 #include <net/if_dl.h> 95 #include <net/if_media.h> 96 #include <net/if_types.h> 97 98 #include <netinet/in.h> 99 #include <netinet/if_ether.h> 100 #include <netinet/ip_ipsp.h> 101 102 #if NBPFILTER > 0 103 #include <net/bpf.h> 104 #endif 105 106 #include "pppoe.h" 107 #if NPPPOE > 0 108 #include <net/if_pppoe.h> 109 #endif 110 111 #include "bpe.h" 112 #if NBPE > 0 113 #include <net/if_bpe.h> 114 #endif 115 116 #ifdef INET6 117 #include <netinet6/in6_var.h> 118 #include <netinet6/nd6.h> 119 #endif 120 121 #ifdef PIPEX 122 #include <net/pipex.h> 123 #endif 124 125 #ifdef MPLS 126 #include <netmpls/mpls.h> 127 #endif /* MPLS */ 128 129 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] = 130 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 131 u_int8_t etheranyaddr[ETHER_ADDR_LEN] = 132 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 133 #define senderr(e) { error = (e); goto bad;} 134 135 int 136 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data) 137 { 138 struct ifreq *ifr = (struct ifreq *)data; 139 int error = 0; 140 141 switch (cmd) { 142 case SIOCSIFADDR: 143 break; 144 145 case SIOCSIFMTU: 146 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu) 147 error = EINVAL; 148 else 149 ifp->if_mtu = ifr->ifr_mtu; 150 break; 151 152 case SIOCADDMULTI: 153 case SIOCDELMULTI: 154 if (ifp->if_flags & IFF_MULTICAST) { 155 error = (cmd == SIOCADDMULTI) ? 156 ether_addmulti(ifr, arp) : 157 ether_delmulti(ifr, arp); 158 } else 159 error = ENOTTY; 160 break; 161 162 default: 163 error = ENOTTY; 164 } 165 166 return (error); 167 } 168 169 170 void 171 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt) 172 { 173 switch (rt_key(rt)->sa_family) { 174 case AF_INET: 175 arp_rtrequest(ifp, req, rt); 176 break; 177 #ifdef INET6 178 case AF_INET6: 179 nd6_rtrequest(ifp, req, rt); 180 break; 181 #endif 182 default: 183 break; 184 } 185 } 186 187 int 188 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 189 struct rtentry *rt, struct ether_header *eh) 190 { 191 struct arpcom *ac = (struct arpcom *)ifp; 192 sa_family_t af = dst->sa_family; 193 int error = 0; 194 195 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 196 senderr(ENETDOWN); 197 198 KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) || 199 af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT); 200 201 #ifdef DIAGNOSTIC 202 if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) { 203 printf("%s: trying to send packet on wrong domain. " 204 "if %d vs. mbuf %d\n", ifp->if_xname, 205 ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid)); 206 } 207 #endif 208 209 switch (af) { 210 case AF_INET: 211 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); 212 if (error) 213 return (error); 214 eh->ether_type = htons(ETHERTYPE_IP); 215 216 /* If broadcasting on a simplex interface, loopback a copy */ 217 if (ISSET(m->m_flags, M_BCAST) && 218 ISSET(ifp->if_flags, IFF_SIMPLEX) && 219 !m->m_pkthdr.pf.routed) { 220 struct mbuf *mcopy; 221 222 /* XXX Should we input an unencrypted IPsec packet? */ 223 mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT); 224 if (mcopy != NULL) 225 if_input_local(ifp, mcopy, af); 226 } 227 break; 228 #ifdef INET6 229 case AF_INET6: 230 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 231 if (error) 232 return (error); 233 eh->ether_type = htons(ETHERTYPE_IPV6); 234 break; 235 #endif 236 #ifdef MPLS 237 case AF_MPLS: 238 if (rt) 239 dst = rt_key(rt); 240 else 241 senderr(EHOSTUNREACH); 242 243 if (!ISSET(ifp->if_xflags, IFXF_MPLS)) 244 senderr(ENETUNREACH); 245 246 af = dst->sa_family; 247 if (af == AF_MPLS) 248 af = rt->rt_gateway->sa_family; 249 250 switch (af) { 251 case AF_LINK: 252 if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost)) 253 senderr(EHOSTUNREACH); 254 memcpy(eh->ether_dhost, LLADDR(satosdl(dst)), 255 sizeof(eh->ether_dhost)); 256 break; 257 #ifdef INET6 258 case AF_INET6: 259 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); 260 if (error) 261 return (error); 262 break; 263 #endif 264 case AF_INET: 265 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); 266 if (error) 267 return (error); 268 break; 269 default: 270 senderr(EHOSTUNREACH); 271 } 272 /* XXX handling for simplex devices in case of M/BCAST ?? */ 273 if (m->m_flags & (M_BCAST | M_MCAST)) 274 eh->ether_type = htons(ETHERTYPE_MPLS_MCAST); 275 else 276 eh->ether_type = htons(ETHERTYPE_MPLS); 277 break; 278 #endif /* MPLS */ 279 case pseudo_AF_HDRCMPLT: 280 /* take the whole header from the sa */ 281 memcpy(eh, dst->sa_data, sizeof(*eh)); 282 return (0); 283 284 case AF_UNSPEC: 285 /* take the dst and type from the sa, but get src below */ 286 memcpy(eh, dst->sa_data, sizeof(*eh)); 287 break; 288 289 default: 290 printf("%s: can't handle af%d\n", ifp->if_xname, af); 291 senderr(EAFNOSUPPORT); 292 } 293 294 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost)); 295 296 return (0); 297 298 bad: 299 m_freem(m); 300 return (error); 301 } 302 303 struct mbuf* 304 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 305 struct rtentry *rt, int *errorp) 306 { 307 struct ether_header eh; 308 int error; 309 310 error = ether_resolve(ifp, m, dst, rt, &eh); 311 switch (error) { 312 case 0: 313 break; 314 case EAGAIN: 315 error = 0; 316 default: 317 *errorp = error; 318 return (NULL); 319 } 320 321 m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT); 322 if (m == NULL) { 323 *errorp = ENOBUFS; 324 return (NULL); 325 } 326 327 m_adj(m, ETHER_ALIGN); 328 memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh)); 329 330 return (m); 331 } 332 333 int 334 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 335 struct rtentry *rt) 336 { 337 int error; 338 339 m = ether_encap(ifp, m, dst, rt, &error); 340 if (m == NULL) 341 return (error); 342 343 return (if_enqueue(ifp, m)); 344 } 345 346 /* 347 * Process a received Ethernet packet; 348 * the packet is in the mbuf chain m without 349 * the ether header, which is provided separately. 350 */ 351 int 352 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie) 353 { 354 struct ether_header *eh; 355 void (*input)(struct ifnet *, struct mbuf *); 356 u_int16_t etype; 357 struct arpcom *ac; 358 359 /* Drop short frames */ 360 if (m->m_len < ETHER_HDR_LEN) 361 goto dropanyway; 362 363 ac = (struct arpcom *)ifp; 364 eh = mtod(m, struct ether_header *); 365 366 /* Is the packet for us? */ 367 if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) { 368 369 /* If not, it must be multicast or broadcast to go further */ 370 if (!ETHER_IS_MULTICAST(eh->ether_dhost)) 371 goto dropanyway; 372 373 /* 374 * If this is not a simplex interface, drop the packet 375 * if it came from us. 376 */ 377 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 378 if (memcmp(ac->ac_enaddr, eh->ether_shost, 379 ETHER_ADDR_LEN) == 0) 380 goto dropanyway; 381 } 382 383 if (memcmp(etherbroadcastaddr, eh->ether_dhost, 384 ETHER_ADDR_LEN) == 0) 385 m->m_flags |= M_BCAST; 386 else 387 m->m_flags |= M_MCAST; 388 ifp->if_imcasts++; 389 } 390 391 /* 392 * HW vlan tagged packets that were not collected by vlan(4) must 393 * be dropped now. 394 */ 395 if (m->m_flags & M_VLANTAG) 396 goto dropanyway; 397 398 etype = ntohs(eh->ether_type); 399 400 switch (etype) { 401 case ETHERTYPE_IP: 402 input = ipv4_input; 403 break; 404 405 case ETHERTYPE_ARP: 406 if (ifp->if_flags & IFF_NOARP) 407 goto dropanyway; 408 input = arpinput; 409 break; 410 411 case ETHERTYPE_REVARP: 412 if (ifp->if_flags & IFF_NOARP) 413 goto dropanyway; 414 input = revarpinput; 415 break; 416 417 #ifdef INET6 418 /* 419 * Schedule IPv6 software interrupt for incoming IPv6 packet. 420 */ 421 case ETHERTYPE_IPV6: 422 input = ipv6_input; 423 break; 424 #endif /* INET6 */ 425 #if NPPPOE > 0 || defined(PIPEX) 426 case ETHERTYPE_PPPOEDISC: 427 case ETHERTYPE_PPPOE: 428 if (m->m_flags & (M_MCAST | M_BCAST)) 429 goto dropanyway; 430 #ifdef PIPEX 431 if (pipex_enable) { 432 struct pipex_session *session; 433 434 if ((session = pipex_pppoe_lookup_session(m)) != NULL) { 435 pipex_pppoe_input(m, session); 436 return (1); 437 } 438 } 439 #endif 440 if (etype == ETHERTYPE_PPPOEDISC) 441 niq_enqueue(&pppoediscinq, m); 442 else 443 niq_enqueue(&pppoeinq, m); 444 return (1); 445 #endif 446 #ifdef MPLS 447 case ETHERTYPE_MPLS: 448 case ETHERTYPE_MPLS_MCAST: 449 input = mpls_input; 450 break; 451 #endif 452 #if NBPE > 0 453 case ETHERTYPE_PBB: 454 bpe_input(ifp, m); 455 return (1); 456 #endif 457 default: 458 goto dropanyway; 459 } 460 461 m_adj(m, sizeof(*eh)); 462 (*input)(ifp, m); 463 return (1); 464 dropanyway: 465 m_freem(m); 466 return (1); 467 } 468 469 /* 470 * Convert Ethernet address to printable (loggable) representation. 471 */ 472 static char digits[] = "0123456789abcdef"; 473 char * 474 ether_sprintf(u_char *ap) 475 { 476 int i; 477 static char etherbuf[ETHER_ADDR_LEN * 3]; 478 char *cp = etherbuf; 479 480 for (i = 0; i < ETHER_ADDR_LEN; i++) { 481 *cp++ = digits[*ap >> 4]; 482 *cp++ = digits[*ap++ & 0xf]; 483 *cp++ = ':'; 484 } 485 *--cp = 0; 486 return (etherbuf); 487 } 488 489 /* 490 * Generate a (hopefully) acceptable MAC address, if asked. 491 */ 492 void 493 ether_fakeaddr(struct ifnet *ifp) 494 { 495 static int unit; 496 int rng = arc4random(); 497 498 /* Non-multicast; locally administered address */ 499 ((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe; 500 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1; 501 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xba; 502 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf); 503 ((struct arpcom *)ifp)->ac_enaddr[4] = rng; 504 ((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8; 505 } 506 507 /* 508 * Perform common duties while attaching to interface list 509 */ 510 void 511 ether_ifattach(struct ifnet *ifp) 512 { 513 struct arpcom *ac = (struct arpcom *)ifp; 514 515 /* 516 * Any interface which provides a MAC address which is obviously 517 * invalid gets whacked, so that users will notice. 518 */ 519 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) 520 ether_fakeaddr(ifp); 521 522 ifp->if_type = IFT_ETHER; 523 ifp->if_addrlen = ETHER_ADDR_LEN; 524 ifp->if_hdrlen = ETHER_HDR_LEN; 525 ifp->if_mtu = ETHERMTU; 526 if (ifp->if_output == NULL) 527 ifp->if_output = ether_output; 528 ifp->if_rtrequest = ether_rtrequest; 529 530 if_ih_insert(ifp, ether_input, NULL); 531 532 if (ifp->if_hardmtu == 0) 533 ifp->if_hardmtu = ETHERMTU; 534 535 if_alloc_sadl(ifp); 536 memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen); 537 LIST_INIT(&ac->ac_multiaddrs); 538 #if NBPFILTER > 0 539 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN); 540 #endif 541 } 542 543 void 544 ether_ifdetach(struct ifnet *ifp) 545 { 546 struct arpcom *ac = (struct arpcom *)ifp; 547 struct ether_multi *enm; 548 549 /* Undo pseudo-driver changes. */ 550 if_deactivate(ifp); 551 552 if_ih_remove(ifp, ether_input, NULL); 553 554 KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); 555 556 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 557 enm != NULL; 558 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 559 LIST_REMOVE(enm, enm_list); 560 free(enm, M_IFMADDR, sizeof *enm); 561 } 562 } 563 564 #if 0 565 /* 566 * This is for reference. We have table-driven versions of the 567 * crc32 generators, which are faster than the double-loop. 568 */ 569 u_int32_t __pure 570 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 571 { 572 u_int32_t c, carry; 573 size_t i, j; 574 575 for (i = 0; i < len; i++) { 576 c = buf[i]; 577 for (j = 0; j < 8; j++) { 578 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); 579 crc >>= 1; 580 c >>= 1; 581 if (carry) 582 crc = (crc ^ ETHER_CRC_POLY_LE); 583 } 584 } 585 586 return (crc); 587 } 588 589 u_int32_t __pure 590 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len) 591 { 592 u_int32_t c, carry; 593 size_t i, j; 594 595 for (i = 0; i < len; i++) { 596 c = buf[i]; 597 for (j = 0; j < 8; j++) { 598 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); 599 crc <<= 1; 600 c >>= 1; 601 if (carry) 602 crc = (crc ^ ETHER_CRC_POLY_BE) | carry; 603 } 604 } 605 606 return (crc); 607 } 608 #else 609 u_int32_t __pure 610 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len) 611 { 612 static const u_int32_t crctab[] = { 613 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 614 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 615 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 616 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 617 }; 618 size_t i; 619 620 for (i = 0; i < len; i++) { 621 crc ^= buf[i]; 622 crc = (crc >> 4) ^ crctab[crc & 0xf]; 623 crc = (crc >> 4) ^ crctab[crc & 0xf]; 624 } 625 626 return (crc); 627 } 628 629 u_int32_t __pure 630 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len) 631 { 632 static const u_int8_t rev[] = { 633 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 634 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf 635 }; 636 static const u_int32_t crctab[] = { 637 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 638 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 639 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 640 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd 641 }; 642 size_t i; 643 u_int8_t data; 644 645 for (i = 0; i < len; i++) { 646 data = buf[i]; 647 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]]; 648 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]]; 649 } 650 651 return (crc); 652 } 653 #endif 654 655 u_int32_t 656 ether_crc32_le(const u_int8_t *buf, size_t len) 657 { 658 return ether_crc32_le_update(0xffffffff, buf, len); 659 } 660 661 u_int32_t 662 ether_crc32_be(const u_int8_t *buf, size_t len) 663 { 664 return ether_crc32_be_update(0xffffffff, buf, len); 665 } 666 667 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] = 668 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 669 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] = 670 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 671 672 #ifdef INET6 673 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] = 674 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 675 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] = 676 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 677 #endif 678 679 /* 680 * Convert a sockaddr into an Ethernet address or range of Ethernet 681 * addresses. 682 */ 683 int 684 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN], 685 u_int8_t addrhi[ETHER_ADDR_LEN]) 686 { 687 struct sockaddr_in *sin; 688 #ifdef INET6 689 struct sockaddr_in6 *sin6; 690 #endif /* INET6 */ 691 692 switch (sa->sa_family) { 693 694 case AF_UNSPEC: 695 memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN); 696 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 697 break; 698 699 case AF_INET: 700 sin = satosin(sa); 701 if (sin->sin_addr.s_addr == INADDR_ANY) { 702 /* 703 * An IP address of INADDR_ANY means listen to 704 * or stop listening to all of the Ethernet 705 * multicast addresses used for IP. 706 * (This is for the sake of IP multicast routers.) 707 */ 708 memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN); 709 memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN); 710 } else { 711 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 712 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 713 } 714 break; 715 #ifdef INET6 716 case AF_INET6: 717 sin6 = satosin6(sa); 718 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 719 /* 720 * An IP6 address of 0 means listen to or stop 721 * listening to all of the Ethernet multicast 722 * address used for IP6. 723 * 724 * (This might not be healthy, given IPv6's reliance on 725 * multicast for things like neighbor discovery. 726 * Perhaps initializing all-nodes, solicited nodes, and 727 * possibly all-routers for this interface afterwards 728 * is not a bad idea.) 729 */ 730 731 memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN); 732 memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN); 733 } else { 734 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 735 memcpy(addrhi, addrlo, ETHER_ADDR_LEN); 736 } 737 break; 738 #endif 739 740 default: 741 return (EAFNOSUPPORT); 742 } 743 return (0); 744 } 745 746 /* 747 * Add an Ethernet multicast address or range of addresses to the list for a 748 * given interface. 749 */ 750 int 751 ether_addmulti(struct ifreq *ifr, struct arpcom *ac) 752 { 753 struct ether_multi *enm; 754 u_char addrlo[ETHER_ADDR_LEN]; 755 u_char addrhi[ETHER_ADDR_LEN]; 756 int s = splnet(), error; 757 758 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 759 if (error != 0) { 760 splx(s); 761 return (error); 762 } 763 764 /* 765 * Verify that we have valid Ethernet multicast addresses. 766 */ 767 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 768 splx(s); 769 return (EINVAL); 770 } 771 /* 772 * See if the address range is already in the list. 773 */ 774 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 775 if (enm != NULL) { 776 /* 777 * Found it; just increment the reference count. 778 */ 779 ++enm->enm_refcount; 780 splx(s); 781 return (0); 782 } 783 /* 784 * New address or range; malloc a new multicast record 785 * and link it into the interface's multicast list. 786 */ 787 enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 788 if (enm == NULL) { 789 splx(s); 790 return (ENOBUFS); 791 } 792 memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN); 793 memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN); 794 enm->enm_refcount = 1; 795 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 796 ac->ac_multicnt++; 797 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 798 ac->ac_multirangecnt++; 799 splx(s); 800 /* 801 * Return ENETRESET to inform the driver that the list has changed 802 * and its reception filter should be adjusted accordingly. 803 */ 804 return (ENETRESET); 805 } 806 807 /* 808 * Delete a multicast address record. 809 */ 810 int 811 ether_delmulti(struct ifreq *ifr, struct arpcom *ac) 812 { 813 struct ether_multi *enm; 814 u_char addrlo[ETHER_ADDR_LEN]; 815 u_char addrhi[ETHER_ADDR_LEN]; 816 int s = splnet(), error; 817 818 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 819 if (error != 0) { 820 splx(s); 821 return (error); 822 } 823 824 /* 825 * Look up the address in our list. 826 */ 827 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 828 if (enm == NULL) { 829 splx(s); 830 return (ENXIO); 831 } 832 if (--enm->enm_refcount != 0) { 833 /* 834 * Still some claims to this record. 835 */ 836 splx(s); 837 return (0); 838 } 839 /* 840 * No remaining claims to this record; unlink and free it. 841 */ 842 LIST_REMOVE(enm, enm_list); 843 free(enm, M_IFMADDR, sizeof *enm); 844 ac->ac_multicnt--; 845 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 846 ac->ac_multirangecnt--; 847 splx(s); 848 /* 849 * Return ENETRESET to inform the driver that the list has changed 850 * and its reception filter should be adjusted accordingly. 851 */ 852 return (ENETRESET); 853 } 854