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
netrom
nr_dev.c
Go to the documentation of this file.
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
*
7
* Copyright Jonathan Naylor G4KLX (
[email protected]
)
8
*/
9
#include <linux/module.h>
10
#include <
linux/proc_fs.h
>
11
#include <linux/kernel.h>
12
#include <
linux/interrupt.h
>
13
#include <linux/fs.h>
14
#include <linux/types.h>
15
#include <linux/sysctl.h>
16
#include <linux/string.h>
17
#include <linux/socket.h>
18
#include <linux/errno.h>
19
#include <linux/fcntl.h>
20
#include <linux/in.h>
21
#include <linux/if_ether.h>
/* For the statistics structure. */
22
#include <linux/slab.h>
23
24
#include <asm/uaccess.h>
25
#include <asm/io.h>
26
27
#include <
linux/inet.h
>
28
#include <linux/netdevice.h>
29
#include <
linux/etherdevice.h
>
30
#include <linux/if_arp.h>
31
#include <
linux/skbuff.h
>
32
33
#include <
net/ip.h
>
34
#include <
net/arp.h
>
35
36
#include <
net/ax25.h
>
37
#include <
net/netrom.h
>
38
39
/*
40
* Only allow IP over NET/ROM frames through if the netrom device is up.
41
*/
42
43
int
nr_rx_ip
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
44
{
45
struct
net_device_stats
*
stats
= &dev->
stats
;
46
47
if
(!netif_running(dev)) {
48
stats->
rx_dropped
++;
49
return
0;
50
}
51
52
stats->
rx_packets
++;
53
stats->
rx_bytes
+= skb->
len
;
54
55
skb->
protocol
=
htons
(
ETH_P_IP
);
56
57
/* Spoof incoming device */
58
skb->
dev
=
dev
;
59
skb->
mac_header
= skb->
network_header
;
60
skb_reset_network_header(skb);
61
skb->
pkt_type
=
PACKET_HOST
;
62
63
netif_rx
(skb);
64
65
return
1;
66
}
67
68
#ifdef CONFIG_INET
69
70
static
int
nr_rebuild_header(
struct
sk_buff
*
skb
)
71
{
72
unsigned
char
*bp = skb->
data
;
73
74
if
(
arp_find
(bp + 7, skb))
75
return
1;
76
77
bp[6] &= ~
AX25_CBIT
;
78
bp[6] &= ~
AX25_EBIT
;
79
bp[6] |=
AX25_SSSID_SPARE
;
80
bp +=
AX25_ADDR_LEN
;
81
82
bp[6] &= ~
AX25_CBIT
;
83
bp[6] |=
AX25_EBIT
;
84
bp[6] |=
AX25_SSSID_SPARE
;
85
86
return
0;
87
}
88
89
#else
90
91
static
int
nr_rebuild_header(
struct
sk_buff
*skb)
92
{
93
return
1;
94
}
95
96
#endif
97
98
static
int
nr_header(
struct
sk_buff
*skb,
struct
net_device
*
dev
,
99
unsigned
short
type
,
100
const
void
*
daddr
,
const
void
*
saddr
,
unsigned
int
len)
101
{
102
unsigned
char
*buff =
skb_push
(skb,
NR_NETWORK_LEN
+
NR_TRANSPORT_LEN
);
103
104
memcpy
(buff, (saddr !=
NULL
) ? saddr : dev->
dev_addr
, dev->
addr_len
);
105
buff[6] &= ~
AX25_CBIT
;
106
buff[6] &= ~
AX25_EBIT
;
107
buff[6] |=
AX25_SSSID_SPARE
;
108
buff +=
AX25_ADDR_LEN
;
109
110
if
(daddr !=
NULL
)
111
memcpy
(buff, daddr, dev->
addr_len
);
112
buff[6] &= ~
AX25_CBIT
;
113
buff[6] |=
AX25_EBIT
;
114
buff[6] |=
AX25_SSSID_SPARE
;
115
buff +=
AX25_ADDR_LEN
;
116
117
*buff++ =
sysctl_netrom_network_ttl_initialiser
;
118
119
*buff++ =
NR_PROTO_IP
;
120
*buff++ =
NR_PROTO_IP
;
121
*buff++ = 0;
122
*buff++ = 0;
123
*buff++ =
NR_PROTOEXT
;
124
125
if
(daddr !=
NULL
)
126
return
37;
127
128
return
-37;
129
}
130
131
static
int
__must_check
nr_set_mac_address(
struct
net_device
*dev,
void
*
addr
)
132
{
133
struct
sockaddr
*
sa
=
addr
;
134
int
err
;
135
136
if
(!
memcmp
(dev->
dev_addr
, sa->
sa_data
, dev->
addr_len
))
137
return
0;
138
139
if
(dev->
flags
&
IFF_UP
) {
140
err =
ax25_listen_register
((
ax25_address
*)sa->
sa_data
,
NULL
);
141
if
(err)
142
return
err
;
143
144
ax25_listen_release
((
ax25_address
*)dev->
dev_addr
,
NULL
);
145
}
146
147
memcpy
(dev->
dev_addr
, sa->
sa_data
, dev->
addr_len
);
148
149
return
0;
150
}
151
152
static
int
nr_open(
struct
net_device
*dev)
153
{
154
int
err
;
155
156
err =
ax25_listen_register
((
ax25_address
*)dev->
dev_addr
,
NULL
);
157
if
(err)
158
return
err
;
159
160
netif_start_queue(dev);
161
162
return
0;
163
}
164
165
static
int
nr_close(
struct
net_device
*dev)
166
{
167
ax25_listen_release
((
ax25_address
*)dev->
dev_addr
,
NULL
);
168
netif_stop_queue(dev);
169
return
0;
170
}
171
172
static
netdev_tx_t
nr_xmit(
struct
sk_buff
*skb,
struct
net_device
*dev)
173
{
174
struct
net_device_stats
*
stats
= &dev->
stats
;
175
unsigned
int
len = skb->
len
;
176
177
if
(!
nr_route_frame
(skb,
NULL
)) {
178
kfree_skb
(skb);
179
stats->
tx_errors
++;
180
return
NETDEV_TX_OK
;
181
}
182
183
stats->
tx_packets
++;
184
stats->
tx_bytes
+= len;
185
186
return
NETDEV_TX_OK
;
187
}
188
189
static
const
struct
header_ops
nr_header_ops = {
190
.create = nr_header,
191
.rebuild= nr_rebuild_header,
192
};
193
194
static
const
struct
net_device_ops
nr_netdev_ops = {
195
.ndo_open = nr_open,
196
.ndo_stop = nr_close,
197
.ndo_start_xmit = nr_xmit,
198
.ndo_set_mac_address = nr_set_mac_address,
199
};
200
201
void
nr_setup
(
struct
net_device
*dev)
202
{
203
dev->
mtu
=
NR_MAX_PACKET_SIZE
;
204
dev->
netdev_ops
= &nr_netdev_ops;
205
dev->
header_ops
= &nr_header_ops;
206
dev->
hard_header_len
=
NR_NETWORK_LEN
+
NR_TRANSPORT_LEN
;
207
dev->
addr_len
=
AX25_ADDR_LEN
;
208
dev->
type
=
ARPHRD_NETROM
;
209
210
/* New-style flags. */
211
dev->
flags
=
IFF_NOARP
;
212
}
Generated on Thu Jan 10 2013 15:01:09 for Linux Kernel by
1.8.2