1 //==========================================================================
3 // src/sys/net/if_ethersubr.c
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
8 // -------------------------------------------
10 // Portions of this software may have been derived from OpenBSD,
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
17 // -------------------------------------------
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
23 * Copyright (c) 1982, 1989, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
55 * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.70.2.17 2001/08/01 00:47:49 fenner Exp $
58 #include <sys/param.h>
59 #include <sys/malloc.h>
61 #include <sys/socket.h>
62 #include <sys/sockio.h>
63 #include <sys/sysctl.h>
66 #include <net/netisr.h>
67 #include <net/route.h>
68 #include <net/if_dl.h>
69 #include <net/if_types.h>
70 #include <net/ethernet.h>
72 #if defined(INET) || defined(INET6)
73 #include <netinet/in.h>
74 #include <netinet/in_var.h>
75 #include <netinet/if_ether.h>
78 #include <netinet6/nd6.h>
82 #include <netipx/ipx.h>
83 #include <netipx/ipx_if.h>
84 int (*ef_inputp)(struct ifnet*, struct ether_header *eh, struct mbuf *m);
85 int (*ef_outputp)(struct ifnet *ifp, struct mbuf **mp,
86 struct sockaddr *dst, short *tp, int *hlen);
91 #include <netns/ns_if.h>
93 int ether_outputdebug = 0;
94 int ether_inputdebug = 0;
98 #include <netatalk/at.h>
99 #include <netatalk/at_var.h>
100 #include <netatalk/at_extern.h>
102 #define llc_snap_org_code llc_un.type_snap.org_code
103 #define llc_snap_ether_type llc_un.type_snap.ether_type
105 extern u_char at_org_code[3];
106 extern u_char aarp_org_code[3];
107 #endif /* NETATALK */
110 #include <net/bridge.h>
115 #include <net/if_vlan_var.h>
116 #endif /* NVLAN > 0 */
118 /* netgraph node hooks for ng_ether(4) */
119 void (*ng_ether_input_p)(struct ifnet *ifp,
120 struct mbuf **mp, struct ether_header *eh);
121 void (*ng_ether_input_orphan_p)(struct ifnet *ifp,
122 struct mbuf *m, struct ether_header *eh);
123 int (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
124 void (*ng_ether_attach_p)(struct ifnet *ifp);
125 void (*ng_ether_detach_p)(struct ifnet *ifp);
127 static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
129 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
130 #define senderr(e) do { error = (e); goto bad;} while (0)
131 #define IFP2AC(IFP) ((struct arpcom *)IFP)
134 * Ethernet output routine.
135 * Encapsulate a packet of type family for the local net.
136 * Use trailer local net encapsulation if enough data in first
137 * packet leaves a multiple of 512 bytes of data in remainder.
138 * Assumes that ifp is actually pointer to arpcom structure.
141 ether_output(ifp, m, dst, rt0)
142 register struct ifnet *ifp;
144 struct sockaddr *dst;
148 int error = 0, hdrcmplt = 0;
149 u_char esrc[6], edst[6];
150 register struct rtentry *rt;
151 register struct ether_header *eh;
152 int off, loop_copy = 0;
153 int hlen; /* link layer header lenght */
154 struct arpcom *ac = IFP2AC(ifp);
156 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
160 if ((rt->rt_flags & RTF_UP) == 0) {
161 rt0 = rt = rtalloc1(dst, 1, 0UL);
165 senderr(EHOSTUNREACH);
167 if (rt->rt_flags & RTF_GATEWAY) {
168 if (rt->rt_gwroute == 0)
170 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
171 rtfree(rt); rt = rt0;
172 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
174 if ((rt = rt->rt_gwroute) == 0)
175 senderr(EHOSTUNREACH);
178 if (rt->rt_flags & RTF_REJECT)
179 if (rt->rt_rmx.rmx_expire == 0 ||
180 time_second < rt->rt_rmx.rmx_expire)
181 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
183 hlen = ETHER_HDR_LEN;
184 switch (dst->sa_family) {
187 if (!arpresolve(ac, rt, m, dst, edst, rt0))
188 return (0); /* if not yet resolved */
189 off = m->m_pkthdr.len - m->m_len;
190 type = htons(ETHERTYPE_IP);
195 if (!nd6_storelladdr(&ac->ac_if, rt, m, dst, (u_char *)edst)) {
196 /* Something bad happened */
199 off = m->m_pkthdr.len - m->m_len;
200 type = htons(ETHERTYPE_IPV6);
206 error = ef_outputp(ifp, &m, dst, &type, &hlen);
210 type = htons(ETHERTYPE_IPX);
211 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
212 (caddr_t)edst, sizeof (edst));
218 struct at_ifaddr *aa;
220 if ((aa = at_ifawithnet((struct sockaddr_at *)dst)) == NULL) {
223 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst))
226 * In the phase 2 case, need to prepend an mbuf for the llc header.
227 * Since we must preserve the value of m, which is passed to us by
228 * value, we m_copy() the first mbuf, and use it for our llc header.
230 if ( aa->aa_flags & AFA_PHASE2 ) {
233 M_PREPEND(m, sizeof(struct llc), M_WAIT);
234 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
235 llc.llc_control = LLC_UI;
236 bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
237 llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
238 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
239 type = htons(m->m_pkthdr.len);
240 hlen = sizeof(struct llc) + ETHER_HDR_LEN;
242 type = htons(ETHERTYPE_AT);
246 #endif /* NETATALK */
251 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
254 case 0x0: /* Novell 802.3 */
255 type = htons( m->m_pkthdr.len);
257 case 0xe0e0: /* Novell 802.2 and Token-Ring */
258 M_PREPEND(m, 3, M_WAIT);
259 type = htons( m->m_pkthdr.len);
260 cp = mtod(m, u_char *);
266 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
267 (caddr_t)edst, sizeof (edst));
269 * XXX if ns_thishost is the same as the node's ethernet
270 * address then just the default code will catch this anyhow.
271 * So I'm not sure if this next clause should be here at all?
274 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){
275 m->m_pkthdr.rcvif = ifp;
276 schednetisr(NETISR_NS);
287 if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){
288 m->m_flags |= M_BCAST;
293 case pseudo_AF_HDRCMPLT:
295 eh = (struct ether_header *)dst->sa_data;
296 (void)memcpy(esrc, eh->ether_shost, sizeof (esrc));
300 loop_copy = -1; /* if this is for us, don't do it */
301 eh = (struct ether_header *)dst->sa_data;
302 (void)memcpy(edst, eh->ether_dhost, sizeof (edst));
303 type = eh->ether_type;
307 printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
309 senderr(EAFNOSUPPORT);
313 * Add local net header. If no space in first mbuf,
316 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
319 eh = mtod(m, struct ether_header *);
320 (void)memcpy(&eh->ether_type, &type,
321 sizeof(eh->ether_type));
322 (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
324 (void)memcpy(eh->ether_shost, esrc,
325 sizeof(eh->ether_shost));
327 (void)memcpy(eh->ether_shost, ac->ac_enaddr,
328 sizeof(eh->ether_shost));
331 * If a simplex interface, and the packet is being sent to our
332 * Ethernet address or a broadcast address, loopback a copy.
333 * XXX To make a simplex device behave exactly like a duplex
334 * device, we should copy in the case of sending to our own
335 * ethernet address (thus letting the original actually appear
336 * on the wire). However, we don't do that here for security
337 * reasons and compatibility with the original behavior.
339 if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
340 if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
341 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
348 (void) if_simloop(ifp, n, dst->sa_family, hlen);
349 } else if (bcmp(eh->ether_dhost,
350 eh->ether_shost, ETHER_ADDR_LEN) == 0) {
351 (void) if_simloop(ifp, m, dst->sa_family, hlen);
352 return (0); /* XXX */
356 /* Handle ng_ether(4) processing, if any */
357 if (ng_ether_output_p != NULL) {
358 if ((error = (*ng_ether_output_p)(ifp, &m)) != 0) {
367 /* Continue with link-layer output */
368 return ether_output_frame(ifp, m);
372 * Ethernet link layer output routine to send a raw frame to the device.
374 * This assumes that the 14 byte Ethernet header is present and contiguous
375 * in the first mbuf (if BRIDGE'ing).
378 ether_output_frame(ifp, m)
382 int s, len, error = 0;
385 struct altq_pktattr pktattr;
389 if (do_bridge && BDG_USED(ifp) ) {
390 struct ether_header *eh; /* a ptr suffices */
392 m->m_pkthdr.rcvif = NULL;
393 eh = mtod(m, struct ether_header *);
394 m_adj(m, ETHER_HDR_LEN);
395 m = bdg_forward(m, eh, ifp);
402 if (ALTQ_IS_ENABLED(&ifp->if_snd))
403 altq_etherclassify(&ifp->if_snd, m, &pktattr);
406 len = m->m_pkthdr.len;
409 * Queue message on interface, and start output if interface
413 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
415 IFQ_ENQUEUE(&ifp->if_snd, m, error);
418 /* mbuf is already freed */
422 ifp->if_obytes += len;
423 if (mflags & M_MCAST)
425 if ((ifp->if_flags & IFF_OACTIVE) == 0)
426 (*ifp->if_start)(ifp);
432 * Process a received Ethernet packet;
433 * the packet is in the mbuf chain m without
434 * the ether header, which is provided separately.
436 * First we perform any link layer operations, then continue
437 * to the upper layers with ether_demux().
440 ether_input(ifp, eh, m)
442 struct ether_header *eh;
446 struct ether_header save_eh;
450 /* Check for a BPF tap */
451 if (ifp->if_bpf != NULL) {
454 /* This kludge is OK; BPF treats the "mbuf" as read-only */
456 mh.mh_data = (char *)eh;
457 mh.mh_len = ETHER_HDR_LEN;
458 bpf_mtap(ifp, (struct mbuf *)&mh);
462 /* Handle ng_ether(4) processing, if any */
463 if (ng_ether_input_p != NULL) {
464 (*ng_ether_input_p)(ifp, &m, eh);
470 /* Check for bridging mode */
471 if (do_bridge && BDG_USED(ifp) ) {
474 /* Check with bridging code */
475 if ((bif = bridge_in(ifp, eh)) == BDG_DROP) {
479 if (bif != BDG_LOCAL) {
480 struct mbuf *oldm = m ;
482 save_eh = *eh ; /* because it might change */
483 m = bdg_forward(m, eh, bif); /* needs forwarding */
485 * Do not continue if bdg_forward() processed our
486 * packet (and cleared the mbuf pointer m) or if
487 * it dropped (m_free'd) the packet itself.
490 if (bif == BDG_BCAST || bif == BDG_MCAST)
491 printf("bdg_forward drop MULTICAST PKT\n");
494 if (m != oldm) /* m changed! */
500 goto recvLocal; /* receive locally */
502 /* If not local and not multicast, just drop it */
512 /* Continue with upper layer processing */
513 ether_demux(ifp, eh, m);
517 * Upper layer processing for a received Ethernet packet.
520 ether_demux(ifp, eh, m)
522 struct ether_header *eh;
528 #if defined(NETATALK)
529 register struct llc *l;
533 if (! (do_bridge && BDG_USED(ifp) ) )
535 /* Discard packet if upper layers shouldn't see it because it was
536 unicast to a different Ethernet address. If the driver is working
537 properly, then this situation can only happen when the interface
538 is in promiscuous mode. */
539 if ((ifp->if_flags & IFF_PROMISC) != 0
540 && (eh->ether_dhost[0] & 1) == 0
541 && bcmp(eh->ether_dhost,
542 IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0) {
547 /* Discard packet if interface is not up */
548 if ((ifp->if_flags & IFF_UP) == 0) {
552 if (eh->ether_dhost[0] & 1) {
554 * If this is not a simplex interface, drop the packet
555 * if it came from us.
557 if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
559 struct sockaddr_dl *sdl = NULL;
561 /* find link-layer address */
562 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
563 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
564 sdl->sdl_family == AF_LINK)
567 if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
568 ETHER_ADDR_LEN) == 0) {
573 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
574 sizeof(etherbroadcastaddr)) == 0)
575 m->m_flags |= M_BCAST;
577 m->m_flags |= M_MCAST;
579 if (m->m_flags & (M_BCAST|M_MCAST))
582 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
584 ether_type = ntohs(eh->ether_type);
587 if (ether_type == vlan_proto) {
588 if (vlan_input(eh, m) < 0)
589 ifp->if_data.ifi_noproto++;
592 #endif /* NVLAN > 0 */
594 switch (ether_type) {
597 if (ipflow_fastforward(m))
599 schednetisr(NETISR_IP);
604 if (ifp->if_flags & IFF_NOARP) {
605 /* Discard packet if ARP is disabled on interface */
609 schednetisr(NETISR_ARP);
615 if (ef_inputp && ef_inputp(ifp, eh, m) == 0)
617 schednetisr(NETISR_IPX);
623 schednetisr(NETISR_IPV6);
628 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
629 schednetisr(NETISR_NS);
636 schednetisr(NETISR_ATALK);
640 /* probably this should be done with a NETISR as well */
641 aarpinput(IFP2AC(ifp), m); /* XXX */
643 #endif /* NETATALK */
646 if (ef_inputp && ef_inputp(ifp, eh, m) == 0)
650 checksum = mtod(m, ushort *);
652 if ((ether_type <= ETHERMTU) &&
653 ((*checksum == 0xffff) || (*checksum == 0xE0E0))){
654 if(*checksum == 0xE0E0) {
655 m->m_pkthdr.len -= 3;
659 schednetisr(NETISR_NS);
664 #if defined(NETATALK)
665 if (ether_type > ETHERMTU)
667 l = mtod(m, struct llc *);
668 switch (l->llc_dsap) {
670 switch (l->llc_control) {
672 if (l->llc_ssap != LLC_SNAP_LSAP)
675 if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
676 sizeof(at_org_code)) == 0 &&
677 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
679 m_adj( m, sizeof( struct llc ));
680 schednetisr(NETISR_ATALK);
684 if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
685 sizeof(aarp_org_code)) == 0 &&
686 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
687 m_adj( m, sizeof( struct llc ));
688 aarpinput(IFP2AC(ifp), m); /* XXX */
698 if (ng_ether_input_orphan_p != NULL)
699 (*ng_ether_input_orphan_p)(ifp, m, eh);
705 if (ng_ether_input_orphan_p != NULL)
706 (*ng_ether_input_orphan_p)(ifp, m, eh);
710 #endif /* NETATALK */
723 * Perform common duties while attaching to interface list
726 ether_ifattach(ifp, bpf)
727 register struct ifnet *ifp;
730 register struct ifaddr *ifa;
731 register struct sockaddr_dl *sdl;
734 ifp->if_type = IFT_ETHER;
737 ifp->if_mtu = ETHERMTU;
738 ifp->if_resolvemulti = ether_resolvemulti;
739 if (ifp->if_baudrate == 0)
740 ifp->if_baudrate = 10000000;
741 ifa = ifnet_addrs[ifp->if_index - 1];
742 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
743 sdl->sdl_type = IFT_ETHER;
744 sdl->sdl_alen = ifp->if_addrlen;
745 bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
748 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
750 if (ng_ether_attach_p != NULL)
751 (*ng_ether_attach_p)(ifp);
755 * Perform common duties while detaching an Ethernet interface
758 ether_ifdetach(ifp, bpf)
762 if (ng_ether_detach_p != NULL)
763 (*ng_ether_detach_p)(ifp);
771 SYSCTL_DECL(_net_link);
772 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
775 ether_ioctl(ifp, command, data)
780 struct ifaddr *ifa = (struct ifaddr *) data;
781 struct ifreq *ifr = (struct ifreq *) data;
786 ifp->if_flags |= IFF_UP;
788 switch (ifa->ifa_addr->sa_family) {
791 ifp->if_init(ifp->if_softc); /* before arpwhohas */
792 arp_ifinit(IFP2AC(ifp), ifa);
797 * XXX - This code is probably wrong
801 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
802 struct arpcom *ac = IFP2AC(ifp);
804 if (ipx_nullhost(*ina))
809 bcopy((caddr_t) ina->x_host.c_host,
810 (caddr_t) ac->ac_enaddr,
811 sizeof(ac->ac_enaddr));
817 ifp->if_init(ifp->if_softc);
823 * XXX - This code is probably wrong
827 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
828 struct arpcom *ac = IFP2AC(ifp);
830 if (ns_nullhost(*ina))
832 *(union ns_host *) (ac->ac_enaddr);
834 bcopy((caddr_t) ina->x_host.c_host,
835 (caddr_t) ac->ac_enaddr,
836 sizeof(ac->ac_enaddr));
842 ifp->if_init(ifp->if_softc);
847 ifp->if_init(ifp->if_softc);
856 sa = (struct sockaddr *) & ifr->ifr_data;
857 bcopy(IFP2AC(ifp)->ac_enaddr,
858 (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
864 * Set the interface MTU.
866 if (ifr->ifr_mtu > ETHERMTU) {
869 ifp->if_mtu = ifr->ifr_mtu;
877 ether_resolvemulti(ifp, llsa, sa)
879 struct sockaddr **llsa;
882 struct sockaddr_dl *sdl;
883 struct sockaddr_in *sin;
885 struct sockaddr_in6 *sin6;
889 switch(sa->sa_family) {
892 * No mapping needed. Just check that it's a valid MC address.
894 sdl = (struct sockaddr_dl *)sa;
895 e_addr = (u_char *)LLADDR(sdl);
896 if ((e_addr[0] & 1) != 1)
897 return EADDRNOTAVAIL;
903 sin = (struct sockaddr_in *)sa;
904 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
905 return EADDRNOTAVAIL;
906 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
908 sdl->sdl_len = sizeof *sdl;
909 sdl->sdl_family = AF_LINK;
910 sdl->sdl_index = ifp->if_index;
911 sdl->sdl_type = IFT_ETHER;
912 sdl->sdl_alen = ETHER_ADDR_LEN;
913 e_addr = (u_char *)LLADDR(sdl);
914 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
915 *llsa = (struct sockaddr *)sdl;
920 sin6 = (struct sockaddr_in6 *)sa;
921 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
923 * An IP6 address of 0 means listen to all
924 * of the Ethernet multicast address used for IP6.
925 * (This is used for multicast routers.)
927 ifp->if_flags |= IFF_ALLMULTI;
931 if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
932 return EADDRNOTAVAIL;
933 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
935 sdl->sdl_len = sizeof *sdl;
936 sdl->sdl_family = AF_LINK;
937 sdl->sdl_index = ifp->if_index;
938 sdl->sdl_type = IFT_ETHER;
939 sdl->sdl_alen = ETHER_ADDR_LEN;
940 e_addr = LLADDR(sdl);
941 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
942 *llsa = (struct sockaddr *)sdl;
948 * Well, the text isn't quite right, but it's the name