xref: /openbsd/sys/net/if_ethersubr.c (revision 5af055cd)
1 /*	$OpenBSD: if_ethersubr.c,v 1.234 2016/03/01 01:48:14 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 #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 	int error = 0;
197 
198 #ifdef DIAGNOSTIC
199 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
200 		printf("%s: trying to send packet on wrong domain. "
201 		    "if %d vs. mbuf %d\n", ifp->if_xname,
202 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
203 	}
204 #endif
205 
206 	esrc = ac->ac_enaddr;
207 
208 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
209 		senderr(ENETDOWN);
210 
211 	switch (dst->sa_family) {
212 	case AF_INET:
213 		error = arpresolve(ifp, rt, m, dst, edst);
214 		if (error)
215 			return (error == EAGAIN ? 0 : error);
216 		/* If broadcasting on a simplex interface, loopback a copy */
217 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
218 		    !m->m_pkthdr.pf.routed)
219 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
220 		etype = htons(ETHERTYPE_IP);
221 		break;
222 #ifdef INET6
223 	case AF_INET6:
224 		error = nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst);
225 		if (error)
226 			return (error);
227 		etype = htons(ETHERTYPE_IPV6);
228 		break;
229 #endif
230 #ifdef MPLS
231        case AF_MPLS:
232 		if (rt)
233 			dst = rt_key(rt);
234 		else
235 			senderr(EHOSTUNREACH);
236 
237 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
238 			senderr(ENETUNREACH);
239 
240 		switch (dst->sa_family) {
241 			case AF_LINK:
242 				if (satosdl(dst)->sdl_alen < sizeof(edst))
243 					senderr(EHOSTUNREACH);
244 				memcpy(edst, LLADDR(satosdl(dst)),
245 				    sizeof(edst));
246 				break;
247 			case AF_INET:
248 			case AF_MPLS:
249 				error = arpresolve(ifp, rt, m, dst, edst);
250 				if (error)
251 					return (error == EAGAIN ? 0 : error);
252 				break;
253 			default:
254 				senderr(EHOSTUNREACH);
255 		}
256 		/* XXX handling for simplex devices in case of M/BCAST ?? */
257 		if (m->m_flags & (M_BCAST | M_MCAST))
258 			etype = htons(ETHERTYPE_MPLS_MCAST);
259 		else
260 			etype = htons(ETHERTYPE_MPLS);
261 		break;
262 #endif /* MPLS */
263 	case pseudo_AF_HDRCMPLT:
264 		eh = (struct ether_header *)dst->sa_data;
265 		esrc = eh->ether_shost;
266 		/* FALLTHROUGH */
267 
268 	case AF_UNSPEC:
269 		eh = (struct ether_header *)dst->sa_data;
270 		memcpy(edst, eh->ether_dhost, sizeof(edst));
271 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
272 		etype = eh->ether_type;
273 		break;
274 
275 	default:
276 		printf("%s: can't handle af%d\n", ifp->if_xname,
277 			dst->sa_family);
278 		senderr(EAFNOSUPPORT);
279 	}
280 
281 	/* XXX Should we feed-back an unencrypted IPsec packet ? */
282 	if (mcopy)
283 		if_input_local(ifp, mcopy, dst->sa_family);
284 
285 	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
286 	if (m == NULL)
287 		return (ENOBUFS);
288 	eh = mtod(m, struct ether_header *);
289 	eh->ether_type = etype;
290 	memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost));
291 	memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
292 
293 	return (if_enqueue(ifp, m));
294 bad:
295 	m_freem(m);
296 	return (error);
297 }
298 
299 /*
300  * Process a received Ethernet packet;
301  * the packet is in the mbuf chain m without
302  * the ether header, which is provided separately.
303  */
304 int
305 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
306 {
307 	struct ether_header *eh;
308 	struct niqueue *inq;
309 	u_int16_t etype;
310 	int llcfound = 0;
311 	struct llc *l;
312 	struct arpcom *ac;
313 #if NPPPOE > 0
314 	struct ether_header *eh_tmp;
315 #endif
316 
317 	ac = (struct arpcom *)ifp;
318 	eh = mtod(m, struct ether_header *);
319 	m_adj(m, ETHER_HDR_LEN);
320 
321 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
322 		/*
323 		 * If this is not a simplex interface, drop the packet
324 		 * if it came from us.
325 		 */
326 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
327 			if (memcmp(ac->ac_enaddr, eh->ether_shost,
328 			    ETHER_ADDR_LEN) == 0) {
329 				m_freem(m);
330 				return (1);
331 			}
332 		}
333 
334 		if (memcmp(etherbroadcastaddr, eh->ether_dhost,
335 		    sizeof(etherbroadcastaddr)) == 0)
336 			m->m_flags |= M_BCAST;
337 		else
338 			m->m_flags |= M_MCAST;
339 		ifp->if_imcasts++;
340 	}
341 
342 	/*
343 	 * If packet has been filtered by the bpf listener, drop it now
344 	 * also HW vlan tagged packets that were not collected by vlan(4)
345 	 * must be dropped now.
346 	 */
347 	if (m->m_flags & (M_FILDROP | M_VLANTAG)) {
348 		m_freem(m);
349 		return (1);
350 	}
351 
352 	/*
353 	 * If packet is unicast, make sure it is for us.  Drop otherwise.
354 	 * This check is required in promiscous mode, and for some hypervisors
355 	 * where the MAC filter is 'best effort' only.
356 	 */
357 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
358 		if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) {
359 			m_freem(m);
360 			return (1);
361 		}
362 	}
363 
364 	etype = ntohs(eh->ether_type);
365 
366 decapsulate:
367 	switch (etype) {
368 	case ETHERTYPE_IP:
369 		inq = &ipintrq;
370 		break;
371 
372 	case ETHERTYPE_ARP:
373 		if (ifp->if_flags & IFF_NOARP)
374 			goto dropanyway;
375 		arpinput(m);
376 		return (1);
377 
378 	case ETHERTYPE_REVARP:
379 		if (ifp->if_flags & IFF_NOARP)
380 			goto dropanyway;
381 		revarpinput(m);
382 		return (1);
383 
384 #ifdef INET6
385 	/*
386 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
387 	 */
388 	case ETHERTYPE_IPV6:
389 		inq = &ip6intrq;
390 		break;
391 #endif /* INET6 */
392 #if NPPPOE > 0 || defined(PIPEX)
393 	case ETHERTYPE_PPPOEDISC:
394 	case ETHERTYPE_PPPOE:
395 #ifndef PPPOE_SERVER
396 		if (m->m_flags & (M_MCAST | M_BCAST))
397 			goto dropanyway;
398 #endif
399 		M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
400 		if (m == NULL)
401 			return (1);
402 
403 		eh_tmp = mtod(m, struct ether_header *);
404 		/*
405 		 * danger!
406 		 * eh_tmp and eh may overlap because eh
407 		 * is stolen from the mbuf above.
408 		 */
409 		memmove(eh_tmp, eh, sizeof(struct ether_header));
410 #ifdef PIPEX
411 		if (pipex_enable) {
412 			struct pipex_session *session;
413 
414 			KERNEL_LOCK();
415 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
416 				pipex_pppoe_input(m, session);
417 				KERNEL_UNLOCK();
418 				return (1);
419 			}
420 			KERNEL_UNLOCK();
421 		}
422 #endif
423 		if (etype == ETHERTYPE_PPPOEDISC)
424 			inq = &pppoediscinq;
425 		else
426 			inq = &pppoeinq;
427 		break;
428 #endif
429 #ifdef MPLS
430 	case ETHERTYPE_MPLS:
431 	case ETHERTYPE_MPLS_MCAST:
432 		mpls_input(m);
433 		return (1);
434 #endif
435 	default:
436 		if (llcfound || etype > ETHERMTU)
437 			goto dropanyway;
438 		llcfound = 1;
439 		l = mtod(m, struct llc *);
440 		switch (l->llc_dsap) {
441 		case LLC_SNAP_LSAP:
442 			if (l->llc_control == LLC_UI &&
443 			    l->llc_dsap == LLC_SNAP_LSAP &&
444 			    l->llc_ssap == LLC_SNAP_LSAP) {
445 				/* SNAP */
446 				if (m->m_pkthdr.len > etype)
447 					m_adj(m, etype - m->m_pkthdr.len);
448 				m_adj(m, 6);
449 				M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
450 				if (m == NULL)
451 					return (1);
452 				*mtod(m, struct ether_header *) = *eh;
453 				goto decapsulate;
454 			}
455 		default:
456 			goto dropanyway;
457 		}
458 	}
459 
460 	niq_enqueue(inq, m);
461 	return (1);
462 dropanyway:
463 	m_freem(m);
464 	return (1);
465 }
466 
467 /*
468  * Convert Ethernet address to printable (loggable) representation.
469  */
470 static char digits[] = "0123456789abcdef";
471 char *
472 ether_sprintf(u_char *ap)
473 {
474 	int i;
475 	static char etherbuf[ETHER_ADDR_LEN * 3];
476 	char *cp = etherbuf;
477 
478 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
479 		*cp++ = digits[*ap >> 4];
480 		*cp++ = digits[*ap++ & 0xf];
481 		*cp++ = ':';
482 	}
483 	*--cp = 0;
484 	return (etherbuf);
485 }
486 
487 /*
488  * Generate a (hopefully) acceptable MAC address, if asked.
489  */
490 void
491 ether_fakeaddr(struct ifnet *ifp)
492 {
493 	static int unit;
494 	int rng = arc4random();
495 
496 	/* Non-multicast; locally administered address */
497 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
498 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
499 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
500 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
501 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
502 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
503 }
504 
505 /*
506  * Perform common duties while attaching to interface list
507  */
508 void
509 ether_ifattach(struct ifnet *ifp)
510 {
511 	struct arpcom *ac = (struct arpcom *)ifp;
512 
513 	/*
514 	 * Any interface which provides a MAC address which is obviously
515 	 * invalid gets whacked, so that users will notice.
516 	 */
517 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
518 		ether_fakeaddr(ifp);
519 
520 	ifp->if_type = IFT_ETHER;
521 	ifp->if_addrlen = ETHER_ADDR_LEN;
522 	ifp->if_hdrlen = ETHER_HDR_LEN;
523 	ifp->if_mtu = ETHERMTU;
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