xref: /openbsd-src/sys/net/if_ethersubr.c (revision 2badd5e3f47d2d4252969cd98d7042b4e701b5ac)
1 /*	$OpenBSD: if_ethersubr.c,v 1.55 2001/08/19 15:28:24 jason 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 #ifndef OLDIP6OUTPUT
305 		if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
306 			return(0); /* it must be impossible, but... */
307 #else
308 		if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst))
309 			return(0);	/* if not yet resolves */
310 #endif
311 		etype = htons(ETHERTYPE_IPV6);
312 		break;
313 #endif
314 #ifdef NS
315 	case AF_NS:
316 		etype = htons(ETHERTYPE_NS);
317  		bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
318 		    (caddr_t)edst, sizeof (edst));
319 		if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
320 			return (looutput(ifp, m, dst, rt));
321 		/* If broadcasting on a simplex interface, loopback a copy */
322 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
323 			mcopy = m_copy(m, 0, (int)M_COPYALL);
324 		break;
325 #endif
326 #ifdef IPX
327 	case AF_IPX:
328 		etype = htons(ETHERTYPE_IPX);
329  		bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host,
330 		    (caddr_t)edst, sizeof (edst));
331 		/* If broadcasting on a simplex interface, loopback a copy */
332 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
333 			mcopy = m_copy(m, 0, (int)M_COPYALL);
334 		break;
335 #endif
336 #if 0	/*NRL INET6*/
337 	case AF_INET6:
338 		/*
339 		 * The bottom line here is to either queue the outgoing packet
340 		 * in the discovery engine, or fill in edst with something
341 		 * that'll work.
342 		 */
343 		if (m->m_flags & M_MCAST) {
344 			/*
345 			 * If multicast dest., then use IPv6 -> Ethernet
346 			 * mcast mapping.  Really simple.
347 			 */
348 			ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr,
349 			    edst);
350 		} else {
351 			/* Do unicast neighbor discovery stuff. */
352 			if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
353 				return 0;
354 		}
355 		etype = htons(ETHERTYPE_IPV6);
356 		break;
357 #endif /* INET6 */
358 #ifdef NETATALK
359 	case AF_APPLETALK: {
360 		struct at_ifaddr *aa;
361 
362 		if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
363 #ifdef NETATALKDEBUG
364 			extern char *prsockaddr(struct sockaddr *);
365 			printf("aarpresolv: failed for %s\n", prsockaddr(dst));
366 #endif /* NETATALKDEBUG */
367 			return (0);
368 		}
369 
370 		/*
371 		 * ifaddr is the first thing in at_ifaddr
372 		 */
373 		aa = (struct at_ifaddr *)at_ifawithnet(
374 			(struct sockaddr_at *)dst,
375 			ifp->if_addrlist.tqh_first);
376 		if (aa == 0)
377 			goto bad;
378 
379 		/*
380 		 * In the phase 2 case, we need to prepend an mbuf for the llc
381 		 * header. Since we must preserve the value of m, which is
382 		 * passed to us by value, we m_copy() the first mbuf,
383 		 * and use it for our llc header.
384 		 */
385 		if ( aa->aa_flags & AFA_PHASE2 ) {
386 			struct llc llc;
387 
388 			/* XXX Really this should use netisr too */
389 			M_PREPEND(m, AT_LLC_SIZE, M_WAIT);
390 			/*
391 			 * FreeBSD doesn't count the LLC len in
392 			 * ifp->obytes, so they increment a length
393 			 * field here. We don't do this.
394 			 */
395 			llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
396 			llc.llc_control = LLC_UI;
397 			bcopy(at_org_code, llc.llc_snap.org_code,
398 				sizeof(at_org_code));
399 			llc.llc_snap.ether_type = htons( ETHERTYPE_AT );
400 			bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
401 			etype = htons(m->m_pkthdr.len);
402 		} else {
403 			etype = htons(ETHERTYPE_AT);
404 		}
405 		} break;
406 #endif /* NETATALK */
407 #ifdef	ISO
408 	case AF_ISO: {
409 		int	snpalen;
410 		struct	llc *l;
411 		register struct sockaddr_dl *sdl;
412 
413 		if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
414 		    sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
415 			bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
416 		} else {
417 			error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
418 						(char *)edst, &snpalen);
419 			if (error)
420 				goto bad; /* Not Resolved */
421 		}
422 		/* If broadcasting on a simplex interface, loopback a copy */
423 		if (*edst & 1)
424 			m->m_flags |= (M_BCAST|M_MCAST);
425 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
426 		    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
427 			M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
428 			if (mcopy) {
429 				eh = mtod(mcopy, struct ether_header *);
430 				bcopy(edst, eh->ether_dhost, sizeof (edst));
431 				bcopy(ac->ac_enaddr, eh->ether_shost,
432 				    sizeof (edst));
433 			}
434 		}
435 		M_PREPEND(m, 3, M_DONTWAIT);
436 		if (m == NULL)
437 			return (0);
438 		etype = htons(m->m_pkthdr.len);
439 		l = mtod(m, struct llc *);
440 		l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
441 		l->llc_control = LLC_UI;
442 #ifdef ARGO_DEBUG
443 		if (argo_debug[D_ETHER]) {
444 			int i;
445 			printf("unoutput: sending pkt to: ");
446 			for (i=0; i<6; i++)
447 				printf("%x ", edst[i] & 0xff);
448 			printf("\n");
449 		}
450 #endif
451 		} break;
452 #endif /* ISO */
453 /*	case AF_NSAP: */
454 	case AF_CCITT: {
455 		register struct sockaddr_dl *sdl =
456 			(struct sockaddr_dl *) rt -> rt_gateway;
457 
458 		if (sdl && sdl->sdl_family == AF_LINK
459 		    && sdl->sdl_alen > 0) {
460 			bcopy(LLADDR(sdl), (char *)edst,
461 				sizeof(edst));
462 		} else goto bad; /* Not a link interface ? Funny ... */
463 		if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
464 		    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
465 			M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
466 			if (mcopy) {
467 				eh = mtod(mcopy, struct ether_header *);
468 				bcopy(edst, eh->ether_dhost, sizeof (edst));
469 				bcopy(ac->ac_enaddr, eh->ether_shost,
470 				    sizeof (edst));
471 			}
472 		}
473 		etype = htons(m->m_pkthdr.len);
474 #ifdef LLC_DEBUG
475 		{
476 			int i;
477 			register struct llc *l = mtod(m, struct llc *);
478 
479 			printf("ether_output: sending LLC2 pkt to: ");
480 			for (i=0; i<6; i++)
481 				printf("%x ", edst[i] & 0xff);
482 			printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
483 			    m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
484 			    l->llc_control & 0xff);
485 
486 		}
487 #endif /* LLC_DEBUG */
488 		} break;
489 
490 	case pseudo_AF_HDRCMPLT:
491 		hdrcmplt = 1;
492 		eh = (struct ether_header *)dst->sa_data;
493 		bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc));
494 		/* FALLTHROUGH */
495 
496 	case AF_UNSPEC:
497 		eh = (struct ether_header *)dst->sa_data;
498  		bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
499 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
500 		etype = eh->ether_type;
501 		break;
502 
503 	default:
504 		printf("%s: can't handle af%d\n", ifp->if_xname,
505 			dst->sa_family);
506 		senderr(EAFNOSUPPORT);
507 	}
508 
509 	/* XXX Should we feed-back an unencrypted IPsec packet ? */
510 	if (mcopy)
511 		(void) looutput(ifp, mcopy, dst, rt);
512 
513 	/*
514 	 * Add local net header.  If no space in first mbuf,
515 	 * allocate another.
516 	 */
517 	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
518 	if (m == 0)
519 		senderr(ENOBUFS);
520 	eh = mtod(m, struct ether_header *);
521 	bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
522 		sizeof(eh->ether_type));
523  	bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
524 	if (hdrcmplt)
525 	 	bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
526 		    sizeof(eh->ether_shost));
527 	else
528 	 	bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
529 		    sizeof(eh->ether_shost));
530 
531 #if NBRIDGE > 0
532 	/*
533 	 * Interfaces that are bridge members need special handling
534 	 * for output.
535 	 */
536 	if (ifp->if_bridge) {
537 		struct m_tag *mtag;
538 
539 		/*
540 		 * Check if this packet has already been sent out through
541 		 * this bridge, in which case we simply send it out
542 		 * without further bridge processing.
543 		 */
544 		for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
545 		    mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
546 #ifdef DEBUG
547 			/* Check that the information is there */
548 			if (mtag->m_tag_len != sizeof(caddr_t)) {
549 				error = EINVAL;
550 				goto bad;
551 			}
552 #endif
553 			if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
554 				break;
555 		}
556 		if (mtag == NULL) {
557 			/* Attach a tag so we can detect loops */
558 			mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
559 			    M_NOWAIT);
560 			if (mtag == NULL) {
561 				error = ENOBUFS;
562 				goto bad;
563 			}
564 			bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
565 			m_tag_prepend(m, mtag);
566 			bridge_output(ifp, m, NULL, NULL);
567 			return (error);
568 		}
569 	}
570 #endif
571 
572 	mflags = m->m_flags;
573 	len = m->m_pkthdr.len;
574 	s = splimp();
575 	/*
576 	 * Queue message on interface, and start output if interface
577 	 * not yet active.
578 	 */
579 	IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
580 	if (error) {
581 		/* mbuf is already freed */
582 		splx(s);
583 		return (error);
584 	}
585 	ifp->if_obytes += len + sizeof (struct ether_header);
586 	if (mflags & M_MCAST)
587 		ifp->if_omcasts++;
588 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
589 		(*ifp->if_start)(ifp);
590 	splx(s);
591 	return (error);
592 
593 bad:
594 	if (m)
595 		m_freem(m);
596 	return (error);
597 }
598 
599 #ifdef ALTQ
600 /*
601  * This routine is a slight hack to allow a packet to be classified
602  * if the Ethernet headers are present.  It will go away when ALTQ's
603  * classification engine understands link headers.
604  */
605 void
606 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m,
607     struct altq_pktattr *pktattr)
608 {
609 	struct ether_header *eh;
610 	u_int16_t ether_type;
611 	int hlen, af, hdrsize;
612 	caddr_t hdr;
613 
614 	hlen = ETHER_HDR_LEN;
615 	eh = mtod(m, struct ether_header *);
616 
617 	ether_type = htons(eh->ether_type);
618 
619 	if (ether_type < ETHERMTU) {
620 		/* LLC/SNAP */
621 		struct llc *llc = (struct llc *)(eh + 1);
622 		hlen += 8;
623 
624 		if (m->m_len < hlen ||
625 		    llc->llc_dsap != LLC_SNAP_LSAP ||
626 		    llc->llc_ssap != LLC_SNAP_LSAP ||
627 		    llc->llc_control != LLC_UI) {
628 			/* Not SNAP. */
629 			goto bad;
630 		}
631 
632 		ether_type = htons(llc->llc_un.type_snap.ether_type);
633 	}
634 
635 	switch (ether_type) {
636 	case ETHERTYPE_IP:
637 		af = AF_INET;
638 		hdrsize = 20;		/* sizeof(struct ip) */
639 		break;
640 
641 	case ETHERTYPE_IPV6:
642 		af = AF_INET6;
643 		hdrsize = 40;		/* sizeof(struct ip6_hdr) */
644 		break;
645 
646 	default:
647 		af = AF_UNSPEC;
648 		hdrsize = 0;
649 		break;
650 	}
651 
652 	if (m->m_len < (hlen + hdrsize)) {
653 		/*
654 		 * Ethernet and protocol header not in a single
655 		 * mbuf.  We can't cope with this situation right
656 		 * now (but it shouldn't ever happen, really, anyhow).
657 		 * XXX Should use m_pulldown().
658 		 */
659 		printf("altq_etherclassify: headers span multiple mbufs: "
660 		    "%d < %d\n", m->m_len, (hlen + hdrsize));
661 		goto bad;
662 	}
663 
664 	m->m_data += hlen;
665 	m->m_len -= hlen;
666 
667 	hdr = mtod(m, caddr_t);
668 
669 	if (ALTQ_NEEDS_CLASSIFY(ifq))
670 		pktattr->pattr_class =
671 		    (*ifq->altq_classify)(ifq->altq_clfier, m, af);
672 	pktattr->pattr_af = af;
673 	pktattr->pattr_hdr = hdr;
674 
675 	m->m_data -= hlen;
676 	m->m_len += hlen;
677 
678 	return;
679 
680  bad:
681 	pktattr->pattr_class = NULL;
682 	pktattr->pattr_hdr = NULL;
683 	pktattr->pattr_af = AF_UNSPEC;
684 }
685 #endif /* ALTQ */
686 
687 /*
688  * Temporary function to migrate while
689  * removing ether_header * from ether_input().
690  */
691 void
692 ether_input_mbuf(ifp, m)
693 	struct ifnet *ifp;
694 	struct mbuf *m;
695 {
696 	struct ether_header *eh;
697 
698 	eh = mtod(m, struct ether_header *);
699 	m_adj(m, ETHER_HDR_LEN);
700 	ether_input(ifp, eh, m);
701 }
702 
703 /*
704  * Process a received Ethernet packet;
705  * the packet is in the mbuf chain m without
706  * the ether header, which is provided separately.
707  */
708 void
709 ether_input(ifp, eh, m)
710 	struct ifnet *ifp;
711 	register struct ether_header *eh;
712 	struct mbuf *m;
713 {
714 	register struct ifqueue *inq;
715 	u_int16_t etype;
716 	int s, llcfound = 0;
717 	register struct llc *l;
718 	struct arpcom *ac;
719 
720 	if ((ifp->if_flags & IFF_UP) == 0) {
721 		m_freem(m);
722 		return;
723 	}
724 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
725 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
726 			struct ifaddr *ifa;
727 			struct sockaddr_dl *sdl = NULL;
728 
729 			for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
730 			    ifa = ifa->ifa_list.tqe_next)
731 				if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
732 				    sdl->sdl_family == AF_LINK)
733 					break;
734 
735 			/*
736 			 * If this is not a simplex interface, drop the packet
737 			 * if it came from us.
738 			 */
739 			if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
740 			    ETHER_ADDR_LEN) == 0) {
741 				m_freem(m);
742 				return;
743 			}
744 		}
745 
746 		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
747 		    sizeof(etherbroadcastaddr)) == 0)
748 			m->m_flags |= M_BCAST;
749 		else
750 			m->m_flags |= M_MCAST;
751 		ifp->if_imcasts++;
752 	}
753 
754 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
755 
756 	etype = ntohs(eh->ether_type);
757 
758 #if NBRIDGE > 0
759 	/*
760 	 * Tap the packet off here for a bridge, if configured and
761 	 * active for this interface.  bridge_input returns
762 	 * NULL if it has consumed the packet, otherwise, it
763 	 * gets processed as normal.
764 	 */
765 	if (ifp->if_bridge) {
766 		if (m->m_flags & M_PROTO1)
767 			m->m_flags &= ~M_PROTO1;
768 		else {
769 			m = bridge_input(ifp, eh, m);
770 			if (m == NULL)
771 				return;
772 			/* The bridge has determined it's for us. */
773 			ifp = m->m_pkthdr.rcvif;
774 		}
775 	}
776 #endif
777 
778 #if NVLAN > 0
779 	if (etype == ETHERTYPE_8021Q) {
780 		if (vlan_input(eh, m) < 0)
781 			ifp->if_noproto++;
782 		return;
783        }
784 #endif /* NVLAN > 0 */
785 
786 	ac = (struct arpcom *)ifp;
787 
788 	/*
789 	 * If packet is unicast and we're in promiscuous mode, make sure it
790 	 * is for us.  Drop otherwise.
791 	 */
792 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
793 	    (ifp->if_flags & IFF_PROMISC)) {
794 		if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
795 		    ETHER_ADDR_LEN)) {
796 			m_freem(m);
797 			return;
798 		}
799 	}
800 
801 decapsulate:
802 
803 	switch (etype) {
804 #ifdef INET
805 	case ETHERTYPE_IP:
806 		schednetisr(NETISR_IP);
807 		inq = &ipintrq;
808 		break;
809 
810 	case ETHERTYPE_ARP:
811 		if (ifp->if_flags & IFF_NOARP)
812 			goto dropanyway;
813 		schednetisr(NETISR_ARP);
814 		inq = &arpintrq;
815 		break;
816 
817 	case ETHERTYPE_REVARP:
818 		if (ifp->if_flags & IFF_NOARP)
819 			goto dropanyway;
820 		revarpinput(m);	/* XXX queue? */
821 		return;
822 
823 #endif
824 #ifdef INET6
825 	/*
826 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
827 	 */
828 	case ETHERTYPE_IPV6:
829 		schednetisr(NETISR_IPV6);
830 		inq = &ip6intrq;
831 		break;
832 #endif /* INET6 */
833 #ifdef IPX
834 	case ETHERTYPE_IPX:
835 		schednetisr(NETISR_IPX);
836 		inq = &ipxintrq;
837 		break;
838 #endif
839 #ifdef NS
840 	case ETHERTYPE_NS:
841 		schednetisr(NETISR_NS);
842 		inq = &nsintrq;
843 		break;
844 #endif
845 #ifdef NETATALK
846 	case ETHERTYPE_AT:
847 		schednetisr(NETISR_ATALK);
848 		inq = &atintrq1;
849 		break;
850 	case ETHERTYPE_AARP:
851 		/* probably this should be done with a NETISR as well */
852 		/* XXX queue this */
853 		aarpinput((struct arpcom *)ifp, m);
854 		return;
855 #endif
856 	default:
857 		if (llcfound || etype > ETHERMTU)
858 			goto dropanyway;
859 		llcfound = 1;
860 		l = mtod(m, struct llc *);
861 		switch (l->llc_dsap) {
862 		case LLC_SNAP_LSAP:
863 #ifdef NETATALK
864 			/*
865 			 * Some protocols (like Appletalk) need special
866 			 * handling depending on if they are type II
867 			 * or SNAP encapsulated. Everything else
868 			 * gets handled by stripping off the SNAP header
869 			 * and going back up to decapsulate.
870 			 */
871 			if (l->llc_control == LLC_UI &&
872 			    l->llc_ssap == LLC_SNAP_LSAP &&
873 			    Bcmp(&(l->llc_snap.org_code)[0],
874 			    at_org_code, sizeof(at_org_code)) == 0 &&
875 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
876 				inq = &atintrq2;
877 				m_adj(m, AT_LLC_SIZE);
878 				schednetisr(NETISR_ATALK);
879 				break;
880 			}
881 
882 			if (l->llc_control == LLC_UI &&
883 			    l->llc_ssap == LLC_SNAP_LSAP &&
884 			    Bcmp(&(l->llc_snap.org_code)[0],
885 			    aarp_org_code, sizeof(aarp_org_code)) == 0 &&
886 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
887 				m_adj(m, AT_LLC_SIZE);
888 				/* XXX Really this should use netisr too */
889 				aarpinput((struct arpcom *)ifp, m);
890 				return;
891 			}
892 #endif /* NETATALK */
893 			if (l->llc_control == LLC_UI &&
894 			    l->llc_dsap == LLC_SNAP_LSAP &&
895 			    l->llc_ssap == LLC_SNAP_LSAP) {
896 				/* SNAP */
897 				if (m->m_pkthdr.len > etype)
898 					m_adj(m, etype - m->m_pkthdr.len);
899 				m->m_data += 6;		/* XXX */
900 				m->m_len -= 6;		/* XXX */
901 				m->m_pkthdr.len -= 6;	/* XXX */
902 				M_PREPEND(m, sizeof *eh, M_DONTWAIT);
903 				if (m == 0)
904 					return;
905 				*mtod(m, struct ether_header *) = *eh;
906 				goto decapsulate;
907 			}
908 			goto dropanyway;
909 #ifdef	ISO
910 		case LLC_ISO_LSAP:
911 			switch (l->llc_control) {
912 			case LLC_UI:
913 				/* LLC_UI_P forbidden in class 1 service */
914 				if ((l->llc_dsap == LLC_ISO_LSAP) &&
915 				    (l->llc_ssap == LLC_ISO_LSAP)) {
916 					/* LSAP for ISO */
917 					if (m->m_pkthdr.len > etype)
918 						m_adj(m, etype - m->m_pkthdr.len);
919 					m->m_data += 3;		/* XXX */
920 					m->m_len -= 3;		/* XXX */
921 					m->m_pkthdr.len -= 3;	/* XXX */
922 					M_PREPEND(m, sizeof *eh, M_DONTWAIT);
923 					if (m == 0)
924 						return;
925 					*mtod(m, struct ether_header *) = *eh;
926 #ifdef ARGO_DEBUG
927 					if (argo_debug[D_ETHER])
928 						printf("clnp packet");
929 #endif
930 					schednetisr(NETISR_ISO);
931 					inq = &clnlintrq;
932 					break;
933 				}
934 				goto dropanyway;
935 
936 			case LLC_XID:
937 			case LLC_XID_P:
938 				if(m->m_len < 6)
939 					goto dropanyway;
940 				l->llc_window = 0;
941 				l->llc_fid = 9;
942 				l->llc_class = 1;
943 				l->llc_dsap = l->llc_ssap = 0;
944 				/* Fall through to */
945 			case LLC_TEST:
946 			case LLC_TEST_P:
947 			{
948 				struct sockaddr sa;
949 				register struct ether_header *eh2;
950 				int i;
951 				u_char c = l->llc_dsap;
952 
953 				l->llc_dsap = l->llc_ssap;
954 				l->llc_ssap = c;
955 				if (m->m_flags & (M_BCAST | M_MCAST))
956 					bcopy(ac->ac_enaddr,
957 					    eh->ether_dhost, 6);
958 				sa.sa_family = AF_UNSPEC;
959 				sa.sa_len = sizeof(sa);
960 				eh2 = (struct ether_header *)sa.sa_data;
961 				for (i = 0; i < 6; i++) {
962 					eh2->ether_shost[i] = c = eh->ether_dhost[i];
963 					eh2->ether_dhost[i] =
964 						eh->ether_dhost[i] = eh->ether_shost[i];
965 					eh->ether_shost[i] = c;
966 				}
967 				ifp->if_output(ifp, m, &sa, NULL);
968 				return;
969 			}
970 			break;
971 			}
972 #endif /* ISO */
973 #ifdef CCITT
974 		case LLC_X25_LSAP:
975 			if (m->m_pkthdr.len > etype)
976 				m_adj(m, etype - m->m_pkthdr.len);
977 			M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
978 			if (m == 0)
979 				return;
980 			if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
981 			    eh->ether_dhost, LLC_X25_LSAP, 6,
982 			    mtod(m, struct sdl_hdr *)))
983 				panic("ETHER cons addr failure");
984 			mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
985 #ifdef LLC_DEBUG
986 			printf("llc packet\n");
987 #endif /* LLC_DEBUG */
988 			schednetisr(NETISR_CCITT);
989 			inq = &llcintrq;
990 			break;
991 #endif /* CCITT */
992 		dropanyway:
993 		default:
994 			m_freem(m);
995 			return;
996 		}
997 	}
998 
999 	s = splimp();
1000 	if (IF_QFULL(inq)) {
1001 		IF_DROP(inq);
1002 		m_freem(m);
1003 	} else
1004 		IF_ENQUEUE(inq, m);
1005 	splx(s);
1006 }
1007 
1008 /*
1009  * Convert Ethernet address to printable (loggable) representation.
1010  */
1011 static char digits[] = "0123456789abcdef";
1012 char *
1013 ether_sprintf(ap)
1014 	register u_char *ap;
1015 {
1016 	register int i;
1017 	static char etherbuf[18];
1018 	register char *cp = etherbuf;
1019 
1020 	for (i = 0; i < 6; i++) {
1021 		*cp++ = digits[*ap >> 4];
1022 		*cp++ = digits[*ap++ & 0xf];
1023 		*cp++ = ':';
1024 	}
1025 	*--cp = 0;
1026 	return (etherbuf);
1027 }
1028 
1029 /*
1030  * Perform common duties while attaching to interface list
1031  */
1032 void
1033 ether_ifattach(ifp)
1034 	register struct ifnet *ifp;
1035 {
1036 	register struct ifaddr *ifa;
1037 	register struct sockaddr_dl *sdl;
1038 
1039 	/*
1040 	 * Any interface which provides a MAC address which is obviously
1041 	 * invalid gets whacked, so that users will notice.
1042 	 */
1043 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
1044 		((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
1045 		((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
1046 		((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
1047 		((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
1048 		((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
1049 		((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)arc4random();
1050 	}
1051 
1052 	ifp->if_type = IFT_ETHER;
1053 	ifp->if_addrlen = 6;
1054 	ifp->if_hdrlen = 14;
1055 	ifp->if_mtu = ETHERMTU;
1056 	ifp->if_output = ether_output;
1057 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1058 		if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
1059 		    sdl->sdl_family == AF_LINK) {
1060 			sdl->sdl_type = IFT_ETHER;
1061 			sdl->sdl_alen = ifp->if_addrlen;
1062 			bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
1063 			    LLADDR(sdl), ifp->if_addrlen);
1064 			break;
1065 		}
1066 	}
1067 	LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
1068 #if NBPFILTER > 0
1069 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
1070 #endif
1071 }
1072 
1073 void
1074 ether_ifdetach(ifp)
1075 	struct ifnet *ifp;
1076 {
1077 	struct arpcom *ac = (struct arpcom *)ifp;
1078 	struct ether_multi *enm;
1079 
1080 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
1081 	    enm != LIST_END(&ac->ac_multiaddrs);
1082 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
1083 		LIST_REMOVE(enm, enm_list);
1084 		free(enm, M_IFMADDR);
1085 	}
1086 }
1087 
1088 u_char	ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
1089 u_char	ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
1090 
1091 #ifdef INET6
1092 u_char	ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
1093 u_char	ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
1094 #endif
1095 
1096 /*
1097  * Add an Ethernet multicast address or range of addresses to the list for a
1098  * given interface.
1099  */
1100 int
1101 ether_addmulti(ifr, ac)
1102 	struct ifreq *ifr;
1103 	register struct arpcom *ac;
1104 {
1105 	register struct ether_multi *enm;
1106 #ifdef INET
1107 	struct sockaddr_in *sin;
1108 #endif
1109 #ifdef INET6
1110 	struct sockaddr_in6 *sin6;
1111 #endif /* INET6 */
1112 	u_char addrlo[6];
1113 	u_char addrhi[6];
1114 	int s = splimp();
1115 
1116 	switch (ifr->ifr_addr.sa_family) {
1117 
1118 	case AF_UNSPEC:
1119 		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
1120 		bcopy(addrlo, addrhi, 6);
1121 		break;
1122 
1123 #ifdef INET
1124 	case AF_INET:
1125 		sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1126 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1127 			/*
1128 			 * An IP address of INADDR_ANY means listen to all
1129 			 * of the Ethernet multicast addresses used for IP.
1130 			 * (This is for the sake of IP multicast routers.)
1131 			 */
1132 			bcopy(ether_ipmulticast_min, addrlo, 6);
1133 			bcopy(ether_ipmulticast_max, addrhi, 6);
1134 		}
1135 		else {
1136 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1137 			bcopy(addrlo, addrhi, 6);
1138 		}
1139 		break;
1140 #endif
1141 #ifdef INET6
1142 	case AF_INET6:
1143 		sin6 = (struct sockaddr_in6 *)
1144 			&(((struct in6_ifreq *)ifr)->ifr_addr);
1145 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1146 			/*
1147 			 * An unspecified IPv6 address means listen to all
1148 			 * of the IPv6 multicast addresses on this Ethernet.
1149 			 * (Multicast routers like this.)
1150 			 */
1151 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1152 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1153 		} else {
1154 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1155 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1156 		}
1157 		break;
1158 #endif /* INET6 */
1159 
1160 	default:
1161 		splx(s);
1162 		return (EAFNOSUPPORT);
1163 	}
1164 
1165 	/*
1166 	 * Verify that we have valid Ethernet multicast addresses.
1167 	 */
1168 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1169 		splx(s);
1170 		return (EINVAL);
1171 	}
1172 	/*
1173 	 * See if the address range is already in the list.
1174 	 */
1175 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1176 	if (enm != NULL) {
1177 		/*
1178 		 * Found it; just increment the reference count.
1179 		 */
1180 		++enm->enm_refcount;
1181 		splx(s);
1182 		return (0);
1183 	}
1184 	/*
1185 	 * New address or range; malloc a new multicast record
1186 	 * and link it into the interface's multicast list.
1187 	 */
1188 	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1189 	if (enm == NULL) {
1190 		splx(s);
1191 		return (ENOBUFS);
1192 	}
1193 	bcopy(addrlo, enm->enm_addrlo, 6);
1194 	bcopy(addrhi, enm->enm_addrhi, 6);
1195 	enm->enm_ac = ac;
1196 	enm->enm_refcount = 1;
1197 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1198 	ac->ac_multicnt++;
1199 	splx(s);
1200 	/*
1201 	 * Return ENETRESET to inform the driver that the list has changed
1202 	 * and its reception filter should be adjusted accordingly.
1203 	 */
1204 	return (ENETRESET);
1205 }
1206 
1207 /*
1208  * Delete a multicast address record.
1209  */
1210 int
1211 ether_delmulti(ifr, ac)
1212 	struct ifreq *ifr;
1213 	register struct arpcom *ac;
1214 {
1215 	register struct ether_multi *enm;
1216 #ifdef INET
1217 	struct sockaddr_in *sin;
1218 #endif
1219 #ifdef INET6
1220 	struct sockaddr_in6 *sin6;
1221 #endif /* INET6 */
1222 	u_char addrlo[6];
1223 	u_char addrhi[6];
1224 	int s = splimp();
1225 
1226 	switch (ifr->ifr_addr.sa_family) {
1227 
1228 	case AF_UNSPEC:
1229 		bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
1230 		bcopy(addrlo, addrhi, 6);
1231 		break;
1232 
1233 #ifdef INET
1234 	case AF_INET:
1235 		sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1236 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1237 			/*
1238 			 * An IP address of INADDR_ANY means stop listening
1239 			 * to the range of Ethernet multicast addresses used
1240 			 * for IP.
1241 			 */
1242 			bcopy(ether_ipmulticast_min, addrlo, 6);
1243 			bcopy(ether_ipmulticast_max, addrhi, 6);
1244 		}
1245 		else {
1246 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1247 			bcopy(addrlo, addrhi, 6);
1248 		}
1249 		break;
1250 #endif
1251 #ifdef INET6
1252 	case AF_INET6:
1253 		sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
1254 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1255 			/*
1256 			 * An unspecified IPv6 address means stop listening to
1257 			 * all IPv6 multicast addresses on this Ethernet.'
1258 			 *
1259 			 * (This might not be healthy, given IPv6's reliance on
1260 			 * multicast for things like neighbor discovery.
1261 			 * Perhaps initializing all-nodes, solicited nodes, and
1262 			 * possibly all-routers for this interface afterwards
1263 			 * is not a bad idea.)
1264 			 */
1265 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1266 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1267 		} else {
1268 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1269 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1270 		}
1271 		break;
1272 #endif /* INET6 */
1273 
1274 	default:
1275 		splx(s);
1276 		return (EAFNOSUPPORT);
1277 	}
1278 
1279 	/*
1280 	 * Look up the address in our list.
1281 	 */
1282 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1283 	if (enm == NULL) {
1284 		splx(s);
1285 		return (ENXIO);
1286 	}
1287 	if (--enm->enm_refcount != 0) {
1288 		/*
1289 		 * Still some claims to this record.
1290 		 */
1291 		splx(s);
1292 		return (0);
1293 	}
1294 	/*
1295 	 * No remaining claims to this record; unlink and free it.
1296 	 */
1297 	LIST_REMOVE(enm, enm_list);
1298 	free(enm, M_IFMADDR);
1299 	ac->ac_multicnt--;
1300 	splx(s);
1301 	/*
1302 	 * Return ENETRESET to inform the driver that the list has changed
1303 	 * and its reception filter should be adjusted accordingly.
1304 	 */
1305 	return (ENETRESET);
1306 }
1307