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