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_ds_in.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
* Copyright (C) Joerg Reuter DL1BKE (
[email protected]
)
9
*/
10
#include <linux/errno.h>
11
#include <linux/types.h>
12
#include <linux/socket.h>
13
#include <linux/in.h>
14
#include <linux/kernel.h>
15
#include <
linux/timer.h
>
16
#include <linux/string.h>
17
#include <
linux/sockios.h
>
18
#include <linux/net.h>
19
#include <
net/ax25.h
>
20
#include <
linux/inet.h
>
21
#include <linux/netdevice.h>
22
#include <
linux/skbuff.h
>
23
#include <
net/sock.h
>
24
#include <
net/tcp_states.h
>
25
#include <asm/uaccess.h>
26
#include <linux/fcntl.h>
27
#include <
linux/mm.h
>
28
#include <
linux/interrupt.h
>
29
30
/*
31
* State machine for state 1, Awaiting Connection State.
32
* The handling of the timer(s) is in file ax25_ds_timer.c.
33
* Handling of state 0 and connection release is in ax25.c.
34
*/
35
static
int
ax25_ds_state1_machine(
ax25_cb
*ax25,
struct
sk_buff
*
skb
,
int
frametype,
int
pf
,
int
type
)
36
{
37
switch
(frametype) {
38
case
AX25_SABM
:
39
ax25->
modulus
=
AX25_MODULUS
;
40
ax25->
window
= ax25->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
41
ax25_send_control
(ax25,
AX25_UA
, pf,
AX25_RESPONSE
);
42
break
;
43
44
case
AX25_SABME
:
45
ax25->
modulus
=
AX25_EMODULUS
;
46
ax25->
window
= ax25->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
47
ax25_send_control
(ax25,
AX25_UA
, pf,
AX25_RESPONSE
);
48
break
;
49
50
case
AX25_DISC
:
51
ax25_send_control
(ax25,
AX25_DM
, pf,
AX25_RESPONSE
);
52
break
;
53
54
case
AX25_UA
:
55
ax25_calculate_rtt
(ax25);
56
ax25_stop_t1timer
(ax25);
57
ax25_start_t3timer
(ax25);
58
ax25_start_idletimer
(ax25);
59
ax25->
vs
= 0;
60
ax25->
va
= 0;
61
ax25->
vr
= 0;
62
ax25->
state
=
AX25_STATE_3
;
63
ax25->
n2count
= 0;
64
if
(ax25->
sk
!=
NULL
) {
65
bh_lock_sock
(ax25->
sk
);
66
ax25->
sk
->sk_state =
TCP_ESTABLISHED
;
67
/*
68
* For WAIT_SABM connections we will produce an accept
69
* ready socket here
70
*/
71
if
(!sock_flag(ax25->
sk
,
SOCK_DEAD
))
72
ax25->
sk
->sk_state_change(ax25->
sk
);
73
bh_unlock_sock
(ax25->
sk
);
74
}
75
ax25_dama_on
(ax25);
76
77
/* according to DK4EG's spec we are required to
78
* send a RR RESPONSE FINAL NR=0.
79
*/
80
81
ax25_std_enquiry_response
(ax25);
82
break
;
83
84
case
AX25_DM
:
85
if
(pf)
86
ax25_disconnect
(ax25,
ECONNREFUSED
);
87
break
;
88
89
default
:
90
if
(pf)
91
ax25_send_control
(ax25,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
92
break
;
93
}
94
95
return
0;
96
}
97
98
/*
99
* State machine for state 2, Awaiting Release State.
100
* The handling of the timer(s) is in file ax25_ds_timer.c
101
* Handling of state 0 and connection release is in ax25.c.
102
*/
103
static
int
ax25_ds_state2_machine(
ax25_cb
*ax25,
struct
sk_buff
*skb,
int
frametype,
int
pf,
int
type)
104
{
105
switch
(frametype) {
106
case
AX25_SABM
:
107
case
AX25_SABME
:
108
ax25_send_control
(ax25,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
109
ax25_dama_off
(ax25);
110
break
;
111
112
case
AX25_DISC
:
113
ax25_send_control
(ax25,
AX25_UA
, pf,
AX25_RESPONSE
);
114
ax25_dama_off
(ax25);
115
ax25_disconnect
(ax25, 0);
116
break
;
117
118
case
AX25_DM
:
119
case
AX25_UA
:
120
if
(pf) {
121
ax25_dama_off
(ax25);
122
ax25_disconnect
(ax25, 0);
123
}
124
break
;
125
126
case
AX25_I
:
127
case
AX25_REJ
:
128
case
AX25_RNR
:
129
case
AX25_RR
:
130
if
(pf) {
131
ax25_send_control
(ax25,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
132
ax25_dama_off
(ax25);
133
}
134
break
;
135
136
default
:
137
break
;
138
}
139
140
return
0;
141
}
142
143
/*
144
* State machine for state 3, Connected State.
145
* The handling of the timer(s) is in file ax25_timer.c
146
* Handling of state 0 and connection release is in ax25.c.
147
*/
148
static
int
ax25_ds_state3_machine(
ax25_cb
*ax25,
struct
sk_buff
*skb,
int
frametype,
int
ns
,
int
nr
,
int
pf,
int
type)
149
{
150
int
queued = 0;
151
152
switch
(frametype) {
153
case
AX25_SABM
:
154
case
AX25_SABME
:
155
if
(frametype ==
AX25_SABM
) {
156
ax25->
modulus
=
AX25_MODULUS
;
157
ax25->
window
= ax25->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
158
}
else
{
159
ax25->
modulus
=
AX25_EMODULUS
;
160
ax25->
window
= ax25->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
161
}
162
ax25_send_control
(ax25,
AX25_UA
, pf,
AX25_RESPONSE
);
163
ax25_stop_t1timer
(ax25);
164
ax25_start_t3timer
(ax25);
165
ax25_start_idletimer
(ax25);
166
ax25->
condition
= 0x00;
167
ax25->
vs
= 0;
168
ax25->
va
= 0;
169
ax25->
vr
= 0;
170
ax25_requeue_frames
(ax25);
171
ax25_dama_on
(ax25);
172
break
;
173
174
case
AX25_DISC
:
175
ax25_send_control
(ax25,
AX25_UA
, pf,
AX25_RESPONSE
);
176
ax25_dama_off
(ax25);
177
ax25_disconnect
(ax25, 0);
178
break
;
179
180
case
AX25_DM
:
181
ax25_dama_off
(ax25);
182
ax25_disconnect
(ax25,
ECONNRESET
);
183
break
;
184
185
case
AX25_RR
:
186
case
AX25_RNR
:
187
if
(frametype ==
AX25_RR
)
188
ax25->
condition
&= ~
AX25_COND_PEER_RX_BUSY
;
189
else
190
ax25->
condition
|=
AX25_COND_PEER_RX_BUSY
;
191
192
if
(
ax25_validate_nr
(ax25, nr)) {
193
if
(
ax25_check_iframes_acked
(ax25, nr))
194
ax25->
n2count
=0;
195
if
(type ==
AX25_COMMAND
&& pf)
196
ax25_ds_enquiry_response
(ax25);
197
}
else
{
198
ax25_ds_nr_error_recovery
(ax25);
199
ax25->
state
=
AX25_STATE_1
;
200
}
201
break
;
202
203
case
AX25_REJ
:
204
ax25->
condition
&= ~
AX25_COND_PEER_RX_BUSY
;
205
206
if
(
ax25_validate_nr
(ax25, nr)) {
207
if
(ax25->
va
!= nr)
208
ax25->
n2count
=0;
209
210
ax25_frames_acked
(ax25, nr);
211
ax25_calculate_rtt
(ax25);
212
ax25_stop_t1timer
(ax25);
213
ax25_start_t3timer
(ax25);
214
ax25_requeue_frames
(ax25);
215
216
if
(type ==
AX25_COMMAND
&& pf)
217
ax25_ds_enquiry_response
(ax25);
218
}
else
{
219
ax25_ds_nr_error_recovery
(ax25);
220
ax25->
state
=
AX25_STATE_1
;
221
}
222
break
;
223
224
case
AX25_I
:
225
if
(!
ax25_validate_nr
(ax25, nr)) {
226
ax25_ds_nr_error_recovery
(ax25);
227
ax25->
state
=
AX25_STATE_1
;
228
break
;
229
}
230
if
(ax25->
condition
&
AX25_COND_PEER_RX_BUSY
) {
231
ax25_frames_acked
(ax25, nr);
232
ax25->
n2count
= 0;
233
}
else
{
234
if
(
ax25_check_iframes_acked
(ax25, nr))
235
ax25->
n2count
= 0;
236
}
237
if
(ax25->
condition
&
AX25_COND_OWN_RX_BUSY
) {
238
if
(pf)
ax25_ds_enquiry_response
(ax25);
239
break
;
240
}
241
if
(ns == ax25->
vr
) {
242
ax25->
vr
= (ax25->
vr
+ 1) % ax25->
modulus
;
243
queued =
ax25_rx_iframe
(ax25, skb);
244
if
(ax25->
condition
&
AX25_COND_OWN_RX_BUSY
)
245
ax25->
vr
=
ns
;
/* ax25->vr - 1 */
246
ax25->
condition
&= ~
AX25_COND_REJECT
;
247
if
(pf) {
248
ax25_ds_enquiry_response
(ax25);
249
}
else
{
250
if
(!(ax25->
condition
&
AX25_COND_ACK_PENDING
)) {
251
ax25->
condition
|=
AX25_COND_ACK_PENDING
;
252
ax25_start_t2timer
(ax25);
253
}
254
}
255
}
else
{
256
if
(ax25->
condition
&
AX25_COND_REJECT
) {
257
if
(pf)
ax25_ds_enquiry_response
(ax25);
258
}
else
{
259
ax25->
condition
|=
AX25_COND_REJECT
;
260
ax25_ds_enquiry_response
(ax25);
261
ax25->
condition
&= ~
AX25_COND_ACK_PENDING
;
262
}
263
}
264
break
;
265
266
case
AX25_FRMR
:
267
case
AX25_ILLEGAL
:
268
ax25_ds_establish_data_link
(ax25);
269
ax25->
state
=
AX25_STATE_1
;
270
break
;
271
272
default
:
273
break
;
274
}
275
276
return
queued;
277
}
278
279
/*
280
* Higher level upcall for a LAPB frame
281
*/
282
int
ax25_ds_frame_in
(
ax25_cb
*ax25,
struct
sk_buff
*skb,
int
type)
283
{
284
int
queued = 0, frametype,
ns
,
nr
,
pf
;
285
286
frametype =
ax25_decode
(ax25, skb, &ns, &nr, &pf);
287
288
switch
(ax25->
state
) {
289
case
AX25_STATE_1
:
290
queued = ax25_ds_state1_machine(ax25, skb, frametype, pf, type);
291
break
;
292
case
AX25_STATE_2
:
293
queued = ax25_ds_state2_machine(ax25, skb, frametype, pf, type);
294
break
;
295
case
AX25_STATE_3
:
296
queued = ax25_ds_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
297
break
;
298
}
299
300
return
queued;
301
}
302
Generated on Thu Jan 10 2013 14:56:49 for Linux Kernel by
1.8.2