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