xref: /openbsd-src/sys/net/if_ethersubr.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: if_ethersubr.c,v 1.72 2003/10/25 19:31:05 mcbride 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 	register 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 	register 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 	register struct mbuf *m = m0;
253 	register struct rtentry *rt;
254 	struct mbuf *mcopy = (struct mbuf *)0;
255 	register 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 		register 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 		register 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 			register 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 	register struct ether_header *eh;
624 	struct mbuf *m;
625 {
626 	register struct ifqueue *inq;
627 	u_int16_t etype;
628 	int s, llcfound = 0;
629 	register 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 				register 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 	register u_char *ap;
932 {
933 	register int i;
934 	static char etherbuf[18];
935 	register 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 	register 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_free_sadl(ifp);
1002 }
1003 
1004 #if 0
1005 /*
1006  * This is for reference.  We have a table-driven version
1007  * of the little-endian crc32 generator, which is faster
1008  * than the double-loop.
1009  */
1010 u_int32_t
1011 ether_crc32_le(const u_int8_t *buf, size_t len)
1012 {
1013 	u_int32_t c, crc, carry;
1014 	size_t i, j;
1015 
1016 	crc = 0xffffffffU;	/* initial value */
1017 
1018 	for (i = 0; i < len; i++) {
1019 		c = buf[i];
1020 		for (j = 0; j < 8; j++) {
1021 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
1022 			crc >>= 1;
1023 			c >>= 1;
1024 			if (carry)
1025 				crc = (crc ^ ETHER_CRC_POLY_LE);
1026 		}
1027 	}
1028 
1029 	return (crc);
1030 }
1031 #else
1032 u_int32_t
1033 ether_crc32_le(const u_int8_t *buf, size_t len)
1034 {
1035 	static const u_int32_t crctab[] = {
1036 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
1037 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1038 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
1039 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
1040 	};
1041 	u_int32_t crc;
1042 	int i;
1043 
1044 	crc = 0xffffffffU;	/* initial value */
1045 
1046 	for (i = 0; i < len; i++) {
1047 		crc ^= buf[i];
1048 		crc = (crc >> 4) ^ crctab[crc & 0xf];
1049 		crc = (crc >> 4) ^ crctab[crc & 0xf];
1050 	}
1051 
1052 	return (crc);
1053 }
1054 #endif
1055 
1056 u_int32_t
1057 ether_crc32_be(const u_int8_t *buf, size_t len)
1058 {
1059 	u_int32_t c, crc, carry;
1060 	size_t i, j;
1061 
1062 	crc = 0xffffffffU;	/* initial value */
1063 
1064 	for (i = 0; i < len; i++) {
1065 		c = buf[i];
1066 		for (j = 0; j < 8; j++) {
1067 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
1068 			crc <<= 1;
1069 			c >>= 1;
1070 			if (carry)
1071 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
1072 		}
1073 	}
1074 
1075 	return (crc);
1076 }
1077 
1078 #ifdef INET
1079 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
1080     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
1081 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
1082     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
1083 #endif
1084 
1085 #ifdef INET6
1086 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
1087     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
1088 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
1089     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
1090 #endif
1091 
1092 /*
1093  * Convert a sockaddr into an Ethernet address or range of Ethernet
1094  * addresses.
1095  */
1096 int
1097 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
1098     u_int8_t addrhi[ETHER_ADDR_LEN])
1099 {
1100 #ifdef INET
1101 	struct sockaddr_in *sin;
1102 #endif /* INET */
1103 #ifdef INET6
1104 	struct sockaddr_in6 *sin6;
1105 #endif /* INET6 */
1106 
1107 	switch (sa->sa_family) {
1108 
1109 	case AF_UNSPEC:
1110 		bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
1111 		bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1112 		break;
1113 
1114 #ifdef INET
1115 	case AF_INET:
1116 		sin = satosin(sa);
1117 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1118 			/*
1119 			 * An IP address of INADDR_ANY means listen to
1120 			 * or stop listening to all of the Ethernet
1121 			 * multicast addresses used for IP.
1122 			 * (This is for the sake of IP multicast routers.)
1123 			 */
1124 			bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
1125 			bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
1126 		} else {
1127 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1128 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1129 		}
1130 		break;
1131 #endif
1132 #ifdef INET6
1133 	case AF_INET6:
1134 		sin6 = satosin6(sa);
1135 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1136 			/*
1137 			 * An IP6 address of 0 means listen to or stop
1138 			 * listening to all of the Ethernet multicast
1139 			 * address used for IP6.
1140 			 *
1141 			 * (This might not be healthy, given IPv6's reliance on
1142 			 * multicast for things like neighbor discovery.
1143 			 * Perhaps initializing all-nodes, solicited nodes, and
1144 			 * possibly all-routers for this interface afterwards
1145 			 * is not a bad idea.)
1146 			 */
1147 
1148 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1149 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1150 		} else {
1151 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1152 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1153 		}
1154 		break;
1155 #endif
1156 
1157 	default:
1158 		return (EAFNOSUPPORT);
1159 	}
1160 	return (0);
1161 }
1162 
1163 /*
1164  * Add an Ethernet multicast address or range of addresses to the list for a
1165  * given interface.
1166  */
1167 int
1168 ether_addmulti(ifr, ac)
1169 	struct ifreq *ifr;
1170 	register struct arpcom *ac;
1171 {
1172 	register struct ether_multi *enm;
1173 	u_char addrlo[ETHER_ADDR_LEN];
1174 	u_char addrhi[ETHER_ADDR_LEN];
1175 	int s = splimp(), error;
1176 
1177 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1178 	if (error != 0) {
1179 		splx(s);
1180 		return (error);
1181 	}
1182 
1183 	/*
1184 	 * Verify that we have valid Ethernet multicast addresses.
1185 	 */
1186 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1187 		splx(s);
1188 		return (EINVAL);
1189 	}
1190 	/*
1191 	 * See if the address range is already in the list.
1192 	 */
1193 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1194 	if (enm != NULL) {
1195 		/*
1196 		 * Found it; just increment the reference count.
1197 		 */
1198 		++enm->enm_refcount;
1199 		splx(s);
1200 		return (0);
1201 	}
1202 	/*
1203 	 * New address or range; malloc a new multicast record
1204 	 * and link it into the interface's multicast list.
1205 	 */
1206 	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1207 	if (enm == NULL) {
1208 		splx(s);
1209 		return (ENOBUFS);
1210 	}
1211 	bcopy(addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
1212 	bcopy(addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
1213 	enm->enm_ac = ac;
1214 	enm->enm_refcount = 1;
1215 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1216 	ac->ac_multicnt++;
1217 	splx(s);
1218 	/*
1219 	 * Return ENETRESET to inform the driver that the list has changed
1220 	 * and its reception filter should be adjusted accordingly.
1221 	 */
1222 	return (ENETRESET);
1223 }
1224 
1225 /*
1226  * Delete a multicast address record.
1227  */
1228 int
1229 ether_delmulti(ifr, ac)
1230 	struct ifreq *ifr;
1231 	register struct arpcom *ac;
1232 {
1233 	register struct ether_multi *enm;
1234 	u_char addrlo[ETHER_ADDR_LEN];
1235 	u_char addrhi[ETHER_ADDR_LEN];
1236 	int s = splimp(), error;
1237 
1238 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1239 	if (error != 0) {
1240 		splx(s);
1241 		return (error);
1242 	}
1243 
1244 	/*
1245 	 * Look up the address in our list.
1246 	 */
1247 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1248 	if (enm == NULL) {
1249 		splx(s);
1250 		return (ENXIO);
1251 	}
1252 	if (--enm->enm_refcount != 0) {
1253 		/*
1254 		 * Still some claims to this record.
1255 		 */
1256 		splx(s);
1257 		return (0);
1258 	}
1259 	/*
1260 	 * No remaining claims to this record; unlink and free it.
1261 	 */
1262 	LIST_REMOVE(enm, enm_list);
1263 	free(enm, M_IFMADDR);
1264 	ac->ac_multicnt--;
1265 	splx(s);
1266 	/*
1267 	 * Return ENETRESET to inform the driver that the list has changed
1268 	 * and its reception filter should be adjusted accordingly.
1269 	 */
1270 	return (ENETRESET);
1271 }
1272