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