blob: a869403b229419562f6749b347b6ad7f8955e220 [file] [log] [blame]
Jing Min Zhao5e35941d2006-03-20 23:41:17 -08001/****************************************************************************
2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
3 * conntrack/NAT module.
4 *
Jing Min Zhao7582e9d2006-05-03 23:19:59 -07005 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
Jing Min Zhao5e35941d2006-03-20 23:41:17 -08006 *
7 * This source code is licensed under General Public License version 2.
8 *
9 * See ip_conntrack_helper_h323_asn1.h for details.
10 *
11 ****************************************************************************/
12
13#ifdef __KERNEL__
14#include <linux/kernel.h>
15#else
16#include <stdio.h>
17#endif
Patrick McHardyf587de02006-12-02 22:08:46 -080018#include <linux/netfilter/nf_conntrack_h323_asn1.h>
Jing Min Zhao5e35941d2006-03-20 23:41:17 -080019
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;
90 struct field_t *fields;
91} field_t;
92
93/* Bit Stream */
94typedef struct {
95 unsigned char *buf;
96 unsigned char *beg;
97 unsigned char *end;
98 unsigned char *cur;
99 unsigned bit;
100} bitstr_t;
101
102/* Tool Functions */
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;}
106#define CHECK_BOUND(bs,n) if(bs->cur+(n)>bs->end)return(H323_ERROR_BOUND)
107static unsigned get_len(bitstr_t * bs);
108static unsigned get_bit(bitstr_t * bs);
109static unsigned get_bits(bitstr_t * bs, unsigned b);
110static unsigned get_bitmap(bitstr_t * bs, unsigned b);
111static unsigned get_uint(bitstr_t * bs, int b);
112
113/* Decoder Functions */
114static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
115static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
116static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
117static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
118static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
119static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
120static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
121static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
122static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
123static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
124static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
125static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
126
127/* Decoder Functions Vector */
128typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
129static decoder_t Decoders[] = {
130 decode_nul,
131 decode_bool,
132 decode_oid,
133 decode_int,
134 decode_enum,
135 decode_bitstr,
136 decode_numstr,
137 decode_octstr,
138 decode_bmpstr,
139 decode_seq,
140 decode_seqof,
141 decode_choice,
142};
143
144/****************************************************************************
145 * H.323 Types
146 ****************************************************************************/
Patrick McHardyf587de02006-12-02 22:08:46 -0800147#include "nf_conntrack_h323_types.c"
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800148
149/****************************************************************************
150 * Functions
151 ****************************************************************************/
152/* Assume bs is aligned && v < 16384 */
153unsigned get_len(bitstr_t * bs)
154{
155 unsigned v;
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
168/****************************************************************************/
169unsigned get_bit(bitstr_t * bs)
170{
171 unsigned b = (*bs->cur) & (0x80 >> bs->bit);
172
173 INC_BIT(bs);
174
175 return b;
176}
177
178/****************************************************************************/
179/* Assume b <= 8 */
180unsigned get_bits(bitstr_t * bs, unsigned b)
181{
182 unsigned v, l;
183
184 v = (*bs->cur) & (0xffU >> bs->bit);
185 l = b + bs->bit;
186
187 if (l < 8) {
188 v >>= 8 - l;
189 bs->bit = l;
190 } else if (l == 8) {
191 bs->cur++;
192 bs->bit = 0;
193 } else { /* l > 8 */
194
195 v <<= 8;
196 v += *(++bs->cur);
197 v >>= 16 - l;
198 bs->bit = l - 8;
199 }
200
201 return v;
202}
203
204/****************************************************************************/
205/* Assume b <= 32 */
206unsigned get_bitmap(bitstr_t * bs, unsigned b)
207{
208 unsigned v, l, shift, bytes;
209
210 if (!b)
211 return 0;
212
213 l = bs->bit + b;
214
215 if (l < 8) {
216 v = (unsigned) (*bs->cur) << (bs->bit + 24);
217 bs->bit = l;
218 } else if (l == 8) {
219 v = (unsigned) (*bs->cur++) << (bs->bit + 24);
220 bs->bit = 0;
221 } else {
222 for (bytes = l >> 3, shift = 24, v = 0; bytes;
223 bytes--, shift -= 8)
224 v |= (unsigned) (*bs->cur++) << shift;
225
226 if (l < 32) {
227 v |= (unsigned) (*bs->cur) << shift;
228 v <<= bs->bit;
229 } else if (l > 32) {
230 v <<= bs->bit;
231 v |= (*bs->cur) >> (8 - bs->bit);
232 }
233
234 bs->bit = l & 0x7;
235 }
236
237 v &= 0xffffffff << (32 - b);
238
239 return v;
240}
241
242/****************************************************************************
243 * Assume bs is aligned and sizeof(unsigned int) == 4
244 ****************************************************************************/
245unsigned get_uint(bitstr_t * bs, int b)
246{
247 unsigned v = 0;
248
249 switch (b) {
250 case 4:
251 v |= *bs->cur++;
252 v <<= 8;
253 case 3:
254 v |= *bs->cur++;
255 v <<= 8;
256 case 2:
257 v |= *bs->cur++;
258 v <<= 8;
259 case 1:
260 v |= *bs->cur++;
261 break;
262 }
263 return v;
264}
265
266/****************************************************************************/
267int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
268{
269 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
270
271 return H323_ERROR_NONE;
272}
273
274/****************************************************************************/
275int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
276{
277 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
278
279 INC_BIT(bs);
280
281 CHECK_BOUND(bs, 0);
282 return H323_ERROR_NONE;
283}
284
285/****************************************************************************/
286int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
287{
288 int len;
289
290 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
291
292 BYTE_ALIGN(bs);
293 CHECK_BOUND(bs, 1);
294 len = *bs->cur++;
295 bs->cur += len;
296
297 CHECK_BOUND(bs, 0);
298 return H323_ERROR_NONE;
299}
300
301/****************************************************************************/
302int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
303{
304 unsigned len;
305
306 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
307
308 switch (f->sz) {
309 case BYTE: /* Range == 256 */
310 BYTE_ALIGN(bs);
311 bs->cur++;
312 break;
313 case WORD: /* 257 <= Range <= 64K */
314 BYTE_ALIGN(bs);
315 bs->cur += 2;
316 break;
317 case CONS: /* 64K < Range < 4G */
318 len = get_bits(bs, 2) + 1;
319 BYTE_ALIGN(bs);
320 if (base && (f->attr & DECODE)) { /* timeToLive */
321 unsigned v = get_uint(bs, len) + f->lb;
322 PRINT(" = %u", v);
323 *((unsigned *) (base + f->offset)) = v;
324 }
325 bs->cur += len;
326 break;
327 case UNCO:
328 BYTE_ALIGN(bs);
329 CHECK_BOUND(bs, 2);
330 len = get_len(bs);
331 bs->cur += len;
332 break;
333 default: /* 2 <= Range <= 255 */
334 INC_BITS(bs, f->sz);
335 break;
336 }
337
338 PRINT("\n");
339
340 CHECK_BOUND(bs, 0);
341 return H323_ERROR_NONE;
342}
343
344/****************************************************************************/
345int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
346{
347 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
348
349 if ((f->attr & EXT) && get_bit(bs)) {
350 INC_BITS(bs, 7);
351 } else {
352 INC_BITS(bs, f->sz);
353 }
354
355 CHECK_BOUND(bs, 0);
356 return H323_ERROR_NONE;
357}
358
359/****************************************************************************/
360int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
361{
362 unsigned len;
363
364 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
365
366 BYTE_ALIGN(bs);
367 switch (f->sz) {
368 case FIXD: /* fixed length > 16 */
369 len = f->lb;
370 break;
371 case WORD: /* 2-byte length */
372 CHECK_BOUND(bs, 2);
373 len = (*bs->cur++) << 8;
374 len += (*bs->cur++) + f->lb;
375 break;
376 case SEMI:
377 CHECK_BOUND(bs, 2);
378 len = get_len(bs);
379 break;
380 default:
381 len = 0;
382 break;
383 }
384
385 bs->cur += len >> 3;
386 bs->bit = len & 7;
387
388 CHECK_BOUND(bs, 0);
389 return H323_ERROR_NONE;
390}
391
392/****************************************************************************/
393int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
394{
395 unsigned len;
396
397 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
398
399 /* 2 <= Range <= 255 */
400 len = get_bits(bs, f->sz) + f->lb;
401
402 BYTE_ALIGN(bs);
403 INC_BITS(bs, (len << 2));
404
405 CHECK_BOUND(bs, 0);
406 return H323_ERROR_NONE;
407}
408
409/****************************************************************************/
410int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
411{
412 unsigned len;
413
414 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
415
416 switch (f->sz) {
417 case FIXD: /* Range == 1 */
418 if (f->lb > 2) {
419 BYTE_ALIGN(bs);
420 if (base && (f->attr & DECODE)) {
421 /* The IP Address */
422 IFTHEN(f->lb == 4,
423 PRINT(" = %d.%d.%d.%d:%d",
424 bs->cur[0], bs->cur[1],
425 bs->cur[2], bs->cur[3],
426 bs->cur[4] * 256 + bs->cur[5]));
427 *((unsigned *) (base + f->offset)) =
428 bs->cur - bs->buf;
429 }
430 }
431 len = f->lb;
432 break;
433 case BYTE: /* Range == 256 */
434 BYTE_ALIGN(bs);
435 CHECK_BOUND(bs, 1);
436 len = (*bs->cur++) + f->lb;
437 break;
438 case SEMI:
439 BYTE_ALIGN(bs);
440 CHECK_BOUND(bs, 2);
441 len = get_len(bs) + f->lb;
442 break;
443 default: /* 2 <= Range <= 255 */
444 len = get_bits(bs, f->sz) + f->lb;
445 BYTE_ALIGN(bs);
446 break;
447 }
448
449 bs->cur += len;
450
451 PRINT("\n");
452
453 CHECK_BOUND(bs, 0);
454 return H323_ERROR_NONE;
455}
456
457/****************************************************************************/
458int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
459{
460 unsigned len;
461
462 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
463
464 switch (f->sz) {
465 case BYTE: /* Range == 256 */
466 BYTE_ALIGN(bs);
467 CHECK_BOUND(bs, 1);
468 len = (*bs->cur++) + f->lb;
469 break;
470 default: /* 2 <= Range <= 255 */
471 len = get_bits(bs, f->sz) + f->lb;
472 BYTE_ALIGN(bs);
473 break;
474 }
475
476 bs->cur += len << 1;
477
478 CHECK_BOUND(bs, 0);
479 return H323_ERROR_NONE;
480}
481
482/****************************************************************************/
483int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
484{
485 unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
486 int err;
487 field_t *son;
488 unsigned char *beg = NULL;
489
490 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
491
492 /* Decode? */
493 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
494
495 /* Extensible? */
496 ext = (f->attr & EXT) ? get_bit(bs) : 0;
497
498 /* Get fields bitmap */
499 bmp = get_bitmap(bs, f->sz);
500 if (base)
501 *(unsigned *) base = bmp;
502
503 /* Decode the root components */
504 for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
505 if (son->attr & STOP) {
506 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
507 son->name);
508 return H323_ERROR_STOP;
509 }
510
511 if (son->attr & OPT) { /* Optional component */
512 if (!((0x80000000U >> (opt++)) & bmp)) /* Not exist */
513 continue;
514 }
515
516 /* Decode */
517 if (son->attr & OPEN) { /* Open field */
518 CHECK_BOUND(bs, 2);
519 len = get_len(bs);
520 CHECK_BOUND(bs, len);
Jing Min Zhao25845b52007-07-05 17:05:01 -0700521 if (!base || !(son->attr & DECODE)) {
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800522 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
523 " ", son->name);
524 bs->cur += len;
525 continue;
526 }
527 beg = bs->cur;
528
529 /* Decode */
530 if ((err = (Decoders[son->type]) (bs, son, base,
Patrick McHardy71859892006-05-23 15:07:07 -0700531 level + 1)) <
532 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800533 return err;
534
535 bs->cur = beg + len;
536 bs->bit = 0;
537 } else if ((err = (Decoders[son->type]) (bs, son, base,
Patrick McHardy71859892006-05-23 15:07:07 -0700538 level + 1)) <
539 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800540 return err;
541 }
542
543 /* No extension? */
544 if (!ext)
545 return H323_ERROR_NONE;
546
547 /* Get the extension bitmap */
548 bmp2_len = get_bits(bs, 7) + 1;
549 CHECK_BOUND(bs, (bmp2_len + 7) >> 3);
550 bmp2 = get_bitmap(bs, bmp2_len);
551 bmp |= bmp2 >> f->sz;
552 if (base)
553 *(unsigned *) base = bmp;
554 BYTE_ALIGN(bs);
555
556 /* Decode the extension components */
557 for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800558 /* Check Range */
559 if (i >= f->ub) { /* Newer Version? */
560 CHECK_BOUND(bs, 2);
561 len = get_len(bs);
562 CHECK_BOUND(bs, len);
563 bs->cur += len;
564 continue;
565 }
566
Jing Min Zhao558585a2007-07-07 22:13:17 -0700567 if (son->attr & STOP) {
568 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
569 son->name);
570 return H323_ERROR_STOP;
571 }
572
573 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
574 continue;
575
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800576 CHECK_BOUND(bs, 2);
577 len = get_len(bs);
578 CHECK_BOUND(bs, len);
579 if (!base || !(son->attr & DECODE)) {
580 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
581 son->name);
582 bs->cur += len;
583 continue;
584 }
585 beg = bs->cur;
586
587 if ((err = (Decoders[son->type]) (bs, son, base,
Patrick McHardy71859892006-05-23 15:07:07 -0700588 level + 1)) <
589 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800590 return err;
591
592 bs->cur = beg + len;
593 bs->bit = 0;
594 }
595 return H323_ERROR_NONE;
596}
597
598/****************************************************************************/
599int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
600{
601 unsigned count, effective_count = 0, i, len = 0;
602 int err;
603 field_t *son;
604 unsigned char *beg = NULL;
605
606 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
607
608 /* Decode? */
609 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
610
611 /* Decode item count */
612 switch (f->sz) {
613 case BYTE:
614 BYTE_ALIGN(bs);
615 CHECK_BOUND(bs, 1);
616 count = *bs->cur++;
617 break;
618 case WORD:
619 BYTE_ALIGN(bs);
620 CHECK_BOUND(bs, 2);
621 count = *bs->cur++;
622 count <<= 8;
623 count = *bs->cur++;
624 break;
625 case SEMI:
626 BYTE_ALIGN(bs);
627 CHECK_BOUND(bs, 2);
628 count = get_len(bs);
629 break;
630 default:
631 count = get_bits(bs, f->sz);
632 break;
633 }
634 count += f->lb;
635
636 /* Write Count */
637 if (base) {
638 effective_count = count > f->ub ? f->ub : count;
639 *(unsigned *) base = effective_count;
640 base += sizeof(unsigned);
641 }
642
643 /* Decode nested field */
644 son = f->fields;
645 if (base)
646 base -= son->offset;
647 for (i = 0; i < count; i++) {
648 if (son->attr & OPEN) {
649 BYTE_ALIGN(bs);
650 len = get_len(bs);
651 CHECK_BOUND(bs, len);
652 if (!base || !(son->attr & DECODE)) {
653 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
654 " ", son->name);
655 bs->cur += len;
656 continue;
657 }
658 beg = bs->cur;
659
660 if ((err = (Decoders[son->type]) (bs, son,
661 i <
662 effective_count ?
663 base : NULL,
Patrick McHardy71859892006-05-23 15:07:07 -0700664 level + 1)) <
665 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800666 return err;
667
668 bs->cur = beg + len;
669 bs->bit = 0;
670 } else
Patrick McHardy71859892006-05-23 15:07:07 -0700671 if ((err = (Decoders[son->type]) (bs, son,
672 i <
673 effective_count ?
674 base : NULL,
675 level + 1)) <
676 H323_ERROR_NONE)
677 return err;
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800678
679 if (base)
680 base += son->offset;
681 }
682
683 return H323_ERROR_NONE;
684}
685
686
687/****************************************************************************/
688int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
689{
690 unsigned type, ext, len = 0;
691 int err;
692 field_t *son;
693 unsigned char *beg = NULL;
694
695 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
696
697 /* Decode? */
698 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
699
700 /* Decode the choice index number */
701 if ((f->attr & EXT) && get_bit(bs)) {
702 ext = 1;
703 type = get_bits(bs, 7) + f->lb;
704 } else {
705 ext = 0;
706 type = get_bits(bs, f->sz);
Jing Min Zhao25845b52007-07-05 17:05:01 -0700707 if (type >= f->lb)
708 return H323_ERROR_RANGE;
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800709 }
710
Patrick McHardy4228e2a2006-05-03 23:17:11 -0700711 /* Write Type */
712 if (base)
713 *(unsigned *) base = type;
714
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800715 /* Check Range */
716 if (type >= f->ub) { /* Newer version? */
717 BYTE_ALIGN(bs);
718 len = get_len(bs);
719 CHECK_BOUND(bs, len);
720 bs->cur += len;
721 return H323_ERROR_NONE;
722 }
723
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800724 /* Transfer to son level */
725 son = &f->fields[type];
726 if (son->attr & STOP) {
727 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name);
728 return H323_ERROR_STOP;
729 }
730
731 if (ext || (son->attr & OPEN)) {
732 BYTE_ALIGN(bs);
733 len = get_len(bs);
734 CHECK_BOUND(bs, len);
735 if (!base || !(son->attr & DECODE)) {
736 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
737 son->name);
738 bs->cur += len;
739 return H323_ERROR_NONE;
740 }
741 beg = bs->cur;
742
Patrick McHardy71859892006-05-23 15:07:07 -0700743 if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
744 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800745 return err;
746
747 bs->cur = beg + len;
748 bs->bit = 0;
Patrick McHardy71859892006-05-23 15:07:07 -0700749 } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
750 H323_ERROR_NONE)
Jing Min Zhao5e35941d2006-03-20 23:41:17 -0800751 return err;
752
753 return H323_ERROR_NONE;
754}
755
756/****************************************************************************/
757int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
758{
759 static field_t ras_message = {
760 FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
761 0, _RasMessage
762 };
763 bitstr_t bs;
764
765 bs.buf = bs.beg = bs.cur = buf;
766 bs.end = buf + sz;
767 bs.bit = 0;
768
769 return decode_choice(&bs, &ras_message, (char *) ras, 0);
770}
771
772/****************************************************************************/
773static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
774 size_t sz, H323_UserInformation * uuie)
775{
776 static field_t h323_userinformation = {
777 FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
778 0, _H323_UserInformation
779 };
780 bitstr_t bs;
781
782 bs.buf = buf;
783 bs.beg = bs.cur = beg;
784 bs.end = beg + sz;
785 bs.bit = 0;
786
787 return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
788}
789
790/****************************************************************************/
791int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
792 MultimediaSystemControlMessage *
793 mscm)
794{
795 static field_t multimediasystemcontrolmessage = {
796 FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
797 DECODE | EXT, 0, _MultimediaSystemControlMessage
798 };
799 bitstr_t bs;
800
801 bs.buf = bs.beg = bs.cur = buf;
802 bs.end = buf + sz;
803 bs.bit = 0;
804
805 return decode_choice(&bs, &multimediasystemcontrolmessage,
806 (char *) mscm, 0);
807}
808
809/****************************************************************************/
810int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
811{
812 unsigned char *p = buf;
813 int len;
814
815 if (!p || sz < 1)
816 return H323_ERROR_BOUND;
817
818 /* Protocol Discriminator */
819 if (*p != 0x08) {
820 PRINT("Unknown Protocol Discriminator\n");
821 return H323_ERROR_RANGE;
822 }
823 p++;
824 sz--;
825
826 /* CallReferenceValue */
827 if (sz < 1)
828 return H323_ERROR_BOUND;
829 len = *p++;
830 sz--;
831 if (sz < len)
832 return H323_ERROR_BOUND;
833 p += len;
834 sz -= len;
835
836 /* Message Type */
837 if (sz < 1)
838 return H323_ERROR_BOUND;
839 q931->MessageType = *p++;
840 PRINT("MessageType = %02X\n", q931->MessageType);
841 if (*p & 0x80) {
842 p++;
843 sz--;
844 }
845
846 /* Decode Information Elements */
847 while (sz > 0) {
848 if (*p == 0x7e) { /* UserUserIE */
849 if (sz < 3)
850 break;
851 p++;
852 len = *p++ << 8;
853 len |= *p++;
854 sz -= 3;
855 if (sz < len)
856 break;
857 p++;
858 len--;
859 return DecodeH323_UserInformation(buf, p, len,
860 &q931->UUIE);
861 }
862 p++;
863 sz--;
864 if (sz < 1)
865 break;
866 len = *p++;
867 if (sz < len)
868 break;
869 p += len;
870 sz -= len;
871 }
872
873 PRINT("Q.931 UUIE not found\n");
874
875 return H323_ERROR_BOUND;
876}