Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/ax25/ax25_std_in.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
*
4
* Copyright (C) Alan Cox GW4PTS ([email protected])
5
* Copyright (C) Jonathan Naylor G4KLX ([email protected])
6
* Copyright (C) Joerg Reuter DL1BKE ([email protected])
7
* Copyright (C) Hans-Joachim Hetscher DD8NE ([email protected])
8
*
9
* Most of this code is based on the SDL diagrams published in the 7th ARRL
10
* Computer Networking Conference papers. The diagrams have mistakes in them,
11
* but are mostly correct. Before you modify the code could you read the SDL
12
* diagrams as the code is not obvious and probably very easy to break.
13
*/
14
#include <linux/errno.h>
15
#include <linux/types.h>
16
#include <linux/socket.h>
17
#include <linux/in.h>
18
#include <linux/kernel.h>
19
#include <linux/timer.h>
20
#include <linux/string.h>
21
#include <linux/sockios.h>
22
#include <linux/net.h>
23
#include <net/ax25.h>
24
#include <linux/inet.h>
25
#include <linux/netdevice.h>
26
#include <linux/skbuff.h>
27
#include <net/sock.h>
28
#include <net/tcp_states.h>
29
#include <linux/uaccess.h>
30
#include <linux/fcntl.h>
31
#include <linux/mm.h>
32
#include <linux/interrupt.h>
33
34
/*
35
* State machine for state 1, Awaiting Connection State.
36
* The handling of the timer(s) is in file ax25_std_timer.c.
37
* Handling of state 0 and connection release is in ax25.c.
38
*/
39
static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
40
{
41
switch (frametype) {
42
case AX25_SABM:
43
ax25->modulus = AX25_MODULUS;
44
ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
45
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
46
break;
47
48
case AX25_SABME:
49
ax25->modulus = AX25_EMODULUS;
50
ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
51
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
52
break;
53
54
case AX25_DISC:
55
ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
56
break;
57
58
case AX25_UA:
59
if (pf) {
60
ax25_calculate_rtt(ax25);
61
ax25_stop_t1timer(ax25);
62
ax25_start_t3timer(ax25);
63
ax25_start_idletimer(ax25);
64
ax25->vs = 0;
65
ax25->va = 0;
66
ax25->vr = 0;
67
ax25->state = AX25_STATE_3;
68
ax25->n2count = 0;
69
if (ax25->sk != NULL) {
70
bh_lock_sock(ax25->sk);
71
ax25->sk->sk_state = TCP_ESTABLISHED;
72
/* For WAIT_SABM connections we will produce an accept ready socket here */
73
if (!sock_flag(ax25->sk, SOCK_DEAD))
74
ax25->sk->sk_state_change(ax25->sk);
75
bh_unlock_sock(ax25->sk);
76
}
77
}
78
break;
79
80
case AX25_DM:
81
if (pf) {
82
if (ax25->modulus == AX25_MODULUS) {
83
ax25_disconnect(ax25, ECONNREFUSED);
84
} else {
85
ax25->modulus = AX25_MODULUS;
86
ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
87
}
88
}
89
break;
90
91
default:
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_std_timer.c
101
* Handling of state 0 and connection release is in ax25.c.
102
*/
103
static int ax25_std_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_DM, pf, AX25_RESPONSE);
109
break;
110
111
case AX25_DISC:
112
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
113
ax25_disconnect(ax25, 0);
114
break;
115
116
case AX25_DM:
117
case AX25_UA:
118
if (pf)
119
ax25_disconnect(ax25, 0);
120
break;
121
122
case AX25_I:
123
case AX25_REJ:
124
case AX25_RNR:
125
case AX25_RR:
126
if (pf) ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
127
break;
128
129
default:
130
break;
131
}
132
133
return 0;
134
}
135
136
/*
137
* State machine for state 3, Connected State.
138
* The handling of the timer(s) is in file ax25_std_timer.c
139
* Handling of state 0 and connection release is in ax25.c.
140
*/
141
static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
142
{
143
int queued = 0;
144
145
switch (frametype) {
146
case AX25_SABM:
147
case AX25_SABME:
148
if (frametype == AX25_SABM) {
149
ax25->modulus = AX25_MODULUS;
150
ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
151
} else {
152
ax25->modulus = AX25_EMODULUS;
153
ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
154
}
155
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
156
ax25_stop_t1timer(ax25);
157
ax25_stop_t2timer(ax25);
158
ax25_start_t3timer(ax25);
159
ax25_start_idletimer(ax25);
160
ax25->condition = 0x00;
161
ax25->vs = 0;
162
ax25->va = 0;
163
ax25->vr = 0;
164
ax25_requeue_frames(ax25);
165
break;
166
167
case AX25_DISC:
168
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
169
ax25_disconnect(ax25, 0);
170
break;
171
172
case AX25_DM:
173
ax25_disconnect(ax25, ECONNRESET);
174
break;
175
176
case AX25_RR:
177
case AX25_RNR:
178
if (frametype == AX25_RR)
179
ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
180
else
181
ax25->condition |= AX25_COND_PEER_RX_BUSY;
182
if (type == AX25_COMMAND && pf)
183
ax25_std_enquiry_response(ax25);
184
if (ax25_validate_nr(ax25, nr)) {
185
ax25_check_iframes_acked(ax25, nr);
186
} else {
187
ax25_std_nr_error_recovery(ax25);
188
ax25->state = AX25_STATE_1;
189
}
190
break;
191
192
case AX25_REJ:
193
ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
194
if (type == AX25_COMMAND && pf)
195
ax25_std_enquiry_response(ax25);
196
if (ax25_validate_nr(ax25, nr)) {
197
ax25_frames_acked(ax25, nr);
198
ax25_calculate_rtt(ax25);
199
ax25_stop_t1timer(ax25);
200
ax25_start_t3timer(ax25);
201
ax25_requeue_frames(ax25);
202
} else {
203
ax25_std_nr_error_recovery(ax25);
204
ax25->state = AX25_STATE_1;
205
}
206
break;
207
208
case AX25_I:
209
if (!ax25_validate_nr(ax25, nr)) {
210
ax25_std_nr_error_recovery(ax25);
211
ax25->state = AX25_STATE_1;
212
break;
213
}
214
if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
215
ax25_frames_acked(ax25, nr);
216
} else {
217
ax25_check_iframes_acked(ax25, nr);
218
}
219
if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
220
if (pf) ax25_std_enquiry_response(ax25);
221
break;
222
}
223
if (ns == ax25->vr) {
224
ax25->vr = (ax25->vr + 1) % ax25->modulus;
225
queued = ax25_rx_iframe(ax25, skb);
226
if (ax25->condition & AX25_COND_OWN_RX_BUSY)
227
ax25->vr = ns; /* ax25->vr - 1 */
228
ax25->condition &= ~AX25_COND_REJECT;
229
if (pf) {
230
ax25_std_enquiry_response(ax25);
231
} else {
232
if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
233
ax25->condition |= AX25_COND_ACK_PENDING;
234
ax25_start_t2timer(ax25);
235
}
236
}
237
} else {
238
if (ax25->condition & AX25_COND_REJECT) {
239
if (pf) ax25_std_enquiry_response(ax25);
240
} else {
241
ax25->condition |= AX25_COND_REJECT;
242
ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
243
ax25->condition &= ~AX25_COND_ACK_PENDING;
244
}
245
}
246
break;
247
248
case AX25_FRMR:
249
case AX25_ILLEGAL:
250
ax25_std_establish_data_link(ax25);
251
ax25->state = AX25_STATE_1;
252
break;
253
254
default:
255
break;
256
}
257
258
return queued;
259
}
260
261
/*
262
* State machine for state 4, Timer Recovery State.
263
* The handling of the timer(s) is in file ax25_std_timer.c
264
* Handling of state 0 and connection release is in ax25.c.
265
*/
266
static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
267
{
268
int queued = 0;
269
270
switch (frametype) {
271
case AX25_SABM:
272
case AX25_SABME:
273
if (frametype == AX25_SABM) {
274
ax25->modulus = AX25_MODULUS;
275
ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
276
} else {
277
ax25->modulus = AX25_EMODULUS;
278
ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
279
}
280
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
281
ax25_stop_t1timer(ax25);
282
ax25_stop_t2timer(ax25);
283
ax25_start_t3timer(ax25);
284
ax25_start_idletimer(ax25);
285
ax25->condition = 0x00;
286
ax25->vs = 0;
287
ax25->va = 0;
288
ax25->vr = 0;
289
ax25->state = AX25_STATE_3;
290
ax25->n2count = 0;
291
ax25_requeue_frames(ax25);
292
break;
293
294
case AX25_DISC:
295
ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
296
ax25_disconnect(ax25, 0);
297
break;
298
299
case AX25_DM:
300
ax25_disconnect(ax25, ECONNRESET);
301
break;
302
303
case AX25_RR:
304
case AX25_RNR:
305
if (frametype == AX25_RR)
306
ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
307
else
308
ax25->condition |= AX25_COND_PEER_RX_BUSY;
309
if (type == AX25_RESPONSE && pf) {
310
ax25_stop_t1timer(ax25);
311
ax25->n2count = 0;
312
if (ax25_validate_nr(ax25, nr)) {
313
ax25_frames_acked(ax25, nr);
314
if (ax25->vs == ax25->va) {
315
ax25_start_t3timer(ax25);
316
ax25->state = AX25_STATE_3;
317
} else {
318
ax25_requeue_frames(ax25);
319
}
320
} else {
321
ax25_std_nr_error_recovery(ax25);
322
ax25->state = AX25_STATE_1;
323
}
324
break;
325
}
326
if (type == AX25_COMMAND && pf)
327
ax25_std_enquiry_response(ax25);
328
if (ax25_validate_nr(ax25, nr)) {
329
ax25_frames_acked(ax25, nr);
330
} else {
331
ax25_std_nr_error_recovery(ax25);
332
ax25->state = AX25_STATE_1;
333
}
334
break;
335
336
case AX25_REJ:
337
ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
338
if (pf && type == AX25_RESPONSE) {
339
ax25_stop_t1timer(ax25);
340
ax25->n2count = 0;
341
if (ax25_validate_nr(ax25, nr)) {
342
ax25_frames_acked(ax25, nr);
343
if (ax25->vs == ax25->va) {
344
ax25_start_t3timer(ax25);
345
ax25->state = AX25_STATE_3;
346
} else {
347
ax25_requeue_frames(ax25);
348
}
349
} else {
350
ax25_std_nr_error_recovery(ax25);
351
ax25->state = AX25_STATE_1;
352
}
353
break;
354
}
355
if (type == AX25_COMMAND && pf)
356
ax25_std_enquiry_response(ax25);
357
if (ax25_validate_nr(ax25, nr)) {
358
ax25_frames_acked(ax25, nr);
359
ax25_requeue_frames(ax25);
360
} else {
361
ax25_std_nr_error_recovery(ax25);
362
ax25->state = AX25_STATE_1;
363
}
364
break;
365
366
case AX25_I:
367
if (!ax25_validate_nr(ax25, nr)) {
368
ax25_std_nr_error_recovery(ax25);
369
ax25->state = AX25_STATE_1;
370
break;
371
}
372
ax25_frames_acked(ax25, nr);
373
if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
374
if (pf)
375
ax25_std_enquiry_response(ax25);
376
break;
377
}
378
if (ns == ax25->vr) {
379
ax25->vr = (ax25->vr + 1) % ax25->modulus;
380
queued = ax25_rx_iframe(ax25, skb);
381
if (ax25->condition & AX25_COND_OWN_RX_BUSY)
382
ax25->vr = ns; /* ax25->vr - 1 */
383
ax25->condition &= ~AX25_COND_REJECT;
384
if (pf) {
385
ax25_std_enquiry_response(ax25);
386
} else {
387
if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
388
ax25->condition |= AX25_COND_ACK_PENDING;
389
ax25_start_t2timer(ax25);
390
}
391
}
392
} else {
393
if (ax25->condition & AX25_COND_REJECT) {
394
if (pf) ax25_std_enquiry_response(ax25);
395
} else {
396
ax25->condition |= AX25_COND_REJECT;
397
ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
398
ax25->condition &= ~AX25_COND_ACK_PENDING;
399
}
400
}
401
break;
402
403
case AX25_FRMR:
404
case AX25_ILLEGAL:
405
ax25_std_establish_data_link(ax25);
406
ax25->state = AX25_STATE_1;
407
break;
408
409
default:
410
break;
411
}
412
413
return queued;
414
}
415
416
/*
417
* Higher level upcall for a LAPB frame
418
*/
419
int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
420
{
421
int queued = 0, frametype, ns, nr, pf;
422
423
frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
424
425
switch (ax25->state) {
426
case AX25_STATE_1:
427
queued = ax25_std_state1_machine(ax25, skb, frametype, pf, type);
428
break;
429
case AX25_STATE_2:
430
queued = ax25_std_state2_machine(ax25, skb, frametype, pf, type);
431
break;
432
case AX25_STATE_3:
433
queued = ax25_std_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
434
break;
435
case AX25_STATE_4:
436
queued = ax25_std_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
437
break;
438
}
439
440
ax25_kick(ax25);
441
442
return queued;
443
}
444
445