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	const 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 int 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 int get_len(bitstr_t *bs);
108static unsigned int get_bit(bitstr_t *bs);
109static unsigned int get_bits(bitstr_t *bs, unsigned int b);
110static unsigned int get_bitmap(bitstr_t *bs, unsigned int b);
111static unsigned int get_uint(bitstr_t *bs, int b);
112
113/* Decoder Functions */
114static int decode_nul(bitstr_t *bs, const struct field_t *f, char *base, int level);
115static int decode_bool(bitstr_t *bs, const struct field_t *f, char *base, int level);
116static int decode_oid(bitstr_t *bs, const struct field_t *f, char *base, int level);
117static int decode_int(bitstr_t *bs, const struct field_t *f, char *base, int level);
118static int decode_enum(bitstr_t *bs, const struct field_t *f, char *base, int level);
119static int decode_bitstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
120static int decode_numstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
121static int decode_octstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
122static int decode_bmpstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
123static int decode_seq(bitstr_t *bs, const struct field_t *f, char *base, int level);
124static int decode_seqof(bitstr_t *bs, const struct field_t *f, char *base, int level);
125static int decode_choice(bitstr_t *bs, const struct field_t *f, char *base, int level);
126
127/* Decoder Functions Vector */
128typedef int (*decoder_t)(bitstr_t *, const struct field_t *, char *, int);
129static const 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 */
153static unsigned int get_len(bitstr_t *bs)
154{
155	unsigned int 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/****************************************************************************/
169static unsigned int get_bit(bitstr_t *bs)
170{
171	unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
172
173	INC_BIT(bs);
174
175	return b;
176}
177
178/****************************************************************************/
179/* Assume b <= 8 */
180static unsigned int get_bits(bitstr_t *bs, unsigned int b)
181{
182	unsigned int 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 */
206static unsigned int get_bitmap(bitstr_t *bs, unsigned int b)
207{
208	unsigned int 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 int)(*bs->cur) << (bs->bit + 24);
217		bs->bit = l;
218	} else if (l == 8) {
219		v = (unsigned int)(*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 int)(*bs->cur++) << shift;
225
226		if (l < 32) {
227			v |= (unsigned int)(*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 ****************************************************************************/
245static unsigned int get_uint(bitstr_t *bs, int b)
246{
247	unsigned int 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/****************************************************************************/
267static int decode_nul(bitstr_t *bs, const struct field_t *f,
268                      char *base, int level)
269{
270	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
271
272	return H323_ERROR_NONE;
273}
274
275/****************************************************************************/
276static int decode_bool(bitstr_t *bs, const struct field_t *f,
277                       char *base, int level)
278{
279	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
280
281	INC_BIT(bs);
282
283	CHECK_BOUND(bs, 0);
284	return H323_ERROR_NONE;
285}
286
287/****************************************************************************/
288static int decode_oid(bitstr_t *bs, const struct field_t *f,
289                      char *base, int level)
290{
291	int len;
292
293	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
294
295	BYTE_ALIGN(bs);
296	CHECK_BOUND(bs, 1);
297	len = *bs->cur++;
298	bs->cur += len;
299
300	CHECK_BOUND(bs, 0);
301	return H323_ERROR_NONE;
302}
303
304/****************************************************************************/
305static int decode_int(bitstr_t *bs, const struct field_t *f,
306                      char *base, int level)
307{
308	unsigned int len;
309
310	PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
311
312	switch (f->sz) {
313	case BYTE:		/* Range == 256 */
314		BYTE_ALIGN(bs);
315		bs->cur++;
316		break;
317	case WORD:		/* 257 <= Range <= 64K */
318		BYTE_ALIGN(bs);
319		bs->cur += 2;
320		break;
321	case CONS:		/* 64K < Range < 4G */
322		len = get_bits(bs, 2) + 1;
323		BYTE_ALIGN(bs);
324		if (base && (f->attr & DECODE)) {	/* timeToLive */
325			unsigned int v = get_uint(bs, len) + f->lb;
326			PRINT(" = %u", v);
327			*((unsigned int *)(base + f->offset)) = v;
328		}
329		bs->cur += len;
330		break;
331	case UNCO:
332		BYTE_ALIGN(bs);
333		CHECK_BOUND(bs, 2);
334		len = get_len(bs);
335		bs->cur += len;
336		break;
337	default:		/* 2 <= Range <= 255 */
338		INC_BITS(bs, f->sz);
339		break;
340	}
341
342	PRINT("\n");
343
344	CHECK_BOUND(bs, 0);
345	return H323_ERROR_NONE;
346}
347
348/****************************************************************************/
349static int decode_enum(bitstr_t *bs, const struct field_t *f,
350                       char *base, int level)
351{
352	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
353
354	if ((f->attr & EXT) && get_bit(bs)) {
355		INC_BITS(bs, 7);
356	} else {
357		INC_BITS(bs, f->sz);
358	}
359
360	CHECK_BOUND(bs, 0);
361	return H323_ERROR_NONE;
362}
363
364/****************************************************************************/
365static int decode_bitstr(bitstr_t *bs, const struct field_t *f,
366                         char *base, int level)
367{
368	unsigned int len;
369
370	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
371
372	BYTE_ALIGN(bs);
373	switch (f->sz) {
374	case FIXD:		/* fixed length > 16 */
375		len = f->lb;
376		break;
377	case WORD:		/* 2-byte length */
378		CHECK_BOUND(bs, 2);
379		len = (*bs->cur++) << 8;
380		len += (*bs->cur++) + f->lb;
381		break;
382	case SEMI:
383		CHECK_BOUND(bs, 2);
384		len = get_len(bs);
385		break;
386	default:
387		len = 0;
388		break;
389	}
390
391	bs->cur += len >> 3;
392	bs->bit = len & 7;
393
394	CHECK_BOUND(bs, 0);
395	return H323_ERROR_NONE;
396}
397
398/****************************************************************************/
399static int decode_numstr(bitstr_t *bs, const struct field_t *f,
400                         char *base, int level)
401{
402	unsigned int len;
403
404	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
405
406	/* 2 <= Range <= 255 */
407	len = get_bits(bs, f->sz) + f->lb;
408
409	BYTE_ALIGN(bs);
410	INC_BITS(bs, (len << 2));
411
412	CHECK_BOUND(bs, 0);
413	return H323_ERROR_NONE;
414}
415
416/****************************************************************************/
417static int decode_octstr(bitstr_t *bs, const struct field_t *f,
418                         char *base, int level)
419{
420	unsigned int len;
421
422	PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
423
424	switch (f->sz) {
425	case FIXD:		/* Range == 1 */
426		if (f->lb > 2) {
427			BYTE_ALIGN(bs);
428			if (base && (f->attr & DECODE)) {
429				/* The IP Address */
430				IFTHEN(f->lb == 4,
431				       PRINT(" = %d.%d.%d.%d:%d",
432					     bs->cur[0], bs->cur[1],
433					     bs->cur[2], bs->cur[3],
434					     bs->cur[4] * 256 + bs->cur[5]));
435				*((unsigned int *)(base + f->offset)) =
436				    bs->cur - bs->buf;
437			}
438		}
439		len = f->lb;
440		break;
441	case BYTE:		/* Range == 256 */
442		BYTE_ALIGN(bs);
443		CHECK_BOUND(bs, 1);
444		len = (*bs->cur++) + f->lb;
445		break;
446	case SEMI:
447		BYTE_ALIGN(bs);
448		CHECK_BOUND(bs, 2);
449		len = get_len(bs) + f->lb;
450		break;
451	default:		/* 2 <= Range <= 255 */
452		len = get_bits(bs, f->sz) + f->lb;
453		BYTE_ALIGN(bs);
454		break;
455	}
456
457	bs->cur += len;
458
459	PRINT("\n");
460
461	CHECK_BOUND(bs, 0);
462	return H323_ERROR_NONE;
463}
464
465/****************************************************************************/
466static int decode_bmpstr(bitstr_t *bs, const struct field_t *f,
467                         char *base, int level)
468{
469	unsigned int len;
470
471	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
472
473	switch (f->sz) {
474	case BYTE:		/* Range == 256 */
475		BYTE_ALIGN(bs);
476		CHECK_BOUND(bs, 1);
477		len = (*bs->cur++) + f->lb;
478		break;
479	default:		/* 2 <= Range <= 255 */
480		len = get_bits(bs, f->sz) + f->lb;
481		BYTE_ALIGN(bs);
482		break;
483	}
484
485	bs->cur += len << 1;
486
487	CHECK_BOUND(bs, 0);
488	return H323_ERROR_NONE;
489}
490
491/****************************************************************************/
492static int decode_seq(bitstr_t *bs, const struct field_t *f,
493                      char *base, int level)
494{
495	unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
496	int err;
497	const struct field_t *son;
498	unsigned char *beg = NULL;
499
500	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
501
502	/* Decode? */
503	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
504
505	/* Extensible? */
506	ext = (f->attr & EXT) ? get_bit(bs) : 0;
507
508	/* Get fields bitmap */
509	bmp = get_bitmap(bs, f->sz);
510	if (base)
511		*(unsigned int *)base = bmp;
512
513	/* Decode the root components */
514	for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
515		if (son->attr & STOP) {
516			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
517			      son->name);
518			return H323_ERROR_STOP;
519		}
520
521		if (son->attr & OPT) {	/* Optional component */
522			if (!((0x80000000U >> (opt++)) & bmp))	/* Not exist */
523				continue;
524		}
525
526		/* Decode */
527		if (son->attr & OPEN) {	/* Open field */
528			CHECK_BOUND(bs, 2);
529			len = get_len(bs);
530			CHECK_BOUND(bs, len);
531			if (!base || !(son->attr & DECODE)) {
532				PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
533				      " ", son->name);
534				bs->cur += len;
535				continue;
536			}
537			beg = bs->cur;
538
539			/* Decode */
540			if ((err = (Decoders[son->type]) (bs, son, base,
541							  level + 1)) <
542			    H323_ERROR_NONE)
543				return err;
544
545			bs->cur = beg + len;
546			bs->bit = 0;
547		} else if ((err = (Decoders[son->type]) (bs, son, base,
548							 level + 1)) <
549			   H323_ERROR_NONE)
550			return err;
551	}
552
553	/* No extension? */
554	if (!ext)
555		return H323_ERROR_NONE;
556
557	/* Get the extension bitmap */
558	bmp2_len = get_bits(bs, 7) + 1;
559	CHECK_BOUND(bs, (bmp2_len + 7) >> 3);
560	bmp2 = get_bitmap(bs, bmp2_len);
561	bmp |= bmp2 >> f->sz;
562	if (base)
563		*(unsigned int *)base = bmp;
564	BYTE_ALIGN(bs);
565
566	/* Decode the extension components */
567	for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
568		/* Check Range */
569		if (i >= f->ub) {	/* Newer Version? */
570			CHECK_BOUND(bs, 2);
571			len = get_len(bs);
572			CHECK_BOUND(bs, len);
573			bs->cur += len;
574			continue;
575		}
576
577		if (son->attr & STOP) {
578			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
579			      son->name);
580			return H323_ERROR_STOP;
581		}
582
583		if (!((0x80000000 >> opt) & bmp2))	/* Not present */
584			continue;
585
586		CHECK_BOUND(bs, 2);
587		len = get_len(bs);
588		CHECK_BOUND(bs, len);
589		if (!base || !(son->attr & DECODE)) {
590			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
591			      son->name);
592			bs->cur += len;
593			continue;
594		}
595		beg = bs->cur;
596
597		if ((err = (Decoders[son->type]) (bs, son, base,
598						  level + 1)) <
599		    H323_ERROR_NONE)
600			return err;
601
602		bs->cur = beg + len;
603		bs->bit = 0;
604	}
605	return H323_ERROR_NONE;
606}
607
608/****************************************************************************/
609static int decode_seqof(bitstr_t *bs, const struct field_t *f,
610                        char *base, int level)
611{
612	unsigned int count, effective_count = 0, i, len = 0;
613	int err;
614	const struct field_t *son;
615	unsigned char *beg = NULL;
616
617	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
618
619	/* Decode? */
620	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
621
622	/* Decode item count */
623	switch (f->sz) {
624	case BYTE:
625		BYTE_ALIGN(bs);
626		CHECK_BOUND(bs, 1);
627		count = *bs->cur++;
628		break;
629	case WORD:
630		BYTE_ALIGN(bs);
631		CHECK_BOUND(bs, 2);
632		count = *bs->cur++;
633		count <<= 8;
634		count += *bs->cur++;
635		break;
636	case SEMI:
637		BYTE_ALIGN(bs);
638		CHECK_BOUND(bs, 2);
639		count = get_len(bs);
640		break;
641	default:
642		count = get_bits(bs, f->sz);
643		break;
644	}
645	count += f->lb;
646
647	/* Write Count */
648	if (base) {
649		effective_count = count > f->ub ? f->ub : count;
650		*(unsigned int *)base = effective_count;
651		base += sizeof(unsigned int);
652	}
653
654	/* Decode nested field */
655	son = f->fields;
656	if (base)
657		base -= son->offset;
658	for (i = 0; i < count; i++) {
659		if (son->attr & OPEN) {
660			BYTE_ALIGN(bs);
661			len = get_len(bs);
662			CHECK_BOUND(bs, len);
663			if (!base || !(son->attr & DECODE)) {
664				PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
665				      " ", son->name);
666				bs->cur += len;
667				continue;
668			}
669			beg = bs->cur;
670
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			bs->cur = beg + len;
680			bs->bit = 0;
681		} else
682			if ((err = (Decoders[son->type]) (bs, son,
683							  i <
684							  effective_count ?
685							  base : NULL,
686							  level + 1)) <
687			    H323_ERROR_NONE)
688				return err;
689
690		if (base)
691			base += son->offset;
692	}
693
694	return H323_ERROR_NONE;
695}
696
697
698/****************************************************************************/
699static int decode_choice(bitstr_t *bs, const struct field_t *f,
700                         char *base, int level)
701{
702	unsigned int type, ext, len = 0;
703	int err;
704	const struct field_t *son;
705	unsigned char *beg = NULL;
706
707	PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
708
709	/* Decode? */
710	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
711
712	/* Decode the choice index number */
713	if ((f->attr & EXT) && get_bit(bs)) {
714		ext = 1;
715		type = get_bits(bs, 7) + f->lb;
716	} else {
717		ext = 0;
718		type = get_bits(bs, f->sz);
719		if (type >= f->lb)
720			return H323_ERROR_RANGE;
721	}
722
723	/* Write Type */
724	if (base)
725		*(unsigned int *)base = type;
726
727	/* Check Range */
728	if (type >= f->ub) {	/* Newer version? */
729		BYTE_ALIGN(bs);
730		len = get_len(bs);
731		CHECK_BOUND(bs, len);
732		bs->cur += len;
733		return H323_ERROR_NONE;
734	}
735
736	/* Transfer to son level */
737	son = &f->fields[type];
738	if (son->attr & STOP) {
739		PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name);
740		return H323_ERROR_STOP;
741	}
742
743	if (ext || (son->attr & OPEN)) {
744		BYTE_ALIGN(bs);
745		len = get_len(bs);
746		CHECK_BOUND(bs, len);
747		if (!base || !(son->attr & DECODE)) {
748			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
749			      son->name);
750			bs->cur += len;
751			return H323_ERROR_NONE;
752		}
753		beg = bs->cur;
754
755		if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
756		    H323_ERROR_NONE)
757			return err;
758
759		bs->cur = beg + len;
760		bs->bit = 0;
761	} else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
762		   H323_ERROR_NONE)
763		return err;
764
765	return H323_ERROR_NONE;
766}
767
768/****************************************************************************/
769int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
770{
771	static const struct field_t ras_message = {
772		FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
773		0, _RasMessage
774	};
775	bitstr_t bs;
776
777	bs.buf = bs.beg = bs.cur = buf;
778	bs.end = buf + sz;
779	bs.bit = 0;
780
781	return decode_choice(&bs, &ras_message, (char *) ras, 0);
782}
783
784/****************************************************************************/
785static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
786				      size_t sz, H323_UserInformation *uuie)
787{
788	static const struct field_t h323_userinformation = {
789		FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
790		0, _H323_UserInformation
791	};
792	bitstr_t bs;
793
794	bs.buf = buf;
795	bs.beg = bs.cur = beg;
796	bs.end = beg + sz;
797	bs.bit = 0;
798
799	return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
800}
801
802/****************************************************************************/
803int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
804					 MultimediaSystemControlMessage *
805					 mscm)
806{
807	static const struct field_t multimediasystemcontrolmessage = {
808		FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
809		DECODE | EXT, 0, _MultimediaSystemControlMessage
810	};
811	bitstr_t bs;
812
813	bs.buf = bs.beg = bs.cur = buf;
814	bs.end = buf + sz;
815	bs.bit = 0;
816
817	return decode_choice(&bs, &multimediasystemcontrolmessage,
818			     (char *) mscm, 0);
819}
820
821/****************************************************************************/
822int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
823{
824	unsigned char *p = buf;
825	int len;
826
827	if (!p || sz < 1)
828		return H323_ERROR_BOUND;
829
830	/* Protocol Discriminator */
831	if (*p != 0x08) {
832		PRINT("Unknown Protocol Discriminator\n");
833		return H323_ERROR_RANGE;
834	}
835	p++;
836	sz--;
837
838	/* CallReferenceValue */
839	if (sz < 1)
840		return H323_ERROR_BOUND;
841	len = *p++;
842	sz--;
843	if (sz < len)
844		return H323_ERROR_BOUND;
845	p += len;
846	sz -= len;
847
848	/* Message Type */
849	if (sz < 1)
850		return H323_ERROR_BOUND;
851	q931->MessageType = *p++;
852	PRINT("MessageType = %02X\n", q931->MessageType);
853	if (*p & 0x80) {
854		p++;
855		sz--;
856	}
857
858	/* Decode Information Elements */
859	while (sz > 0) {
860		if (*p == 0x7e) {	/* UserUserIE */
861			if (sz < 3)
862				break;
863			p++;
864			len = *p++ << 8;
865			len |= *p++;
866			sz -= 3;
867			if (sz < len)
868				break;
869			p++;
870			len--;
871			return DecodeH323_UserInformation(buf, p, len,
872							  &q931->UUIE);
873		}
874		p++;
875		sz--;
876		if (sz < 1)
877			break;
878		len = *p++;
879		if (sz < len)
880			break;
881		p += len;
882		sz -= len;
883	}
884
885	PRINT("Q.931 UUIE not found\n");
886
887	return H323_ERROR_BOUND;
888}
889