xref: /openbsd-src/sys/net/if_ethersubr.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*	$OpenBSD: if_ethersubr.c,v 1.60 2001/12/09 13:09:13 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 		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 		printf("altq_etherclassify: headers span multiple mbufs: "
656 		    "%d < %d\n", m->m_len, (hlen + hdrsize));
657 		goto bad;
658 	}
659 
660 	m->m_data += hlen;
661 	m->m_len -= hlen;
662 
663 	hdr = mtod(m, caddr_t);
664 
665 	if (ALTQ_NEEDS_CLASSIFY(ifq))
666 		pktattr->pattr_class =
667 		    (*ifq->altq_classify)(ifq->altq_clfier, m, af);
668 	pktattr->pattr_af = af;
669 	pktattr->pattr_hdr = hdr;
670 
671 	m->m_data -= hlen;
672 	m->m_len += hlen;
673 
674 	return;
675 
676  bad:
677 	pktattr->pattr_class = NULL;
678 	pktattr->pattr_hdr = NULL;
679 	pktattr->pattr_af = AF_UNSPEC;
680 }
681 #endif /* ALTQ */
682 
683 /*
684  * Temporary function to migrate while
685  * removing ether_header * from ether_input().
686  */
687 void
688 ether_input_mbuf(ifp, m)
689 	struct ifnet *ifp;
690 	struct mbuf *m;
691 {
692 	struct ether_header *eh;
693 
694 	eh = mtod(m, struct ether_header *);
695 	m_adj(m, ETHER_HDR_LEN);
696 	ether_input(ifp, eh, m);
697 }
698 
699 /*
700  * Process a received Ethernet packet;
701  * the packet is in the mbuf chain m without
702  * the ether header, which is provided separately.
703  */
704 void
705 ether_input(ifp, eh, m)
706 	struct ifnet *ifp;
707 	register struct ether_header *eh;
708 	struct mbuf *m;
709 {
710 	register struct ifqueue *inq;
711 	u_int16_t etype;
712 	int s, llcfound = 0;
713 	register struct llc *l;
714 	struct arpcom *ac;
715 
716 	if ((ifp->if_flags & IFF_UP) == 0) {
717 		m_freem(m);
718 		return;
719 	}
720 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
721 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
722 			struct ifaddr *ifa;
723 			struct sockaddr_dl *sdl = NULL;
724 
725 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
726 				if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
727 				    sdl->sdl_family == AF_LINK)
728 					break;
729 			}
730 			/*
731 			 * If this is not a simplex interface, drop the packet
732 			 * if it came from us.
733 			 */
734 			if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
735 			    ETHER_ADDR_LEN) == 0) {
736 				m_freem(m);
737 				return;
738 			}
739 		}
740 
741 		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
742 		    sizeof(etherbroadcastaddr)) == 0)
743 			m->m_flags |= M_BCAST;
744 		else
745 			m->m_flags |= M_MCAST;
746 		ifp->if_imcasts++;
747 	}
748 
749 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
750 
751 	etype = ntohs(eh->ether_type);
752 
753 #if NBRIDGE > 0
754 	/*
755 	 * Tap the packet off here for a bridge, if configured and
756 	 * active for this interface.  bridge_input returns
757 	 * NULL if it has consumed the packet, otherwise, it
758 	 * gets processed as normal.
759 	 */
760 	if (ifp->if_bridge) {
761 		if (m->m_flags & M_PROTO1)
762 			m->m_flags &= ~M_PROTO1;
763 		else {
764 			m = bridge_input(ifp, eh, m);
765 			if (m == NULL)
766 				return;
767 			/* The bridge has determined it's for us. */
768 			ifp = m->m_pkthdr.rcvif;
769 		}
770 	}
771 #endif
772 
773 #if NVLAN > 0
774 	if (etype == ETHERTYPE_8021Q) {
775 		if (vlan_input(eh, m) < 0)
776 			ifp->if_noproto++;
777 		return;
778        }
779 #endif /* NVLAN > 0 */
780 
781 	ac = (struct arpcom *)ifp;
782 
783 	/*
784 	 * If packet is unicast and we're in promiscuous mode, make sure it
785 	 * is for us.  Drop otherwise.
786 	 */
787 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
788 	    (ifp->if_flags & IFF_PROMISC)) {
789 		if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
790 		    ETHER_ADDR_LEN)) {
791 			m_freem(m);
792 			return;
793 		}
794 	}
795 
796 decapsulate:
797 
798 	switch (etype) {
799 #ifdef INET
800 	case ETHERTYPE_IP:
801 		schednetisr(NETISR_IP);
802 		inq = &ipintrq;
803 		break;
804 
805 	case ETHERTYPE_ARP:
806 		if (ifp->if_flags & IFF_NOARP)
807 			goto dropanyway;
808 		schednetisr(NETISR_ARP);
809 		inq = &arpintrq;
810 		break;
811 
812 	case ETHERTYPE_REVARP:
813 		if (ifp->if_flags & IFF_NOARP)
814 			goto dropanyway;
815 		revarpinput(m);	/* XXX queue? */
816 		return;
817 
818 #endif
819 #ifdef INET6
820 	/*
821 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
822 	 */
823 	case ETHERTYPE_IPV6:
824 		schednetisr(NETISR_IPV6);
825 		inq = &ip6intrq;
826 		break;
827 #endif /* INET6 */
828 #ifdef IPX
829 	case ETHERTYPE_IPX:
830 		schednetisr(NETISR_IPX);
831 		inq = &ipxintrq;
832 		break;
833 #endif
834 #ifdef NS
835 	case ETHERTYPE_NS:
836 		schednetisr(NETISR_NS);
837 		inq = &nsintrq;
838 		break;
839 #endif
840 #ifdef NETATALK
841 	case ETHERTYPE_AT:
842 		schednetisr(NETISR_ATALK);
843 		inq = &atintrq1;
844 		break;
845 	case ETHERTYPE_AARP:
846 		/* probably this should be done with a NETISR as well */
847 		/* XXX queue this */
848 		aarpinput((struct arpcom *)ifp, m);
849 		return;
850 #endif
851 	default:
852 		if (llcfound || etype > ETHERMTU)
853 			goto dropanyway;
854 		llcfound = 1;
855 		l = mtod(m, struct llc *);
856 		switch (l->llc_dsap) {
857 		case LLC_SNAP_LSAP:
858 #ifdef NETATALK
859 			/*
860 			 * Some protocols (like Appletalk) need special
861 			 * handling depending on if they are type II
862 			 * or SNAP encapsulated. Everything else
863 			 * gets handled by stripping off the SNAP header
864 			 * and going back up to decapsulate.
865 			 */
866 			if (l->llc_control == LLC_UI &&
867 			    l->llc_ssap == LLC_SNAP_LSAP &&
868 			    Bcmp(&(l->llc_snap.org_code)[0],
869 			    at_org_code, sizeof(at_org_code)) == 0 &&
870 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
871 				inq = &atintrq2;
872 				m_adj(m, AT_LLC_SIZE);
873 				schednetisr(NETISR_ATALK);
874 				break;
875 			}
876 
877 			if (l->llc_control == LLC_UI &&
878 			    l->llc_ssap == LLC_SNAP_LSAP &&
879 			    Bcmp(&(l->llc_snap.org_code)[0],
880 			    aarp_org_code, sizeof(aarp_org_code)) == 0 &&
881 			    ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
882 				m_adj(m, AT_LLC_SIZE);
883 				/* XXX Really this should use netisr too */
884 				aarpinput((struct arpcom *)ifp, m);
885 				return;
886 			}
887 #endif /* NETATALK */
888 			if (l->llc_control == LLC_UI &&
889 			    l->llc_dsap == LLC_SNAP_LSAP &&
890 			    l->llc_ssap == LLC_SNAP_LSAP) {
891 				/* SNAP */
892 				if (m->m_pkthdr.len > etype)
893 					m_adj(m, etype - m->m_pkthdr.len);
894 				m->m_data += 6;		/* XXX */
895 				m->m_len -= 6;		/* XXX */
896 				m->m_pkthdr.len -= 6;	/* XXX */
897 				M_PREPEND(m, sizeof *eh, M_DONTWAIT);
898 				if (m == 0)
899 					return;
900 				*mtod(m, struct ether_header *) = *eh;
901 				goto decapsulate;
902 			}
903 			goto dropanyway;
904 #ifdef	ISO
905 		case LLC_ISO_LSAP:
906 			switch (l->llc_control) {
907 			case LLC_UI:
908 				/* LLC_UI_P forbidden in class 1 service */
909 				if ((l->llc_dsap == LLC_ISO_LSAP) &&
910 				    (l->llc_ssap == LLC_ISO_LSAP)) {
911 					/* LSAP for ISO */
912 					if (m->m_pkthdr.len > etype)
913 						m_adj(m, etype - m->m_pkthdr.len);
914 					m->m_data += 3;		/* XXX */
915 					m->m_len -= 3;		/* XXX */
916 					m->m_pkthdr.len -= 3;	/* XXX */
917 					M_PREPEND(m, sizeof *eh, M_DONTWAIT);
918 					if (m == 0)
919 						return;
920 					*mtod(m, struct ether_header *) = *eh;
921 #ifdef ARGO_DEBUG
922 					if (argo_debug[D_ETHER])
923 						printf("clnp packet");
924 #endif
925 					schednetisr(NETISR_ISO);
926 					inq = &clnlintrq;
927 					break;
928 				}
929 				goto dropanyway;
930 
931 			case LLC_XID:
932 			case LLC_XID_P:
933 				if(m->m_len < 6)
934 					goto dropanyway;
935 				l->llc_window = 0;
936 				l->llc_fid = 9;
937 				l->llc_class = 1;
938 				l->llc_dsap = l->llc_ssap = 0;
939 				/* Fall through to */
940 			case LLC_TEST:
941 			case LLC_TEST_P:
942 			{
943 				struct sockaddr sa;
944 				register struct ether_header *eh2;
945 				int i;
946 				u_char c = l->llc_dsap;
947 
948 				l->llc_dsap = l->llc_ssap;
949 				l->llc_ssap = c;
950 				if (m->m_flags & (M_BCAST | M_MCAST))
951 					bcopy(ac->ac_enaddr,
952 					    eh->ether_dhost, 6);
953 				sa.sa_family = AF_UNSPEC;
954 				sa.sa_len = sizeof(sa);
955 				eh2 = (struct ether_header *)sa.sa_data;
956 				for (i = 0; i < 6; i++) {
957 					eh2->ether_shost[i] = c = eh->ether_dhost[i];
958 					eh2->ether_dhost[i] =
959 						eh->ether_dhost[i] = eh->ether_shost[i];
960 					eh->ether_shost[i] = c;
961 				}
962 				ifp->if_output(ifp, m, &sa, NULL);
963 				return;
964 			}
965 			break;
966 			}
967 #endif /* ISO */
968 #ifdef CCITT
969 		case LLC_X25_LSAP:
970 			if (m->m_pkthdr.len > etype)
971 				m_adj(m, etype - m->m_pkthdr.len);
972 			M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
973 			if (m == 0)
974 				return;
975 			if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
976 			    eh->ether_dhost, LLC_X25_LSAP, 6,
977 			    mtod(m, struct sdl_hdr *)))
978 				panic("ETHER cons addr failure");
979 			mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
980 #ifdef LLC_DEBUG
981 			printf("llc packet\n");
982 #endif /* LLC_DEBUG */
983 			schednetisr(NETISR_CCITT);
984 			inq = &llcintrq;
985 			break;
986 #endif /* CCITT */
987 		dropanyway:
988 		default:
989 			m_freem(m);
990 			return;
991 		}
992 	}
993 
994 	s = splimp();
995 	if (IF_QFULL(inq)) {
996 		IF_DROP(inq);
997 		m_freem(m);
998 	} else
999 		IF_ENQUEUE(inq, m);
1000 	splx(s);
1001 }
1002 
1003 /*
1004  * Convert Ethernet address to printable (loggable) representation.
1005  */
1006 static char digits[] = "0123456789abcdef";
1007 char *
1008 ether_sprintf(ap)
1009 	register u_char *ap;
1010 {
1011 	register int i;
1012 	static char etherbuf[18];
1013 	register char *cp = etherbuf;
1014 
1015 	for (i = 0; i < 6; i++) {
1016 		*cp++ = digits[*ap >> 4];
1017 		*cp++ = digits[*ap++ & 0xf];
1018 		*cp++ = ':';
1019 	}
1020 	*--cp = 0;
1021 	return (etherbuf);
1022 }
1023 
1024 /*
1025  * Perform common duties while attaching to interface list
1026  */
1027 void
1028 ether_ifattach(ifp)
1029 	register struct ifnet *ifp;
1030 {
1031 	register struct ifaddr *ifa;
1032 	register struct sockaddr_dl *sdl;
1033 
1034 	/*
1035 	 * Any interface which provides a MAC address which is obviously
1036 	 * invalid gets whacked, so that users will notice.
1037 	 */
1038 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
1039 		((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
1040 		((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
1041 		((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
1042 		((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
1043 		((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
1044 		/*
1045 		 * XXX use of random() by anything except the scheduler is
1046 		 * normally invalid, but this is boot time, so pre-scheduler,
1047 		 * and the random subsystem is not alive yet
1048 		 */
1049 		((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff;
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