1 /* $NetBSD: if_fddisubr.c,v 1.77 2008/11/07 00:20:13 dyoung Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Copyright (c) 1982, 1989, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)if_fddisubr.c 8.1 (Berkeley) 6/10/93
62 * Id: if_fddisubr.c,v 1.15 1997/03/21 22:35:50 thomas Exp
66 * Copyright (c) 1995, 1996
67 * Matt Thomas <matt@3am-software.com>. 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. The name of its contributor may not be used to endorse or promote
78 * products derived from this software without specific prior written
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
93 * @(#)if_fddisubr.c 8.1 (Berkeley) 6/10/93
95 * Id: if_fddisubr.c,v 1.15 1997/03/21 22:35:50 thomas Exp
98 #include <sys/cdefs.h>
99 __KERNEL_RCSID(0, "$NetBSD: if_fddisubr.c,v 1.77 2008/11/07 00:20:13 dyoung Exp $");
101 #include "opt_inet.h"
102 #include "opt_atalk.h"
105 #include "opt_mbuftrace.h"
107 #include "bpfilter.h"
109 #include <sys/param.h>
110 #include <sys/systm.h>
111 #include <sys/kernel.h>
112 #include <sys/malloc.h>
113 #include <sys/mbuf.h>
114 #include <sys/protosw.h>
115 #include <sys/socket.h>
116 #include <sys/ioctl.h>
117 #include <sys/errno.h>
118 #include <sys/syslog.h>
123 #include <net/netisr.h>
124 #include <net/route.h>
125 #include <net/if_llc.h>
126 #include <net/if_dl.h>
127 #include <net/if_types.h>
134 #include <netinet/in.h>
135 #include <netinet/in_var.h>
136 #include <netinet/if_inarp.h>
137 #include "opt_gateway.h"
139 #include <net/if_fddi.h>
142 #include <netipx/ipx.h>
143 #include <netipx/ipx_if.h>
148 #include <netinet/in.h>
149 #include <netinet/in_var.h>
151 #include <netinet6/nd6.h>
157 #include <netinet/ip_carp.h>
161 #include <netdnet/dn.h>
165 #include <netiso/argo_debug.h>
166 #include <netiso/iso.h>
167 #include <netiso/iso_var.h>
168 #include <netiso/iso_snpac.h>
173 #include <netatalk/at.h>
174 #include <netatalk/at_var.h>
175 #include <netatalk/at_extern.h>
177 #define llc_snap_org_code llc_un.type_snap.org_code
178 #define llc_snap_ether_type llc_un.type_snap.ether_type
180 extern u_char at_org_code
[ 3 ];
181 extern u_char aarp_org_code
[ 3 ];
182 #endif /* NETATALK */
185 #include "bpfilter.h"
187 #define senderr(e) { error = (e); goto bad;}
190 * This really should be defined in if_llc.h but in case it isn't.
193 #define llc_snap llc_un.type_snap
196 #define FDDIADDR(ifp) LLADDR((ifp)->if_sadl)
197 #define CFDDIADDR(ifp) CLLADDR((ifp)->if_sadl)
199 static int fddi_output(struct ifnet
*, struct mbuf
*,
200 const struct sockaddr
*, struct rtentry
*);
201 static void fddi_input(struct ifnet
*, struct mbuf
*);
204 * FDDI output routine.
205 * Encapsulate a packet of type family for the local net.
206 * Assumes that ifp is actually pointer to ethercom structure.
209 fddi_output(struct ifnet
*ifp0
, struct mbuf
*m0
, const struct sockaddr
*dst
,
213 int error
= 0, hdrcmplt
= 0;
214 uint8_t esrc
[6], edst
[6];
217 struct fddi_header
*fh
;
218 struct mbuf
*mcopy
= NULL
;
219 struct ifnet
*ifp
= ifp0
;
220 ALTQ_DECL(struct altq_pktattr pktattr
;)
222 MCLAIM(m
, ifp
->if_mowner
);
225 if (ifp
->if_type
== IFT_CARP
) {
228 /* loop back if this is going to the carp interface */
229 if (dst
!= NULL
&& ifp0
->if_link_state
== LINK_STATE_UP
&&
230 (ifa
= ifa_ifwithaddr(dst
)) != NULL
&&
231 ifa
->ifa_ifp
== ifp0
)
232 return (looutput(ifp0
, m
, dst
, rt0
));
234 ifp
= ifp
->if_carpdev
;
235 /* ac = (struct arpcom *)ifp; */
237 if ((ifp0
->if_flags
& (IFF_UP
|IFF_RUNNING
)) !=
238 (IFF_UP
|IFF_RUNNING
))
241 #endif /* NCARP > 0 */
242 if ((ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) != (IFF_UP
|IFF_RUNNING
))
244 #if !defined(__bsdi__) || _BSDI_VERSION >= 199401
245 if ((rt
= rt0
) != NULL
) {
246 if ((rt
->rt_flags
& RTF_UP
) == 0) {
247 if ((rt0
= rt
= rtalloc1(dst
, 1)) != NULL
)
250 senderr(EHOSTUNREACH
);
252 if (rt
->rt_flags
& RTF_GATEWAY
) {
253 if (rt
->rt_gwroute
== 0)
255 if (((rt
= rt
->rt_gwroute
)->rt_flags
& RTF_UP
) == 0) {
256 rtfree(rt
); rt
= rt0
;
257 lookup
: rt
->rt_gwroute
= rtalloc1(rt
->rt_gateway
, 1);
258 if ((rt
= rt
->rt_gwroute
) == 0)
259 senderr(EHOSTUNREACH
);
262 if (rt
->rt_flags
& RTF_REJECT
)
263 if (rt
->rt_rmx
.rmx_expire
== 0 ||
264 time_second
< rt
->rt_rmx
.rmx_expire
)
265 senderr(rt
== rt0
? EHOSTDOWN
: EHOSTUNREACH
);
270 * If the queueing discipline needs packet classification,
271 * do it before prepending link headers.
273 IFQ_CLASSIFY(&ifp
->if_snd
, m
, dst
->sa_family
, &pktattr
);
275 switch (dst
->sa_family
) {
279 if (m
->m_flags
& M_BCAST
)
280 memcpy(edst
, fddibroadcastaddr
, sizeof(edst
));
281 else if (m
->m_flags
& M_MCAST
) {
282 ETHER_MAP_IP_MULTICAST(&satocsin(dst
)->sin_addr
,
284 } else if (!arpresolve(ifp
, rt
, m
, dst
, edst
))
285 return (0); /* if not yet resolved */
286 /* If broadcasting on a simplex interface, loopback a copy */
287 if ((m
->m_flags
& M_BCAST
) && (ifp
->if_flags
& IFF_SIMPLEX
))
288 mcopy
= m_copy(m
, 0, (int)M_COPYALL
);
289 etype
= htons(ETHERTYPE_IP
);
295 if (!nd6_storelladdr(ifp
, rt
, m
, dst
, edst
, sizeof(edst
))){
296 /* something bad happened */
299 etype
= htons(ETHERTYPE_IPV6
);
304 struct arphdr
*ah
= mtod(m
, struct arphdr
*);
305 if (m
->m_flags
& M_BCAST
)
306 memcpy(edst
, etherbroadcastaddr
, sizeof(edst
));
308 void *tha
= ar_tha(ah
);
311 memcpy(edst
, tha
, sizeof(edst
));
314 ah
->ar_hrd
= htons(ARPHRD_ETHER
);
316 switch (ntohs(ah
->ar_op
)) {
317 case ARPOP_REVREQUEST
:
319 etype
= htons(ETHERTYPE_REVARP
);
325 etype
= htons(ETHERTYPE_ARP
);
333 etype
= htons(ETHERTYPE_IPX
);
334 memcpy(edst
, &(((struct sockaddr_ipx
*)dst
)->sipx_addr
.x_host
),
336 /* If broadcasting on a simplex interface, loopback a copy */
337 if ((m
->m_flags
& M_BCAST
) && (ifp
->if_flags
& IFF_SIMPLEX
))
338 mcopy
= m_copy(m
, 0, (int)M_COPYALL
);
343 struct at_ifaddr
*aa
;
344 if (!aarpresolve(ifp
, m
, (const struct sockaddr_at
*)dst
, edst
)) {
346 printf("aarpresolv: failed\n");
351 * ifaddr is the first thing in at_ifaddr
353 if ((aa
= (struct at_ifaddr
*)at_ifawithnet(
354 (const struct sockaddr_at
*)dst
, ifp
)) == NULL
)
358 * In the phase 2 case, we need to prepend an mbuf for the llc
359 * header. Since we must preserve the value of m, which is
360 * passed to us by value, we m_copy() the first mbuf, and use
361 * it for our llc header.
363 if (aa
->aa_flags
& AFA_PHASE2
) {
366 M_PREPEND(m
, sizeof(struct llc
), M_NOWAIT
);
369 llc
.llc_dsap
= llc
.llc_ssap
= LLC_SNAP_LSAP
;
370 llc
.llc_control
= LLC_UI
;
371 memcpy(llc
.llc_snap_org_code
, at_org_code
,
372 sizeof(at_org_code
));
373 llc
.llc_snap_ether_type
= htons(ETHERTYPE_ATALK
);
374 memcpy(mtod(m
, void *), &llc
, sizeof(struct llc
));
377 etype
= htons(ETHERTYPE_ATALK
);
381 #endif /* NETATALK */
386 const struct sockaddr_dl
*sdl
;
388 if (rt
&& (sdl
= satocsdl(rt
->rt_gateway
)) &&
389 sdl
->sdl_family
== AF_LINK
&& sdl
->sdl_alen
> 0) {
390 memcpy(edst
, CLLADDR(sdl
), sizeof(edst
));
392 iso_snparesolve(ifp
, (const struct sockaddr_iso
*)dst
,
393 (char *)edst
, &snpalen
)) != 0)
394 goto bad
; /* Not Resolved */
395 /* If broadcasting on a simplex interface, loopback a copy */
397 m
->m_flags
|= (M_BCAST
|M_MCAST
);
398 if ((m
->m_flags
& M_BCAST
) && (ifp
->if_flags
& IFF_SIMPLEX
) &&
399 (mcopy
= m_copy(m
, 0, (int)M_COPYALL
))) {
400 M_PREPEND(mcopy
, sizeof (*fh
), M_DONTWAIT
);
402 fh
= mtod(mcopy
, struct fddi_header
*);
403 memcpy(fh
->fddi_dhost
, edst
, sizeof (edst
));
404 memcpy(fh
->fddi_shost
, CFDDIADDR(ifp
),
408 M_PREPEND(m
, 3, M_DONTWAIT
);
412 l
= mtod(m
, struct llc
*);
413 l
->llc_dsap
= l
->llc_ssap
= LLC_ISO_LSAP
;
414 l
->llc_control
= LLC_UI
;
418 case pseudo_AF_HDRCMPLT
:
420 const struct fddi_header
*fh1
=
421 (const struct fddi_header
*)dst
->sa_data
;
423 memcpy(esrc
, fh1
->fddi_shost
, sizeof (esrc
));
429 const struct fddi_header
*fh1
=
430 (const struct fddi_header
*)dst
->sa_data
;
431 memcpy(edst
, fh1
->fddi_dhost
, sizeof (edst
));
433 m
->m_flags
|= (M_BCAST
|M_MCAST
);
440 const struct ether_header
*eh
;
441 eh
= (const struct ether_header
*)dst
->sa_data
;
442 memcpy(edst
, eh
->ether_dhost
, sizeof(edst
));
444 m
->m_flags
|= (M_BCAST
|M_MCAST
);
445 etype
= eh
->ether_type
;
452 fh
= mtod(m
, struct fddi_header
*);
453 error
= EPROTONOSUPPORT
;
454 switch (fh
->fddi_fc
& (FDDIFC_C
|FDDIFC_L
|FDDIFC_F
)) {
455 case FDDIFC_LLC_ASYNC
: {
456 /* legal priorities are 0 through 7 */
457 if ((fh
->fddi_fc
& FDDIFC_Z
) > 7)
461 case FDDIFC_LLC_SYNC
: {
462 /* FDDIFC_Z bits reserved, must be zero */
463 if (fh
->fddi_fc
& FDDIFC_Z
)
468 /* FDDIFC_Z bits must be non zero */
469 if ((fh
->fddi_fc
& FDDIFC_Z
) == 0)
474 /* anything else is too dangerous */
479 if (fh
->fddi_dhost
[0] & 1)
480 m
->m_flags
|= (M_BCAST
|M_MCAST
);
485 printf("%s: can't handle af%d\n", ifp
->if_xname
,
487 senderr(EAFNOSUPPORT
);
492 (void) looutput(ifp
, mcopy
, dst
, rt
);
495 M_PREPEND(m
, sizeof (struct llc
), M_DONTWAIT
);
498 l
= mtod(m
, struct llc
*);
499 l
->llc_control
= LLC_UI
;
500 l
->llc_dsap
= l
->llc_ssap
= LLC_SNAP_LSAP
;
501 l
->llc_snap
.org_code
[0] = l
->llc_snap
.org_code
[1] = l
->llc_snap
.org_code
[2] = 0;
502 memcpy(&l
->llc_snap
.ether_type
, &etype
, sizeof(uint16_t));
505 * Add local net header. If no space in first mbuf,
508 M_PREPEND(m
, sizeof (struct fddi_header
), M_DONTWAIT
);
511 fh
= mtod(m
, struct fddi_header
*);
512 fh
->fddi_fc
= FDDIFC_LLC_ASYNC
|FDDIFC_LLC_PRIO4
;
513 memcpy(fh
->fddi_dhost
, edst
, sizeof (edst
));
518 memcpy(fh
->fddi_shost
, esrc
, sizeof(fh
->fddi_shost
));
520 memcpy(fh
->fddi_shost
, CFDDIADDR(ifp
), sizeof(fh
->fddi_shost
));
523 if (ifp0
!= ifp
&& ifp0
->if_type
== IFT_CARP
) {
524 if_set_sadl(ifp0
, fh
->fddi_shost
, sizeof(fh
->fddi_shost
),
529 ifp0
->if_obytes
+= m
->m_pkthdr
.len
;
530 #endif /* NCARP > 0 */
531 return ifq_enqueue(ifp
, m ALTQ_COMMA
ALTQ_DECL(&pktattr
));
540 * Process a received FDDI packet;
541 * the packet is in the mbuf chain m with
545 fddi_input(struct ifnet
*ifp
, struct mbuf
*m
)
547 #if defined(INET) || defined(INET6) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
552 struct fddi_header
*fh
;
554 MCLAIM(m
, &((struct ethercom
*)ifp
)->ec_rx_mowner
);
555 if ((ifp
->if_flags
& IFF_UP
) == 0) {
560 fh
= mtod(m
, struct fddi_header
*);
562 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
563 if (fh
->fddi_dhost
[0] & 1) {
564 if (memcmp(fddibroadcastaddr
, fh
->fddi_dhost
,
565 sizeof(fddibroadcastaddr
)) == 0)
566 m
->m_flags
|= M_BCAST
;
568 m
->m_flags
|= M_MCAST
;
570 } else if ((ifp
->if_flags
& IFF_PROMISC
)
571 && memcmp(CFDDIADDR(ifp
), (void *)fh
->fddi_dhost
,
572 sizeof(fh
->fddi_dhost
)) != 0) {
579 * If this has a LLC priority of 0, then mark it so upper
580 * layers have a hint that it really came via a FDDI/Ethernet
583 if ((fh
->fddi_fc
& FDDIFC_LLC_PRIO7
) == FDDIFC_LLC_PRIO0
)
584 m
->m_flags
|= M_LINK0
;
587 l
= (struct llc
*)(fh
+1);
588 switch (l
->llc_dsap
) {
589 #if defined(INET) || defined(INET6) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
593 if (l
->llc_control
!= LLC_UI
|| l
->llc_ssap
!= LLC_SNAP_LSAP
)
596 /* Strip off the FDDI header. */
597 m_adj(m
, sizeof(struct fddi_header
));
600 if (memcmp(&(l
->llc_snap_org_code
)[0], at_org_code
,
601 sizeof(at_org_code
)) == 0 &&
602 ntohs(l
->llc_snap_ether_type
) == ETHERTYPE_ATALK
) {
604 m_adj( m
, sizeof( struct llc
));
605 schednetisr(NETISR_ATALK
);
609 if (memcmp(&(l
->llc_snap_org_code
)[0], aarp_org_code
,
610 sizeof(aarp_org_code
)) == 0 &&
611 ntohs(l
->llc_snap_ether_type
) == ETHERTYPE_AARP
) {
612 m_adj( m
, sizeof( struct llc
));
613 aarpinput(ifp
, m
); /* XXX */
616 #endif /* NETATALK */
617 if (l
->llc_snap
.org_code
[0] != 0 || l
->llc_snap
.org_code
[1] != 0|| l
->llc_snap
.org_code
[2] != 0)
619 etype
= ntohs(l
->llc_snap
.ether_type
);
622 if (ifp
->if_carp
&& ifp
->if_type
!= IFT_CARP
&&
623 (carp_input(m
, (uint8_t *)&fh
->fddi_shost
,
624 (uint8_t *)&fh
->fddi_dhost
, l
->llc_snap
.ether_type
) == 0))
632 if (ipflow_fastforward(m
))
635 schednetisr(NETISR_IP
);
640 #if !defined(__bsdi__) || _BSDI_VERSION >= 199401
641 schednetisr(NETISR_ARP
);
651 schednetisr(NETISR_IPX
);
658 if (ip6flow_fastforward(m
))
661 schednetisr(NETISR_IPV6
);
667 case ETHERTYPE_DECNET
:
668 schednetisr(NETISR_DECNET
);
673 case ETHERTYPE_ATALK
:
674 schednetisr(NETISR_ATALK
);
678 /* probably this should be done with a NETISR as well */
679 aarpinput(ifp
, m
); /* XXX */
681 #endif /* NETATALK */
688 #endif /* INET || NS */
691 switch (l
->llc_control
) {
693 /* LLC_UI_P forbidden in class 1 service */
694 if ((l
->llc_dsap
== LLC_ISO_LSAP
) &&
695 (l
->llc_ssap
== LLC_ISO_LSAP
)) {
697 schednetisr(NETISR_ISO
);
706 LLC_XID_BASIC_MINLEN
+ sizeof(struct fddi_header
))
709 l
->llc_fid
= LLC_XID_FORMAT_BASIC
;
710 l
->llc_class
= LLC_XID_CLASS_I
;
711 l
->llc_dsap
= l
->llc_ssap
= 0;
712 /* Fall through to */
717 struct ether_header
*eh
;
719 u_char c
= l
->llc_dsap
;
721 l
->llc_dsap
= l
->llc_ssap
;
723 eh
= (struct ether_header
*)sa
.sa_data
;
724 if (m
->m_flags
& (M_BCAST
| M_MCAST
))
725 memcpy(eh
->ether_dhost
, CFDDIADDR(ifp
), 6);
726 sa
.sa_family
= AF_UNSPEC
;
727 sa
.sa_len
= sizeof(sa
);
728 for (i
= 0; i
< 6; i
++) {
729 eh
->ether_shost
[i
] = fh
->fddi_dhost
[i
];
730 eh
->ether_dhost
[i
] = fh
->fddi_shost
[i
];
733 m_adj(m
, sizeof(struct fddi_header
));
734 ifp
->if_output(ifp
, m
, &sa
, NULL
);
746 #if defined(INET) || defined(INET6) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
753 #if defined(INET) || defined(INET6) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
765 * Perform common duties while attaching to interface list
768 fddi_ifattach(struct ifnet
*ifp
, void *lla
)
770 struct ethercom
*ec
= (struct ethercom
*)ifp
;
772 ifp
->if_type
= IFT_FDDI
;
774 ifp
->if_dlt
= DLT_FDDI
;
775 ifp
->if_mtu
= FDDIMTU
;
776 ifp
->if_output
= fddi_output
;
777 ifp
->if_input
= fddi_input
;
778 ifp
->if_baudrate
= IF_Mbps(100);
779 #ifdef IFF_NOTRAILERS
780 ifp
->if_flags
|= IFF_NOTRAILERS
;
784 * Update the max_linkhdr
786 if (ALIGN(ifp
->if_hdrlen
) > max_linkhdr
)
787 max_linkhdr
= ALIGN(ifp
->if_hdrlen
);
789 LIST_INIT(&ec
->ec_multiaddrs
);
790 if_set_sadl(ifp
, lla
, 6, true);
792 ifp
->if_broadcastaddr
= fddibroadcastaddr
;
794 bpfattach(ifp
, DLT_FDDI
, sizeof(struct fddi_header
));
795 #endif /* NBPFILTER > 0 */
797 strlcpy(ec
->ec_tx_mowner
.mo_name
, ifp
->if_xname
,
798 sizeof(ec
->ec_tx_mowner
.mo_name
));
799 strlcpy(ec
->ec_tx_mowner
.mo_descr
, "tx",
800 sizeof(ec
->ec_tx_mowner
.mo_descr
));
801 strlcpy(ec
->ec_rx_mowner
.mo_name
, ifp
->if_xname
,
802 sizeof(ec
->ec_rx_mowner
.mo_name
));
803 strlcpy(ec
->ec_rx_mowner
.mo_descr
, "rx",
804 sizeof(ec
->ec_rx_mowner
.mo_descr
));
805 MOWNER_ATTACH(&ec
->ec_tx_mowner
);
806 MOWNER_ATTACH(&ec
->ec_rx_mowner
);
807 ifp
->if_mowner
= &ec
->ec_tx_mowner
;