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