Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
802
fddi.c
Go to the documentation of this file.
1
/*
2
* INET An implementation of the TCP/IP protocol suite for the LINUX
3
* operating system. INET is implemented using the BSD Socket
4
* interface as the means of communication with the user level.
5
*
6
* FDDI-type device handling.
7
*
8
* Version: @(#)fddi.c 1.0.0 08/12/96
9
*
10
* Authors: Lawrence V. Stefani, <
[email protected]
>
11
*
12
* fddi.c is based on previous eth.c and tr.c work by
13
* Ross Biro
14
* Fred N. van Kempen, <
[email protected]
>
15
* Mark Evans, <
[email protected]
>
16
* Florian La Roche, <
[email protected]
>
17
* Alan Cox, <
[email protected]
>
18
*
19
* This program is free software; you can redistribute it and/or
20
* modify it under the terms of the GNU General Public License
21
* as published by the Free Software Foundation; either version
22
* 2 of the License, or (at your option) any later version.
23
*
24
* Changes
25
* Alan Cox : New arp/rebuild header
26
* Maciej W. Rozycki : IPv6 support
27
*/
28
29
#include <linux/module.h>
30
#include <linux/types.h>
31
#include <linux/kernel.h>
32
#include <linux/string.h>
33
#include <
linux/mm.h
>
34
#include <linux/socket.h>
35
#include <linux/in.h>
36
#include <
linux/inet.h
>
37
#include <linux/netdevice.h>
38
#include <
linux/fddidevice.h
>
39
#include <linux/if_ether.h>
40
#include <
linux/skbuff.h
>
41
#include <linux/errno.h>
42
#include <
net/arp.h
>
43
#include <
net/sock.h
>
44
45
/*
46
* Create the FDDI MAC header for an arbitrary protocol layer
47
*
48
* saddr=NULL means use device source address
49
* daddr=NULL means leave destination address (eg unresolved arp)
50
*/
51
52
static
int
fddi_header(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
53
unsigned
short
type
,
54
const
void
*
daddr
,
const
void
*
saddr
,
unsigned
int
len)
55
{
56
int
hl =
FDDI_K_SNAP_HLEN
;
57
struct
fddihdr
*fddi;
58
59
if
(type !=
ETH_P_IP
&& type !=
ETH_P_IPV6
&& type !=
ETH_P_ARP
)
60
hl=
FDDI_K_8022_HLEN
-3;
61
fddi = (
struct
fddihdr
*)
skb_push
(skb, hl);
62
fddi->
fc
=
FDDI_FC_K_ASYNC_LLC_DEF
;
63
if
(type ==
ETH_P_IP
|| type ==
ETH_P_IPV6
|| type ==
ETH_P_ARP
)
64
{
65
fddi->
hdr
.
llc_snap
.dsap =
FDDI_EXTENDED_SAP
;
66
fddi->
hdr
.
llc_snap
.ssap =
FDDI_EXTENDED_SAP
;
67
fddi->
hdr
.
llc_snap
.ctrl =
FDDI_UI_CMD
;
68
fddi->
hdr
.
llc_snap
.oui[0] = 0x00;
69
fddi->
hdr
.
llc_snap
.oui[1] = 0x00;
70
fddi->
hdr
.
llc_snap
.oui[2] = 0x00;
71
fddi->
hdr
.
llc_snap
.ethertype =
htons
(type);
72
}
73
74
/* Set the source and destination hardware addresses */
75
76
if
(saddr !=
NULL
)
77
memcpy
(fddi->
saddr
, saddr, dev->
addr_len
);
78
else
79
memcpy
(fddi->
saddr
, dev->
dev_addr
, dev->
addr_len
);
80
81
if
(daddr !=
NULL
)
82
{
83
memcpy
(fddi->
daddr
, daddr, dev->
addr_len
);
84
return
hl;
85
}
86
87
return
-hl;
88
}
89
90
91
/*
92
* Rebuild the FDDI MAC header. This is called after an ARP
93
* (or in future other address resolution) has completed on
94
* this sk_buff. We now let ARP fill in the other fields.
95
*/
96
97
static
int
fddi_rebuild_header(
struct
sk_buff
*skb)
98
{
99
struct
fddihdr
*fddi = (
struct
fddihdr
*)skb->
data
;
100
101
#ifdef CONFIG_INET
102
if
(fddi->
hdr
.
llc_snap
.ethertype ==
htons
(
ETH_P_IP
))
103
/* Try to get ARP to resolve the header and fill destination address */
104
return
arp_find
(fddi->
daddr
, skb);
105
else
106
#endif
107
{
108
printk
(
"%s: Don't know how to resolve type %04X addresses.\n"
,
109
skb->
dev
->name,
ntohs
(fddi->
hdr
.
llc_snap
.ethertype));
110
return
0;
111
}
112
}
113
114
115
/*
116
* Determine the packet's protocol ID and fill in skb fields.
117
* This routine is called before an incoming packet is passed
118
* up. It's used to fill in specific skb fields and to set
119
* the proper pointer to the start of packet data (skb->data).
120
*/
121
122
__be16
fddi_type_trans
(
struct
sk_buff
*skb,
struct
net_device
*dev)
123
{
124
struct
fddihdr
*fddi = (
struct
fddihdr
*)skb->
data
;
125
__be16
type;
126
127
/*
128
* Set mac.raw field to point to FC byte, set data field to point
129
* to start of packet data. Assume 802.2 SNAP frames for now.
130
*/
131
132
skb->
dev
= dev;
133
skb_reset_mac_header(skb);
/* point to frame control (FC) */
134
135
if
(fddi->
hdr
.
llc_8022_1
.dsap==0xe0)
136
{
137
skb_pull
(skb,
FDDI_K_8022_HLEN
-3);
138
type =
htons
(
ETH_P_802_2
);
139
}
140
else
141
{
142
skb_pull
(skb,
FDDI_K_SNAP_HLEN
);
/* adjust for 21 byte header */
143
type=fddi->
hdr
.
llc_snap
.ethertype;
144
}
145
146
/* Set packet type based on destination address and flag settings */
147
148
if
(*fddi->
daddr
& 0x01)
149
{
150
if
(
memcmp
(fddi->
daddr
, dev->
broadcast
,
FDDI_K_ALEN
) == 0)
151
skb->
pkt_type
=
PACKET_BROADCAST
;
152
else
153
skb->
pkt_type
=
PACKET_MULTICAST
;
154
}
155
156
else
if
(dev->
flags
&
IFF_PROMISC
)
157
{
158
if
(
memcmp
(fddi->
daddr
, dev->
dev_addr
,
FDDI_K_ALEN
))
159
skb->
pkt_type
=
PACKET_OTHERHOST
;
160
}
161
162
/* Assume 802.2 SNAP frames, for now */
163
164
return
type
;
165
}
166
167
EXPORT_SYMBOL
(
fddi_type_trans
);
168
169
int
fddi_change_mtu
(
struct
net_device
*dev,
int
new_mtu)
170
{
171
if
((new_mtu <
FDDI_K_SNAP_HLEN
) || (new_mtu >
FDDI_K_SNAP_DLEN
))
172
return
-
EINVAL
;
173
dev->
mtu
= new_mtu;
174
return
0;
175
}
176
EXPORT_SYMBOL
(
fddi_change_mtu
);
177
178
static
const
struct
header_ops
fddi_header_ops = {
179
.create = fddi_header,
180
.rebuild = fddi_rebuild_header,
181
};
182
183
184
static
void
fddi_setup(
struct
net_device
*dev)
185
{
186
dev->
header_ops
= &fddi_header_ops;
187
dev->
type
=
ARPHRD_FDDI
;
188
dev->
hard_header_len
=
FDDI_K_SNAP_HLEN
+3;
/* Assume 802.2 SNAP hdr len + 3 pad bytes */
189
dev->
mtu
=
FDDI_K_SNAP_DLEN
;
/* Assume max payload of 802.2 SNAP frame */
190
dev->
addr_len
=
FDDI_K_ALEN
;
191
dev->
tx_queue_len
= 100;
/* Long queues on FDDI */
192
dev->
flags
=
IFF_BROADCAST
|
IFF_MULTICAST
;
193
194
memset
(dev->
broadcast
, 0xFF,
FDDI_K_ALEN
);
195
}
196
208
struct
net_device
*
alloc_fddidev
(
int
sizeof_priv)
209
{
210
return
alloc_netdev
(sizeof_priv,
"fddi%d"
, fddi_setup);
211
}
212
EXPORT_SYMBOL
(
alloc_fddidev
);
213
214
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 14:56:35 for Linux Kernel by
1.8.2