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
ax25
ax25_ip.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 (C) Jonathan Naylor G4KLX (
[email protected]
)
8
*/
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/in.h>
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <
linux/timer.h
>
16
#include <linux/string.h>
17
#include <
linux/sockios.h
>
18
#include <linux/net.h>
19
#include <linux/slab.h>
20
#include <
net/ax25.h
>
21
#include <
linux/inet.h
>
22
#include <linux/netdevice.h>
23
#include <linux/if_arp.h>
24
#include <
linux/skbuff.h
>
25
#include <
net/sock.h
>
26
#include <asm/uaccess.h>
27
#include <linux/fcntl.h>
28
#include <
linux/termios.h
>
/* For TIOCINQ/OUTQ */
29
#include <
linux/mm.h
>
30
#include <
linux/interrupt.h
>
31
#include <
linux/notifier.h
>
32
#include <
linux/proc_fs.h
>
33
#include <linux/stat.h>
34
#include <linux/netfilter.h>
35
#include <linux/sysctl.h>
36
#include <
net/ip.h
>
37
#include <
net/arp.h
>
38
39
/*
40
* IP over AX.25 encapsulation.
41
*/
42
43
/*
44
* Shove an AX.25 UI header on an IP packet and handle ARP
45
*/
46
47
#ifdef CONFIG_INET
48
49
int
ax25_hard_header
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
50
unsigned
short
type
,
const
void
*
daddr
,
51
const
void
*
saddr
,
unsigned
int
len
)
52
{
53
unsigned
char
*buff;
54
55
/* they sometimes come back to us... */
56
if
(type ==
ETH_P_AX25
)
57
return
0;
58
59
/* header is an AX.25 UI frame from us to them */
60
buff =
skb_push
(skb,
AX25_HEADER_LEN
);
61
*buff++ = 0x00;
/* KISS DATA */
62
63
if
(daddr !=
NULL
)
64
memcpy
(buff, daddr, dev->
addr_len
);
/* Address specified */
65
66
buff[6] &= ~
AX25_CBIT
;
67
buff[6] &= ~
AX25_EBIT
;
68
buff[6] |=
AX25_SSSID_SPARE
;
69
buff +=
AX25_ADDR_LEN
;
70
71
if
(saddr !=
NULL
)
72
memcpy
(buff, saddr, dev->
addr_len
);
73
else
74
memcpy
(buff, dev->
dev_addr
, dev->
addr_len
);
75
76
buff[6] &= ~
AX25_CBIT
;
77
buff[6] |=
AX25_EBIT
;
78
buff[6] |=
AX25_SSSID_SPARE
;
79
buff +=
AX25_ADDR_LEN
;
80
81
*buff++ =
AX25_UI
;
/* UI */
82
83
/* Append a suitable AX.25 PID */
84
switch
(type) {
85
case
ETH_P_IP
:
86
*buff++ =
AX25_P_IP
;
87
break
;
88
case
ETH_P_ARP
:
89
*buff++ =
AX25_P_ARP
;
90
break
;
91
default
:
92
printk
(
KERN_ERR
"AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n"
, type);
93
*buff++ = 0;
94
break
;
95
}
96
97
if
(daddr !=
NULL
)
98
return
AX25_HEADER_LEN
;
99
100
return
-
AX25_HEADER_LEN
;
/* Unfinished header */
101
}
102
103
int
ax25_rebuild_header
(
struct
sk_buff
*skb)
104
{
105
struct
sk_buff
*ourskb;
106
unsigned
char
*bp = skb->
data
;
107
ax25_route
*route;
108
struct
net_device
*dev =
NULL
;
109
ax25_address
*
src
, *
dst
;
110
ax25_digi
*digipeat =
NULL
;
111
ax25_dev
*
ax25_dev
;
112
ax25_cb
*ax25;
113
char
ip_mode =
' '
;
114
115
dst = (
ax25_address
*)(bp + 1);
116
src = (
ax25_address
*)(bp + 8);
117
118
if
(
arp_find
(bp + 1, skb))
119
return
1;
120
121
route =
ax25_get_route
(dst,
NULL
);
122
if
(route) {
123
digipeat = route->
digipeat
;
124
dev = route->
dev
;
125
ip_mode = route->
ip_mode
;
126
}
127
128
if
(dev ==
NULL
)
129
dev = skb->
dev
;
130
131
if
((ax25_dev = ax25_dev_ax25dev(dev)) ==
NULL
) {
132
goto
put
;
133
}
134
135
if
(bp[16] ==
AX25_P_IP
) {
136
if
(ip_mode ==
'V'
|| (ip_mode ==
' '
&& ax25_dev->
values
[
AX25_VALUES_IPDEFMODE
])) {
137
/*
138
* We copy the buffer and release the original thereby
139
* keeping it straight
140
*
141
* Note: we report 1 back so the caller will
142
* not feed the frame direct to the physical device
143
* We don't want that to happen. (It won't be upset
144
* as we have pulled the frame from the queue by
145
* freeing it).
146
*
147
* NB: TCP modifies buffers that are still
148
* on a device queue, thus we use skb_copy()
149
* instead of using skb_clone() unless this
150
* gets fixed.
151
*/
152
153
ax25_address
src_c;
154
ax25_address
dst_c;
155
156
if
((ourskb =
skb_copy
(skb,
GFP_ATOMIC
)) ==
NULL
) {
157
kfree_skb
(skb);
158
goto
put
;
159
}
160
161
if
(skb->
sk
!=
NULL
)
162
skb_set_owner_w(ourskb, skb->
sk
);
163
164
kfree_skb
(skb);
165
/* dl9sau: bugfix
166
* after kfree_skb(), dst and src which were pointer
167
* to bp which is part of skb->data would not be valid
168
* anymore hope that after skb_pull(ourskb, ..) our
169
* dsc_c and src_c will not become invalid
170
*/
171
bp = ourskb->
data
;
172
dst_c = *(
ax25_address
*)(bp + 1);
173
src_c = *(
ax25_address
*)(bp + 8);
174
175
skb_pull
(ourskb,
AX25_HEADER_LEN
- 1);
/* Keep PID */
176
skb_reset_network_header(ourskb);
177
178
ax25=
ax25_send_frame
(
179
ourskb,
180
ax25_dev->
values
[
AX25_VALUES_PACLEN
],
181
&src_c,
182
&dst_c, digipeat, dev);
183
if
(ax25) {
184
ax25_cb_put(ax25);
185
}
186
goto
put
;
187
}
188
}
189
190
bp[7] &= ~
AX25_CBIT
;
191
bp[7] &= ~
AX25_EBIT
;
192
bp[7] |=
AX25_SSSID_SPARE
;
193
194
bp[14] &= ~
AX25_CBIT
;
195
bp[14] |=
AX25_EBIT
;
196
bp[14] |=
AX25_SSSID_SPARE
;
197
198
skb_pull
(skb,
AX25_KISS_HEADER_LEN
);
199
200
if
(digipeat !=
NULL
) {
201
if
((ourskb =
ax25_rt_build_path
(skb, src, dst, route->
digipeat
)) ==
NULL
) {
202
kfree_skb
(skb);
203
goto
put
;
204
}
205
206
skb = ourskb;
207
}
208
209
ax25_queue_xmit
(skb, dev);
210
211
put
:
212
if
(route)
213
ax25_put_route(route);
214
215
return
1;
216
}
217
218
#else
/* INET */
219
220
int
ax25_hard_header
(
struct
sk_buff
*skb,
struct
net_device
*dev,
221
unsigned
short
type,
const
void
*daddr,
222
const
void
*saddr,
unsigned
int
len)
223
{
224
return
-
AX25_HEADER_LEN
;
225
}
226
227
int
ax25_rebuild_header
(
struct
sk_buff
*skb)
228
{
229
return
1;
230
}
231
232
#endif
233
234
const
struct
header_ops
ax25_header_ops
= {
235
.create =
ax25_hard_header
,
236
.rebuild =
ax25_rebuild_header
,
237
};
238
239
EXPORT_SYMBOL
(
ax25_hard_header
);
240
EXPORT_SYMBOL
(
ax25_rebuild_header
);
241
EXPORT_SYMBOL
(ax25_header_ops);
242
Generated on Thu Jan 10 2013 14:56:50 for Linux Kernel by
1.8.2