xref: /openbsd-src/sys/net/if_ethersubr.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: if_ethersubr.c,v 1.239 2016/07/12 09:33:13 mpi Exp $	*/
2 /*	$NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1982, 1989, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
62  */
63 
64 /*
65 %%% portions-copyright-nrl-95
66 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
67 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
68 Reserved. All rights under this copyright have been assigned to the US
69 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
70 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
71 software.
72 You should have received a copy of the license with this software. If you
73 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
74 */
75 
76 #include "bpfilter.h"
77 
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/mbuf.h>
83 #include <sys/protosw.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/errno.h>
87 #include <sys/syslog.h>
88 #include <sys/timeout.h>
89 
90 #include <net/if.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
93 #include <net/if_llc.h>
94 #include <net/if_dl.h>
95 #include <net/if_media.h>
96 #include <net/if_types.h>
97 
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #include <netinet/ip_ipsp.h>
101 
102 #if NBPFILTER > 0
103 #include <net/bpf.h>
104 #endif
105 
106 #include "pppoe.h"
107 #if NPPPOE > 0
108 #include <net/if_pppoe.h>
109 #endif
110 
111 #ifdef INET6
112 #include <netinet6/in6_var.h>
113 #include <netinet6/nd6.h>
114 #endif
115 
116 #ifdef PIPEX
117 #include <net/pipex.h>
118 #endif
119 
120 #ifdef MPLS
121 #include <netmpls/mpls.h>
122 #endif /* MPLS */
123 
124 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
125     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
126 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
127     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
128 #define senderr(e) { error = (e); goto bad;}
129 
130 int
131 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
132 {
133 	struct ifreq *ifr = (struct ifreq *)data;
134 	int error = 0;
135 
136 	switch (cmd) {
137 	case SIOCSIFADDR:
138 		break;
139 
140 	case SIOCSIFMTU:
141 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
142 			error = EINVAL;
143 		else
144 			ifp->if_mtu = ifr->ifr_mtu;
145 		break;
146 
147 	case SIOCADDMULTI:
148 	case SIOCDELMULTI:
149 		if (ifp->if_flags & IFF_MULTICAST) {
150 			error = (cmd == SIOCADDMULTI) ?
151 			    ether_addmulti(ifr, arp) :
152 			    ether_delmulti(ifr, arp);
153 		} else
154 			error = ENOTTY;
155 		break;
156 
157 	default:
158 		error = ENOTTY;
159 	}
160 
161 	return (error);
162 }
163 
164 
165 void
166 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
167 {
168 	switch (rt_key(rt)->sa_family) {
169 	case AF_INET:
170 		arp_rtrequest(ifp, req, rt);
171 		break;
172 #ifdef INET6
173 	case AF_INET6:
174 		nd6_rtrequest(ifp, req, rt);
175 		break;
176 #endif
177 	default:
178 		break;
179 	}
180 }
181 /*
182  * Ethernet output routine.
183  * Encapsulate a packet of type family for the local net.
184  * Assumes that ifp is actually pointer to arpcom structure.
185  */
186 int
187 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
188     struct rtentry *rt)
189 {
190 	u_int16_t etype;
191 	u_char edst[ETHER_ADDR_LEN];
192 	u_char *esrc;
193 	struct mbuf *mcopy = NULL;
194 	struct ether_header *eh;
195 	struct arpcom *ac = (struct arpcom *)ifp;
196 	sa_family_t af = dst->sa_family;
197 	int error = 0;
198 
199 	KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
200 		af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
201 
202 #ifdef DIAGNOSTIC
203 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
204 		printf("%s: trying to send packet on wrong domain. "
205 		    "if %d vs. mbuf %d\n", ifp->if_xname,
206 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
207 	}
208 #endif
209 
210 	esrc = ac->ac_enaddr;
211 
212 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
213 		senderr(ENETDOWN);
214 
215 	switch (af) {
216 	case AF_INET:
217 		error = arpresolve(ifp, rt, m, dst, edst);
218 		if (error)
219 			return (error == EAGAIN ? 0 : error);
220 		/* If broadcasting on a simplex interface, loopback a copy */
221 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
222 		    !m->m_pkthdr.pf.routed)
223 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
224 		etype = htons(ETHERTYPE_IP);
225 		break;
226 #ifdef INET6
227 	case AF_INET6:
228 		error = nd6_resolve(ifp, rt, m, dst, edst);
229 		if (error)
230 			return (error == EAGAIN ? 0 : error);
231 		etype = htons(ETHERTYPE_IPV6);
232 		break;
233 #endif
234 #ifdef MPLS
235        case AF_MPLS:
236 		if (rt)
237 			dst = rt_key(rt);
238 		else
239 			senderr(EHOSTUNREACH);
240 
241 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
242 			senderr(ENETUNREACH);
243 
244 		switch (dst->sa_family) {
245 			case AF_LINK:
246 				if (satosdl(dst)->sdl_alen < sizeof(edst))
247 					senderr(EHOSTUNREACH);
248 				memcpy(edst, LLADDR(satosdl(dst)),
249 				    sizeof(edst));
250 				break;
251 			case AF_INET:
252 			case AF_MPLS:
253 				error = arpresolve(ifp, rt, m, dst, edst);
254 				if (error)
255 					return (error == EAGAIN ? 0 : error);
256 				break;
257 			default:
258 				senderr(EHOSTUNREACH);
259 		}
260 		/* XXX handling for simplex devices in case of M/BCAST ?? */
261 		if (m->m_flags & (M_BCAST | M_MCAST))
262 			etype = htons(ETHERTYPE_MPLS_MCAST);
263 		else
264 			etype = htons(ETHERTYPE_MPLS);
265 		break;
266 #endif /* MPLS */
267 	case pseudo_AF_HDRCMPLT:
268 		eh = (struct ether_header *)dst->sa_data;
269 		esrc = eh->ether_shost;
270 		/* FALLTHROUGH */
271 
272 	case AF_UNSPEC:
273 		eh = (struct ether_header *)dst->sa_data;
274 		memcpy(edst, eh->ether_dhost, sizeof(edst));
275 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
276 		etype = eh->ether_type;
277 		break;
278 
279 	default:
280 		printf("%s: can't handle af%d\n", ifp->if_xname,
281 			dst->sa_family);
282 		senderr(EAFNOSUPPORT);
283 	}
284 
285 	/* XXX Should we feed-back an unencrypted IPsec packet ? */
286 	if (mcopy)
287 		if_input_local(ifp, mcopy, dst->sa_family);
288 
289 	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
290 	if (m == NULL)
291 		return (ENOBUFS);
292 	eh = mtod(m, struct ether_header *);
293 	eh->ether_type = etype;
294 	memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost));
295 	memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
296 
297 	return (if_enqueue(ifp, m));
298 bad:
299 	m_freem(m);
300 	return (error);
301 }
302 
303 /*
304  * Process a received Ethernet packet;
305  * the packet is in the mbuf chain m without
306  * the ether header, which is provided separately.
307  */
308 int
309 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
310 {
311 	struct ether_header *eh;
312 	struct niqueue *inq;
313 	u_int16_t etype;
314 	int llcfound = 0;
315 	struct llc *l;
316 	struct arpcom *ac;
317 #if NPPPOE > 0
318 	struct ether_header *eh_tmp;
319 #endif
320 
321 	ac = (struct arpcom *)ifp;
322 	eh = mtod(m, struct ether_header *);
323 	m_adj(m, ETHER_HDR_LEN);
324 
325 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
326 		/*
327 		 * If this is not a simplex interface, drop the packet
328 		 * if it came from us.
329 		 */
330 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
331 			if (memcmp(ac->ac_enaddr, eh->ether_shost,
332 			    ETHER_ADDR_LEN) == 0) {
333 				m_freem(m);
334 				return (1);
335 			}
336 		}
337 
338 		if (memcmp(etherbroadcastaddr, eh->ether_dhost,
339 		    sizeof(etherbroadcastaddr)) == 0)
340 			m->m_flags |= M_BCAST;
341 		else
342 			m->m_flags |= M_MCAST;
343 		ifp->if_imcasts++;
344 	}
345 
346 	/*
347 	 * HW vlan tagged packets that were not collected by vlan(4) must
348 	 * be dropped now.
349 	 */
350 	if (m->m_flags & M_VLANTAG) {
351 		m_freem(m);
352 		return (1);
353 	}
354 
355 	/*
356 	 * If packet is unicast, make sure it is for us.  Drop otherwise.
357 	 * This check is required in promiscous mode, and for some hypervisors
358 	 * where the MAC filter is 'best effort' only.
359 	 */
360 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
361 		if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) {
362 			m_freem(m);
363 			return (1);
364 		}
365 	}
366 
367 	etype = ntohs(eh->ether_type);
368 
369 decapsulate:
370 	switch (etype) {
371 	case ETHERTYPE_IP:
372 		inq = &ipintrq;
373 		break;
374 
375 	case ETHERTYPE_ARP:
376 		if (ifp->if_flags & IFF_NOARP)
377 			goto dropanyway;
378 		arpinput(ifp, m);
379 		return (1);
380 
381 	case ETHERTYPE_REVARP:
382 		if (ifp->if_flags & IFF_NOARP)
383 			goto dropanyway;
384 		revarpinput(ifp, m);
385 		return (1);
386 
387 #ifdef INET6
388 	/*
389 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
390 	 */
391 	case ETHERTYPE_IPV6:
392 		inq = &ip6intrq;
393 		break;
394 #endif /* INET6 */
395 #if NPPPOE > 0 || defined(PIPEX)
396 	case ETHERTYPE_PPPOEDISC:
397 	case ETHERTYPE_PPPOE:
398 		if (m->m_flags & (M_MCAST | M_BCAST))
399 			goto dropanyway;
400 		M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
401 		if (m == NULL)
402 			return (1);
403 
404 		eh_tmp = mtod(m, struct ether_header *);
405 		/*
406 		 * danger!
407 		 * eh_tmp and eh may overlap because eh
408 		 * is stolen from the mbuf above.
409 		 */
410 		memmove(eh_tmp, eh, sizeof(struct ether_header));
411 #ifdef PIPEX
412 		if (pipex_enable) {
413 			struct pipex_session *session;
414 
415 			KERNEL_LOCK();
416 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
417 				pipex_pppoe_input(m, session);
418 				KERNEL_UNLOCK();
419 				return (1);
420 			}
421 			KERNEL_UNLOCK();
422 		}
423 #endif
424 		if (etype == ETHERTYPE_PPPOEDISC)
425 			inq = &pppoediscinq;
426 		else
427 			inq = &pppoeinq;
428 		break;
429 #endif
430 #ifdef MPLS
431 	case ETHERTYPE_MPLS:
432 	case ETHERTYPE_MPLS_MCAST:
433 		mpls_input(m);
434 		return (1);
435 #endif
436 	default:
437 		if (llcfound || etype > ETHERMTU)
438 			goto dropanyway;
439 		llcfound = 1;
440 		l = mtod(m, struct llc *);
441 		switch (l->llc_dsap) {
442 		case LLC_SNAP_LSAP:
443 			if (l->llc_control == LLC_UI &&
444 			    l->llc_dsap == LLC_SNAP_LSAP &&
445 			    l->llc_ssap == LLC_SNAP_LSAP) {
446 				/* SNAP */
447 				if (m->m_pkthdr.len > etype)
448 					m_adj(m, etype - m->m_pkthdr.len);
449 				m_adj(m, 6);
450 				M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
451 				if (m == NULL)
452 					return (1);
453 				*mtod(m, struct ether_header *) = *eh;
454 				goto decapsulate;
455 			}
456 		default:
457 			goto dropanyway;
458 		}
459 	}
460 
461 	niq_enqueue(inq, 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 	ifp->if_output = ether_output;
526 	ifp->if_rtrequest = ether_rtrequest;
527 
528 	if_ih_insert(ifp, ether_input, NULL);
529 
530 	if (ifp->if_hardmtu == 0)
531 		ifp->if_hardmtu = ETHERMTU;
532 
533 	if_alloc_sadl(ifp);
534 	memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
535 	LIST_INIT(&ac->ac_multiaddrs);
536 #if NBPFILTER > 0
537 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
538 #endif
539 }
540 
541 void
542 ether_ifdetach(struct ifnet *ifp)
543 {
544 	struct arpcom *ac = (struct arpcom *)ifp;
545 	struct ether_multi *enm;
546 
547 	/* Undo pseudo-driver changes. */
548 	if_deactivate(ifp);
549 
550 	if_ih_remove(ifp, ether_input, NULL);
551 
552 	KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs));
553 
554 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
555 	    enm != NULL;
556 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
557 		LIST_REMOVE(enm, enm_list);
558 		free(enm, M_IFMADDR, sizeof *enm);
559 	}
560 }
561 
562 #if 0
563 /*
564  * This is for reference.  We have table-driven versions of the
565  * crc32 generators, which are faster than the double-loop.
566  */
567 u_int32_t __pure
568 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
569 {
570 	u_int32_t c, carry;
571 	size_t i, j;
572 
573 	for (i = 0; i < len; i++) {
574 		c = buf[i];
575 		for (j = 0; j < 8; j++) {
576 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
577 			crc >>= 1;
578 			c >>= 1;
579 			if (carry)
580 				crc = (crc ^ ETHER_CRC_POLY_LE);
581 		}
582 	}
583 
584 	return (crc);
585 }
586 
587 u_int32_t __pure
588 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
589 {
590 	u_int32_t c, carry;
591 	size_t i, j;
592 
593 	for (i = 0; i < len; i++) {
594 		c = buf[i];
595 		for (j = 0; j < 8; j++) {
596 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
597 			crc <<= 1;
598 			c >>= 1;
599 			if (carry)
600 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
601 		}
602 	}
603 
604 	return (crc);
605 }
606 #else
607 u_int32_t __pure
608 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
609 {
610 	static const u_int32_t crctab[] = {
611 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
612 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
613 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
614 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
615 	};
616 	size_t i;
617 
618 	for (i = 0; i < len; i++) {
619 		crc ^= buf[i];
620 		crc = (crc >> 4) ^ crctab[crc & 0xf];
621 		crc = (crc >> 4) ^ crctab[crc & 0xf];
622 	}
623 
624 	return (crc);
625 }
626 
627 u_int32_t __pure
628 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
629 {
630 	static const u_int8_t rev[] = {
631 		0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
632 		0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
633 	};
634 	static const u_int32_t crctab[] = {
635 		0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
636 		0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
637 		0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
638 		0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
639 	};
640 	size_t i;
641 	u_int8_t data;
642 
643 	for (i = 0; i < len; i++) {
644 		data = buf[i];
645 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
646 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
647 	}
648 
649 	return (crc);
650 }
651 #endif
652 
653 u_int32_t
654 ether_crc32_le(const u_int8_t *buf, size_t len)
655 {
656 	return ether_crc32_le_update(0xffffffff, buf, len);
657 }
658 
659 u_int32_t
660 ether_crc32_be(const u_int8_t *buf, size_t len)
661 {
662 	return ether_crc32_be_update(0xffffffff, buf, len);
663 }
664 
665 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
666     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
667 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
668     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
669 
670 #ifdef INET6
671 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
672     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
673 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
674     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
675 #endif
676 
677 /*
678  * Convert a sockaddr into an Ethernet address or range of Ethernet
679  * addresses.
680  */
681 int
682 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
683     u_int8_t addrhi[ETHER_ADDR_LEN])
684 {
685 	struct sockaddr_in *sin;
686 #ifdef INET6
687 	struct sockaddr_in6 *sin6;
688 #endif /* INET6 */
689 
690 	switch (sa->sa_family) {
691 
692 	case AF_UNSPEC:
693 		memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
694 		memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
695 		break;
696 
697 	case AF_INET:
698 		sin = satosin(sa);
699 		if (sin->sin_addr.s_addr == INADDR_ANY) {
700 			/*
701 			 * An IP address of INADDR_ANY means listen to
702 			 * or stop listening to all of the Ethernet
703 			 * multicast addresses used for IP.
704 			 * (This is for the sake of IP multicast routers.)
705 			 */
706 			memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
707 			memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
708 		} else {
709 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
710 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
711 		}
712 		break;
713 #ifdef INET6
714 	case AF_INET6:
715 		sin6 = satosin6(sa);
716 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
717 			/*
718 			 * An IP6 address of 0 means listen to or stop
719 			 * listening to all of the Ethernet multicast
720 			 * address used for IP6.
721 			 *
722 			 * (This might not be healthy, given IPv6's reliance on
723 			 * multicast for things like neighbor discovery.
724 			 * Perhaps initializing all-nodes, solicited nodes, and
725 			 * possibly all-routers for this interface afterwards
726 			 * is not a bad idea.)
727 			 */
728 
729 			memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
730 			memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
731 		} else {
732 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
733 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
734 		}
735 		break;
736 #endif
737 
738 	default:
739 		return (EAFNOSUPPORT);
740 	}
741 	return (0);
742 }
743 
744 /*
745  * Add an Ethernet multicast address or range of addresses to the list for a
746  * given interface.
747  */
748 int
749 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
750 {
751 	struct ether_multi *enm;
752 	u_char addrlo[ETHER_ADDR_LEN];
753 	u_char addrhi[ETHER_ADDR_LEN];
754 	int s = splnet(), error;
755 
756 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
757 	if (error != 0) {
758 		splx(s);
759 		return (error);
760 	}
761 
762 	/*
763 	 * Verify that we have valid Ethernet multicast addresses.
764 	 */
765 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
766 		splx(s);
767 		return (EINVAL);
768 	}
769 	/*
770 	 * See if the address range is already in the list.
771 	 */
772 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
773 	if (enm != NULL) {
774 		/*
775 		 * Found it; just increment the reference count.
776 		 */
777 		++enm->enm_refcount;
778 		splx(s);
779 		return (0);
780 	}
781 	/*
782 	 * New address or range; malloc a new multicast record
783 	 * and link it into the interface's multicast list.
784 	 */
785 	enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
786 	if (enm == NULL) {
787 		splx(s);
788 		return (ENOBUFS);
789 	}
790 	memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
791 	memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
792 	enm->enm_refcount = 1;
793 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
794 	ac->ac_multicnt++;
795 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
796 		ac->ac_multirangecnt++;
797 	splx(s);
798 	/*
799 	 * Return ENETRESET to inform the driver that the list has changed
800 	 * and its reception filter should be adjusted accordingly.
801 	 */
802 	return (ENETRESET);
803 }
804 
805 /*
806  * Delete a multicast address record.
807  */
808 int
809 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
810 {
811 	struct ether_multi *enm;
812 	u_char addrlo[ETHER_ADDR_LEN];
813 	u_char addrhi[ETHER_ADDR_LEN];
814 	int s = splnet(), error;
815 
816 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
817 	if (error != 0) {
818 		splx(s);
819 		return (error);
820 	}
821 
822 	/*
823 	 * Look up the address in our list.
824 	 */
825 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
826 	if (enm == NULL) {
827 		splx(s);
828 		return (ENXIO);
829 	}
830 	if (--enm->enm_refcount != 0) {
831 		/*
832 		 * Still some claims to this record.
833 		 */
834 		splx(s);
835 		return (0);
836 	}
837 	/*
838 	 * No remaining claims to this record; unlink and free it.
839 	 */
840 	LIST_REMOVE(enm, enm_list);
841 	free(enm, M_IFMADDR, sizeof *enm);
842 	ac->ac_multicnt--;
843 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
844 		ac->ac_multirangecnt--;
845 	splx(s);
846 	/*
847 	 * Return ENETRESET to inform the driver that the list has changed
848 	 * and its reception filter should be adjusted accordingly.
849 	 */
850 	return (ENETRESET);
851 }
852