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