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