xref: /openbsd-src/sys/net/if_ethersubr.c (revision c020cf82e0cc147236f01a8dca7052034cf9d30d)
1 /*	$OpenBSD: if_ethersubr.c,v 1.261 2019/11/24 07:50:55 claudio 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 	if (rt == NULL)
174 		return;
175 
176 	switch (rt_key(rt)->sa_family) {
177 	case AF_INET:
178 		arp_rtrequest(ifp, req, rt);
179 		break;
180 #ifdef INET6
181 	case AF_INET6:
182 		nd6_rtrequest(ifp, req, rt);
183 		break;
184 #endif
185 	default:
186 		break;
187 	}
188 }
189 
190 int
191 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
192     struct rtentry *rt, struct ether_header *eh)
193 {
194 	struct arpcom *ac = (struct arpcom *)ifp;
195 	sa_family_t af = dst->sa_family;
196 	int error = 0;
197 
198 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
199 		senderr(ENETDOWN);
200 
201 	KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
202 		af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
203 
204 #ifdef DIAGNOSTIC
205 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
206 		printf("%s: trying to send packet on wrong domain. "
207 		    "if %d vs. mbuf %d\n", ifp->if_xname,
208 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
209 	}
210 #endif
211 
212 	switch (af) {
213 	case AF_INET:
214 		error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
215 		if (error)
216 			return (error);
217 		eh->ether_type = htons(ETHERTYPE_IP);
218 
219 		/* If broadcasting on a simplex interface, loopback a copy */
220 		if (ISSET(m->m_flags, M_BCAST) &&
221 		    ISSET(ifp->if_flags, IFF_SIMPLEX) &&
222 		    !m->m_pkthdr.pf.routed) {
223 			struct mbuf *mcopy;
224 
225 			/* XXX Should we input an unencrypted IPsec packet? */
226 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
227 			if (mcopy != NULL)
228 				if_input_local(ifp, mcopy, af);
229 		}
230 		break;
231 #ifdef INET6
232 	case AF_INET6:
233 		error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
234 		if (error)
235 			return (error);
236 		eh->ether_type = htons(ETHERTYPE_IPV6);
237 		break;
238 #endif
239 #ifdef MPLS
240 	case AF_MPLS:
241 		if (rt == NULL)
242 			senderr(EHOSTUNREACH);
243 
244 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
245 			senderr(ENETUNREACH);
246 
247 		dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
248 		    rt->rt_gateway : rt_key(rt);
249 
250 		switch (dst->sa_family) {
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 (ETHER_IS_BROADCAST(eh->ether_dhost))
384 			m->m_flags |= M_BCAST;
385 		else
386 			m->m_flags |= M_MCAST;
387 		ifp->if_imcasts++;
388 	}
389 
390 	/*
391 	 * HW vlan tagged packets that were not collected by vlan(4) must
392 	 * be dropped now.
393 	 */
394 	if (m->m_flags & M_VLANTAG)
395 		goto dropanyway;
396 
397 	etype = ntohs(eh->ether_type);
398 
399 	switch (etype) {
400 	case ETHERTYPE_IP:
401 		input = ipv4_input;
402 		break;
403 
404 	case ETHERTYPE_ARP:
405 		if (ifp->if_flags & IFF_NOARP)
406 			goto dropanyway;
407 		input = arpinput;
408 		break;
409 
410 	case ETHERTYPE_REVARP:
411 		if (ifp->if_flags & IFF_NOARP)
412 			goto dropanyway;
413 		input = revarpinput;
414 		break;
415 
416 #ifdef INET6
417 	/*
418 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
419 	 */
420 	case ETHERTYPE_IPV6:
421 		input = ipv6_input;
422 		break;
423 #endif /* INET6 */
424 #if NPPPOE > 0 || defined(PIPEX)
425 	case ETHERTYPE_PPPOEDISC:
426 	case ETHERTYPE_PPPOE:
427 		if (m->m_flags & (M_MCAST | M_BCAST))
428 			goto dropanyway;
429 #ifdef PIPEX
430 		if (pipex_enable) {
431 			struct pipex_session *session;
432 
433 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
434 				pipex_pppoe_input(m, session);
435 				return (1);
436 			}
437 		}
438 #endif
439 		if (etype == ETHERTYPE_PPPOEDISC)
440 			niq_enqueue(&pppoediscinq, m);
441 		else
442 			niq_enqueue(&pppoeinq, m);
443 		return (1);
444 #endif
445 #ifdef MPLS
446 	case ETHERTYPE_MPLS:
447 	case ETHERTYPE_MPLS_MCAST:
448 		input = mpls_input;
449 		break;
450 #endif
451 #if NBPE > 0
452 	case ETHERTYPE_PBB:
453 		bpe_input(ifp, m);
454 		return (1);
455 #endif
456 	default:
457 		goto dropanyway;
458 	}
459 
460 	m_adj(m, sizeof(*eh));
461 	(*input)(ifp, m);
462 	return (1);
463 dropanyway:
464 	m_freem(m);
465 	return (1);
466 }
467 
468 /*
469  * Convert Ethernet address to printable (loggable) representation.
470  */
471 static char digits[] = "0123456789abcdef";
472 char *
473 ether_sprintf(u_char *ap)
474 {
475 	int i;
476 	static char etherbuf[ETHER_ADDR_LEN * 3];
477 	char *cp = etherbuf;
478 
479 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
480 		*cp++ = digits[*ap >> 4];
481 		*cp++ = digits[*ap++ & 0xf];
482 		*cp++ = ':';
483 	}
484 	*--cp = 0;
485 	return (etherbuf);
486 }
487 
488 /*
489  * Generate a (hopefully) acceptable MAC address, if asked.
490  */
491 void
492 ether_fakeaddr(struct ifnet *ifp)
493 {
494 	static int unit;
495 	int rng = arc4random();
496 
497 	/* Non-multicast; locally administered address */
498 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
499 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
500 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
501 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
502 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
503 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
504 }
505 
506 /*
507  * Perform common duties while attaching to interface list
508  */
509 void
510 ether_ifattach(struct ifnet *ifp)
511 {
512 	struct arpcom *ac = (struct arpcom *)ifp;
513 
514 	/*
515 	 * Any interface which provides a MAC address which is obviously
516 	 * invalid gets whacked, so that users will notice.
517 	 */
518 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
519 		ether_fakeaddr(ifp);
520 
521 	ifp->if_type = IFT_ETHER;
522 	ifp->if_addrlen = ETHER_ADDR_LEN;
523 	ifp->if_hdrlen = ETHER_HDR_LEN;
524 	ifp->if_mtu = ETHERMTU;
525 	if (ifp->if_output == NULL)
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