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