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