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