1/****************************************************************************
2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
3 * 			      	     conntrack/NAT module.
4 *
5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
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 *
11 ****************************************************************************/
12
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>
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;
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 ****************************************************************************/
147#include "nf_conntrack_h323_types.c"
148
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);
521			if (!base || !(son->attr & DECODE)) {
522				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,
531							  level + 1)) <
532			    H323_ERROR_NONE)
533				return err;
534
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;
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++) {
558		if (i < f->ub && son->attr & STOP) {
559			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
560			      son->name);
561			return H323_ERROR_STOP;
562		}
563
564		if (!((0x80000000 >> opt) & bmp2))	/* Not present */
565			continue;
566
567		/* Check Range */
568		if (i >= f->ub) {	/* Newer Version? */
569			CHECK_BOUND(bs, 2);
570			len = get_len(bs);
571			CHECK_BOUND(bs, len);
572			bs->cur += len;
573			continue;
574		}
575
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;
584		}
585		beg = bs->cur;
586
587		if ((err = (Decoders[son->type]) (bs, son, base,
588						  level + 1)) <
589		    H323_ERROR_NONE)
590			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,
664							  level + 1)) <
665			    H323_ERROR_NONE)
666				return err;
667
668			bs->cur = beg + len;
669			bs->bit = 0;
670		} else
671			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;
678
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);
707		if (type >= f->lb)
708			return H323_ERROR_RANGE;
709	}
710
711	/* Write Type */
712	if (base)
713		*(unsigned *) base = type;
714
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;
722	}
723
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;
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
743		if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
744		    H323_ERROR_NONE)
745			return err;
746
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;
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}
877