1 /*
2 * AX.25 release 037
3 *
4 * This code REQUIRES 2.1.15 or higher/ NET3.038
5 *
6 * This module:
7 * This module is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * Most of this code is based on the SDL diagrams published in the 7th
13 * ARRL Computer Networking Conference papers. The diagrams have mistakes
14 * in them, but are mostly correct. Before you modify the code could you
15 * read the SDL diagrams as the code is not obvious and probably very
16 * easy to break;
17 *
18 * History
19 * AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
20 * AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from
21 * the sock structure.
22 * AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
23 * Jonathan(G4KLX) Added IP mode registration.
24 * AX.25 030 Jonathan(G4KLX) Added AX.25 fragment reception.
25 * Upgraded state machine for SABME.
26 * Added arbitrary protocol id support.
27 * AX.25 031 Joerg(DL1BKE) Added DAMA support
28 * HaJo(DD8NE) Added Idle Disc Timer T5
29 * Joerg(DL1BKE) Renamed it to "IDLE" with a slightly
30 * different behaviour. Fixed defrag
31 * routine (I hope)
32 * AX.25 032 Darryl(G7LED) AX.25 segmentation fixed.
33 * AX.25 033 Jonathan(G4KLX) Remove auto-router.
34 * Modularisation changes.
35 * AX.25 035 Hans(PE1AYX) Fixed interface to IP layer.
36 * AX.25 036 Jonathan(G4KLX) Cloned from ax25_in.c.
37 * AX.25 037 Jonathan(G4KLX) New timer architecture.
38 */
39
40 #include <linux/errno.h>
41 #include <linux/types.h>
42 #include <linux/socket.h>
43 #include <linux/in.h>
44 #include <linux/kernel.h>
45 #include <linux/sched.h>
46 #include <linux/timer.h>
47 #include <linux/string.h>
48 #include <linux/sockios.h>
49 #include <linux/net.h>
50 #include <net/ax25.h>
51 #include <linux/inet.h>
52 #include <linux/netdevice.h>
53 #include <linux/skbuff.h>
54 #include <net/sock.h>
55 #include <net/ip.h> /* For ip_rcv */
56 #include <asm/uaccess.h>
57 #include <asm/system.h>
58 #include <linux/fcntl.h>
59 #include <linux/mm.h>
60 #include <linux/interrupt.h>
61
62 /*
63 * State machine for state 1, Awaiting Connection State.
64 * The handling of the timer(s) is in file ax25_std_timer.c.
65 * Handling of state 0 and connection release is in ax25.c.
66 */
67 static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
68 {
69 switch (frametype) {
70 case AX25_SABM:
71 ax25->modulus = AX25_MODULUS;
72 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
73 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
74 break;
75
76 case AX25_SABME:
77 ax25->modulus = AX25_EMODULUS;
78 ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
79 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
80 break;
81
82 case AX25_DISC:
83 ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
84 break;
85
86 case AX25_UA:
87 if (pf) {
88 ax25_calculate_rtt(ax25);
89 ax25_stop_t1timer(ax25);
90 ax25_start_t3timer(ax25);
91 ax25_start_idletimer(ax25);
92 ax25->vs = 0;
93 ax25->va = 0;
94 ax25->vr = 0;
95 ax25->state = AX25_STATE_3;
96 ax25->n2count = 0;
97 if (ax25->sk != NULL) {
98 ax25->sk->state = TCP_ESTABLISHED;
99 /* For WAIT_SABM connections we will produce an accept ready socket here */
100 if (!ax25->sk->dead)
101 ax25->sk->state_change(ax25->sk);
102 }
103 }
104 break;
105
106 case AX25_DM:
107 if (pf) {
108 if (ax25->modulus == AX25_MODULUS) {
109 ax25_disconnect(ax25, ECONNREFUSED);
110 } else {
111 ax25->modulus = AX25_MODULUS;
112 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
113 }
114 }
115 break;
116
117 default:
118 break;
119 }
120
121 return 0;
122 }
123
124 /*
125 * State machine for state 2, Awaiting Release State.
126 * The handling of the timer(s) is in file ax25_std_timer.c
127 * Handling of state 0 and connection release is in ax25.c.
128 */
129 static int ax25_std_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
130 {
131 switch (frametype) {
132 case AX25_SABM:
133 case AX25_SABME:
134 ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
135 break;
136
137 case AX25_DISC:
138 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
139 ax25_disconnect(ax25, 0);
140 break;
141
142 case AX25_DM:
143 case AX25_UA:
144 if (pf) ax25_disconnect(ax25, 0);
145 break;
146
147 case AX25_I:
148 case AX25_REJ:
149 case AX25_RNR:
150 case AX25_RR:
151 if (pf) ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
152 break;
153
154 default:
155 break;
156 }
157
158 return 0;
159 }
160
161 /*
162 * State machine for state 3, Connected State.
163 * The handling of the timer(s) is in file ax25_std_timer.c
164 * Handling of state 0 and connection release is in ax25.c.
165 */
166 static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
167 {
168 int queued = 0;
169
170 switch (frametype) {
171 case AX25_SABM:
172 case AX25_SABME:
173 if (frametype == AX25_SABM) {
174 ax25->modulus = AX25_MODULUS;
175 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
176 } else {
177 ax25->modulus = AX25_EMODULUS;
178 ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
179 }
180 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
181 ax25_stop_t1timer(ax25);
182 ax25_stop_t2timer(ax25);
183 ax25_start_t3timer(ax25);
184 ax25_start_idletimer(ax25);
185 ax25->condition = 0x00;
186 ax25->vs = 0;
187 ax25->va = 0;
188 ax25->vr = 0;
189 ax25_requeue_frames(ax25);
190 break;
191
192 case AX25_DISC:
193 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
194 ax25_disconnect(ax25, 0);
195 break;
196
197 case AX25_DM:
198 ax25_disconnect(ax25, ECONNRESET);
199 break;
200
201 case AX25_RR:
202 case AX25_RNR:
203 if (frametype == AX25_RR)
204 ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
205 else
206 ax25->condition |= AX25_COND_PEER_RX_BUSY;
207 if (type == AX25_COMMAND && pf)
208 ax25_std_enquiry_response(ax25);
209 if (ax25_validate_nr(ax25, nr)) {
210 ax25_check_iframes_acked(ax25, nr);
211 } else {
212 ax25_std_nr_error_recovery(ax25);
213 ax25->state = AX25_STATE_1;
214 }
215 break;
216
217 case AX25_REJ:
218 ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
219 if (type == AX25_COMMAND && pf)
220 ax25_std_enquiry_response(ax25);
221 if (ax25_validate_nr(ax25, nr)) {
222 ax25_frames_acked(ax25, nr);
223 ax25_calculate_rtt(ax25);
224 ax25_stop_t1timer(ax25);
225 ax25_start_t3timer(ax25);
226 ax25_requeue_frames(ax25);
227 } else {
228 ax25_std_nr_error_recovery(ax25);
229 ax25->state = AX25_STATE_1;
230 }
231 break;
232
233 case AX25_I:
234 if (!ax25_validate_nr(ax25, nr)) {
235 ax25_std_nr_error_recovery(ax25);
236 ax25->state = AX25_STATE_1;
237 break;
238 }
239 if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
240 ax25_frames_acked(ax25, nr);
241 } else {
242 ax25_check_iframes_acked(ax25, nr);
243 }
244 if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
245 if (pf) ax25_std_enquiry_response(ax25);
246 break;
247 }
248 if (ns == ax25->vr) {
249 ax25->vr = (ax25->vr + 1) % ax25->modulus;
250 queued = ax25_rx_iframe(ax25, skb);
251 if (ax25->condition & AX25_COND_OWN_RX_BUSY)
252 ax25->vr = ns; /* ax25->vr - 1 */
253 ax25->condition &= ~AX25_COND_REJECT;
254 if (pf) {
255 ax25_std_enquiry_response(ax25);
256 } else {
257 if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
258 ax25->condition |= AX25_COND_ACK_PENDING;
259 ax25_start_t2timer(ax25);
260 }
261 }
262 } else {
263 if (ax25->condition & AX25_COND_REJECT) {
264 if (pf) ax25_std_enquiry_response(ax25);
265 } else {
266 ax25->condition |= AX25_COND_REJECT;
267 ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
268 ax25->condition &= ~AX25_COND_ACK_PENDING;
269 }
270 }
271 break;
272
273 case AX25_FRMR:
274 case AX25_ILLEGAL:
275 ax25_std_establish_data_link(ax25);
276 ax25->state = AX25_STATE_1;
277 break;
278
279 default:
280 break;
281 }
282
283 return queued;
284 }
285
286 /*
287 * State machine for state 4, Timer Recovery State.
288 * The handling of the timer(s) is in file ax25_std_timer.c
289 * Handling of state 0 and connection release is in ax25.c.
290 */
291 static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
292 {
293 int queued = 0;
294
295 switch (frametype) {
296 case AX25_SABM:
297 case AX25_SABME:
298 if (frametype == AX25_SABM) {
299 ax25->modulus = AX25_MODULUS;
300 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
301 } else {
302 ax25->modulus = AX25_EMODULUS;
303 ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
304 }
305 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
306 ax25_stop_t1timer(ax25);
307 ax25_stop_t2timer(ax25);
308 ax25_start_t3timer(ax25);
309 ax25_start_idletimer(ax25);
310 ax25->condition = 0x00;
311 ax25->vs = 0;
312 ax25->va = 0;
313 ax25->vr = 0;
314 ax25->state = AX25_STATE_3;
315 ax25->n2count = 0;
316 ax25_requeue_frames(ax25);
317 break;
318
319 case AX25_DISC:
320 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
321 ax25_disconnect(ax25, 0);
322 break;
323
324 case AX25_DM:
325 ax25_disconnect(ax25, ECONNRESET);
326 break;
327
328 case AX25_RR:
329 case AX25_RNR:
330 if (frametype == AX25_RR)
331 ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
332 else
333 ax25->condition |= AX25_COND_PEER_RX_BUSY;
334 if (type == AX25_RESPONSE && pf) {
335 ax25_stop_t1timer(ax25);
336 ax25->n2count = 0;
337 if (ax25_validate_nr(ax25, nr)) {
338 ax25_frames_acked(ax25, nr);
339 if (ax25->vs == ax25->va) {
340 ax25_start_t3timer(ax25);
341 ax25->state = AX25_STATE_3;
342 } else {
343 ax25_requeue_frames(ax25);
344 }
345 } else {
346 ax25_std_nr_error_recovery(ax25);
347 ax25->state = AX25_STATE_1;
348 }
349 break;
350 }
351 if (type == AX25_COMMAND && pf)
352 ax25_std_enquiry_response(ax25);
353 if (ax25_validate_nr(ax25, nr)) {
354 ax25_frames_acked(ax25, nr);
355 } else {
356 ax25_std_nr_error_recovery(ax25);
357 ax25->state = AX25_STATE_1;
358 }
359 break;
360
361 case AX25_REJ:
362 ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
363 if (pf && type == AX25_RESPONSE) {
364 ax25_stop_t1timer(ax25);
365 ax25->n2count = 0;
366 if (ax25_validate_nr(ax25, nr)) {
367 ax25_frames_acked(ax25, nr);
368 if (ax25->vs == ax25->va) {
369 ax25_start_t3timer(ax25);
370 ax25->state = AX25_STATE_3;
371 } else {
372 ax25_requeue_frames(ax25);
373 }
374 } else {
375 ax25_std_nr_error_recovery(ax25);
376 ax25->state = AX25_STATE_1;
377 }
378 break;
379 }
380 if (type == AX25_COMMAND && pf)
381 ax25_std_enquiry_response(ax25);
382 if (ax25_validate_nr(ax25, nr)) {
383 ax25_frames_acked(ax25, nr);
384 ax25_requeue_frames(ax25);
385 } else {
386 ax25_std_nr_error_recovery(ax25);
387 ax25->state = AX25_STATE_1;
388 }
389 break;
390
391 case AX25_I:
392 if (!ax25_validate_nr(ax25, nr)) {
393 ax25_std_nr_error_recovery(ax25);
394 ax25->state = AX25_STATE_1;
395 break;
396 }
397 ax25_frames_acked(ax25, nr);
398 if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
399 if (pf) ax25_std_enquiry_response(ax25);
400 break;
401 }
402 if (ns == ax25->vr) {
403 ax25->vr = (ax25->vr + 1) % ax25->modulus;
404 queued = ax25_rx_iframe(ax25, skb);
405 if (ax25->condition & AX25_COND_OWN_RX_BUSY)
406 ax25->vr = ns; /* ax25->vr - 1 */
407 ax25->condition &= ~AX25_COND_REJECT;
408 if (pf) {
409 ax25_std_enquiry_response(ax25);
410 } else {
411 if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
412 ax25->condition |= AX25_COND_ACK_PENDING;
413 ax25_start_t2timer(ax25);
414 }
415 }
416 } else {
417 if (ax25->condition & AX25_COND_REJECT) {
418 if (pf) ax25_std_enquiry_response(ax25);
419 } else {
420 ax25->condition |= AX25_COND_REJECT;
421 ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
422 ax25->condition &= ~AX25_COND_ACK_PENDING;
423 }
424 }
425 break;
426
427 case AX25_FRMR:
428 case AX25_ILLEGAL:
429 ax25_std_establish_data_link(ax25);
430 ax25->state = AX25_STATE_1;
431 break;
432
433 default:
434 break;
435 }
436
437 return queued;
438 }
439
440 /*
441 * Higher level upcall for a LAPB frame
442 */
443 int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
444 {
445 int queued = 0, frametype, ns, nr, pf;
446
447 frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
448
449 switch (ax25->state) {
450 case AX25_STATE_1:
451 queued = ax25_std_state1_machine(ax25, skb, frametype, pf, type);
452 break;
453 case AX25_STATE_2:
454 queued = ax25_std_state2_machine(ax25, skb, frametype, pf, type);
455 break;
456 case AX25_STATE_3:
457 queued = ax25_std_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
458 break;
459 case AX25_STATE_4:
460 queued = ax25_std_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
461 break;
462 }
463
464 ax25_kick(ax25);
465
466 return queued;
467 }
468
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.