xref: /openbsd-src/sys/net/if_ethersubr.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1 /*	$OpenBSD: if_ethersubr.c,v 1.76 2004/04/17 00:09:01 henning 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_INPUT_ENQUEUE(inq, m);
918 	splx(s);
919 }
920 
921 /*
922  * Convert Ethernet address to printable (loggable) representation.
923  */
924 static char digits[] = "0123456789abcdef";
925 char *
926 ether_sprintf(ap)
927 	u_char *ap;
928 {
929 	int i;
930 	static char etherbuf[ETHER_ADDR_LEN * 3];
931 	char *cp = etherbuf;
932 
933 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
934 		*cp++ = digits[*ap >> 4];
935 		*cp++ = digits[*ap++ & 0xf];
936 		*cp++ = ':';
937 	}
938 	*--cp = 0;
939 	return (etherbuf);
940 }
941 
942 /*
943  * Perform common duties while attaching to interface list
944  */
945 void
946 ether_ifattach(ifp)
947 	struct ifnet *ifp;
948 {
949 
950 	/*
951 	 * Any interface which provides a MAC address which is obviously
952 	 * invalid gets whacked, so that users will notice.
953 	 */
954 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
955 		((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
956 		((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
957 		((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
958 		((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
959 		((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
960 		/*
961 		 * XXX use of random() by anything except the scheduler is
962 		 * normally invalid, but this is boot time, so pre-scheduler,
963 		 * and the random subsystem is not alive yet
964 		 */
965 		((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff;
966 	}
967 
968 	ifp->if_type = IFT_ETHER;
969 	ifp->if_addrlen = ETHER_ADDR_LEN;
970 	ifp->if_hdrlen = ETHER_HDR_LEN;
971 	ifp->if_mtu = ETHERMTU;
972 	ifp->if_output = ether_output;
973 
974 	if_alloc_sadl(ifp);
975 	bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
976 	    LLADDR(ifp->if_sadl), ifp->if_addrlen);
977 	LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
978 #if NBPFILTER > 0
979 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
980 #endif
981 }
982 
983 void
984 ether_ifdetach(ifp)
985 	struct ifnet *ifp;
986 {
987 	struct arpcom *ac = (struct arpcom *)ifp;
988 	struct ether_multi *enm;
989 
990 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
991 	    enm != LIST_END(&ac->ac_multiaddrs);
992 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
993 		LIST_REMOVE(enm, enm_list);
994 		free(enm, M_IFMADDR);
995 	}
996 
997 #if 0
998 	/* moved to if_detach() */
999 	if_free_sadl(ifp);
1000 #endif
1001 }
1002 
1003 #if 0
1004 /*
1005  * This is for reference.  We have a table-driven version
1006  * of the little-endian crc32 generator, which is faster
1007  * than the double-loop.
1008  */
1009 u_int32_t
1010 ether_crc32_le(const u_int8_t *buf, size_t len)
1011 {
1012 	u_int32_t c, crc, carry;
1013 	size_t i, j;
1014 
1015 	crc = 0xffffffffU;	/* initial value */
1016 
1017 	for (i = 0; i < len; i++) {
1018 		c = buf[i];
1019 		for (j = 0; j < 8; j++) {
1020 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
1021 			crc >>= 1;
1022 			c >>= 1;
1023 			if (carry)
1024 				crc = (crc ^ ETHER_CRC_POLY_LE);
1025 		}
1026 	}
1027 
1028 	return (crc);
1029 }
1030 #else
1031 u_int32_t
1032 ether_crc32_le(const u_int8_t *buf, size_t len)
1033 {
1034 	static const u_int32_t crctab[] = {
1035 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
1036 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1037 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
1038 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
1039 	};
1040 	u_int32_t crc;
1041 	int i;
1042 
1043 	crc = 0xffffffffU;	/* initial value */
1044 
1045 	for (i = 0; i < len; i++) {
1046 		crc ^= buf[i];
1047 		crc = (crc >> 4) ^ crctab[crc & 0xf];
1048 		crc = (crc >> 4) ^ crctab[crc & 0xf];
1049 	}
1050 
1051 	return (crc);
1052 }
1053 #endif
1054 
1055 u_int32_t
1056 ether_crc32_be(const u_int8_t *buf, size_t len)
1057 {
1058 	u_int32_t c, crc, carry;
1059 	size_t i, j;
1060 
1061 	crc = 0xffffffffU;	/* initial value */
1062 
1063 	for (i = 0; i < len; i++) {
1064 		c = buf[i];
1065 		for (j = 0; j < 8; j++) {
1066 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
1067 			crc <<= 1;
1068 			c >>= 1;
1069 			if (carry)
1070 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
1071 		}
1072 	}
1073 
1074 	return (crc);
1075 }
1076 
1077 #ifdef INET
1078 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
1079     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
1080 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
1081     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
1082 #endif
1083 
1084 #ifdef INET6
1085 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
1086     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
1087 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
1088     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
1089 #endif
1090 
1091 /*
1092  * Convert a sockaddr into an Ethernet address or range of Ethernet
1093  * addresses.
1094  */
1095 int
1096 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
1097     u_int8_t addrhi[ETHER_ADDR_LEN])
1098 {
1099 #ifdef INET
1100 	struct sockaddr_in *sin;
1101 #endif /* INET */
1102 #ifdef INET6
1103 	struct sockaddr_in6 *sin6;
1104 #endif /* INET6 */
1105 
1106 	switch (sa->sa_family) {
1107 
1108 	case AF_UNSPEC:
1109 		bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
1110 		bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1111 		break;
1112 
1113 #ifdef INET
1114 	case AF_INET:
1115 		sin = satosin(sa);
1116 		if (sin->sin_addr.s_addr == INADDR_ANY) {
1117 			/*
1118 			 * An IP address of INADDR_ANY means listen to
1119 			 * or stop listening to all of the Ethernet
1120 			 * multicast addresses used for IP.
1121 			 * (This is for the sake of IP multicast routers.)
1122 			 */
1123 			bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
1124 			bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
1125 		} else {
1126 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1127 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1128 		}
1129 		break;
1130 #endif
1131 #ifdef INET6
1132 	case AF_INET6:
1133 		sin6 = satosin6(sa);
1134 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1135 			/*
1136 			 * An IP6 address of 0 means listen to or stop
1137 			 * listening to all of the Ethernet multicast
1138 			 * address used for IP6.
1139 			 *
1140 			 * (This might not be healthy, given IPv6's reliance on
1141 			 * multicast for things like neighbor discovery.
1142 			 * Perhaps initializing all-nodes, solicited nodes, and
1143 			 * possibly all-routers for this interface afterwards
1144 			 * is not a bad idea.)
1145 			 */
1146 
1147 			bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1148 			bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1149 		} else {
1150 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1151 			bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1152 		}
1153 		break;
1154 #endif
1155 
1156 	default:
1157 		return (EAFNOSUPPORT);
1158 	}
1159 	return (0);
1160 }
1161 
1162 /*
1163  * Add an Ethernet multicast address or range of addresses to the list for a
1164  * given interface.
1165  */
1166 int
1167 ether_addmulti(ifr, ac)
1168 	struct ifreq *ifr;
1169 	struct arpcom *ac;
1170 {
1171 	struct ether_multi *enm;
1172 	u_char addrlo[ETHER_ADDR_LEN];
1173 	u_char addrhi[ETHER_ADDR_LEN];
1174 	int s = splimp(), error;
1175 
1176 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1177 	if (error != 0) {
1178 		splx(s);
1179 		return (error);
1180 	}
1181 
1182 	/*
1183 	 * Verify that we have valid Ethernet multicast addresses.
1184 	 */
1185 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1186 		splx(s);
1187 		return (EINVAL);
1188 	}
1189 	/*
1190 	 * See if the address range is already in the list.
1191 	 */
1192 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1193 	if (enm != NULL) {
1194 		/*
1195 		 * Found it; just increment the reference count.
1196 		 */
1197 		++enm->enm_refcount;
1198 		splx(s);
1199 		return (0);
1200 	}
1201 	/*
1202 	 * New address or range; malloc a new multicast record
1203 	 * and link it into the interface's multicast list.
1204 	 */
1205 	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1206 	if (enm == NULL) {
1207 		splx(s);
1208 		return (ENOBUFS);
1209 	}
1210 	bcopy(addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
1211 	bcopy(addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
1212 	enm->enm_ac = ac;
1213 	enm->enm_refcount = 1;
1214 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1215 	ac->ac_multicnt++;
1216 	splx(s);
1217 	/*
1218 	 * Return ENETRESET to inform the driver that the list has changed
1219 	 * and its reception filter should be adjusted accordingly.
1220 	 */
1221 	return (ENETRESET);
1222 }
1223 
1224 /*
1225  * Delete a multicast address record.
1226  */
1227 int
1228 ether_delmulti(ifr, ac)
1229 	struct ifreq *ifr;
1230 	struct arpcom *ac;
1231 {
1232 	struct ether_multi *enm;
1233 	u_char addrlo[ETHER_ADDR_LEN];
1234 	u_char addrhi[ETHER_ADDR_LEN];
1235 	int s = splimp(), error;
1236 
1237 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1238 	if (error != 0) {
1239 		splx(s);
1240 		return (error);
1241 	}
1242 
1243 	/*
1244 	 * Look up the address in our list.
1245 	 */
1246 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1247 	if (enm == NULL) {
1248 		splx(s);
1249 		return (ENXIO);
1250 	}
1251 	if (--enm->enm_refcount != 0) {
1252 		/*
1253 		 * Still some claims to this record.
1254 		 */
1255 		splx(s);
1256 		return (0);
1257 	}
1258 	/*
1259 	 * No remaining claims to this record; unlink and free it.
1260 	 */
1261 	LIST_REMOVE(enm, enm_list);
1262 	free(enm, M_IFMADDR);
1263 	ac->ac_multicnt--;
1264 	splx(s);
1265 	/*
1266 	 * Return ENETRESET to inform the driver that the list has changed
1267 	 * and its reception filter should be adjusted accordingly.
1268 	 */
1269 	return (ENETRESET);
1270 }
1271