[MIPS] Cobalt: Move UART base definition to arch/mips/cobalt/console.c
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / net / netfilter / nf_conntrack_h323_asn1.c
bloba869403b229419562f6749b347b6ad7f8955e220
1 /****************************************************************************
2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
3 * conntrack/NAT module.
5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
7 * This source code is licensed under General Public License version 2.
9 * See ip_conntrack_helper_h323_asn1.h for details.
11 ****************************************************************************/
13 #ifdef __KERNEL__
14 #include <linux/kernel.h>
15 #else
16 #include <stdio.h>
17 #endif
18 #include <linux/netfilter/nf_conntrack_h323_asn1.h>
20 /* Trace Flag */
21 #ifndef H323_TRACE
22 #define H323_TRACE 0
23 #endif
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
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
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
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
79 /* ASN.1 Field Structure */
80 typedef 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;
93 /* Bit Stream */
94 typedef struct {
95 unsigned char *buf;
96 unsigned char *beg;
97 unsigned char *end;
98 unsigned char *cur;
99 unsigned bit;
100 } bitstr_t;
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)
107 static unsigned get_len(bitstr_t * bs);
108 static unsigned get_bit(bitstr_t * bs);
109 static unsigned get_bits(bitstr_t * bs, unsigned b);
110 static unsigned get_bitmap(bitstr_t * bs, unsigned b);
111 static unsigned get_uint(bitstr_t * bs, int b);
113 /* Decoder Functions */
114 static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
115 static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
116 static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
117 static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
118 static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
119 static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
120 static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
121 static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
122 static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
123 static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
124 static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
125 static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
127 /* Decoder Functions Vector */
128 typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
129 static 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,
144 /****************************************************************************
145 * H.323 Types
146 ****************************************************************************/
147 #include "nf_conntrack_h323_types.c"
149 /****************************************************************************
150 * Functions
151 ****************************************************************************/
152 /* Assume bs is aligned && v < 16384 */
153 unsigned get_len(bitstr_t * bs)
155 unsigned v;
157 v = *bs->cur++;
159 if (v & 0x80) {
160 v &= 0x3f;
161 v <<= 8;
162 v += *bs->cur++;
165 return v;
168 /****************************************************************************/
169 unsigned get_bit(bitstr_t * bs)
171 unsigned b = (*bs->cur) & (0x80 >> bs->bit);
173 INC_BIT(bs);
175 return b;
178 /****************************************************************************/
179 /* Assume b <= 8 */
180 unsigned get_bits(bitstr_t * bs, unsigned b)
182 unsigned v, l;
184 v = (*bs->cur) & (0xffU >> bs->bit);
185 l = b + bs->bit;
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 */
195 v <<= 8;
196 v += *(++bs->cur);
197 v >>= 16 - l;
198 bs->bit = l - 8;
201 return v;
204 /****************************************************************************/
205 /* Assume b <= 32 */
206 unsigned get_bitmap(bitstr_t * bs, unsigned b)
208 unsigned v, l, shift, bytes;
210 if (!b)
211 return 0;
213 l = bs->bit + b;
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;
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);
234 bs->bit = l & 0x7;
237 v &= 0xffffffff << (32 - b);
239 return v;
242 /****************************************************************************
243 * Assume bs is aligned and sizeof(unsigned int) == 4
244 ****************************************************************************/
245 unsigned get_uint(bitstr_t * bs, int b)
247 unsigned v = 0;
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;
263 return v;
266 /****************************************************************************/
267 int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
269 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
271 return H323_ERROR_NONE;
274 /****************************************************************************/
275 int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
277 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
279 INC_BIT(bs);
281 CHECK_BOUND(bs, 0);
282 return H323_ERROR_NONE;
285 /****************************************************************************/
286 int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
288 int len;
290 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
292 BYTE_ALIGN(bs);
293 CHECK_BOUND(bs, 1);
294 len = *bs->cur++;
295 bs->cur += len;
297 CHECK_BOUND(bs, 0);
298 return H323_ERROR_NONE;
301 /****************************************************************************/
302 int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
304 unsigned len;
306 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
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;
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;
338 PRINT("\n");
340 CHECK_BOUND(bs, 0);
341 return H323_ERROR_NONE;
344 /****************************************************************************/
345 int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
347 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
349 if ((f->attr & EXT) && get_bit(bs)) {
350 INC_BITS(bs, 7);
351 } else {
352 INC_BITS(bs, f->sz);
355 CHECK_BOUND(bs, 0);
356 return H323_ERROR_NONE;
359 /****************************************************************************/
360 int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
362 unsigned len;
364 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
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;
385 bs->cur += len >> 3;
386 bs->bit = len & 7;
388 CHECK_BOUND(bs, 0);
389 return H323_ERROR_NONE;
392 /****************************************************************************/
393 int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
395 unsigned len;
397 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
399 /* 2 <= Range <= 255 */
400 len = get_bits(bs, f->sz) + f->lb;
402 BYTE_ALIGN(bs);
403 INC_BITS(bs, (len << 2));
405 CHECK_BOUND(bs, 0);
406 return H323_ERROR_NONE;
409 /****************************************************************************/
410 int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
412 unsigned len;
414 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
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;
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;
449 bs->cur += len;
451 PRINT("\n");
453 CHECK_BOUND(bs, 0);
454 return H323_ERROR_NONE;
457 /****************************************************************************/
458 int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
460 unsigned len;
462 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
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;
476 bs->cur += len << 1;
478 CHECK_BOUND(bs, 0);
479 return H323_ERROR_NONE;
482 /****************************************************************************/
483 int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
485 unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
486 int err;
487 field_t *son;
488 unsigned char *beg = NULL;
490 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
492 /* Decode? */
493 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
495 /* Extensible? */
496 ext = (f->attr & EXT) ? get_bit(bs) : 0;
498 /* Get fields bitmap */
499 bmp = get_bitmap(bs, f->sz);
500 if (base)
501 *(unsigned *) base = bmp;
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;
511 if (son->attr & OPT) { /* Optional component */
512 if (!((0x80000000U >> (opt++)) & bmp)) /* Not exist */
513 continue;
516 /* Decode */
517 if (son->attr & OPEN) { /* Open field */
518 CHECK_BOUND(bs, 2);
519 len = get_len(bs);
520 CHECK_BOUND(bs, len);
521 if (!base || !(son->attr & DECODE)) {
522 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
523 " ", son->name);
524 bs->cur += len;
525 continue;
527 beg = bs->cur;
529 /* Decode */
530 if ((err = (Decoders[son->type]) (bs, son, base,
531 level + 1)) <
532 H323_ERROR_NONE)
533 return err;
535 bs->cur = beg + len;
536 bs->bit = 0;
537 } else if ((err = (Decoders[son->type]) (bs, son, base,
538 level + 1)) <
539 H323_ERROR_NONE)
540 return err;
543 /* No extension? */
544 if (!ext)
545 return H323_ERROR_NONE;
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);
556 /* Decode the extension components */
557 for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
558 /* 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;
567 if (son->attr & STOP) {
568 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
569 son->name);
570 return H323_ERROR_STOP;
573 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
574 continue;
576 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;
585 beg = bs->cur;
587 if ((err = (Decoders[son->type]) (bs, son, base,
588 level + 1)) <
589 H323_ERROR_NONE)
590 return err;
592 bs->cur = beg + len;
593 bs->bit = 0;
595 return H323_ERROR_NONE;
598 /****************************************************************************/
599 int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
601 unsigned count, effective_count = 0, i, len = 0;
602 int err;
603 field_t *son;
604 unsigned char *beg = NULL;
606 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
608 /* Decode? */
609 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
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;
634 count += f->lb;
636 /* Write Count */
637 if (base) {
638 effective_count = count > f->ub ? f->ub : count;
639 *(unsigned *) base = effective_count;
640 base += sizeof(unsigned);
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;
658 beg = bs->cur;
660 if ((err = (Decoders[son->type]) (bs, son,
662 effective_count ?
663 base : NULL,
664 level + 1)) <
665 H323_ERROR_NONE)
666 return err;
668 bs->cur = beg + len;
669 bs->bit = 0;
670 } else
671 if ((err = (Decoders[son->type]) (bs, son,
673 effective_count ?
674 base : NULL,
675 level + 1)) <
676 H323_ERROR_NONE)
677 return err;
679 if (base)
680 base += son->offset;
683 return H323_ERROR_NONE;
687 /****************************************************************************/
688 int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
690 unsigned type, ext, len = 0;
691 int err;
692 field_t *son;
693 unsigned char *beg = NULL;
695 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
697 /* Decode? */
698 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
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);
707 if (type >= f->lb)
708 return H323_ERROR_RANGE;
711 /* Write Type */
712 if (base)
713 *(unsigned *) base = type;
715 /* 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;
724 /* 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;
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;
741 beg = bs->cur;
743 if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
744 H323_ERROR_NONE)
745 return err;
747 bs->cur = beg + len;
748 bs->bit = 0;
749 } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
750 H323_ERROR_NONE)
751 return err;
753 return H323_ERROR_NONE;
756 /****************************************************************************/
757 int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
759 static field_t ras_message = {
760 FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
761 0, _RasMessage
763 bitstr_t bs;
765 bs.buf = bs.beg = bs.cur = buf;
766 bs.end = buf + sz;
767 bs.bit = 0;
769 return decode_choice(&bs, &ras_message, (char *) ras, 0);
772 /****************************************************************************/
773 static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
774 size_t sz, H323_UserInformation * uuie)
776 static field_t h323_userinformation = {
777 FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
778 0, _H323_UserInformation
780 bitstr_t bs;
782 bs.buf = buf;
783 bs.beg = bs.cur = beg;
784 bs.end = beg + sz;
785 bs.bit = 0;
787 return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
790 /****************************************************************************/
791 int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
792 MultimediaSystemControlMessage *
793 mscm)
795 static field_t multimediasystemcontrolmessage = {
796 FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
797 DECODE | EXT, 0, _MultimediaSystemControlMessage
799 bitstr_t bs;
801 bs.buf = bs.beg = bs.cur = buf;
802 bs.end = buf + sz;
803 bs.bit = 0;
805 return decode_choice(&bs, &multimediasystemcontrolmessage,
806 (char *) mscm, 0);
809 /****************************************************************************/
810 int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
812 unsigned char *p = buf;
813 int len;
815 if (!p || sz < 1)
816 return H323_ERROR_BOUND;
818 /* Protocol Discriminator */
819 if (*p != 0x08) {
820 PRINT("Unknown Protocol Discriminator\n");
821 return H323_ERROR_RANGE;
823 p++;
824 sz--;
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;
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--;
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);
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;
873 PRINT("Q.931 UUIE not found\n");
875 return H323_ERROR_BOUND;