xref: /openbsd-src/sys/net/if_ethersubr.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$OpenBSD: if_ethersubr.c,v 1.259 2019/02/20 00:03:15 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 #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 == NULL)
239 			senderr(EHOSTUNREACH);
240 
241 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
242 			senderr(ENETUNREACH);
243 
244 		dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
245 		    rt->rt_gateway : rt_key(rt);
246 
247 		switch (dst->sa_family) {
248 		case AF_LINK:
249 			if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost))
250 				senderr(EHOSTUNREACH);
251 			memcpy(eh->ether_dhost, LLADDR(satosdl(dst)),
252 			    sizeof(eh->ether_dhost));
253 			break;
254 #ifdef INET6
255 		case AF_INET6:
256 			error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
257 			if (error)
258 				return (error);
259 			break;
260 #endif
261 		case AF_INET:
262 			error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
263 			if (error)
264 				return (error);
265 			break;
266 		default:
267 			senderr(EHOSTUNREACH);
268 		}
269 		/* XXX handling for simplex devices in case of M/BCAST ?? */
270 		if (m->m_flags & (M_BCAST | M_MCAST))
271 			eh->ether_type = htons(ETHERTYPE_MPLS_MCAST);
272 		else
273 			eh->ether_type = htons(ETHERTYPE_MPLS);
274 		break;
275 #endif /* MPLS */
276 	case pseudo_AF_HDRCMPLT:
277 		/* take the whole header from the sa */
278 		memcpy(eh, dst->sa_data, sizeof(*eh));
279 		return (0);
280 
281 	case AF_UNSPEC:
282 		/* take the dst and type from the sa, but get src below */
283 		memcpy(eh, dst->sa_data, sizeof(*eh));
284 		break;
285 
286 	default:
287 		printf("%s: can't handle af%d\n", ifp->if_xname, af);
288 		senderr(EAFNOSUPPORT);
289 	}
290 
291 	memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
292 
293 	return (0);
294 
295 bad:
296 	m_freem(m);
297 	return (error);
298 }
299 
300 struct mbuf*
301 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
302     struct rtentry *rt, int *errorp)
303 {
304 	struct ether_header eh;
305 	int error;
306 
307 	error = ether_resolve(ifp, m, dst, rt, &eh);
308 	switch (error) {
309 	case 0:
310 		break;
311 	case EAGAIN:
312 		error = 0;
313 	default:
314 		*errorp = error;
315 		return (NULL);
316 	}
317 
318 	m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT);
319 	if (m == NULL) {
320 		*errorp = ENOBUFS;
321 		return (NULL);
322 	}
323 
324 	m_adj(m, ETHER_ALIGN);
325 	memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh));
326 
327 	return (m);
328 }
329 
330 int
331 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
332     struct rtentry *rt)
333 {
334 	int error;
335 
336 	m = ether_encap(ifp, m, dst, rt, &error);
337 	if (m == NULL)
338 		return (error);
339 
340 	return (if_enqueue(ifp, m));
341 }
342 
343 /*
344  * Process a received Ethernet packet;
345  * the packet is in the mbuf chain m without
346  * the ether header, which is provided separately.
347  */
348 int
349 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
350 {
351 	struct ether_header *eh;
352 	void (*input)(struct ifnet *, struct mbuf *);
353 	u_int16_t etype;
354 	struct arpcom *ac;
355 
356 	/* Drop short frames */
357 	if (m->m_len < ETHER_HDR_LEN)
358 		goto dropanyway;
359 
360 	ac = (struct arpcom *)ifp;
361 	eh = mtod(m, struct ether_header *);
362 
363 	/* Is the packet for us? */
364 	if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) {
365 
366 		/* If not, it must be multicast or broadcast to go further */
367 		if (!ETHER_IS_MULTICAST(eh->ether_dhost))
368 			goto dropanyway;
369 
370 		/*
371 		 * If this is not a simplex interface, drop the packet
372 		 * if it came from us.
373 		 */
374 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
375 			if (memcmp(ac->ac_enaddr, eh->ether_shost,
376 			    ETHER_ADDR_LEN) == 0)
377 				goto dropanyway;
378 		}
379 
380 		if (memcmp(etherbroadcastaddr, eh->ether_dhost,
381 		    ETHER_ADDR_LEN) == 0)
382 			m->m_flags |= M_BCAST;
383 		else
384 			m->m_flags |= M_MCAST;
385 		ifp->if_imcasts++;
386 	}
387 
388 	/*
389 	 * HW vlan tagged packets that were not collected by vlan(4) must
390 	 * be dropped now.
391 	 */
392 	if (m->m_flags & M_VLANTAG)
393 		goto dropanyway;
394 
395 	etype = ntohs(eh->ether_type);
396 
397 	switch (etype) {
398 	case ETHERTYPE_IP:
399 		input = ipv4_input;
400 		break;
401 
402 	case ETHERTYPE_ARP:
403 		if (ifp->if_flags & IFF_NOARP)
404 			goto dropanyway;
405 		input = arpinput;
406 		break;
407 
408 	case ETHERTYPE_REVARP:
409 		if (ifp->if_flags & IFF_NOARP)
410 			goto dropanyway;
411 		input = revarpinput;
412 		break;
413 
414 #ifdef INET6
415 	/*
416 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
417 	 */
418 	case ETHERTYPE_IPV6:
419 		input = ipv6_input;
420 		break;
421 #endif /* INET6 */
422 #if NPPPOE > 0 || defined(PIPEX)
423 	case ETHERTYPE_PPPOEDISC:
424 	case ETHERTYPE_PPPOE:
425 		if (m->m_flags & (M_MCAST | M_BCAST))
426 			goto dropanyway;
427 #ifdef PIPEX
428 		if (pipex_enable) {
429 			struct pipex_session *session;
430 
431 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
432 				pipex_pppoe_input(m, session);
433 				return (1);
434 			}
435 		}
436 #endif
437 		if (etype == ETHERTYPE_PPPOEDISC)
438 			niq_enqueue(&pppoediscinq, m);
439 		else
440 			niq_enqueue(&pppoeinq, m);
441 		return (1);
442 #endif
443 #ifdef MPLS
444 	case ETHERTYPE_MPLS:
445 	case ETHERTYPE_MPLS_MCAST:
446 		input = mpls_input;
447 		break;
448 #endif
449 #if NBPE > 0
450 	case ETHERTYPE_PBB:
451 		bpe_input(ifp, m);
452 		return (1);
453 #endif
454 	default:
455 		goto dropanyway;
456 	}
457 
458 	m_adj(m, sizeof(*eh));
459 	(*input)(ifp, m);
460 	return (1);
461 dropanyway:
462 	m_freem(m);
463 	return (1);
464 }
465 
466 /*
467  * Convert Ethernet address to printable (loggable) representation.
468  */
469 static char digits[] = "0123456789abcdef";
470 char *
471 ether_sprintf(u_char *ap)
472 {
473 	int i;
474 	static char etherbuf[ETHER_ADDR_LEN * 3];
475 	char *cp = etherbuf;
476 
477 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
478 		*cp++ = digits[*ap >> 4];
479 		*cp++ = digits[*ap++ & 0xf];
480 		*cp++ = ':';
481 	}
482 	*--cp = 0;
483 	return (etherbuf);
484 }
485 
486 /*
487  * Generate a (hopefully) acceptable MAC address, if asked.
488  */
489 void
490 ether_fakeaddr(struct ifnet *ifp)
491 {
492 	static int unit;
493 	int rng = arc4random();
494 
495 	/* Non-multicast; locally administered address */
496 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
497 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
498 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
499 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
500 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
501 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
502 }
503 
504 /*
505  * Perform common duties while attaching to interface list
506  */
507 void
508 ether_ifattach(struct ifnet *ifp)
509 {
510 	struct arpcom *ac = (struct arpcom *)ifp;
511 
512 	/*
513 	 * Any interface which provides a MAC address which is obviously
514 	 * invalid gets whacked, so that users will notice.
515 	 */
516 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
517 		ether_fakeaddr(ifp);
518 
519 	ifp->if_type = IFT_ETHER;
520 	ifp->if_addrlen = ETHER_ADDR_LEN;
521 	ifp->if_hdrlen = ETHER_HDR_LEN;
522 	ifp->if_mtu = ETHERMTU;
523 	if (ifp->if_output == NULL)
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