rose: Add length checks to CALL_REQUEST parsing
[pandora-kernel.git] / net / rose / rose_subr.c
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 (g4klx@g4klx.demon.co.uk)
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/timer.h>
15 #include <linux/string.h>
16 #include <linux/sockios.h>
17 #include <linux/net.h>
18 #include <linux/slab.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/system.h>
26 #include <linux/fcntl.h>
27 #include <linux/mm.h>
28 #include <linux/interrupt.h>
29 #include <net/rose.h>
30
31 static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose);
32
33 /*
34  *      This routine purges all of the queues of frames.
35  */
36 void rose_clear_queues(struct sock *sk)
37 {
38         skb_queue_purge(&sk->sk_write_queue);
39         skb_queue_purge(&rose_sk(sk)->ack_queue);
40 }
41
42 /*
43  * This routine purges the input queue of those frames that have been
44  * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
45  * SDL diagram.
46  */
47 void rose_frames_acked(struct sock *sk, unsigned short nr)
48 {
49         struct sk_buff *skb;
50         struct rose_sock *rose = rose_sk(sk);
51
52         /*
53          * Remove all the ack-ed frames from the ack queue.
54          */
55         if (rose->va != nr) {
56                 while (skb_peek(&rose->ack_queue) != NULL && rose->va != nr) {
57                         skb = skb_dequeue(&rose->ack_queue);
58                         kfree_skb(skb);
59                         rose->va = (rose->va + 1) % ROSE_MODULUS;
60                 }
61         }
62 }
63
64 void rose_requeue_frames(struct sock *sk)
65 {
66         struct sk_buff *skb, *skb_prev = NULL;
67
68         /*
69          * Requeue all the un-ack-ed frames on the output queue to be picked
70          * up by rose_kick. This arrangement handles the possibility of an
71          * empty output queue.
72          */
73         while ((skb = skb_dequeue(&rose_sk(sk)->ack_queue)) != NULL) {
74                 if (skb_prev == NULL)
75                         skb_queue_head(&sk->sk_write_queue, skb);
76                 else
77                         skb_append(skb_prev, skb, &sk->sk_write_queue);
78                 skb_prev = skb;
79         }
80 }
81
82 /*
83  *      Validate that the value of nr is between va and vs. Return true or
84  *      false for testing.
85  */
86 int rose_validate_nr(struct sock *sk, unsigned short nr)
87 {
88         struct rose_sock *rose = rose_sk(sk);
89         unsigned short vc = rose->va;
90
91         while (vc != rose->vs) {
92                 if (nr == vc) return 1;
93                 vc = (vc + 1) % ROSE_MODULUS;
94         }
95
96         return nr == rose->vs;
97 }
98
99 /*
100  *  This routine is called when the packet layer internally generates a
101  *  control frame.
102  */
103 void rose_write_internal(struct sock *sk, int frametype)
104 {
105         struct rose_sock *rose = rose_sk(sk);
106         struct sk_buff *skb;
107         unsigned char  *dptr;
108         unsigned char  lci1, lci2;
109         char buffer[100];
110         int len, faclen = 0;
111
112         len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 1;
113
114         switch (frametype) {
115         case ROSE_CALL_REQUEST:
116                 len   += 1 + ROSE_ADDR_LEN + ROSE_ADDR_LEN;
117                 faclen = rose_create_facilities(buffer, rose);
118                 len   += faclen;
119                 break;
120         case ROSE_CALL_ACCEPTED:
121         case ROSE_CLEAR_REQUEST:
122         case ROSE_RESET_REQUEST:
123                 len   += 2;
124                 break;
125         }
126
127         if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
128                 return;
129
130         /*
131          *      Space for AX.25 header and PID.
132          */
133         skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 1);
134
135         dptr = skb_put(skb, skb_tailroom(skb));
136
137         lci1 = (rose->lci >> 8) & 0x0F;
138         lci2 = (rose->lci >> 0) & 0xFF;
139
140         switch (frametype) {
141         case ROSE_CALL_REQUEST:
142                 *dptr++ = ROSE_GFI | lci1;
143                 *dptr++ = lci2;
144                 *dptr++ = frametype;
145                 *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL;
146                 memcpy(dptr, &rose->dest_addr,  ROSE_ADDR_LEN);
147                 dptr   += ROSE_ADDR_LEN;
148                 memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN);
149                 dptr   += ROSE_ADDR_LEN;
150                 memcpy(dptr, buffer, faclen);
151                 dptr   += faclen;
152                 break;
153
154         case ROSE_CALL_ACCEPTED:
155                 *dptr++ = ROSE_GFI | lci1;
156                 *dptr++ = lci2;
157                 *dptr++ = frametype;
158                 *dptr++ = 0x00;         /* Address length */
159                 *dptr++ = 0;            /* Facilities length */
160                 break;
161
162         case ROSE_CLEAR_REQUEST:
163                 *dptr++ = ROSE_GFI | lci1;
164                 *dptr++ = lci2;
165                 *dptr++ = frametype;
166                 *dptr++ = rose->cause;
167                 *dptr++ = rose->diagnostic;
168                 break;
169
170         case ROSE_RESET_REQUEST:
171                 *dptr++ = ROSE_GFI | lci1;
172                 *dptr++ = lci2;
173                 *dptr++ = frametype;
174                 *dptr++ = ROSE_DTE_ORIGINATED;
175                 *dptr++ = 0;
176                 break;
177
178         case ROSE_RR:
179         case ROSE_RNR:
180                 *dptr++ = ROSE_GFI | lci1;
181                 *dptr++ = lci2;
182                 *dptr   = frametype;
183                 *dptr++ |= (rose->vr << 5) & 0xE0;
184                 break;
185
186         case ROSE_CLEAR_CONFIRMATION:
187         case ROSE_RESET_CONFIRMATION:
188                 *dptr++ = ROSE_GFI | lci1;
189                 *dptr++ = lci2;
190                 *dptr++  = frametype;
191                 break;
192
193         default:
194                 printk(KERN_ERR "ROSE: rose_write_internal - invalid frametype %02X\n", frametype);
195                 kfree_skb(skb);
196                 return;
197         }
198
199         rose_transmit_link(skb, rose->neighbour);
200 }
201
202 int rose_decode(struct sk_buff *skb, int *ns, int *nr, int *q, int *d, int *m)
203 {
204         unsigned char *frame;
205
206         frame = skb->data;
207
208         *ns = *nr = *q = *d = *m = 0;
209
210         switch (frame[2]) {
211         case ROSE_CALL_REQUEST:
212         case ROSE_CALL_ACCEPTED:
213         case ROSE_CLEAR_REQUEST:
214         case ROSE_CLEAR_CONFIRMATION:
215         case ROSE_RESET_REQUEST:
216         case ROSE_RESET_CONFIRMATION:
217                 return frame[2];
218         default:
219                 break;
220         }
221
222         if ((frame[2] & 0x1F) == ROSE_RR  ||
223             (frame[2] & 0x1F) == ROSE_RNR) {
224                 *nr = (frame[2] >> 5) & 0x07;
225                 return frame[2] & 0x1F;
226         }
227
228         if ((frame[2] & 0x01) == ROSE_DATA) {
229                 *q  = (frame[0] & ROSE_Q_BIT) == ROSE_Q_BIT;
230                 *d  = (frame[0] & ROSE_D_BIT) == ROSE_D_BIT;
231                 *m  = (frame[2] & ROSE_M_BIT) == ROSE_M_BIT;
232                 *nr = (frame[2] >> 5) & 0x07;
233                 *ns = (frame[2] >> 1) & 0x07;
234                 return ROSE_DATA;
235         }
236
237         return ROSE_ILLEGAL;
238 }
239
240 static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *facilities, int len)
241 {
242         unsigned char *pt;
243         unsigned char l, lg, n = 0;
244         int fac_national_digis_received = 0;
245
246         do {
247                 switch (*p & 0xC0) {
248                 case 0x00:
249                         if (len < 2)
250                                 return -1;
251                         p   += 2;
252                         n   += 2;
253                         len -= 2;
254                         break;
255
256                 case 0x40:
257                         if (len < 3)
258                                 return -1;
259                         if (*p == FAC_NATIONAL_RAND)
260                                 facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF);
261                         p   += 3;
262                         n   += 3;
263                         len -= 3;
264                         break;
265
266                 case 0x80:
267                         if (len < 4)
268                                 return -1;
269                         p   += 4;
270                         n   += 4;
271                         len -= 4;
272                         break;
273
274                 case 0xC0:
275                         if (len < 2)
276                                 return -1;
277                         l = p[1];
278                         if (len < 2 + l)
279                                 return -1;
280                         if (*p == FAC_NATIONAL_DEST_DIGI) {
281                                 if (!fac_national_digis_received) {
282                                         if (l < AX25_ADDR_LEN)
283                                                 return -1;
284                                         memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN);
285                                         facilities->source_ndigis = 1;
286                                 }
287                         }
288                         else if (*p == FAC_NATIONAL_SRC_DIGI) {
289                                 if (!fac_national_digis_received) {
290                                         if (l < AX25_ADDR_LEN)
291                                                 return -1;
292                                         memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN);
293                                         facilities->dest_ndigis = 1;
294                                 }
295                         }
296                         else if (*p == FAC_NATIONAL_FAIL_CALL) {
297                                 if (l < AX25_ADDR_LEN)
298                                         return -1;
299                                 memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN);
300                         }
301                         else if (*p == FAC_NATIONAL_FAIL_ADD) {
302                                 if (l < 1 + ROSE_ADDR_LEN)
303                                         return -1;
304                                 memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN);
305                         }
306                         else if (*p == FAC_NATIONAL_DIGIS) {
307                                 if (l % AX25_ADDR_LEN)
308                                         return -1;
309                                 fac_national_digis_received = 1;
310                                 facilities->source_ndigis = 0;
311                                 facilities->dest_ndigis   = 0;
312                                 for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
313                                         if (pt[6] & AX25_HBIT) {
314                                                 if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
315                                                         return -1;
316                                                 memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
317                                         } else {
318                                                 if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
319                                                         return -1;
320                                                 memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
321                                         }
322                                 }
323                         }
324                         p   += l + 2;
325                         n   += l + 2;
326                         len -= l + 2;
327                         break;
328                 }
329         } while (*p != 0x00 && len > 0);
330
331         return n;
332 }
333
334 static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *facilities, int len)
335 {
336         unsigned char l, n = 0;
337         char callsign[11];
338
339         do {
340                 switch (*p & 0xC0) {
341                 case 0x00:
342                         if (len < 2)
343                                 return -1;
344                         p   += 2;
345                         n   += 2;
346                         len -= 2;
347                         break;
348
349                 case 0x40:
350                         if (len < 3)
351                                 return -1;
352                         p   += 3;
353                         n   += 3;
354                         len -= 3;
355                         break;
356
357                 case 0x80:
358                         if (len < 4)
359                                 return -1;
360                         p   += 4;
361                         n   += 4;
362                         len -= 4;
363                         break;
364
365                 case 0xC0:
366                         if (len < 2)
367                                 return -1;
368                         l = p[1];
369
370                         /* Prevent overflows*/
371                         if (l < 10 || l > 20)
372                                 return -1;
373
374                         if (*p == FAC_CCITT_DEST_NSAP) {
375                                 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
376                                 memcpy(callsign, p + 12,   l - 10);
377                                 callsign[l - 10] = '\0';
378                                 asc2ax(&facilities->source_call, callsign);
379                         }
380                         if (*p == FAC_CCITT_SRC_NSAP) {
381                                 memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
382                                 memcpy(callsign, p + 12, l - 10);
383                                 callsign[l - 10] = '\0';
384                                 asc2ax(&facilities->dest_call, callsign);
385                         }
386                         p   += l + 2;
387                         n   += l + 2;
388                         len -= l + 2;
389                         break;
390                 }
391         } while (*p != 0x00 && len > 0);
392
393         return n;
394 }
395
396 int rose_parse_facilities(unsigned char *p, unsigned packet_len,
397         struct rose_facilities_struct *facilities)
398 {
399         int facilities_len, len;
400
401         facilities_len = *p++;
402
403         if (facilities_len == 0 || (unsigned)facilities_len > packet_len)
404                 return 0;
405
406         while (facilities_len >= 3 && *p == 0x00) {
407                 facilities_len--;
408                 p++;
409
410                 switch (*p) {
411                 case FAC_NATIONAL:              /* National */
412                         len = rose_parse_national(p + 1, facilities, facilities_len - 1);
413                         break;
414
415                 case FAC_CCITT:         /* CCITT */
416                         len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
417                         break;
418
419                 default:
420                         printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p);
421                         len = 1;
422                         break;
423                 }
424
425                 if (len < 0)
426                         return 0;
427                 if (WARN_ON(len >= facilities_len))
428                         return 0;
429                 facilities_len -= len + 1;
430                 p += len + 1;
431         }
432
433         return facilities_len == 0;
434 }
435
436 static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
437 {
438         unsigned char *p = buffer + 1;
439         char *callsign;
440         char buf[11];
441         int len, nb;
442
443         /* National Facilities */
444         if (rose->rand != 0 || rose->source_ndigis == 1 || rose->dest_ndigis == 1) {
445                 *p++ = 0x00;
446                 *p++ = FAC_NATIONAL;
447
448                 if (rose->rand != 0) {
449                         *p++ = FAC_NATIONAL_RAND;
450                         *p++ = (rose->rand >> 8) & 0xFF;
451                         *p++ = (rose->rand >> 0) & 0xFF;
452                 }
453
454                 /* Sent before older facilities */
455                 if ((rose->source_ndigis > 0) || (rose->dest_ndigis > 0)) {
456                         int maxdigi = 0;
457                         *p++ = FAC_NATIONAL_DIGIS;
458                         *p++ = AX25_ADDR_LEN * (rose->source_ndigis + rose->dest_ndigis);
459                         for (nb = 0 ; nb < rose->source_ndigis ; nb++) {
460                                 if (++maxdigi >= ROSE_MAX_DIGIS)
461                                         break;
462                                 memcpy(p, &rose->source_digis[nb], AX25_ADDR_LEN);
463                                 p[6] |= AX25_HBIT;
464                                 p += AX25_ADDR_LEN;
465                         }
466                         for (nb = 0 ; nb < rose->dest_ndigis ; nb++) {
467                                 if (++maxdigi >= ROSE_MAX_DIGIS)
468                                         break;
469                                 memcpy(p, &rose->dest_digis[nb], AX25_ADDR_LEN);
470                                 p[6] &= ~AX25_HBIT;
471                                 p += AX25_ADDR_LEN;
472                         }
473                 }
474
475                 /* For compatibility */
476                 if (rose->source_ndigis > 0) {
477                         *p++ = FAC_NATIONAL_SRC_DIGI;
478                         *p++ = AX25_ADDR_LEN;
479                         memcpy(p, &rose->source_digis[0], AX25_ADDR_LEN);
480                         p   += AX25_ADDR_LEN;
481                 }
482
483                 /* For compatibility */
484                 if (rose->dest_ndigis > 0) {
485                         *p++ = FAC_NATIONAL_DEST_DIGI;
486                         *p++ = AX25_ADDR_LEN;
487                         memcpy(p, &rose->dest_digis[0], AX25_ADDR_LEN);
488                         p   += AX25_ADDR_LEN;
489                 }
490         }
491
492         *p++ = 0x00;
493         *p++ = FAC_CCITT;
494
495         *p++ = FAC_CCITT_DEST_NSAP;
496
497         callsign = ax2asc(buf, &rose->dest_call);
498
499         *p++ = strlen(callsign) + 10;
500         *p++ = (strlen(callsign) + 9) * 2;              /* ??? */
501
502         *p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
503         *p++ = ROSE_ADDR_LEN * 2;
504         memcpy(p, &rose->dest_addr, ROSE_ADDR_LEN);
505         p   += ROSE_ADDR_LEN;
506
507         memcpy(p, callsign, strlen(callsign));
508         p   += strlen(callsign);
509
510         *p++ = FAC_CCITT_SRC_NSAP;
511
512         callsign = ax2asc(buf, &rose->source_call);
513
514         *p++ = strlen(callsign) + 10;
515         *p++ = (strlen(callsign) + 9) * 2;              /* ??? */
516
517         *p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
518         *p++ = ROSE_ADDR_LEN * 2;
519         memcpy(p, &rose->source_addr, ROSE_ADDR_LEN);
520         p   += ROSE_ADDR_LEN;
521
522         memcpy(p, callsign, strlen(callsign));
523         p   += strlen(callsign);
524
525         len       = p - buffer;
526         buffer[0] = len - 1;
527
528         return len;
529 }
530
531 void rose_disconnect(struct sock *sk, int reason, int cause, int diagnostic)
532 {
533         struct rose_sock *rose = rose_sk(sk);
534
535         rose_stop_timer(sk);
536         rose_stop_idletimer(sk);
537
538         rose_clear_queues(sk);
539
540         rose->lci   = 0;
541         rose->state = ROSE_STATE_0;
542
543         if (cause != -1)
544                 rose->cause = cause;
545
546         if (diagnostic != -1)
547                 rose->diagnostic = diagnostic;
548
549         sk->sk_state     = TCP_CLOSE;
550         sk->sk_err       = reason;
551         sk->sk_shutdown |= SEND_SHUTDOWN;
552
553         if (!sock_flag(sk, SOCK_DEAD)) {
554                 sk->sk_state_change(sk);
555                 sock_set_flag(sk, SOCK_DEAD);
556         }
557 }