xref: /openbsd-src/sys/net/if_ethersubr.c (revision 33b792a3c1c87b47219fdf9a73548c4003214de3)
1 /*	$OpenBSD: if_ethersubr.c,v 1.61 2002/02/07 23:20:57 art 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. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
66  */
67 
68 /*
69 %%% portions-copyright-nrl-95
70 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
71 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
72 Reserved. All rights under this copyright have been assigned to the US
73 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
74 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
75 software.
76 You should have received a copy of the license with this software. If you
77 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
78 */
79 
80 #include "bpfilter.h"
81 
82 #include <sys/param.h>
83 #include <sys/systm.h>
84 #include <sys/kernel.h>
85 #include <sys/malloc.h>
86 #include <sys/mbuf.h>
87 #include <sys/protosw.h>
88 #include <sys/socket.h>
89 #include <sys/ioctl.h>
90 #include <sys/errno.h>
91 #include <sys/syslog.h>
92 #include <sys/timeout.h>
93 
94 #include <machine/cpu.h>
95 
96 #include <net/if.h>
97 #include <net/netisr.h>
98 #include <net/route.h>
99 #include <net/if_llc.h>
100 #include <net/if_dl.h>
101 #include <net/if_types.h>
102 
103 #include <netinet/in.h>
104 #ifdef INET
105 #include <netinet/in_var.h>
106 #endif
107 #include <netinet/if_ether.h>
108 #include <netinet/ip_ipsp.h>
109 
110 #if NBPFILTER > 0
111 #include <net/bpf.h>
112 #endif
113 
114 #include "bridge.h"
115 #if NBRIDGE > 0
116 #include <net/if_bridge.h>
117 #endif
118 
119 #include "vlan.h"
120 #if NVLAN > 0
121 #include <net/if_vlan_var.h>
122 #endif /* NVLAN > 0 */
123 
124 #ifdef INET6
125 #ifndef INET
126 #include <netinet/in.h>
127 #endif
128 #include <netinet6/in6_var.h>
129 #include <netinet6/nd6.h>
130 #endif
131 
132 #ifdef NS
133 #include <netns/ns.h>
134 #include <netns/ns_if.h>
135 #endif
136 
137 #ifdef IPX
138 #include <netipx/ipx.h>
139 #include <netipx/ipx_if.h>
140 #endif
141 
142 #ifdef ISO
143 #include <netiso/argo_debug.h>
144 #include <netiso/iso.h>
145 #include <netiso/iso_var.h>
146 #include <netiso/iso_snpac.h>
147 #endif
148 
149 #include <netccitt/x25.h>
150 #include <netccitt/pk.h>
151 #include <netccitt/pk_extern.h>
152 #include <netccitt/dll.h>
153 #include <netccitt/llc_var.h>
154 
155 #ifdef NETATALK
156 #include <netatalk/at.h>
157 #include <netatalk/at_var.h>
158 #include <netatalk/at_extern.h>
159 
160 extern u_char	at_org_code[ 3 ];
161 extern u_char	aarp_org_code[ 3 ];
162 #endif /* NETATALK */
163 
164 #if defined(CCITT)
165 #include <sys/socketvar.h>
166 #endif
167 
168 u_char	etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
169 #define senderr(e) { error = (e); goto bad;}
170 
171 
172 int
173 ether_ioctl(ifp, arp, cmd, data)
174 	register struct ifnet *ifp;
175 	struct arpcom *arp;
176 	u_long cmd;
177 	caddr_t data;
178 {
179 	struct ifaddr *ifa = (struct ifaddr *)data;
180 	int	error = 0;
181 
182 	switch (cmd) {
183 
184 #if defined(CCITT)
185 	case SIOCSIFCONF_X25:
186 		ifp->if_flags |= IFF_UP;
187 		ifa->ifa_rtrequest = cons_rtrequest;
188 		error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
189 		break;
190 #endif /* CCITT */
191 	case SIOCSIFADDR:
192 		switch (ifa->ifa_addr->sa_family) {
193 #ifdef IPX
194 		case AF_IPX:
195 		    {
196 			struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr;
197 
198 			if (ipx_nullhost(*ina))
199 				ina->ipx_host =
200 				    *(union ipx_host *)(arp->ac_enaddr);
201 			else
202 				bcopy(ina->ipx_host.c_host,
203 				    arp->ac_enaddr, sizeof(arp->ac_enaddr));
204 			break;
205 		    }
206 #endif /* IPX */
207 #ifdef NETATALK
208 		case AF_APPLETALK:
209 			/* Nothing to do. */
210 			break;
211 #endif /* NETATALK */
212 #ifdef NS
213 		/* XXX - This code is probably wrong. */
214 		case AF_NS:
215 		    {
216 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
217 
218 			if (ns_nullhost(*ina))
219 				ina->x_host =
220 				    *(union ns_host *)(arp->ac_enaddr);
221 			else
222 				bcopy(ina->x_host.c_host,
223 				    arp->ac_enaddr, sizeof(arp->ac_enaddr));
224 			break;
225 		    }
226 #endif /* NS */
227 		}
228 		break;
229 	default:
230 		break;
231 	}
232 
233 	return error;
234 }
235 
236 /*
237  * Ethernet output routine.
238  * Encapsulate a packet of type family for the local net.
239  * Assumes that ifp is actually pointer to arpcom structure.
240  */
241 int
242 ether_output(ifp, m0, dst, rt0)
243 	register struct ifnet *ifp;
244 	struct mbuf *m0;
245 	struct sockaddr *dst;
246 	struct rtentry *rt0;
247 {
248 	u_int16_t etype;
249 	int s, len, error = 0, hdrcmplt = 0;
250  	u_char edst[6], esrc[6];
251 	register struct mbuf *m = m0;
252 	register struct rtentry *rt;
253 	struct mbuf *mcopy = (struct mbuf *)0;
254 	register struct ether_header *eh;
255 	struct arpcom *ac = (struct arpcom *)ifp;
256 	short mflags;
257 	ALTQ_DECL(struct altq_pktattr pktattr;)
258 
259 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
260 		senderr(ENETDOWN);
261 	if ((rt = rt0) != NULL) {
262 		if ((rt->rt_flags & RTF_UP) == 0) {
263 			if ((rt0 = rt = rtalloc1(dst, 1)) != NULL)
264 				rt->rt_refcnt--;
265 			else
266 				senderr(EHOSTUNREACH);
267 		}
268 		if (rt->rt_flags & RTF_GATEWAY) {
269 			if (rt->rt_gwroute == 0)
270 				goto lookup;
271 			if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
272 				rtfree(rt); rt = rt0;
273 			lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
274 				if ((rt = rt->rt_gwroute) == 0)
275 					senderr(EHOSTUNREACH);
276 			}
277 		}
278 		if (rt->rt_flags & RTF_REJECT)
279 			if (rt->rt_rmx.rmx_expire == 0 ||
280 			    time.tv_sec < rt->rt_rmx.rmx_expire)
281 				senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
282 	}
283 
284 	/*
285 	 * if the queueing discipline needs packet classification,
286 	 * do it before prepending link headers.
287 	 */
288 	IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
289 
290 	switch (dst->sa_family) {
291 
292 #ifdef INET
293 	case AF_INET:
294 		if (!arpresolve(ac, rt, m, dst, edst))
295 			return (0);	/* if not yet resolved */
296 		/* If broadcasting on a simplex interface, loopback a copy */
297 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
298 			mcopy = m_copy(m, 0, (int)M_COPYALL);
299 		etype = htons(ETHERTYPE_IP);
300 		break;
301 #endif
302 #ifdef INET6
303 	case AF_INET6:
304 		if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
305 			return(0); /* it must be impossible, but... */
306 		etype = htons(ETHERTYPE_IPV6);
307 		break;
308 #endif
309 #ifdef NS
310 	case AF_NS:
311 		etype = htons(ETHERTYPE_NS);
312  		bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
313 		    (caddr_t)edst, sizeof (edst));
314 		if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
315 			return (looutput(ifp, m, dst, rt));
316 		/* If broadcasting on a simplex interface, loopback a copy */
317 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
318 			mcopy = m_copy(m, 0, (int)M_COPYALL);
319 		break;
320 #endif
321 #ifdef IPX
322 	case AF_IPX:
323 		etype = htons(ETHERTYPE_IPX);
324  		bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host,
325 		    (caddr_t)edst, sizeof (edst));
326 		/* If broadcasting on a simplex interface, loopback a copy */
327 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
328 			mcopy = m_copy(m, 0, (int)M_COPYALL);
329 		break;
330 #endif
331 #if 0	/*NRL INET6*/
332 	case AF_INET6:
333 		/*
334 		 * The bottom line here is to either queue the outgoing packet
335 		 * in the discovery engine, or fill in edst with something
336 		 * that'll work.
337 		 */
338 		if (m->m_flags & M_MCAST) {
339 			/*
340 			 * If multicast dest., then use IPv6 -> Ethernet
341 			 * mcast mapping.  Really simple.
342 			 */
343 			ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr,
344 			    edst);
345 		} else {
346 			/* Do unicast neighbor discovery stuff. */
347 			if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
348 				return 0;
349 		}
350 		etype = htons(ETHERTYPE_IPV6);
351 		break;
352 #endif /* INET6 */
353 #ifdef NETATALK
354 	case AF_APPLETALK: {
355 		struct at_ifaddr *aa;
356 
357 		if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
358 #ifdef NETATALKDEBUG
359 			extern char *prsockaddr(struct sockaddr *);
360 			printf("aarpresolv: failed for %s\n", prsockaddr(dst));
361 #endif /* NETATALKDEBUG */
362 			return (0);
363 		}
364 
365 		/*
366 		 * ifaddr is the first thing in at_ifaddr
367 		 */
368 		aa = (struct at_ifaddr *)at_ifawithnet(
369 			(struct sockaddr_at *)dst,
370 			TAILQ_FIRST(&ifp->if_addrlist));
371 		if (aa == 0)
372 			goto bad;
373 
374 		/*
375 		 * In the phase 2 case, we need to prepend an mbuf for the llc
376 		 * header. Since we must preserve the value of m, which is
377 		 * passed to us by value, we m_copy() the first mbuf,
378 		 * and use it for our llc header.
379 		 */
380 		if (aa->aa_flags & AFA_PHASE2) {
381 			struct llc llc;
382 
383 			M_PREPEND(m, AT_LLC_SIZE, M_DONTWAIT);
384 			if (m == NULL)
385 				return (0);
386 			/*
387 			 * FreeBSD doesn't count the LLC len in
388 			 * ifp->obytes, so they increment a length
389 			 * field here. We don't do this.
390 			 */
391 			llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
392 			llc.llc_control = LLC_UI;
393 			bcopy(at_org_code, llc.llc_snap.org_code,
394 				sizeof(at_org_code));
395 			llc.llc_snap.ether_type = htons( ETHERTYPE_AT );
396 			bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
397 			etype = htons(m->m_pkthdr.len);
398 		} else {
399 			etype = htons(ETHERTYPE_AT);
400 		}
401 		} break;
402 #endif /* NETATALK */
403 #ifdef	ISO
404 	case AF_ISO: {
405 		int	snpalen;
406 		struct	llc *l;
407 		register struct sockaddr_dl *sdl;
408 
409 		if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
410 		    sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
411 			bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
412 		} else {
413 			error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
414 						(char *)edst, &snpalen);
415 			if (error)
416 				goto bad; /* Not Resolved */
417 		}
418 		/* If broadcasting on a simplex interface, loopback a copy */
419 		if (*edst & 1)
420 			m->m_flags |= (M_BCAST|M_MCAST);
421 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
422 		    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
423 			M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
424 			if (mcopy) {
425 				eh = mtod(mcopy, struct ether_header *);
426 				bcopy(edst, eh->ether_dhost, sizeof (edst));
427 				bcopy(ac->ac_enaddr, eh->ether_shost,
428 				    sizeof (edst));
429 			}
430 		}
431 		M_PREPEND(m, 3, M_DONTWAIT);
432 		if (m == NULL)
433 			return (0);
434 		etype = htons(m->m_pkthdr.len);
435 		l = mtod(m, struct llc *);
436 		l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
437 		l->llc_control = LLC_UI;
438 #ifdef ARGO_DEBUG
439 		if (argo_debug[D_ETHER]) {
440 			int i;
441 			printf("unoutput: sending pkt to: ");
442 			for (i=0; i<6; i++)
443 				printf("%x ", edst[i] & 0xff);
444 			printf("\n");
445 		}
446 #endif
447 		} break;
448 #endif /* ISO */
449 /*	case AF_NSAP: */
450 	case AF_CCITT: {
451 		register struct sockaddr_dl *sdl =
452 			(struct sockaddr_dl *) rt -> rt_gateway;
453 
454 		if (sdl && sdl->sdl_family == AF_LINK
455 		    && sdl->sdl_alen > 0) {
456 			bcopy(LLADDR(sdl), (char *)edst,
457 				sizeof(edst));
458 		} else goto bad; /* Not a link interface ? Funny ... */
459 		if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
460 		    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
461 			M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
462 			if (mcopy) {
463 				eh = mtod(mcopy, struct ether_header *);
464 				bcopy(edst, eh->ether_dhost, sizeof (edst));
465 				bcopy(ac->ac_enaddr, eh->ether_shost,
466 				    sizeof (edst));
467 			}
468 		}
469 		etype = htons(m->m_pkthdr.len);
470 #ifdef LLC_DEBUG
471 		{
472 			int i;
473 			register struct llc *l = mtod(m, struct llc *);
474 
475 			printf("ether_output: sending LLC2 pkt to: ");
476 			for (i=0; i<6; i++)
477 				printf("%x ", edst[i] & 0xff);
478 			printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
479 			    m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
480 			    l->llc_control & 0xff);
481 
482 		}
483 #endif /* LLC_DEBUG */
484 		} break;
485 
486 	case pseudo_AF_HDRCMPLT:
487 		hdrcmplt = 1;
488 		eh = (struct ether_header *)dst->sa_data;
489 		bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc));
490 		/* FALLTHROUGH */
491 
492 	case AF_UNSPEC:
493 		eh = (struct ether_header *)dst->sa_data;
494  		bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
495 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
496 		etype = eh->ether_type;
497 		break;
498 
499 	default:
500 		printf("%s: can't handle af%d\n", ifp->if_xname,
501 			dst->sa_family);
502 		senderr(EAFNOSUPPORT);
503 	}
504 
505 	/* XXX Should we feed-back an unencrypted IPsec packet ? */
506 	if (mcopy)
507 		(void) looutput(ifp, mcopy, dst, rt);
508 
509 	/*
510 	 * Add local net header.  If no space in first mbuf,
511 	 * allocate another.
512 	 */
513 	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
514 	if (m == 0)
515 		senderr(ENOBUFS);
516 	eh = mtod(m, struct ether_header *);
517 	bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
518 		sizeof(eh->ether_type));
519  	bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
520 	if (hdrcmplt)
521 	 	bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
522 		    sizeof(eh->ether_shost));
523 	else
524 	 	bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
525 		    sizeof(eh->ether_shost));
526 
527 #if NBRIDGE > 0
528 	/*
529 	 * Interfaces that are bridge members need special handling
530 	 * for output.
531 	 */
532 	if (ifp->if_bridge) {
533 		struct m_tag *mtag;
534 
535 		/*
536 		 * Check if this packet has already been sent out through
537 		 * this bridge, in which case we simply send it out
538 		 * without further bridge processing.
539 		 */
540 		for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
541 		    mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
542 #ifdef DEBUG
543 			/* Check that the information is there */
544 			if (mtag->m_tag_len != sizeof(caddr_t)) {
545 				error = EINVAL;
546 				goto bad;
547 			}
548 #endif
549 			if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
550 				break;
551 		}
552 		if (mtag == NULL) {
553 			/* Attach a tag so we can detect loops */
554 			mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
555 			    M_NOWAIT);
556 			if (mtag == NULL) {
557 				error = ENOBUFS;
558 				goto bad;
559 			}
560 			bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
561 			m_tag_prepend(m, mtag);
562 			bridge_output(ifp, m, NULL, NULL);
563 			return (error);
564 		}
565 	}
566 #endif
567 
568 	mflags = m->m_flags;
569 	len = m->m_pkthdr.len;
570 	s = splimp();
571 	/*
572 	 * Queue message on interface, and start output if interface
573 	 * not yet active.
574 	 */
575 	IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
576 	if (error) {
577 		/* mbuf is already freed */
578 		splx(s);
579 		return (error);
580 	}
581 	ifp->if_obytes += len + sizeof (struct ether_header);
582 	if (mflags & M_MCAST)
583 		ifp->if_omcasts++;
584 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
585 		(*ifp->if_start)(ifp);
586 	splx(s);
587 	return (error);
588 
589 bad:
590 	if (m)
591 		m_freem(m);
592 	return (error);
593 }
594 
595 #ifdef ALTQ
596 /*
597  * This routine is a slight hack to allow a packet to be classified
598  * if the Ethernet headers are present.  It will go away when ALTQ's
599  * classification engine understands link headers.
600  */
601 void
602 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m,
603     struct altq_pktattr *pktattr)
604 {
605 	struct ether_header *eh;
606 	u_int16_t ether_type;
607 	int hlen, af, hdrsize;
608 	caddr_t hdr;
609 
610 	hlen = ETHER_HDR_LEN;
611 	eh = mtod(m, struct ether_header *);
612 
613 	ether_type = htons(eh->ether_type);
614 
615 	if (ether_type < ETHERMTU) {
616 		/* LLC/SNAP */
617 		struct llc *llc = (struct llc *)(eh + 1);
618 		hlen += 8;
619 
620 		if (m->m_len < hlen ||
621 		    llc->llc_dsap != LLC_SNAP_LSAP ||
622 		    llc->llc_ssap != LLC_SNAP_LSAP ||
623 		    llc->llc_control != LLC_UI) {
624 			/* Not SNAP. */
625 			goto bad;
626 		}
627 
628 		ether_type = htons(llc->llc_un.type_snap.ether_type);
629 	}
630 
631 	switch (ether_type) {
632 	case ETHERTYPE_IP:
633 		af = AF_INET;
634 		hdrsize = 20;		/* sizeof(struct ip) */
635 		break;
636 
637 	case ETHERTYPE_IPV6:
638 		af = AF_INET6;
639 		hdrsize = 40;		/* sizeof(struct ip6_hdr) */
640 		break;
641 
642 	default:
643 		af = AF_UNSPEC;
644 		hdrsize = 0;
645 		break;
646 	}
647 
648 	if (m->m_len < (hlen + hdrsize)) {
649 		/*
650 		 * Ethernet and protocol header not in a single
651 		 * mbuf.  We can't cope with this situation right
652 		 * now (but it shouldn't ever happen, really, anyhow).
653 		 * XXX Should use m_pulldown().
654 		 */
655 #ifdef DEBUG
656 		printf("altq_etherclassify: headers span multiple mbufs: "
657 		    "%d < %d\n", m->m_len, (hlen + hdrsize));
658 #endif
659 		goto bad;
660 	}
661 
662 	m->m_data += hlen;
663 	m->m_len -= hlen;
664 
665 	hdr = mtod(m, caddr_t);
666 
667 	if (ALTQ_NEEDS_CLASSIFY(ifq))
668 		pktattr->pattr_class =
669 		    (*ifq->altq_classify)(ifq->altq_clfier, m, af);
670 	pktattr->pattr_af = af;
671 	pktattr->pattr_hdr = hdr;
672 
673 	m->m_data -= hlen;
674 	m->m_len += hlen;
675 
676 	return;
677 
678  bad:
679 	pktattr->pattr_class = NULL;
680 	pktattr->pattr_hdr = NULL;
681 	pktattr->pattr_af = AF_UNSPEC;
682 }
683 #endif /* ALTQ */
684 
685 /*
686  * Temporary function to migrate while
687  * removing ether_header * from ether_input().
688  */
689 void
690 ether_input_mbuf(ifp, m)
691 	struct ifnet *ifp;
692 	struct mbuf *m;
693 {
694 	struct ether_header *eh;
695 
696 	eh = mtod(m, struct ether_header *);
697 	m_adj(m, ETHER_HDR_LEN);
698 	ether_input(ifp, eh, m);
699 }
700 
701 /*
702  * Process a received Ethernet packet;
703  * the packet is in the mbuf chain m without
704  * the ether header, which is provided separately.
705  */
706 void
707 ether_input(ifp, eh, m)
708 	struct ifnet *ifp;
709 	register struct ether_header *eh;
710 	struct mbuf *m;
711 {
712 	register struct ifqueue *inq;
713 	u_int16_t etype;
714 	int s, llcfound = 0;
715 	register struct llc *l;
716 	struct arpcom *ac;
717 
718 	if ((ifp->if_flags & IFF_UP) == 0) {
719 		m_freem(m);
720 		return;
721 	}
722 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
723 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
724 			struct ifaddr *ifa;
725 			struct sockaddr_dl *sdl = NULL;
726 
727 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
728 				if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
729 				    sdl->sdl_family == AF_LINK)
730 					break;
731 			}
732 			/*
733 			 * If this is not a simplex interface, drop the packet
734 			 * if it came from us.
735 			 */
736 			if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
737 			    ETHER_ADDR_LEN) == 0) {
738 				m_freem(m);
739 				return;
740 			}
741 		}
742 
743 		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
744 		    sizeof(etherbroadcastaddr)) == 0)
745 			m->m_flags |= M_BCAST;
746 		else
747 			m->m_flags |= M_MCAST;
748 		ifp->if_imcasts++;
749 	}
750 
751 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
752 
753 	etype = ntohs(eh->ether_type);
754 
755 #if NBRIDGE > 0
756 	/*
757 	 * Tap the packet off here for a bridge, if configured and
758 	 * active for this interface.  bridge_input returns
759 	 * NULL if it has consumed the packet, otherwise, it
760 	 * gets processed as normal.
761 	 */
762 	if (ifp->if_bridge) {
763 		if (m->m_flags & M_PROTO1)
764 			m->m_flags &= ~M_PROTO1;
765 		else {
766 			m = bridge_input(ifp, eh, m);
767 			if (m == NULL)
768 				return;
769 			/* The bridge has determined it's for us. */
770 			ifp = m->m_pkthdr.rcvif;
771 		}
772 	}
773 #endif
774 
775 #if NVLAN > 0
776 	if (etype == ETHERTYPE_8021Q) {
777 		if (vlan_input(eh, m) < 0)
778 			ifp->if_noproto++;
779 		return;
780        }
781 #endif /* NVLAN > 0 */
782 
783 	ac = (struct arpcom *)ifp;
784 
785 	/*
786 	 * If packet is unicast and we're in promiscuous mode, make sure it
787 	 * is for us.  Drop otherwise.
788 	 */
789 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
790 	    (ifp->if_flags & IFF_PROMISC)) {
791 		if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
792 		    ETHER_ADDR_LEN)) {
793 			m_freem(m);
794 			return;
795 		}
796 	}
797 
798 decapsulate:
799 
800 	switch (etype) {
801 #ifdef INET
802 	case ETHERTYPE_IP:
803 		schednetisr(NETISR_IP);
804 		inq = &ipintrq;
805 		break;
806 
807 	case ETHERTYPE_ARP:
808 		if (ifp->if_flags & IFF_NOARP)
809 			goto dropanyway;
810 		schednetisr(NETISR_ARP);
811 		inq = &arpintrq;
812 		break;
813 
814 	case ETHERTYPE_REVARP:
815 		if (ifp->if_flags & IFF_NOARP)
816 			goto dropanyway;
817 		revarpinput(m);	/* XXX queue? */
818 		return;
819 
820 #endif
821 #ifdef INET6
822 	/*
823 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
824 	 */
825 	case ETHERTYPE_IPV6:
826 		schednetisr(NETISR_IPV6);
827 		inq = &ip6intrq;
828 		break;
829 #endif /* INET6 */
830 #ifdef IPX
831 	case ETHERTYPE_IPX:
832 		schednetisr(NETISR_IPX);
833 		inq = &ipxintrq;
834 		break;
835 #endif
836 #ifdef NS
837 	case ETHERTYPE_NS:
838 		schednetisr(NETISR_NS);
839 		inq = &nsintrq;
840 		break;
841 #endif
842 #ifdef NETATALK
843 	case ETHERTYPE_AT:
844 		schednetisr(NETISR_ATALK);
845 		inq = &atintrq1;
846 		break;
847 	case ETHERTYPE_AARP:
848 		/* probably this should be done with a NETISR as well */
849 		/* XXX queue this */
850 		aarpinput((struct arpcom *)ifp, m);
851 		return;
852 #endif
853 	default:
854 		if (llcfound || etype > ETHERMTU)
855 			goto dropanyway;
856 		llcfound = 1;
857 		l = mtod(m, struct llc *);
858 		switch (l->llc_dsap) {
859 		case LLC_SNAP_LSAP:
860 #ifdef NETATALK
861 			/*
862 			 * Some protocols (like Appletalk) need special
863 			 * handling depending on if they are type II
864 			 * or SNAP encapsulated. Everything else
865 			 * gets handled by stripping off the SNAP header
866 			 * and going back up to decapsulate.
867 			 */
868 			if (l->llc_control == LLC_UI &&
869 			    l->llc_ssap == LLC_SNAP_LSAP &&
870 			    Bcmp(&(l->llc_snap.org_code)[0],
871 			    at_org_code, sizeof(at_org_code)) == 0 &&
872 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
873 				inq = &atintrq2;
874 				m_adj(m, AT_LLC_SIZE);
875 				schednetisr(NETISR_ATALK);
876 				break;
877 			}
878 
879 			if (l->llc_control == LLC_UI &&
880 			    l->llc_ssap == LLC_SNAP_LSAP &&
881 			    Bcmp(&(l->llc_snap.org_code)[0],
882 			    aarp_org_code, sizeof(aarp_org_code)) == 0 &&
883 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
884 				m_adj(m, AT_LLC_SIZE);
885 				/* XXX Really this should use netisr too */
886 				aarpinput((struct arpcom *)ifp, m);
887 				return;
888 			}
889 #endif /* NETATALK */
890 			if (l->llc_control == LLC_UI &&
891 			    l->llc_dsap == LLC_SNAP_LSAP &&
892 			    l->llc_ssap == LLC_SNAP_LSAP) {
893 				/* SNAP */
894 				if (m->m_pkthdr.len > etype)
895 					m_adj(m, etype - m->m_pkthdr.len);
896 				m->m_data += 6;		/* XXX */
897 				m->m_len -= 6;		/* XXX */
898 				m->m_pkthdr.len -= 6;	/* XXX */
899 				M_PREPEND(m, sizeof *eh, M_DONTWAIT);
900 				if (m == 0)
901 					return;
902 				*mtod(m, struct ether_header *) = *eh;
903 				goto decapsulate;
904 			}
905 			goto dropanyway;
906 #ifdef	ISO
907 		case LLC_ISO_LSAP:
908 			switch (l->llc_control) {
909 			case LLC_UI:
910 				/* LLC_UI_P forbidden in class 1 service */
911 				if ((l->llc_dsap == LLC_ISO_LSAP) &&
912 				    (l->llc_ssap == LLC_ISO_LSAP)) {
913 					/* LSAP for ISO */
914 					if (m->m_pkthdr.len > etype)
915 						m_adj(m, etype - m->m_pkthdr.len);
916 					m->m_data += 3;		/* XXX */
917 					m->m_len -= 3;		/* XXX */
918 					m->m_pkthdr.len -= 3;	/* XXX */
919 					M_PREPEND(m, sizeof *eh, M_DONTWAIT);
920 					if (m == 0)
921 						return;
922 					*mtod(m, struct ether_header *) = *eh;
923 #ifdef ARGO_DEBUG
924 					if (argo_debug[D_ETHER])
925 						printf("clnp packet");
926 #endif
927 					schednetisr(NETISR_ISO);
928 					inq = &clnlintrq;
929 					break;
930 				}
931 				goto dropanyway;
932 
933 			case LLC_XID:
934 			case LLC_XID_P:
935 				if(m->m_len < 6)
936 					goto dropanyway;
937 				l->llc_window = 0;
938 				l->llc_fid = 9;
939 				l->llc_class = 1;
940 				l->llc_dsap = l->llc_ssap = 0;
941 				/* Fall through to */
942 			case LLC_TEST:
943 			case LLC_TEST_P:
944 			{
945 				struct sockaddr sa;
946 				register struct ether_header *eh2;
947 				int i;
948 				u_char c = l->llc_dsap;
949 
950 				l->llc_dsap = l->llc_ssap;
951 				l->llc_ssap = c;
952 				if (m->m_flags & (M_BCAST | M_MCAST))
953 					bcopy(ac->ac_enaddr,
954 					    eh->ether_dhost, 6);
955 				sa.sa_family = AF_UNSPEC;
956 				sa.sa_len = sizeof(sa);
957 				eh2 = (struct ether_header *)sa.sa_data;
958 				for (i = 0; i < 6; i++) {
959 					eh2->ether_shost[i] = c = eh->ether_dhost[i];
960 					eh2->ether_dhost[i] =
961 						eh->ether_dhost[i] = eh->ether_shost[i];
962 					eh->ether_shost[i] = c;
963 				}
964 				ifp->if_output(ifp, m, &sa, NULL);
965 				return;
966 			}
967 			break;
968 			}
969 #endif /* ISO */
970 #ifdef CCITT
971 		case LLC_X25_LSAP:
972 			if (m->m_pkthdr.len > etype)
973 				m_adj(m, etype - m->m_pkthdr.len);
974 			M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
975 			if (m == 0)
976 				return;
977 			if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
978 			    eh->ether_dhost, LLC_X25_LSAP, 6,
979 			    mtod(m, struct sdl_hdr *)))
980 				panic("ETHER cons addr failure");
981 			mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
982 #ifdef LLC_DEBUG
983 			printf("llc packet\n");
984 #endif /* LLC_DEBUG */
985 			schednetisr(NETISR_CCITT);
986 			inq = &llcintrq;
987 			break;
988 #endif /* CCITT */
989 		dropanyway:
990 		default:
991 			m_freem(m);
992 			return;
993 		}
994 	}
995 
996 	s = splimp();
997 	if (IF_QFULL(inq)) {
998 		IF_DROP(inq);
999 		m_freem(m);
1000 	} else
1001 		IF_ENQUEUE(inq, m);
1002 	splx(s);
1003 }
1004 
1005 /*
1006  * Convert Ethernet address to printable (loggable) representation.
1007  */
1008 static char digits[] = "0123456789abcdef";
1009 char *
1010 ether_sprintf(ap)
1011 	register u_char *ap;
1012 {
1013 	register int i;
1014 	static char etherbuf[18];
1015 	register char *cp = etherbuf;
1016 
1017 	for (i = 0; i < 6; i++) {
1018 		*cp++ = digits[*ap >> 4];
1019 		*cp++ = digits[*ap++ & 0xf];
1020 		*cp++ = ':';
1021 	}
1022 	*--cp = 0;
1023 	return (etherbuf);
1024 }
1025 
1026 /*
1027  * Perform common duties while attaching to interface list
1028  */
1029 void
1030 ether_ifattach(ifp)
1031 	register struct ifnet *ifp;
1032 {
1033 	register struct ifaddr *ifa;
1034 	register struct sockaddr_dl *sdl;
1035 
1036 	/*
1037 	 * Any interface which provides a MAC address which is obviously
1038 	 * invalid gets whacked, so that users will notice.
1039 	 */
1040 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
1041 		((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
1042 		((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
1043 		((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
1044 		((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
1045 		((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
1046 		/*
1047 		 * XXX use of random() by anything except the scheduler is
1048 		 * normally invalid, but this is boot time, so pre-scheduler,
1049 		 * and the random subsystem is not alive yet
1050 		 */
1051 		((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff;
1052 	}
1053 
1054 	ifp->if_type = IFT_ETHER;
1055 	ifp->if_addrlen = 6;
1056 	ifp->if_hdrlen = 14;
1057 	ifp->if_mtu = ETHERMTU;
1058 	ifp->if_output = ether_output;
1059 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1060 		if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
1061 		    sdl->sdl_family == AF_LINK) {
1062 			sdl->sdl_type = IFT_ETHER;
1063 			sdl->sdl_alen = ifp->if_addrlen;
1064 			bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
1065 			    LLADDR(sdl), ifp->if_addrlen);
1066 			break;
1067 		}
1068 	}
1069 	LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
1070 #if NBPFILTER > 0
1071 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
1072 #endif
1073 }
1074 
1075 void
1076 ether_ifdetach(ifp)
1077 	struct ifnet *ifp;
1078 {
1079 	struct arpcom *ac = (struct arpcom *)ifp;
1080 	struct ether_multi *enm;
1081 
1082 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
1083 	    enm != LIST_END(&ac->ac_multiaddrs);
1084 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
1085 		LIST_REMOVE(enm, enm_list);
1086 		free(enm, M_IFMADDR);
1087 	}
1088 }
1089 
1090 u_char	ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
1091 u_char	ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
1092 
1093 #ifdef INET6
1094 u_char	ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
1095 u_char	ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
1096 #endif
1097 
1098 /*
1099  * Add an Ethernet multicast address or range of addresses to the list for a
1100  * given interface.
1101  */
1102 int
1103 ether_addmulti(ifr, ac)
1104 	struct ifreq *ifr;
1105 	register struct arpcom *ac;
1106 {
1107 	register struct ether_multi *enm;
1108 #ifdef INET
1109 	struct sockaddr_in *sin;
1110 #endif
1111 #ifdef INET6
1112 	struct sockaddr_in6 *sin6;
1113 #endif /* INET6 */
1114 	u_char addrlo[6];
1115 	u_char addrhi[6];
1116 	int s = splimp();
1117 
1118 	switch (ifr->ifr_addr.sa_family) {
1119 
1120 	case AF_UNSPEC:
1121 		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
1122 		bcopy(addrlo, addrhi, 6);
1123 		break;
1124 
1125 #ifdef INET
1126 	case AF_INET:
1127 		sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1128 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1129 			/*
1130 			 * An IP address of INADDR_ANY means listen to all
1131 			 * of the Ethernet multicast addresses used for IP.
1132 			 * (This is for the sake of IP multicast routers.)
1133 			 */
1134 			bcopy(ether_ipmulticast_min, addrlo, 6);
1135 			bcopy(ether_ipmulticast_max, addrhi, 6);
1136 		}
1137 		else {
1138 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1139 			bcopy(addrlo, addrhi, 6);
1140 		}
1141 		break;
1142 #endif
1143 #ifdef INET6
1144 	case AF_INET6:
1145 		sin6 = (struct sockaddr_in6 *)
1146 			&(((struct in6_ifreq *)ifr)->ifr_addr);
1147 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1148 			/*
1149 			 * An unspecified IPv6 address means listen to all
1150 			 * of the IPv6 multicast addresses on this Ethernet.
1151 			 * (Multicast routers like this.)
1152 			 */
1153 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1154 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1155 		} else {
1156 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1157 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1158 		}
1159 		break;
1160 #endif /* INET6 */
1161 
1162 	default:
1163 		splx(s);
1164 		return (EAFNOSUPPORT);
1165 	}
1166 
1167 	/*
1168 	 * Verify that we have valid Ethernet multicast addresses.
1169 	 */
1170 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1171 		splx(s);
1172 		return (EINVAL);
1173 	}
1174 	/*
1175 	 * See if the address range is already in the list.
1176 	 */
1177 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1178 	if (enm != NULL) {
1179 		/*
1180 		 * Found it; just increment the reference count.
1181 		 */
1182 		++enm->enm_refcount;
1183 		splx(s);
1184 		return (0);
1185 	}
1186 	/*
1187 	 * New address or range; malloc a new multicast record
1188 	 * and link it into the interface's multicast list.
1189 	 */
1190 	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1191 	if (enm == NULL) {
1192 		splx(s);
1193 		return (ENOBUFS);
1194 	}
1195 	bcopy(addrlo, enm->enm_addrlo, 6);
1196 	bcopy(addrhi, enm->enm_addrhi, 6);
1197 	enm->enm_ac = ac;
1198 	enm->enm_refcount = 1;
1199 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1200 	ac->ac_multicnt++;
1201 	splx(s);
1202 	/*
1203 	 * Return ENETRESET to inform the driver that the list has changed
1204 	 * and its reception filter should be adjusted accordingly.
1205 	 */
1206 	return (ENETRESET);
1207 }
1208 
1209 /*
1210  * Delete a multicast address record.
1211  */
1212 int
1213 ether_delmulti(ifr, ac)
1214 	struct ifreq *ifr;
1215 	register struct arpcom *ac;
1216 {
1217 	register struct ether_multi *enm;
1218 #ifdef INET
1219 	struct sockaddr_in *sin;
1220 #endif
1221 #ifdef INET6
1222 	struct sockaddr_in6 *sin6;
1223 #endif /* INET6 */
1224 	u_char addrlo[6];
1225 	u_char addrhi[6];
1226 	int s = splimp();
1227 
1228 	switch (ifr->ifr_addr.sa_family) {
1229 
1230 	case AF_UNSPEC:
1231 		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
1232 		bcopy(addrlo, addrhi, 6);
1233 		break;
1234 
1235 #ifdef INET
1236 	case AF_INET:
1237 		sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1238 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1239 			/*
1240 			 * An IP address of INADDR_ANY means stop listening
1241 			 * to the range of Ethernet multicast addresses used
1242 			 * for IP.
1243 			 */
1244 			bcopy(ether_ipmulticast_min, addrlo, 6);
1245 			bcopy(ether_ipmulticast_max, addrhi, 6);
1246 		}
1247 		else {
1248 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1249 			bcopy(addrlo, addrhi, 6);
1250 		}
1251 		break;
1252 #endif
1253 #ifdef INET6
1254 	case AF_INET6:
1255 		sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
1256 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1257 			/*
1258 			 * An unspecified IPv6 address means stop listening to
1259 			 * all IPv6 multicast addresses on this Ethernet.'
1260 			 *
1261 			 * (This might not be healthy, given IPv6's reliance on
1262 			 * multicast for things like neighbor discovery.
1263 			 * Perhaps initializing all-nodes, solicited nodes, and
1264 			 * possibly all-routers for this interface afterwards
1265 			 * is not a bad idea.)
1266 			 */
1267 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1268 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1269 		} else {
1270 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1271 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1272 		}
1273 		break;
1274 #endif /* INET6 */
1275 
1276 	default:
1277 		splx(s);
1278 		return (EAFNOSUPPORT);
1279 	}
1280 
1281 	/*
1282 	 * Look up the address in our list.
1283 	 */
1284 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1285 	if (enm == NULL) {
1286 		splx(s);
1287 		return (ENXIO);
1288 	}
1289 	if (--enm->enm_refcount != 0) {
1290 		/*
1291 		 * Still some claims to this record.
1292 		 */
1293 		splx(s);
1294 		return (0);
1295 	}
1296 	/*
1297 	 * No remaining claims to this record; unlink and free it.
1298 	 */
1299 	LIST_REMOVE(enm, enm_list);
1300 	free(enm, M_IFMADDR);
1301 	ac->ac_multicnt--;
1302 	splx(s);
1303 	/*
1304 	 * Return ENETRESET to inform the driver that the list has changed
1305 	 * and its reception filter should be adjusted accordingly.
1306 	 */
1307 	return (ENETRESET);
1308 }
1309