media: staging: media: use relevant lock
[linux-2.6-block.git] / net / netfilter / nf_conntrack_h323_asn1.c
CommitLineData
ca9b0147 1/*
5e35941d
JMZ
2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
3 * conntrack/NAT module.
4 *
7582e9d1 5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5e35941d
JMZ
6 *
7 * This source code is licensed under General Public License version 2.
8 *
9 * See ip_conntrack_helper_h323_asn1.h for details.
10 *
ca9b0147 11 */
5e35941d
JMZ
12
13#ifdef __KERNEL__
14#include <linux/kernel.h>
15#else
16#include <stdio.h>
17#endif
f587de0e 18#include <linux/netfilter/nf_conntrack_h323_asn1.h>
5e35941d
JMZ
19
20/* Trace Flag */
21#ifndef H323_TRACE
22#define H323_TRACE 0
23#endif
24
25#if H323_TRACE
26#define TAB_SIZE 4
27#define IFTHEN(cond, act) if(cond){act;}
28#ifdef __KERNEL__
29#define PRINT printk
30#else
31#define PRINT printf
32#endif
33#define FNAME(name) name,
34#else
35#define IFTHEN(cond, act)
36#define PRINT(fmt, args...)
37#define FNAME(name)
38#endif
39
40/* ASN.1 Types */
41#define NUL 0
42#define BOOL 1
43#define OID 2
44#define INT 3
45#define ENUM 4
46#define BITSTR 5
47#define NUMSTR 6
48#define NUMDGT 6
49#define TBCDSTR 6
50#define OCTSTR 7
51#define PRTSTR 7
52#define IA5STR 7
53#define GENSTR 7
54#define BMPSTR 8
55#define SEQ 9
56#define SET 9
57#define SEQOF 10
58#define SETOF 10
59#define CHOICE 11
60
61/* Constraint Types */
62#define FIXD 0
63/* #define BITS 1-8 */
64#define BYTE 9
65#define WORD 10
66#define CONS 11
67#define SEMI 12
68#define UNCO 13
69
70/* ASN.1 Type Attributes */
71#define SKIP 0
72#define STOP 1
73#define DECODE 2
74#define EXT 4
75#define OPEN 8
76#define OPT 16
77
78
79/* ASN.1 Field Structure */
80typedef struct field_t {
81#if H323_TRACE
82 char *name;
83#endif
84 unsigned char type;
85 unsigned char sz;
86 unsigned char lb;
87 unsigned char ub;
88 unsigned short attr;
89 unsigned short offset;
905e3e8e 90 const struct field_t *fields;
5e35941d
JMZ
91} field_t;
92
93/* Bit Stream */
67704c2a 94struct bitstr {
5e35941d
JMZ
95 unsigned char *buf;
96 unsigned char *beg;
97 unsigned char *end;
98 unsigned char *cur;
1f807d6e 99 unsigned int bit;
67704c2a 100};
5e35941d
JMZ
101
102/* Tool Functions */
e79ec50b
JE
103#define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;}
104#define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
105#define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
67704c2a
HS
106static unsigned int get_len(struct bitstr *bs);
107static unsigned int get_bit(struct bitstr *bs);
108static unsigned int get_bits(struct bitstr *bs, unsigned int b);
109static unsigned int get_bitmap(struct bitstr *bs, unsigned int b);
110static unsigned int get_uint(struct bitstr *bs, int b);
5e35941d
JMZ
111
112/* Decoder Functions */
67704c2a
HS
113static int decode_nul(struct bitstr *bs, const struct field_t *f, char *base, int level);
114static int decode_bool(struct bitstr *bs, const struct field_t *f, char *base, int level);
115static int decode_oid(struct bitstr *bs, const struct field_t *f, char *base, int level);
116static int decode_int(struct bitstr *bs, const struct field_t *f, char *base, int level);
117static int decode_enum(struct bitstr *bs, const struct field_t *f, char *base, int level);
118static int decode_bitstr(struct bitstr *bs, const struct field_t *f, char *base, int level);
119static int decode_numstr(struct bitstr *bs, const struct field_t *f, char *base, int level);
120static int decode_octstr(struct bitstr *bs, const struct field_t *f, char *base, int level);
121static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, char *base, int level);
122static int decode_seq(struct bitstr *bs, const struct field_t *f, char *base, int level);
123static int decode_seqof(struct bitstr *bs, const struct field_t *f, char *base, int level);
124static int decode_choice(struct bitstr *bs, const struct field_t *f, char *base, int level);
5e35941d
JMZ
125
126/* Decoder Functions Vector */
67704c2a 127typedef int (*decoder_t)(struct bitstr *, const struct field_t *, char *, int);
dc64d02b 128static const decoder_t Decoders[] = {
5e35941d
JMZ
129 decode_nul,
130 decode_bool,
131 decode_oid,
132 decode_int,
133 decode_enum,
134 decode_bitstr,
135 decode_numstr,
136 decode_octstr,
137 decode_bmpstr,
138 decode_seq,
139 decode_seqof,
140 decode_choice,
141};
142
ca9b0147 143/*
5e35941d 144 * H.323 Types
ca9b0147 145 */
f587de0e 146#include "nf_conntrack_h323_types.c"
5e35941d 147
ca9b0147 148/*
5e35941d 149 * Functions
ca9b0147
VR
150 */
151
5e35941d 152/* Assume bs is aligned && v < 16384 */
67704c2a 153static unsigned int get_len(struct bitstr *bs)
5e35941d 154{
1f807d6e 155 unsigned int v;
5e35941d
JMZ
156
157 v = *bs->cur++;
158
159 if (v & 0x80) {
160 v &= 0x3f;
161 v <<= 8;
162 v += *bs->cur++;
163 }
164
165 return v;
166}
167
ec8a8f3c 168static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits)
bc7d811a 169{
ec8a8f3c
ES
170 bits += bs->bit;
171 bytes += bits / BITS_PER_BYTE;
172 if (bits % BITS_PER_BYTE > 0)
173 bytes++;
174
bc7d811a
ES
175 if (*bs->cur + bytes > *bs->end)
176 return 1;
177
178 return 0;
179}
180
67704c2a 181static unsigned int get_bit(struct bitstr *bs)
5e35941d 182{
1f807d6e 183 unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
5e35941d
JMZ
184
185 INC_BIT(bs);
186
187 return b;
188}
189
5e35941d 190/* Assume b <= 8 */
67704c2a 191static unsigned int get_bits(struct bitstr *bs, unsigned int b)
5e35941d 192{
1f807d6e 193 unsigned int v, l;
5e35941d
JMZ
194
195 v = (*bs->cur) & (0xffU >> bs->bit);
196 l = b + bs->bit;
197
198 if (l < 8) {
199 v >>= 8 - l;
200 bs->bit = l;
201 } else if (l == 8) {
202 bs->cur++;
203 bs->bit = 0;
204 } else { /* l > 8 */
205
206 v <<= 8;
207 v += *(++bs->cur);
208 v >>= 16 - l;
209 bs->bit = l - 8;
210 }
211
212 return v;
213}
214
5e35941d 215/* Assume b <= 32 */
67704c2a 216static unsigned int get_bitmap(struct bitstr *bs, unsigned int b)
5e35941d 217{
1f807d6e 218 unsigned int v, l, shift, bytes;
5e35941d
JMZ
219
220 if (!b)
221 return 0;
222
223 l = bs->bit + b;
224
225 if (l < 8) {
1f807d6e 226 v = (unsigned int)(*bs->cur) << (bs->bit + 24);
5e35941d
JMZ
227 bs->bit = l;
228 } else if (l == 8) {
1f807d6e 229 v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
5e35941d
JMZ
230 bs->bit = 0;
231 } else {
232 for (bytes = l >> 3, shift = 24, v = 0; bytes;
233 bytes--, shift -= 8)
1f807d6e 234 v |= (unsigned int)(*bs->cur++) << shift;
5e35941d
JMZ
235
236 if (l < 32) {
1f807d6e 237 v |= (unsigned int)(*bs->cur) << shift;
5e35941d
JMZ
238 v <<= bs->bit;
239 } else if (l > 32) {
240 v <<= bs->bit;
241 v |= (*bs->cur) >> (8 - bs->bit);
242 }
243
244 bs->bit = l & 0x7;
245 }
246
247 v &= 0xffffffff << (32 - b);
248
249 return v;
250}
251
ca9b0147 252/*
5e35941d 253 * Assume bs is aligned and sizeof(unsigned int) == 4
ca9b0147 254 */
67704c2a 255static unsigned int get_uint(struct bitstr *bs, int b)
5e35941d 256{
1f807d6e 257 unsigned int v = 0;
5e35941d
JMZ
258
259 switch (b) {
260 case 4:
261 v |= *bs->cur++;
262 v <<= 8;
e8542dce 263 /* fall through */
5e35941d
JMZ
264 case 3:
265 v |= *bs->cur++;
266 v <<= 8;
e8542dce 267 /* fall through */
5e35941d
JMZ
268 case 2:
269 v |= *bs->cur++;
270 v <<= 8;
e8542dce 271 /* fall through */
5e35941d
JMZ
272 case 1:
273 v |= *bs->cur++;
274 break;
275 }
276 return v;
277}
278
67704c2a 279static int decode_nul(struct bitstr *bs, const struct field_t *f,
905e3e8e 280 char *base, int level)
5e35941d
JMZ
281{
282 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
283
284 return H323_ERROR_NONE;
285}
286
67704c2a 287static int decode_bool(struct bitstr *bs, const struct field_t *f,
905e3e8e 288 char *base, int level)
5e35941d
JMZ
289{
290 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
291
292 INC_BIT(bs);
ec8a8f3c 293 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 294 return H323_ERROR_BOUND;
5e35941d
JMZ
295 return H323_ERROR_NONE;
296}
297
67704c2a 298static int decode_oid(struct bitstr *bs, const struct field_t *f,
905e3e8e 299 char *base, int level)
5e35941d
JMZ
300{
301 int len;
302
303 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
304
305 BYTE_ALIGN(bs);
ec8a8f3c 306 if (nf_h323_error_boundary(bs, 1, 0))
bc7d811a
ES
307 return H323_ERROR_BOUND;
308
5e35941d
JMZ
309 len = *bs->cur++;
310 bs->cur += len;
ec8a8f3c 311 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 312 return H323_ERROR_BOUND;
5e35941d 313
5e35941d
JMZ
314 return H323_ERROR_NONE;
315}
316
67704c2a 317static int decode_int(struct bitstr *bs, const struct field_t *f,
905e3e8e 318 char *base, int level)
5e35941d 319{
1f807d6e 320 unsigned int len;
5e35941d
JMZ
321
322 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
323
324 switch (f->sz) {
325 case BYTE: /* Range == 256 */
326 BYTE_ALIGN(bs);
327 bs->cur++;
328 break;
329 case WORD: /* 257 <= Range <= 64K */
330 BYTE_ALIGN(bs);
331 bs->cur += 2;
332 break;
333 case CONS: /* 64K < Range < 4G */
ec8a8f3c
ES
334 if (nf_h323_error_boundary(bs, 0, 2))
335 return H323_ERROR_BOUND;
5e35941d
JMZ
336 len = get_bits(bs, 2) + 1;
337 BYTE_ALIGN(bs);
338 if (base && (f->attr & DECODE)) { /* timeToLive */
1f807d6e 339 unsigned int v = get_uint(bs, len) + f->lb;
5e35941d 340 PRINT(" = %u", v);
1f807d6e 341 *((unsigned int *)(base + f->offset)) = v;
5e35941d
JMZ
342 }
343 bs->cur += len;
344 break;
345 case UNCO:
346 BYTE_ALIGN(bs);
ec8a8f3c 347 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 348 return H323_ERROR_BOUND;
5e35941d
JMZ
349 len = get_len(bs);
350 bs->cur += len;
351 break;
352 default: /* 2 <= Range <= 255 */
353 INC_BITS(bs, f->sz);
354 break;
355 }
356
357 PRINT("\n");
358
ec8a8f3c 359 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 360 return H323_ERROR_BOUND;
5e35941d
JMZ
361 return H323_ERROR_NONE;
362}
363
67704c2a 364static int decode_enum(struct bitstr *bs, const struct field_t *f,
905e3e8e 365 char *base, int level)
5e35941d
JMZ
366{
367 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
368
369 if ((f->attr & EXT) && get_bit(bs)) {
370 INC_BITS(bs, 7);
371 } else {
372 INC_BITS(bs, f->sz);
373 }
374
ec8a8f3c 375 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 376 return H323_ERROR_BOUND;
5e35941d
JMZ
377 return H323_ERROR_NONE;
378}
379
67704c2a 380static int decode_bitstr(struct bitstr *bs, const struct field_t *f,
905e3e8e 381 char *base, int level)
5e35941d 382{
1f807d6e 383 unsigned int len;
5e35941d
JMZ
384
385 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
386
387 BYTE_ALIGN(bs);
388 switch (f->sz) {
389 case FIXD: /* fixed length > 16 */
390 len = f->lb;
391 break;
392 case WORD: /* 2-byte length */
ec8a8f3c 393 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 394 return H323_ERROR_BOUND;
5e35941d
JMZ
395 len = (*bs->cur++) << 8;
396 len += (*bs->cur++) + f->lb;
397 break;
398 case SEMI:
ec8a8f3c 399 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 400 return H323_ERROR_BOUND;
5e35941d
JMZ
401 len = get_len(bs);
402 break;
403 default:
404 len = 0;
405 break;
406 }
407
408 bs->cur += len >> 3;
409 bs->bit = len & 7;
410
ec8a8f3c 411 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 412 return H323_ERROR_BOUND;
5e35941d
JMZ
413 return H323_ERROR_NONE;
414}
415
67704c2a 416static int decode_numstr(struct bitstr *bs, const struct field_t *f,
905e3e8e 417 char *base, int level)
5e35941d 418{
1f807d6e 419 unsigned int len;
5e35941d
JMZ
420
421 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
422
423 /* 2 <= Range <= 255 */
ec8a8f3c
ES
424 if (nf_h323_error_boundary(bs, 0, f->sz))
425 return H323_ERROR_BOUND;
5e35941d
JMZ
426 len = get_bits(bs, f->sz) + f->lb;
427
428 BYTE_ALIGN(bs);
429 INC_BITS(bs, (len << 2));
430
ec8a8f3c 431 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 432 return H323_ERROR_BOUND;
5e35941d
JMZ
433 return H323_ERROR_NONE;
434}
435
67704c2a 436static int decode_octstr(struct bitstr *bs, const struct field_t *f,
905e3e8e 437 char *base, int level)
5e35941d 438{
1f807d6e 439 unsigned int len;
5e35941d
JMZ
440
441 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
442
443 switch (f->sz) {
444 case FIXD: /* Range == 1 */
445 if (f->lb > 2) {
446 BYTE_ALIGN(bs);
447 if (base && (f->attr & DECODE)) {
448 /* The IP Address */
449 IFTHEN(f->lb == 4,
450 PRINT(" = %d.%d.%d.%d:%d",
451 bs->cur[0], bs->cur[1],
452 bs->cur[2], bs->cur[3],
453 bs->cur[4] * 256 + bs->cur[5]));
1f807d6e 454 *((unsigned int *)(base + f->offset)) =
5e35941d
JMZ
455 bs->cur - bs->buf;
456 }
457 }
458 len = f->lb;
459 break;
460 case BYTE: /* Range == 256 */
461 BYTE_ALIGN(bs);
ec8a8f3c 462 if (nf_h323_error_boundary(bs, 1, 0))
bc7d811a 463 return H323_ERROR_BOUND;
5e35941d
JMZ
464 len = (*bs->cur++) + f->lb;
465 break;
466 case SEMI:
467 BYTE_ALIGN(bs);
ec8a8f3c 468 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 469 return H323_ERROR_BOUND;
5e35941d
JMZ
470 len = get_len(bs) + f->lb;
471 break;
472 default: /* 2 <= Range <= 255 */
ec8a8f3c
ES
473 if (nf_h323_error_boundary(bs, 0, f->sz))
474 return H323_ERROR_BOUND;
5e35941d
JMZ
475 len = get_bits(bs, f->sz) + f->lb;
476 BYTE_ALIGN(bs);
477 break;
478 }
479
480 bs->cur += len;
481
482 PRINT("\n");
483
ec8a8f3c 484 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 485 return H323_ERROR_BOUND;
5e35941d
JMZ
486 return H323_ERROR_NONE;
487}
488
67704c2a 489static int decode_bmpstr(struct bitstr *bs, const struct field_t *f,
905e3e8e 490 char *base, int level)
5e35941d 491{
1f807d6e 492 unsigned int len;
5e35941d
JMZ
493
494 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
495
496 switch (f->sz) {
497 case BYTE: /* Range == 256 */
498 BYTE_ALIGN(bs);
ec8a8f3c 499 if (nf_h323_error_boundary(bs, 1, 0))
bc7d811a 500 return H323_ERROR_BOUND;
5e35941d
JMZ
501 len = (*bs->cur++) + f->lb;
502 break;
503 default: /* 2 <= Range <= 255 */
ec8a8f3c
ES
504 if (nf_h323_error_boundary(bs, 0, f->sz))
505 return H323_ERROR_BOUND;
5e35941d
JMZ
506 len = get_bits(bs, f->sz) + f->lb;
507 BYTE_ALIGN(bs);
508 break;
509 }
510
511 bs->cur += len << 1;
512
ec8a8f3c 513 if (nf_h323_error_boundary(bs, 0, 0))
bc7d811a 514 return H323_ERROR_BOUND;
5e35941d
JMZ
515 return H323_ERROR_NONE;
516}
517
67704c2a 518static int decode_seq(struct bitstr *bs, const struct field_t *f,
905e3e8e 519 char *base, int level)
5e35941d 520{
1f807d6e 521 unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
5e35941d 522 int err;
905e3e8e 523 const struct field_t *son;
5e35941d
JMZ
524 unsigned char *beg = NULL;
525
526 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
527
528 /* Decode? */
529 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
530
531 /* Extensible? */
ec8a8f3c
ES
532 if (nf_h323_error_boundary(bs, 0, 1))
533 return H323_ERROR_BOUND;
5e35941d
JMZ
534 ext = (f->attr & EXT) ? get_bit(bs) : 0;
535
536 /* Get fields bitmap */
ec8a8f3c
ES
537 if (nf_h323_error_boundary(bs, 0, f->sz))
538 return H323_ERROR_BOUND;
5e35941d
JMZ
539 bmp = get_bitmap(bs, f->sz);
540 if (base)
1f807d6e 541 *(unsigned int *)base = bmp;
5e35941d
JMZ
542
543 /* Decode the root components */
544 for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
545 if (son->attr & STOP) {
546 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
547 son->name);
548 return H323_ERROR_STOP;
549 }
550
551 if (son->attr & OPT) { /* Optional component */
552 if (!((0x80000000U >> (opt++)) & bmp)) /* Not exist */
553 continue;
554 }
555
556 /* Decode */
557 if (son->attr & OPEN) { /* Open field */
ec8a8f3c 558 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 559 return H323_ERROR_BOUND;
5e35941d 560 len = get_len(bs);
ec8a8f3c 561 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 562 return H323_ERROR_BOUND;
25845b51 563 if (!base || !(son->attr & DECODE)) {
5e35941d
JMZ
564 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
565 " ", son->name);
566 bs->cur += len;
567 continue;
568 }
569 beg = bs->cur;
570
571 /* Decode */
572 if ((err = (Decoders[son->type]) (bs, son, base,
7185989d
PM
573 level + 1)) <
574 H323_ERROR_NONE)
5e35941d
JMZ
575 return err;
576
577 bs->cur = beg + len;
578 bs->bit = 0;
579 } else if ((err = (Decoders[son->type]) (bs, son, base,
7185989d
PM
580 level + 1)) <
581 H323_ERROR_NONE)
5e35941d
JMZ
582 return err;
583 }
584
585 /* No extension? */
586 if (!ext)
587 return H323_ERROR_NONE;
588
589 /* Get the extension bitmap */
ec8a8f3c
ES
590 if (nf_h323_error_boundary(bs, 0, 7))
591 return H323_ERROR_BOUND;
5e35941d 592 bmp2_len = get_bits(bs, 7) + 1;
ec8a8f3c 593 if (nf_h323_error_boundary(bs, 0, bmp2_len))
bc7d811a 594 return H323_ERROR_BOUND;
5e35941d
JMZ
595 bmp2 = get_bitmap(bs, bmp2_len);
596 bmp |= bmp2 >> f->sz;
597 if (base)
1f807d6e 598 *(unsigned int *)base = bmp;
5e35941d
JMZ
599 BYTE_ALIGN(bs);
600
601 /* Decode the extension components */
602 for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
5e35941d
JMZ
603 /* Check Range */
604 if (i >= f->ub) { /* Newer Version? */
ec8a8f3c 605 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 606 return H323_ERROR_BOUND;
5e35941d 607 len = get_len(bs);
ec8a8f3c 608 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 609 return H323_ERROR_BOUND;
5e35941d
JMZ
610 bs->cur += len;
611 continue;
612 }
613
558585aa
JMZ
614 if (son->attr & STOP) {
615 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
616 son->name);
617 return H323_ERROR_STOP;
618 }
619
620 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
621 continue;
622
ec8a8f3c 623 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 624 return H323_ERROR_BOUND;
5e35941d 625 len = get_len(bs);
ec8a8f3c 626 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 627 return H323_ERROR_BOUND;
5e35941d
JMZ
628 if (!base || !(son->attr & DECODE)) {
629 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
630 son->name);
631 bs->cur += len;
632 continue;
633 }
634 beg = bs->cur;
635
636 if ((err = (Decoders[son->type]) (bs, son, base,
7185989d
PM
637 level + 1)) <
638 H323_ERROR_NONE)
5e35941d
JMZ
639 return err;
640
641 bs->cur = beg + len;
642 bs->bit = 0;
643 }
644 return H323_ERROR_NONE;
645}
646
67704c2a 647static int decode_seqof(struct bitstr *bs, const struct field_t *f,
905e3e8e 648 char *base, int level)
5e35941d 649{
1f807d6e 650 unsigned int count, effective_count = 0, i, len = 0;
5e35941d 651 int err;
905e3e8e 652 const struct field_t *son;
5e35941d
JMZ
653 unsigned char *beg = NULL;
654
655 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
656
657 /* Decode? */
658 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
659
660 /* Decode item count */
661 switch (f->sz) {
662 case BYTE:
663 BYTE_ALIGN(bs);
ec8a8f3c 664 if (nf_h323_error_boundary(bs, 1, 0))
bc7d811a 665 return H323_ERROR_BOUND;
5e35941d
JMZ
666 count = *bs->cur++;
667 break;
668 case WORD:
669 BYTE_ALIGN(bs);
ec8a8f3c 670 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 671 return H323_ERROR_BOUND;
5e35941d
JMZ
672 count = *bs->cur++;
673 count <<= 8;
b4232a22 674 count += *bs->cur++;
5e35941d
JMZ
675 break;
676 case SEMI:
677 BYTE_ALIGN(bs);
ec8a8f3c 678 if (nf_h323_error_boundary(bs, 2, 0))
bc7d811a 679 return H323_ERROR_BOUND;
5e35941d
JMZ
680 count = get_len(bs);
681 break;
682 default:
ec8a8f3c
ES
683 if (nf_h323_error_boundary(bs, 0, f->sz))
684 return H323_ERROR_BOUND;
5e35941d
JMZ
685 count = get_bits(bs, f->sz);
686 break;
687 }
688 count += f->lb;
689
690 /* Write Count */
691 if (base) {
692 effective_count = count > f->ub ? f->ub : count;
1f807d6e
JE
693 *(unsigned int *)base = effective_count;
694 base += sizeof(unsigned int);
5e35941d
JMZ
695 }
696
697 /* Decode nested field */
698 son = f->fields;
699 if (base)
700 base -= son->offset;
701 for (i = 0; i < count; i++) {
702 if (son->attr & OPEN) {
703 BYTE_ALIGN(bs);
ec8a8f3c
ES
704 if (nf_h323_error_boundary(bs, 2, 0))
705 return H323_ERROR_BOUND;
5e35941d 706 len = get_len(bs);
ec8a8f3c 707 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 708 return H323_ERROR_BOUND;
5e35941d
JMZ
709 if (!base || !(son->attr & DECODE)) {
710 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
711 " ", son->name);
712 bs->cur += len;
713 continue;
714 }
715 beg = bs->cur;
716
717 if ((err = (Decoders[son->type]) (bs, son,
718 i <
719 effective_count ?
720 base : NULL,
7185989d
PM
721 level + 1)) <
722 H323_ERROR_NONE)
5e35941d
JMZ
723 return err;
724
725 bs->cur = beg + len;
726 bs->bit = 0;
727 } else
7185989d
PM
728 if ((err = (Decoders[son->type]) (bs, son,
729 i <
730 effective_count ?
731 base : NULL,
732 level + 1)) <
733 H323_ERROR_NONE)
734 return err;
5e35941d
JMZ
735
736 if (base)
737 base += son->offset;
738 }
739
740 return H323_ERROR_NONE;
741}
742
67704c2a 743static int decode_choice(struct bitstr *bs, const struct field_t *f,
905e3e8e 744 char *base, int level)
5e35941d 745{
1f807d6e 746 unsigned int type, ext, len = 0;
5e35941d 747 int err;
905e3e8e 748 const struct field_t *son;
5e35941d
JMZ
749 unsigned char *beg = NULL;
750
751 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
752
753 /* Decode? */
754 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
755
756 /* Decode the choice index number */
ec8a8f3c
ES
757 if (nf_h323_error_boundary(bs, 0, 1))
758 return H323_ERROR_BOUND;
5e35941d
JMZ
759 if ((f->attr & EXT) && get_bit(bs)) {
760 ext = 1;
ec8a8f3c
ES
761 if (nf_h323_error_boundary(bs, 0, 7))
762 return H323_ERROR_BOUND;
5e35941d
JMZ
763 type = get_bits(bs, 7) + f->lb;
764 } else {
765 ext = 0;
ec8a8f3c
ES
766 if (nf_h323_error_boundary(bs, 0, f->sz))
767 return H323_ERROR_BOUND;
5e35941d 768 type = get_bits(bs, f->sz);
25845b51
JMZ
769 if (type >= f->lb)
770 return H323_ERROR_RANGE;
5e35941d
JMZ
771 }
772
4228e2a9
PM
773 /* Write Type */
774 if (base)
1f807d6e 775 *(unsigned int *)base = type;
4228e2a9 776
5e35941d
JMZ
777 /* Check Range */
778 if (type >= f->ub) { /* Newer version? */
779 BYTE_ALIGN(bs);
ec8a8f3c
ES
780 if (nf_h323_error_boundary(bs, 2, 0))
781 return H323_ERROR_BOUND;
5e35941d 782 len = get_len(bs);
ec8a8f3c 783 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 784 return H323_ERROR_BOUND;
5e35941d
JMZ
785 bs->cur += len;
786 return H323_ERROR_NONE;
787 }
788
5e35941d
JMZ
789 /* Transfer to son level */
790 son = &f->fields[type];
791 if (son->attr & STOP) {
792 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name);
793 return H323_ERROR_STOP;
794 }
795
796 if (ext || (son->attr & OPEN)) {
797 BYTE_ALIGN(bs);
ec8a8f3c
ES
798 if (nf_h323_error_boundary(bs, len, 0))
799 return H323_ERROR_BOUND;
5e35941d 800 len = get_len(bs);
ec8a8f3c 801 if (nf_h323_error_boundary(bs, len, 0))
bc7d811a 802 return H323_ERROR_BOUND;
5e35941d
JMZ
803 if (!base || !(son->attr & DECODE)) {
804 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
805 son->name);
806 bs->cur += len;
807 return H323_ERROR_NONE;
808 }
809 beg = bs->cur;
810
7185989d
PM
811 if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
812 H323_ERROR_NONE)
5e35941d
JMZ
813 return err;
814
815 bs->cur = beg + len;
816 bs->bit = 0;
7185989d
PM
817 } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
818 H323_ERROR_NONE)
5e35941d
JMZ
819 return err;
820
821 return H323_ERROR_NONE;
822}
823
1f807d6e 824int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
5e35941d 825{
905e3e8e 826 static const struct field_t ras_message = {
5e35941d
JMZ
827 FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
828 0, _RasMessage
829 };
67704c2a 830 struct bitstr bs;
5e35941d
JMZ
831
832 bs.buf = bs.beg = bs.cur = buf;
833 bs.end = buf + sz;
834 bs.bit = 0;
835
836 return decode_choice(&bs, &ras_message, (char *) ras, 0);
837}
838
5e35941d 839static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
1f807d6e 840 size_t sz, H323_UserInformation *uuie)
5e35941d 841{
905e3e8e 842 static const struct field_t h323_userinformation = {
5e35941d
JMZ
843 FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
844 0, _H323_UserInformation
845 };
67704c2a 846 struct bitstr bs;
5e35941d
JMZ
847
848 bs.buf = buf;
849 bs.beg = bs.cur = beg;
850 bs.end = beg + sz;
851 bs.bit = 0;
852
853 return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
854}
855
5e35941d
JMZ
856int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
857 MultimediaSystemControlMessage *
858 mscm)
859{
905e3e8e 860 static const struct field_t multimediasystemcontrolmessage = {
5e35941d
JMZ
861 FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
862 DECODE | EXT, 0, _MultimediaSystemControlMessage
863 };
67704c2a 864 struct bitstr bs;
5e35941d
JMZ
865
866 bs.buf = bs.beg = bs.cur = buf;
867 bs.end = buf + sz;
868 bs.bit = 0;
869
870 return decode_choice(&bs, &multimediasystemcontrolmessage,
871 (char *) mscm, 0);
872}
873
1f807d6e 874int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
5e35941d
JMZ
875{
876 unsigned char *p = buf;
877 int len;
878
879 if (!p || sz < 1)
880 return H323_ERROR_BOUND;
881
882 /* Protocol Discriminator */
883 if (*p != 0x08) {
884 PRINT("Unknown Protocol Discriminator\n");
885 return H323_ERROR_RANGE;
886 }
887 p++;
888 sz--;
889
890 /* CallReferenceValue */
891 if (sz < 1)
892 return H323_ERROR_BOUND;
893 len = *p++;
894 sz--;
895 if (sz < len)
896 return H323_ERROR_BOUND;
897 p += len;
898 sz -= len;
899
900 /* Message Type */
c2b9b4fe 901 if (sz < 2)
5e35941d
JMZ
902 return H323_ERROR_BOUND;
903 q931->MessageType = *p++;
c2b9b4fe 904 sz--;
5e35941d
JMZ
905 PRINT("MessageType = %02X\n", q931->MessageType);
906 if (*p & 0x80) {
907 p++;
908 sz--;
909 }
910
911 /* Decode Information Elements */
912 while (sz > 0) {
913 if (*p == 0x7e) { /* UserUserIE */
914 if (sz < 3)
915 break;
916 p++;
917 len = *p++ << 8;
918 len |= *p++;
919 sz -= 3;
920 if (sz < len)
921 break;
922 p++;
923 len--;
924 return DecodeH323_UserInformation(buf, p, len,
925 &q931->UUIE);
926 }
927 p++;
928 sz--;
929 if (sz < 1)
930 break;
931 len = *p++;
e8daf27c 932 sz--;
5e35941d
JMZ
933 if (sz < len)
934 break;
935 p += len;
936 sz -= len;
937 }
938
939 PRINT("Q.931 UUIE not found\n");
940
941 return H323_ERROR_BOUND;
942}