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