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