cleanup
[linux-2.4.21-pre4.git] / net / ax25 / ax25_std_in.c
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 }