Blame view

net/netfilter/nf_conntrack_h323_asn1.c 19.7 KB
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
1
2
3
4
  /****************************************************************************
   * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
   * 			      	     conntrack/NAT module.
   *
7582e9d17   Jing Min Zhao   [NETFILTER]: H.32...
5
   * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
6
7
8
9
10
11
12
13
14
15
16
17
   *
   * This source code is licensed under General Public License version 2.
   *
   * See ip_conntrack_helper_h323_asn1.h for details.
   *
   ****************************************************************************/
  
  #ifdef __KERNEL__
  #include <linux/kernel.h>
  #else
  #include <stdio.h>
  #endif
f587de0e2   Patrick McHardy   [NETFILTER]: nf_c...
18
  #include <linux/netfilter/nf_conntrack_h323_asn1.h>
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  
  /* Trace Flag */
  #ifndef H323_TRACE
  #define H323_TRACE 0
  #endif
  
  #if H323_TRACE
  #define TAB_SIZE 4
  #define IFTHEN(cond, act) if(cond){act;}
  #ifdef __KERNEL__
  #define PRINT printk
  #else
  #define PRINT printf
  #endif
  #define FNAME(name) name,
  #else
  #define IFTHEN(cond, act)
  #define PRINT(fmt, args...)
  #define FNAME(name)
  #endif
  
  /* ASN.1 Types */
  #define NUL 0
  #define BOOL 1
  #define OID 2
  #define INT 3
  #define ENUM 4
  #define BITSTR 5
  #define NUMSTR 6
  #define NUMDGT 6
  #define TBCDSTR 6
  #define OCTSTR 7
  #define PRTSTR 7
  #define IA5STR 7
  #define GENSTR 7
  #define BMPSTR 8
  #define SEQ 9
  #define SET 9
  #define SEQOF 10
  #define SETOF 10
  #define CHOICE 11
  
  /* Constraint Types */
  #define FIXD 0
  /* #define BITS 1-8 */
  #define BYTE 9
  #define WORD 10
  #define CONS 11
  #define SEMI 12
  #define UNCO 13
  
  /* ASN.1 Type Attributes */
  #define SKIP 0
  #define STOP 1
  #define DECODE 2
  #define EXT 4
  #define OPEN 8
  #define OPT 16
  
  
  /* ASN.1 Field Structure */
  typedef struct field_t {
  #if H323_TRACE
  	char *name;
  #endif
  	unsigned char type;
  	unsigned char sz;
  	unsigned char lb;
  	unsigned char ub;
  	unsigned short attr;
  	unsigned short offset;
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
90
  	const struct field_t *fields;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
91
92
93
94
95
96
97
98
  } field_t;
  
  /* Bit Stream */
  typedef struct {
  	unsigned char *buf;
  	unsigned char *beg;
  	unsigned char *end;
  	unsigned char *cur;
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
99
  	unsigned int bit;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
100
101
102
  } bitstr_t;
  
  /* Tool Functions */
e79ec50b9   Jan Engelhardt   [NETFILTER]: Pare...
103
104
105
106
  #define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;}
  #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
  #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
  #define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
107
108
109
110
111
  static unsigned int get_len(bitstr_t *bs);
  static unsigned int get_bit(bitstr_t *bs);
  static unsigned int get_bits(bitstr_t *bs, unsigned int b);
  static unsigned int get_bitmap(bitstr_t *bs, unsigned int b);
  static unsigned int get_uint(bitstr_t *bs, int b);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
112
113
  
  /* Decoder Functions */
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
114
115
116
117
118
119
120
121
122
123
124
125
  static int decode_nul(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_bool(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_oid(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_int(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_enum(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_bitstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_numstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_octstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_bmpstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_seq(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_seqof(bitstr_t *bs, const struct field_t *f, char *base, int level);
  static int decode_choice(bitstr_t *bs, const struct field_t *f, char *base, int level);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
126
127
  
  /* Decoder Functions Vector */
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
128
  typedef int (*decoder_t)(bitstr_t *, const struct field_t *, char *, int);
dc64d02ba   Stephen Hemminger   [NETFILTER]: nf_c...
129
  static const decoder_t Decoders[] = {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  	decode_nul,
  	decode_bool,
  	decode_oid,
  	decode_int,
  	decode_enum,
  	decode_bitstr,
  	decode_numstr,
  	decode_octstr,
  	decode_bmpstr,
  	decode_seq,
  	decode_seqof,
  	decode_choice,
  };
  
  /****************************************************************************
   * H.323 Types
   ****************************************************************************/
f587de0e2   Patrick McHardy   [NETFILTER]: nf_c...
147
  #include "nf_conntrack_h323_types.c"
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
148
149
150
151
152
  
  /****************************************************************************
   * Functions
   ****************************************************************************/
  /* Assume bs is aligned && v < 16384 */
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
153
  static unsigned int get_len(bitstr_t *bs)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
154
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
155
  	unsigned int v;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
156
157
158
159
160
161
162
163
164
165
166
167
168
  
  	v = *bs->cur++;
  
  	if (v & 0x80) {
  		v &= 0x3f;
  		v <<= 8;
  		v += *bs->cur++;
  	}
  
  	return v;
  }
  
  /****************************************************************************/
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
169
  static unsigned int get_bit(bitstr_t *bs)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
170
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
171
  	unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
172
173
174
175
176
177
178
179
  
  	INC_BIT(bs);
  
  	return b;
  }
  
  /****************************************************************************/
  /* Assume b <= 8 */
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
180
  static unsigned int get_bits(bitstr_t *bs, unsigned int b)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
181
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
182
  	unsigned int v, l;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  
  	v = (*bs->cur) & (0xffU >> bs->bit);
  	l = b + bs->bit;
  
  	if (l < 8) {
  		v >>= 8 - l;
  		bs->bit = l;
  	} else if (l == 8) {
  		bs->cur++;
  		bs->bit = 0;
  	} else {		/* l > 8 */
  
  		v <<= 8;
  		v += *(++bs->cur);
  		v >>= 16 - l;
  		bs->bit = l - 8;
  	}
  
  	return v;
  }
  
  /****************************************************************************/
  /* Assume b <= 32 */
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
206
  static unsigned int get_bitmap(bitstr_t *bs, unsigned int b)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
207
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
208
  	unsigned int v, l, shift, bytes;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
209
210
211
212
213
214
215
  
  	if (!b)
  		return 0;
  
  	l = bs->bit + b;
  
  	if (l < 8) {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
216
  		v = (unsigned int)(*bs->cur) << (bs->bit + 24);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
217
218
  		bs->bit = l;
  	} else if (l == 8) {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
219
  		v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
220
221
222
223
  		bs->bit = 0;
  	} else {
  		for (bytes = l >> 3, shift = 24, v = 0; bytes;
  		     bytes--, shift -= 8)
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
224
  			v |= (unsigned int)(*bs->cur++) << shift;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
225
226
  
  		if (l < 32) {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
227
  			v |= (unsigned int)(*bs->cur) << shift;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  			v <<= bs->bit;
  		} else if (l > 32) {
  			v <<= bs->bit;
  			v |= (*bs->cur) >> (8 - bs->bit);
  		}
  
  		bs->bit = l & 0x7;
  	}
  
  	v &= 0xffffffff << (32 - b);
  
  	return v;
  }
  
  /****************************************************************************
   * Assume bs is aligned and sizeof(unsigned int) == 4
   ****************************************************************************/
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
245
  static unsigned int get_uint(bitstr_t *bs, int b)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
246
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
247
  	unsigned int v = 0;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
  
  	switch (b) {
  	case 4:
  		v |= *bs->cur++;
  		v <<= 8;
  	case 3:
  		v |= *bs->cur++;
  		v <<= 8;
  	case 2:
  		v |= *bs->cur++;
  		v <<= 8;
  	case 1:
  		v |= *bs->cur++;
  		break;
  	}
  	return v;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
267
268
  static int decode_nul(bitstr_t *bs, const struct field_t *f,
                        char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
269
270
271
272
273
274
275
276
  {
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
277
278
  static int decode_bool(bitstr_t *bs, const struct field_t *f,
                         char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
279
280
281
282
283
284
285
286
287
288
289
  {
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	INC_BIT(bs);
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
290
291
  static int decode_oid(bitstr_t *bs, const struct field_t *f,
                        char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  {
  	int len;
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	BYTE_ALIGN(bs);
  	CHECK_BOUND(bs, 1);
  	len = *bs->cur++;
  	bs->cur += len;
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
308
309
  static int decode_int(bitstr_t *bs, const struct field_t *f,
                        char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
310
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
311
  	unsigned int len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  
  	PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
  
  	switch (f->sz) {
  	case BYTE:		/* Range == 256 */
  		BYTE_ALIGN(bs);
  		bs->cur++;
  		break;
  	case WORD:		/* 257 <= Range <= 64K */
  		BYTE_ALIGN(bs);
  		bs->cur += 2;
  		break;
  	case CONS:		/* 64K < Range < 4G */
  		len = get_bits(bs, 2) + 1;
  		BYTE_ALIGN(bs);
  		if (base && (f->attr & DECODE)) {	/* timeToLive */
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
328
  			unsigned int v = get_uint(bs, len) + f->lb;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
329
  			PRINT(" = %u", v);
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
330
  			*((unsigned int *)(base + f->offset)) = v;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  		}
  		bs->cur += len;
  		break;
  	case UNCO:
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 2);
  		len = get_len(bs);
  		bs->cur += len;
  		break;
  	default:		/* 2 <= Range <= 255 */
  		INC_BITS(bs, f->sz);
  		break;
  	}
  
  	PRINT("
  ");
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
353
354
  static int decode_enum(bitstr_t *bs, const struct field_t *f,
                         char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  {
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	if ((f->attr & EXT) && get_bit(bs)) {
  		INC_BITS(bs, 7);
  	} else {
  		INC_BITS(bs, f->sz);
  	}
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
370
371
  static int decode_bitstr(bitstr_t *bs, const struct field_t *f,
                           char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
372
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
373
  	unsigned int len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	BYTE_ALIGN(bs);
  	switch (f->sz) {
  	case FIXD:		/* fixed length > 16 */
  		len = f->lb;
  		break;
  	case WORD:		/* 2-byte length */
  		CHECK_BOUND(bs, 2);
  		len = (*bs->cur++) << 8;
  		len += (*bs->cur++) + f->lb;
  		break;
  	case SEMI:
  		CHECK_BOUND(bs, 2);
  		len = get_len(bs);
  		break;
  	default:
  		len = 0;
  		break;
  	}
  
  	bs->cur += len >> 3;
  	bs->bit = len & 7;
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
405
406
  static int decode_numstr(bitstr_t *bs, const struct field_t *f,
                           char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
407
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
408
  	unsigned int len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	/* 2 <= Range <= 255 */
  	len = get_bits(bs, f->sz) + f->lb;
  
  	BYTE_ALIGN(bs);
  	INC_BITS(bs, (len << 2));
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
424
425
  static int decode_octstr(bitstr_t *bs, const struct field_t *f,
                           char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
426
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
427
  	unsigned int len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  
  	PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
  
  	switch (f->sz) {
  	case FIXD:		/* Range == 1 */
  		if (f->lb > 2) {
  			BYTE_ALIGN(bs);
  			if (base && (f->attr & DECODE)) {
  				/* The IP Address */
  				IFTHEN(f->lb == 4,
  				       PRINT(" = %d.%d.%d.%d:%d",
  					     bs->cur[0], bs->cur[1],
  					     bs->cur[2], bs->cur[3],
  					     bs->cur[4] * 256 + bs->cur[5]));
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
442
  				*((unsigned int *)(base + f->offset)) =
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
  				    bs->cur - bs->buf;
  			}
  		}
  		len = f->lb;
  		break;
  	case BYTE:		/* Range == 256 */
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 1);
  		len = (*bs->cur++) + f->lb;
  		break;
  	case SEMI:
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 2);
  		len = get_len(bs) + f->lb;
  		break;
  	default:		/* 2 <= Range <= 255 */
  		len = get_bits(bs, f->sz) + f->lb;
  		BYTE_ALIGN(bs);
  		break;
  	}
  
  	bs->cur += len;
  
  	PRINT("
  ");
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
474
475
  static int decode_bmpstr(bitstr_t *bs, const struct field_t *f,
                           char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
476
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
477
  	unsigned int len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	switch (f->sz) {
  	case BYTE:		/* Range == 256 */
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 1);
  		len = (*bs->cur++) + f->lb;
  		break;
  	default:		/* 2 <= Range <= 255 */
  		len = get_bits(bs, f->sz) + f->lb;
  		BYTE_ALIGN(bs);
  		break;
  	}
  
  	bs->cur += len << 1;
  
  	CHECK_BOUND(bs, 0);
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
501
502
  static int decode_seq(bitstr_t *bs, const struct field_t *f,
                        char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
503
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
504
  	unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
505
  	int err;
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
506
  	const struct field_t *son;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  	unsigned char *beg = NULL;
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	/* Decode? */
  	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
  
  	/* Extensible? */
  	ext = (f->attr & EXT) ? get_bit(bs) : 0;
  
  	/* Get fields bitmap */
  	bmp = get_bitmap(bs, f->sz);
  	if (base)
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
521
  		*(unsigned int *)base = bmp;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
  
  	/* Decode the root components */
  	for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
  		if (son->attr & STOP) {
  			PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE, " ",
  			      son->name);
  			return H323_ERROR_STOP;
  		}
  
  		if (son->attr & OPT) {	/* Optional component */
  			if (!((0x80000000U >> (opt++)) & bmp))	/* Not exist */
  				continue;
  		}
  
  		/* Decode */
  		if (son->attr & OPEN) {	/* Open field */
  			CHECK_BOUND(bs, 2);
  			len = get_len(bs);
  			CHECK_BOUND(bs, len);
25845b515   Jing Min Zhao   [NETFILTER]: nf_c...
542
  			if (!base || !(son->attr & DECODE)) {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
543
544
545
546
547
548
549
550
551
552
  				PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE,
  				      " ", son->name);
  				bs->cur += len;
  				continue;
  			}
  			beg = bs->cur;
  
  			/* Decode */
  			if ((err = (Decoders[son->type]) (bs, son, base,
7185989db   Patrick McHardy   [NETFILTER]: H.32...
553
554
  							  level + 1)) <
  			    H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
555
556
557
558
559
  				return err;
  
  			bs->cur = beg + len;
  			bs->bit = 0;
  		} else if ((err = (Decoders[son->type]) (bs, son, base,
7185989db   Patrick McHardy   [NETFILTER]: H.32...
560
561
  							 level + 1)) <
  			   H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
562
563
564
565
566
567
568
569
570
571
572
573
574
  			return err;
  	}
  
  	/* No extension? */
  	if (!ext)
  		return H323_ERROR_NONE;
  
  	/* Get the extension bitmap */
  	bmp2_len = get_bits(bs, 7) + 1;
  	CHECK_BOUND(bs, (bmp2_len + 7) >> 3);
  	bmp2 = get_bitmap(bs, bmp2_len);
  	bmp |= bmp2 >> f->sz;
  	if (base)
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
575
  		*(unsigned int *)base = bmp;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
576
577
578
579
  	BYTE_ALIGN(bs);
  
  	/* Decode the extension components */
  	for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
580
581
582
583
584
585
586
587
  		/* Check Range */
  		if (i >= f->ub) {	/* Newer Version? */
  			CHECK_BOUND(bs, 2);
  			len = get_len(bs);
  			CHECK_BOUND(bs, len);
  			bs->cur += len;
  			continue;
  		}
558585aad   Jing Min Zhao   [NETFILTER]: nf_c...
588
589
590
591
592
593
594
595
596
  		if (son->attr & STOP) {
  			PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE, " ",
  			      son->name);
  			return H323_ERROR_STOP;
  		}
  
  		if (!((0x80000000 >> opt) & bmp2))	/* Not present */
  			continue;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
597
598
599
600
601
602
603
604
605
606
607
608
609
  		CHECK_BOUND(bs, 2);
  		len = get_len(bs);
  		CHECK_BOUND(bs, len);
  		if (!base || !(son->attr & DECODE)) {
  			PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE, " ",
  			      son->name);
  			bs->cur += len;
  			continue;
  		}
  		beg = bs->cur;
  
  		if ((err = (Decoders[son->type]) (bs, son, base,
7185989db   Patrick McHardy   [NETFILTER]: H.32...
610
611
  						  level + 1)) <
  		    H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
612
613
614
615
616
617
618
619
620
  			return err;
  
  		bs->cur = beg + len;
  		bs->bit = 0;
  	}
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
621
622
  static int decode_seqof(bitstr_t *bs, const struct field_t *f,
                          char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
623
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
624
  	unsigned int count, effective_count = 0, i, len = 0;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
625
  	int err;
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
626
  	const struct field_t *son;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  	unsigned char *beg = NULL;
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	/* Decode? */
  	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
  
  	/* Decode item count */
  	switch (f->sz) {
  	case BYTE:
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 1);
  		count = *bs->cur++;
  		break;
  	case WORD:
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 2);
  		count = *bs->cur++;
  		count <<= 8;
b4232a227   David Sterba   netfilter: h323: ...
647
  		count += *bs->cur++;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
  		break;
  	case SEMI:
  		BYTE_ALIGN(bs);
  		CHECK_BOUND(bs, 2);
  		count = get_len(bs);
  		break;
  	default:
  		count = get_bits(bs, f->sz);
  		break;
  	}
  	count += f->lb;
  
  	/* Write Count */
  	if (base) {
  		effective_count = count > f->ub ? f->ub : count;
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
663
664
  		*(unsigned int *)base = effective_count;
  		base += sizeof(unsigned int);
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  	}
  
  	/* Decode nested field */
  	son = f->fields;
  	if (base)
  		base -= son->offset;
  	for (i = 0; i < count; i++) {
  		if (son->attr & OPEN) {
  			BYTE_ALIGN(bs);
  			len = get_len(bs);
  			CHECK_BOUND(bs, len);
  			if (!base || !(son->attr & DECODE)) {
  				PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE,
  				      " ", son->name);
  				bs->cur += len;
  				continue;
  			}
  			beg = bs->cur;
  
  			if ((err = (Decoders[son->type]) (bs, son,
  							  i <
  							  effective_count ?
  							  base : NULL,
7185989db   Patrick McHardy   [NETFILTER]: H.32...
689
690
  							  level + 1)) <
  			    H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
691
692
693
694
695
  				return err;
  
  			bs->cur = beg + len;
  			bs->bit = 0;
  		} else
7185989db   Patrick McHardy   [NETFILTER]: H.32...
696
697
698
699
700
701
702
  			if ((err = (Decoders[son->type]) (bs, son,
  							  i <
  							  effective_count ?
  							  base : NULL,
  							  level + 1)) <
  			    H323_ERROR_NONE)
  				return err;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
703
704
705
706
707
708
709
710
711
712
  
  		if (base)
  			base += son->offset;
  	}
  
  	return H323_ERROR_NONE;
  }
  
  
  /****************************************************************************/
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
713
714
  static int decode_choice(bitstr_t *bs, const struct field_t *f,
                           char *base, int level)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
715
  {
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
716
  	unsigned int type, ext, len = 0;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
717
  	int err;
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
718
  	const struct field_t *son;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
  	unsigned char *beg = NULL;
  
  	PRINT("%*.s%s
  ", level * TAB_SIZE, " ", f->name);
  
  	/* Decode? */
  	base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
  
  	/* Decode the choice index number */
  	if ((f->attr & EXT) && get_bit(bs)) {
  		ext = 1;
  		type = get_bits(bs, 7) + f->lb;
  	} else {
  		ext = 0;
  		type = get_bits(bs, f->sz);
25845b515   Jing Min Zhao   [NETFILTER]: nf_c...
734
735
  		if (type >= f->lb)
  			return H323_ERROR_RANGE;
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
736
  	}
4228e2a98   Patrick McHardy   [NETFILTER]: H.32...
737
738
  	/* Write Type */
  	if (base)
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
739
  		*(unsigned int *)base = type;
4228e2a98   Patrick McHardy   [NETFILTER]: H.32...
740

5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
741
742
743
744
745
746
747
748
  	/* Check Range */
  	if (type >= f->ub) {	/* Newer version? */
  		BYTE_ALIGN(bs);
  		len = get_len(bs);
  		CHECK_BOUND(bs, len);
  		bs->cur += len;
  		return H323_ERROR_NONE;
  	}
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  	/* Transfer to son level */
  	son = &f->fields[type];
  	if (son->attr & STOP) {
  		PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE, " ", son->name);
  		return H323_ERROR_STOP;
  	}
  
  	if (ext || (son->attr & OPEN)) {
  		BYTE_ALIGN(bs);
  		len = get_len(bs);
  		CHECK_BOUND(bs, len);
  		if (!base || !(son->attr & DECODE)) {
  			PRINT("%*.s%s
  ", (level + 1) * TAB_SIZE, " ",
  			      son->name);
  			bs->cur += len;
  			return H323_ERROR_NONE;
  		}
  		beg = bs->cur;
7185989db   Patrick McHardy   [NETFILTER]: H.32...
769
770
  		if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
  		    H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
771
772
773
774
  			return err;
  
  		bs->cur = beg + len;
  		bs->bit = 0;
7185989db   Patrick McHardy   [NETFILTER]: H.32...
775
776
  	} else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
  		   H323_ERROR_NONE)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
777
778
779
780
781
782
  		return err;
  
  	return H323_ERROR_NONE;
  }
  
  /****************************************************************************/
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
783
  int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
784
  {
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
785
  	static const struct field_t ras_message = {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
  		FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
  		0, _RasMessage
  	};
  	bitstr_t bs;
  
  	bs.buf = bs.beg = bs.cur = buf;
  	bs.end = buf + sz;
  	bs.bit = 0;
  
  	return decode_choice(&bs, &ras_message, (char *) ras, 0);
  }
  
  /****************************************************************************/
  static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
800
  				      size_t sz, H323_UserInformation *uuie)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
801
  {
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
802
  	static const struct field_t h323_userinformation = {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  		FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
  		0, _H323_UserInformation
  	};
  	bitstr_t bs;
  
  	bs.buf = buf;
  	bs.beg = bs.cur = beg;
  	bs.end = beg + sz;
  	bs.bit = 0;
  
  	return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
  }
  
  /****************************************************************************/
  int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
  					 MultimediaSystemControlMessage *
  					 mscm)
  {
905e3e8ec   Jan Engelhardt   [NETFILTER]: nf_c...
821
  	static const struct field_t multimediasystemcontrolmessage = {
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  		FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
  		DECODE | EXT, 0, _MultimediaSystemControlMessage
  	};
  	bitstr_t bs;
  
  	bs.buf = bs.beg = bs.cur = buf;
  	bs.end = buf + sz;
  	bs.bit = 0;
  
  	return decode_choice(&bs, &multimediasystemcontrolmessage,
  			     (char *) mscm, 0);
  }
  
  /****************************************************************************/
1f807d6eb   Jan Engelhardt   [NETFILTER]: nf_c...
836
  int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
5e35941d9   Jing Min Zhao   [NETFILTER]: Add ...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
  {
  	unsigned char *p = buf;
  	int len;
  
  	if (!p || sz < 1)
  		return H323_ERROR_BOUND;
  
  	/* Protocol Discriminator */
  	if (*p != 0x08) {
  		PRINT("Unknown Protocol Discriminator
  ");
  		return H323_ERROR_RANGE;
  	}
  	p++;
  	sz--;
  
  	/* CallReferenceValue */
  	if (sz < 1)
  		return H323_ERROR_BOUND;
  	len = *p++;
  	sz--;
  	if (sz < len)
  		return H323_ERROR_BOUND;
  	p += len;
  	sz -= len;
  
  	/* Message Type */
  	if (sz < 1)
  		return H323_ERROR_BOUND;
  	q931->MessageType = *p++;
  	PRINT("MessageType = %02X
  ", q931->MessageType);
  	if (*p & 0x80) {
  		p++;
  		sz--;
  	}
  
  	/* Decode Information Elements */
  	while (sz > 0) {
  		if (*p == 0x7e) {	/* UserUserIE */
  			if (sz < 3)
  				break;
  			p++;
  			len = *p++ << 8;
  			len |= *p++;
  			sz -= 3;
  			if (sz < len)
  				break;
  			p++;
  			len--;
  			return DecodeH323_UserInformation(buf, p, len,
  							  &q931->UUIE);
  		}
  		p++;
  		sz--;
  		if (sz < 1)
  			break;
  		len = *p++;
  		if (sz < len)
  			break;
  		p += len;
  		sz -= len;
  	}
  
  	PRINT("Q.931 UUIE not found
  ");
  
  	return H323_ERROR_BOUND;
  }