1 //==========================================================================
3 // sys/net/if_ethersubr.c
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
10 // -------------------------------------------
12 // Portions of this software may have been derived from OpenBSD or other sources,
13 // and are covered by the appropriate copyright disclaimers included herein.
15 // -------------------------------------------
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
22 // Contributors: gthomas
28 //####DESCRIPTIONEND####
30 //==========================================================================
33 /* $OpenBSD: if_ethersubr.c,v 1.32 1999/12/08 06:50:17 itojun Exp $ */
34 /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
37 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
38 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the project nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * Copyright (c) 1982, 1989, 1993
67 * The Regents of the University of California. All rights reserved.
69 * Redistribution and use in source and binary forms, with or without
70 * modification, are permitted provided that the following conditions
72 * 1. Redistributions of source code must retain the above copyright
73 * notice, this list of conditions and the following disclaimer.
74 * 2. Redistributions in binary form must reproduce the above copyright
75 * notice, this list of conditions and the following disclaimer in the
76 * documentation and/or other materials provided with the distribution.
77 * 3. All advertising materials mentioning features or use of this software
78 * must display the following acknowledgement:
79 * This product includes software developed by the University of
80 * California, Berkeley and its contributors.
81 * 4. Neither the name of the University nor the names of its contributors
82 * may be used to endorse or promote products derived from this software
83 * without specific prior written permission.
85 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
86 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
88 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
91 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
93 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
94 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
97 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
101 %%% portions-copyright-nrl-95
102 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
103 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
104 Reserved. All rights under this copyright have been assigned to the US
105 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
106 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
108 You should have received a copy of the license with this software. If you
109 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
112 #include <sys/param.h>
114 #include <sys/systm.h>
116 #include <sys/kernel.h>
117 #include <sys/malloc.h>
118 #include <sys/mbuf.h>
119 #include <sys/protosw.h>
120 #include <sys/socket.h>
121 #include <sys/ioctl.h>
122 #include <sys/errno.h>
124 #include <sys/syslog.h>
127 #include <machine/cpu.h>
130 #include <net/netisr.h>
131 #include <net/route.h>
132 #include <net/if_llc.h>
133 #include <net/if_dl.h>
134 #include <net/if_types.h>
136 #include <netinet/in.h>
138 #include <netinet/in_var.h>
140 #include <netinet/if_ether.h>
146 #include <net/if_bridge.h>
151 #include <netinet/in.h>
153 #include <netinet6/in6_var.h>
154 #include <netinet6/nd6.h>
158 #include <netns/ns.h>
159 #include <netns/ns_if.h>
163 #include <netipx/ipx.h>
164 #include <netipx/ipx_if.h>
168 #include <netiso/argo_debug.h>
169 #include <netiso/iso.h>
170 #include <netiso/iso_var.h>
171 #include <netiso/iso_snpac.h>
175 #include <netccitt/x25.h>
176 #include <netccitt/pk.h>
177 #include <netccitt/pk_extern.h>
178 #include <netccitt/dll.h>
179 #include <netccitt/llc_var.h>
183 #include <netatalk/at.h>
184 #include <netatalk/at_var.h>
185 #include <netatalk/at_extern.h>
187 #define llc_snap_org_code llc_un.type_snap.org_code
188 #define llc_snap_ether_type llc_un.type_snap.ether_type
190 extern u_char at_org_code[ 3 ];
191 extern u_char aarp_org_code[ 3 ];
192 #endif /* NETATALK */
195 #include <sys/socketvar.h>
199 #include <netinet6/in6.h>
200 #include <netinet6/in6_var.h>
203 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
204 #define senderr(e) { error = (e); goto bad;}
208 ether_ioctl(ifp, arp, cmd, data)
209 register struct ifnet *ifp;
214 struct ifaddr *ifa = (struct ifaddr *)data;
220 case SIOCSIFCONF_X25:
221 ifp->if_flags |= IFF_UP;
222 ifa->ifa_rtrequest = cons_rtrequest;
223 error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
227 switch (ifa->ifa_addr->sa_family) {
231 struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr;
233 if (ipx_nullhost(*ina))
235 *(union ipx_host *)(arp->ac_enaddr);
237 bcopy(ina->ipx_host.c_host,
238 arp->ac_enaddr, sizeof(arp->ac_enaddr));
246 #endif /* NETATALK */
248 /* XXX - This code is probably wrong. */
251 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
253 if (ns_nullhost(*ina))
255 *(union ns_host *)(arp->ac_enaddr);
257 bcopy(ina->x_host.c_host,
258 arp->ac_enaddr, sizeof(arp->ac_enaddr));
272 * Ethernet output routine.
273 * Encapsulate a packet of type family for the local net.
274 * Assumes that ifp is actually pointer to arpcom structure.
277 ether_output(ifp, m0, dst, rt0)
278 register struct ifnet *ifp;
280 struct sockaddr *dst;
286 register struct mbuf *m = m0;
287 register struct rtentry *rt;
288 struct mbuf *mcopy = (struct mbuf *)0;
289 register struct ether_header *eh;
290 struct arpcom *ac = (struct arpcom *)ifp;
292 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
294 ifp->if_lastchange = time;
295 if ((rt = rt0) != NULL) {
296 if ((rt->rt_flags & RTF_UP) == 0) {
297 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL)
300 senderr(EHOSTUNREACH);
302 if (rt->rt_flags & RTF_GATEWAY) {
303 if (rt->rt_gwroute == 0)
305 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
306 rtfree(rt); rt = rt0;
307 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
308 if ((rt = rt->rt_gwroute) == 0)
309 senderr(EHOSTUNREACH);
312 if (rt->rt_flags & RTF_REJECT)
313 if (rt->rt_rmx.rmx_expire == 0 ||
314 time.tv_sec < rt->rt_rmx.rmx_expire)
315 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
317 switch (dst->sa_family) {
321 if (!arpresolve(ac, rt, m, dst, edst))
322 return (0); /* if not yet resolved */
323 /* If broadcasting on a simplex interface, loopback a copy */
324 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
325 mcopy = m_copy(m, 0, (int)M_COPYALL);
326 etype = htons(ETHERTYPE_IP);
332 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
333 return(0); /* it must be impossible, but... */
335 if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst))
336 return(0); /* if not yet resolves */
338 etype = htons(ETHERTYPE_IPV6);
343 etype = htons(ETHERTYPE_NS);
344 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
345 (caddr_t)edst, sizeof (edst));
346 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
347 return (looutput(ifp, m, dst, rt));
348 /* If broadcasting on a simplex interface, loopback a copy */
349 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
350 mcopy = m_copy(m, 0, (int)M_COPYALL);
355 etype = htons(ETHERTYPE_IPX);
356 bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host,
357 (caddr_t)edst, sizeof (edst));
358 if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst)))
359 return (looutput(ifp, m, dst, rt));
360 /* If broadcasting on a simplex interface, loopback a copy */
361 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
362 mcopy = m_copy(m, 0, (int)M_COPYALL);
368 * The bottom line here is to either queue the outgoing packet
369 * in the discovery engine, or fill in edst with something
372 if (m->m_flags & M_MCAST) {
374 * If multicast dest., then use IPv6 -> Ethernet
375 * mcast mapping. Really simple.
377 ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr,
380 /* Do unicast neighbor discovery stuff. */
381 if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
384 etype = htons(ETHERTYPE_IPV6);
389 struct at_ifaddr *aa;
391 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
393 extern char *prsockaddr(struct sockaddr *);
394 printf("aarpresolv: failed for %s\n", prsockaddr(dst));
395 #endif /* NETATALKDEBUG */
400 * ifaddr is the first thing in at_ifaddr
402 aa = (struct at_ifaddr *)at_ifawithnet(
403 (struct sockaddr_at *)dst,
404 ifp->if_addrlist.tqh_first);
409 * In the phase 2 case, we need to prepend an mbuf for the llc
410 * header. Since we must preserve the value of m, which is
411 * passed to us by value, we m_copy() the first mbuf,
412 * and use it for our llc header.
414 if ( aa->aa_flags & AFA_PHASE2 ) {
417 /* XXX Really this should use netisr too */
418 M_PREPEND(m, AT_LLC_SIZE, M_WAIT);
420 * FreeBSD doesn't count the LLC len in
421 * ifp->obytes, so they increment a length
422 * field here. We don't do this.
424 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
425 llc.llc_control = LLC_UI;
426 bcopy(at_org_code, llc.llc_snap_org_code,
427 sizeof(at_org_code));
428 llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
429 bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
430 etype = htons(m->m_pkthdr.len);
432 etype = htons(ETHERTYPE_AT);
435 #endif /* NETATALK */
440 register struct sockaddr_dl *sdl;
442 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
443 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
444 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
446 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
447 (char *)edst, &snpalen);
449 goto bad; /* Not Resolved */
451 /* If broadcasting on a simplex interface, loopback a copy */
453 m->m_flags |= (M_BCAST|M_MCAST);
454 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
455 (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
456 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
458 eh = mtod(mcopy, struct ether_header *);
459 bcopy(edst, eh->ether_dhost, sizeof (edst));
460 bcopy(ac->ac_enaddr, eh->ether_shost,
464 M_PREPEND(m, 3, M_DONTWAIT);
467 etype = htons(m->m_pkthdr.len);
468 l = mtod(m, struct llc *);
469 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
470 l->llc_control = LLC_UI;
472 if (argo_debug[D_ETHER]) {
474 printf("unoutput: sending pkt to: ");
476 printf("%x ", edst[i] & 0xff);
484 register struct sockaddr_dl *sdl =
485 (struct sockaddr_dl *) rt -> rt_gateway;
487 if (sdl && sdl->sdl_family == AF_LINK
488 && sdl->sdl_alen > 0) {
489 bcopy(LLADDR(sdl), (char *)edst,
491 } else goto bad; /* Not a link interface ? Funny ... */
492 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
493 (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
494 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
496 eh = mtod(mcopy, struct ether_header *);
497 bcopy(edst, eh->ether_dhost, sizeof (edst));
498 bcopy(ac->ac_enaddr, eh->ether_shost,
502 etype = htons(m->m_pkthdr.len);
506 register struct llc *l = mtod(m, struct llc *);
508 printf("ether_output: sending LLC2 pkt to: ");
510 printf("%x ", edst[i] & 0xff);
511 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
512 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
513 l->llc_control & 0xff);
516 #endif /* LLC_DEBUG */
520 eh = (struct ether_header *)dst->sa_data;
521 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
522 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
523 etype = eh->ether_type;
528 // diag_printf("%s: can't handle af%d\n", ifp->if_xname,
531 printf("%s: can't handle af%d\n", ifp->if_xname,
534 senderr(EAFNOSUPPORT);
538 (void) looutput(ifp, mcopy, dst, rt);
541 * Add local net header. If no space in first mbuf,
544 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
547 eh = mtod(m, struct ether_header *);
548 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
549 sizeof(eh->ether_type));
550 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
551 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
552 sizeof(eh->ether_shost));
556 * Interfaces that are bridge members need special handling
559 if (ifp->if_bridge) {
560 bridge_output(ifp, m, NULL, NULL);
567 * Queue message on interface, and start output if interface
570 if (IF_QFULL(&ifp->if_snd)) {
571 // Let the interface try a dequeue anyway, in case the
572 // interface has "got better" from whatever made the queue
573 // fill up - being unplugged for example.
574 if ((ifp->if_flags & IFF_OACTIVE) == 0)
575 (*ifp->if_start)(ifp);
576 IF_DROP(&ifp->if_snd);
580 ifp->if_obytes += m->m_pkthdr.len;
581 IF_ENQUEUE(&ifp->if_snd, m);
582 if (m->m_flags & M_MCAST)
584 if ((ifp->if_flags & IFF_OACTIVE) == 0)
585 (*ifp->if_start)(ifp);
596 * Process a received Ethernet packet;
597 * the packet is in the mbuf chain m without
598 * the ether header, which is provided separately.
601 ether_input(ifp, eh, m)
603 register struct ether_header *eh;
606 register struct ifqueue *inq;
609 register struct llc *l;
610 struct arpcom *ac = (struct arpcom *)ifp;
612 unsigned int sched_what;
615 if ((ifp->if_flags & IFF_UP) == 0) {
619 ifp->if_lastchange = time;
620 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
621 if (eh->ether_dhost[0] & 1) {
622 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
623 sizeof(etherbroadcastaddr)) == 0)
624 m->m_flags |= M_BCAST;
626 m->m_flags |= M_MCAST;
628 if (m->m_flags & (M_BCAST|M_MCAST))
633 * Tap the packet off here for a bridge, if configured and
634 * active for this interface. bridge_input returns
635 * NULL if it has consumed the packet, otherwise, it
636 * gets processed as normal.
638 if (ifp->if_bridge) {
639 m = bridge_input(ifp, eh, m);
642 /* The bridge has determined it's for us. */
647 * If packet is unicast and we're in promiscuous mode, make sure it
648 * is for us. Drop otherwise.
650 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
651 (ifp->if_flags & IFF_PROMISC)) {
652 if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
660 etype = ntohs(eh->ether_type);
665 sched_what = NETISR_IP;
667 schednetisr(NETISR_IP);
673 if (ifp->if_flags & IFF_NOARP)
676 sched_what = NETISR_ARP;
678 schednetisr(NETISR_ARP);
683 case ETHERTYPE_REVARP:
684 if (ifp->if_flags & IFF_NOARP)
686 revarpinput(m); /* XXX queue? */
692 * Schedule IPv6 software interrupt for incoming IPv6 packet.
696 sched_what = NETISR_IPV6;
698 schednetisr(NETISR_IPV6);
706 sched_what = NETISR_IPX;
708 schednetisr(NETISR_IPX);
716 sched_what = NETISR_NS;
718 schednetisr(NETISR_NS);
726 sched_what = NETISR_ATALK;
728 schednetisr(NETISR_ATALK);
733 /* probably this should be done with a NETISR as well */
735 aarpinput((struct arpcom *)ifp, m);
739 if (llcfound || etype > ETHERMTU)
742 l = mtod(m, struct llc *);
743 switch (l->llc_dsap) {
747 * Some protocols (like Appletalk) need special
748 * handling depending on if they are type II
749 * or SNAP encapsulated. Everything else
750 * gets handled by stripping off the SNAP header
751 * and going back up to decapsulate.
753 if (l->llc_control == LLC_UI &&
754 l->llc_ssap == LLC_SNAP_LSAP &&
755 Bcmp(&(l->llc_snap_org_code)[0],
756 at_org_code, sizeof(at_org_code)) == 0 &&
757 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
759 m_adj(m, AT_LLC_SIZE);
761 sched_what = NETISR_ATALK;
763 schednetisr(NETISR_ATALK);
768 if (l->llc_control == LLC_UI &&
769 l->llc_ssap == LLC_SNAP_LSAP &&
770 Bcmp(&(l->llc_snap_org_code)[0],
771 aarp_org_code, sizeof(aarp_org_code)) == 0 &&
772 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
773 m_adj(m, AT_LLC_SIZE);
774 /* XXX Really this should use netisr too */
775 aarpinput((struct arpcom *)ifp, m);
778 #endif /* NETATALK */
779 if (l->llc_control == LLC_UI &&
780 l->llc_dsap == LLC_SNAP_LSAP &&
781 l->llc_ssap == LLC_SNAP_LSAP) {
783 if (m->m_pkthdr.len > etype)
784 m_adj(m, etype - m->m_pkthdr.len);
785 m->m_data += 6; /* XXX */
786 m->m_len -= 6; /* XXX */
787 m->m_pkthdr.len -= 6; /* XXX */
788 M_PREPEND(m, sizeof *eh, M_DONTWAIT);
791 *mtod(m, struct ether_header *) = *eh;
797 switch (l->llc_control) {
799 /* LLC_UI_P forbidden in class 1 service */
800 if ((l->llc_dsap == LLC_ISO_LSAP) &&
801 (l->llc_ssap == LLC_ISO_LSAP)) {
803 if (m->m_pkthdr.len > etype)
804 m_adj(m, etype - m->m_pkthdr.len);
805 m->m_data += 3; /* XXX */
806 m->m_len -= 3; /* XXX */
807 m->m_pkthdr.len -= 3; /* XXX */
808 M_PREPEND(m, sizeof *eh, M_DONTWAIT);
811 *mtod(m, struct ether_header *) = *eh;
813 if (argo_debug[D_ETHER])
814 printf("clnp packet");
817 sched_what = NETISR_ISO;
819 schednetisr(NETISR_ISO);
833 l->llc_dsap = l->llc_ssap = 0;
834 /* Fall through to */
839 register struct ether_header *eh2;
841 u_char c = l->llc_dsap;
843 l->llc_dsap = l->llc_ssap;
845 if (m->m_flags & (M_BCAST | M_MCAST))
848 sa.sa_family = AF_UNSPEC;
849 sa.sa_len = sizeof(sa);
850 eh2 = (struct ether_header *)sa.sa_data;
851 for (i = 0; i < 6; i++) {
852 eh2->ether_shost[i] = c = eh->ether_dhost[i];
853 eh2->ether_dhost[i] =
854 eh->ether_dhost[i] = eh->ether_shost[i];
855 eh->ether_shost[i] = c;
857 ifp->if_output(ifp, m, &sa, NULL);
865 if (m->m_pkthdr.len > etype)
866 m_adj(m, etype - m->m_pkthdr.len);
867 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
870 if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
871 eh->ether_dhost, LLC_X25_LSAP, 6,
872 mtod(m, struct sdl_hdr *)))
873 panic("ETHER cons addr failure");
874 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
876 printf("llc packet\n");
877 #endif /* LLC_DEBUG */
879 sched_what = NETISR_CCITT;
881 schednetisr(NETISR_CCITT);
901 schednetisr(sched_what);
906 * Convert Ethernet address to printable (loggable) representation.
908 static char digits[] = "0123456789abcdef";
914 static char etherbuf[18];
915 register char *cp = etherbuf;
917 for (i = 0; i < 6; i++) {
918 *cp++ = digits[*ap >> 4];
919 *cp++ = digits[*ap++ & 0xf];
927 * Perform common duties while attaching to interface list
931 register struct ifnet *ifp;
933 register struct ifaddr *ifa;
934 register struct sockaddr_dl *sdl;
936 ifp->if_type = IFT_ETHER;
939 ifp->if_mtu = ETHERMTU;
940 ifp->if_output = ether_output;
941 for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
942 ifa = ifa->ifa_list.tqe_next)
943 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
944 sdl->sdl_family == AF_LINK) {
945 sdl->sdl_type = IFT_ETHER;
946 sdl->sdl_alen = ifp->if_addrlen;
947 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
948 LLADDR(sdl), ifp->if_addrlen);
951 LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
958 struct arpcom *ac = (struct arpcom *)ifp;
959 struct ether_multi *enm;
961 for (enm = LIST_FIRST(&ac->ac_multiaddrs); enm;
962 enm = LIST_FIRST(&ac->ac_multiaddrs)) {
963 LIST_REMOVE(enm, enm_list);
964 free(enm, M_IFMADDR);
968 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
969 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
972 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
973 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
977 * Add an Ethernet multicast address or range of addresses to the list for a
981 ether_addmulti(ifr, ac)
983 register struct arpcom *ac;
985 register struct ether_multi *enm;
986 struct sockaddr_in *sin;
988 struct sockaddr_in6 *sin6;
994 switch (ifr->ifr_addr.sa_family) {
997 bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
998 bcopy(addrlo, addrhi, 6);
1003 sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1004 if (sin->sin_addr.s_addr == INADDR_ANY) {
1006 * An IP address of INADDR_ANY means listen to all
1007 * of the Ethernet multicast addresses used for IP.
1008 * (This is for the sake of IP multicast routers.)
1010 bcopy(ether_ipmulticast_min, addrlo, 6);
1011 bcopy(ether_ipmulticast_max, addrhi, 6);
1014 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1015 bcopy(addrlo, addrhi, 6);
1021 sin6 = (struct sockaddr_in6 *)
1022 &(((struct in6_ifreq *)ifr)->ifr_addr);
1023 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1025 * An unspecified IPv6 address means listen to all
1026 * of the IPv6 multicast addresses on this Ethernet.
1027 * (Multicast routers like this.)
1029 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1030 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1032 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1033 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1040 return (EAFNOSUPPORT);
1044 * Verify that we have valid Ethernet multicast addresses.
1046 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1051 * See if the address range is already in the list.
1053 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1056 * Found it; just increment the reference count.
1058 ++enm->enm_refcount;
1063 * New address or range; malloc a new multicast record
1064 * and link it into the interface's multicast list.
1066 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1071 bcopy(addrlo, enm->enm_addrlo, 6);
1072 bcopy(addrhi, enm->enm_addrhi, 6);
1074 enm->enm_refcount = 1;
1075 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1079 * Return ENETRESET to inform the driver that the list has changed
1080 * and its reception filter should be adjusted accordingly.
1086 * Delete a multicast address record.
1089 ether_delmulti(ifr, ac)
1091 register struct arpcom *ac;
1093 register struct ether_multi *enm;
1094 struct sockaddr_in *sin;
1096 struct sockaddr_in6 *sin6;
1102 switch (ifr->ifr_addr.sa_family) {
1105 bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
1106 bcopy(addrlo, addrhi, 6);
1111 sin = (struct sockaddr_in *)&(ifr->ifr_addr);
1112 if (sin->sin_addr.s_addr == INADDR_ANY) {
1114 * An IP address of INADDR_ANY means stop listening
1115 * to the range of Ethernet multicast addresses used
1118 bcopy(ether_ipmulticast_min, addrlo, 6);
1119 bcopy(ether_ipmulticast_max, addrhi, 6);
1122 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
1123 bcopy(addrlo, addrhi, 6);
1129 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
1130 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1132 * An unspecified IPv6 address means stop listening to
1133 * all IPv6 multicast addresses on this Ethernet.'
1135 * (This might not be healthy, given IPv6's reliance on
1136 * multicast for things like neighbor discovery.
1137 * Perhaps initializing all-nodes, solicited nodes, and
1138 * possibly all-routers for this interface afterwards
1139 * is not a bad idea.)
1141 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
1142 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
1144 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1145 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1152 return (EAFNOSUPPORT);
1156 * Look up the address in our list.
1158 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1163 if (--enm->enm_refcount != 0) {
1165 * Still some claims to this record.
1171 * No remaining claims to this record; unlink and free it.
1173 LIST_REMOVE(enm, enm_list);
1174 free(enm, M_IFMADDR);
1178 * Return ENETRESET to inform the driver that the list has changed
1179 * and its reception filter should be adjusted accordingly.