Blame view
net/netfilter/nf_conntrack_h323_asn1.c
20.1 KB
40b0b3f8f treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
ca9b01473 netfilter: nf_con... |
2 |
/* |
05ba4c895 netfilter: Update... |
3 |
* BER and PER decoding library for H.323 conntrack/NAT module. |
5e35941d9 [NETFILTER]: Add ... |
4 |
* |
7582e9d17 [NETFILTER]: H.32... |
5 |
* Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
5e35941d9 [NETFILTER]: Add ... |
6 |
* |
05ba4c895 netfilter: Update... |
7 |
* See nf_conntrack_helper_h323_asn1.h for details. |
ca9b01473 netfilter: nf_con... |
8 |
*/ |
5e35941d9 [NETFILTER]: Add ... |
9 10 11 12 13 14 |
#ifdef __KERNEL__ #include <linux/kernel.h> #else #include <stdio.h> #endif |
f587de0e2 [NETFILTER]: nf_c... |
15 |
#include <linux/netfilter/nf_conntrack_h323_asn1.h> |
5e35941d9 [NETFILTER]: Add ... |
16 17 18 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 |
/* 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 [NETFILTER]: nf_c... |
87 |
const struct field_t *fields; |
5e35941d9 [NETFILTER]: Add ... |
88 89 90 |
} field_t; /* Bit Stream */ |
67704c2a0 netfilter: nf_con... |
91 |
struct bitstr { |
5e35941d9 [NETFILTER]: Add ... |
92 93 94 95 |
unsigned char *buf; unsigned char *beg; unsigned char *end; unsigned char *cur; |
1f807d6eb [NETFILTER]: nf_c... |
96 |
unsigned int bit; |
67704c2a0 netfilter: nf_con... |
97 |
}; |
5e35941d9 [NETFILTER]: Add ... |
98 99 |
/* Tool Functions */ |
e79ec50b9 [NETFILTER]: Pare... |
100 101 102 |
#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;} |
67704c2a0 netfilter: nf_con... |
103 104 105 106 107 |
static unsigned int get_len(struct bitstr *bs); static unsigned int get_bit(struct bitstr *bs); static unsigned int get_bits(struct bitstr *bs, unsigned int b); static unsigned int get_bitmap(struct bitstr *bs, unsigned int b); static unsigned int get_uint(struct bitstr *bs, int b); |
5e35941d9 [NETFILTER]: Add ... |
108 109 |
/* Decoder Functions */ |
67704c2a0 netfilter: nf_con... |
110 111 112 113 114 115 116 117 118 119 120 121 |
static int decode_nul(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_bool(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_oid(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_int(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_enum(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_bitstr(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_numstr(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_octstr(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_seq(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_seqof(struct bitstr *bs, const struct field_t *f, char *base, int level); static int decode_choice(struct bitstr *bs, const struct field_t *f, char *base, int level); |
5e35941d9 [NETFILTER]: Add ... |
122 123 |
/* Decoder Functions Vector */ |
67704c2a0 netfilter: nf_con... |
124 |
typedef int (*decoder_t)(struct bitstr *, const struct field_t *, char *, int); |
dc64d02ba [NETFILTER]: nf_c... |
125 |
static const decoder_t Decoders[] = { |
5e35941d9 [NETFILTER]: Add ... |
126 127 128 129 130 131 132 133 134 135 136 137 138 |
decode_nul, decode_bool, decode_oid, decode_int, decode_enum, decode_bitstr, decode_numstr, decode_octstr, decode_bmpstr, decode_seq, decode_seqof, decode_choice, }; |
ca9b01473 netfilter: nf_con... |
139 |
/* |
5e35941d9 [NETFILTER]: Add ... |
140 |
* H.323 Types |
ca9b01473 netfilter: nf_con... |
141 |
*/ |
f587de0e2 [NETFILTER]: nf_c... |
142 |
#include "nf_conntrack_h323_types.c" |
5e35941d9 [NETFILTER]: Add ... |
143 |
|
ca9b01473 netfilter: nf_con... |
144 |
/* |
5e35941d9 [NETFILTER]: Add ... |
145 |
* Functions |
ca9b01473 netfilter: nf_con... |
146 |
*/ |
5e35941d9 [NETFILTER]: Add ... |
147 |
/* Assume bs is aligned && v < 16384 */ |
67704c2a0 netfilter: nf_con... |
148 |
static unsigned int get_len(struct bitstr *bs) |
5e35941d9 [NETFILTER]: Add ... |
149 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
150 |
unsigned int v; |
5e35941d9 [NETFILTER]: Add ... |
151 152 153 154 155 156 157 158 159 160 161 |
v = *bs->cur++; if (v & 0x80) { v &= 0x3f; v <<= 8; v += *bs->cur++; } return v; } |
ec8a8f3c3 netfilter: nf_ct_... |
162 |
static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits) |
bc7d811ac netfilter: nf_ct_... |
163 |
{ |
ec8a8f3c3 netfilter: nf_ct_... |
164 165 166 167 |
bits += bs->bit; bytes += bits / BITS_PER_BYTE; if (bits % BITS_PER_BYTE > 0) bytes++; |
f5e85ce8e netfilter: nf_con... |
168 |
if (bs->cur + bytes > bs->end) |
bc7d811ac netfilter: nf_ct_... |
169 170 171 172 |
return 1; return 0; } |
67704c2a0 netfilter: nf_con... |
173 |
static unsigned int get_bit(struct bitstr *bs) |
5e35941d9 [NETFILTER]: Add ... |
174 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
175 |
unsigned int b = (*bs->cur) & (0x80 >> bs->bit); |
5e35941d9 [NETFILTER]: Add ... |
176 177 178 179 180 |
INC_BIT(bs); return b; } |
5e35941d9 [NETFILTER]: Add ... |
181 |
/* Assume b <= 8 */ |
67704c2a0 netfilter: nf_con... |
182 |
static unsigned int get_bits(struct bitstr *bs, unsigned int b) |
5e35941d9 [NETFILTER]: Add ... |
183 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
184 |
unsigned int v, l; |
5e35941d9 [NETFILTER]: Add ... |
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
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; } |
5e35941d9 [NETFILTER]: Add ... |
205 |
/* Assume b <= 32 */ |
67704c2a0 netfilter: nf_con... |
206 |
static unsigned int get_bitmap(struct bitstr *bs, unsigned int b) |
5e35941d9 [NETFILTER]: Add ... |
207 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
208 |
unsigned int v, l, shift, bytes; |
5e35941d9 [NETFILTER]: Add ... |
209 210 211 212 213 214 215 |
if (!b) return 0; l = bs->bit + b; if (l < 8) { |
1f807d6eb [NETFILTER]: nf_c... |
216 |
v = (unsigned int)(*bs->cur) << (bs->bit + 24); |
5e35941d9 [NETFILTER]: Add ... |
217 218 |
bs->bit = l; } else if (l == 8) { |
1f807d6eb [NETFILTER]: nf_c... |
219 |
v = (unsigned int)(*bs->cur++) << (bs->bit + 24); |
5e35941d9 [NETFILTER]: Add ... |
220 221 222 223 |
bs->bit = 0; } else { for (bytes = l >> 3, shift = 24, v = 0; bytes; bytes--, shift -= 8) |
1f807d6eb [NETFILTER]: nf_c... |
224 |
v |= (unsigned int)(*bs->cur++) << shift; |
5e35941d9 [NETFILTER]: Add ... |
225 226 |
if (l < 32) { |
1f807d6eb [NETFILTER]: nf_c... |
227 |
v |= (unsigned int)(*bs->cur) << shift; |
5e35941d9 [NETFILTER]: Add ... |
228 229 230 231 232 233 234 235 236 237 238 239 240 |
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; } |
ca9b01473 netfilter: nf_con... |
241 |
/* |
5e35941d9 [NETFILTER]: Add ... |
242 |
* Assume bs is aligned and sizeof(unsigned int) == 4 |
ca9b01473 netfilter: nf_con... |
243 |
*/ |
67704c2a0 netfilter: nf_con... |
244 |
static unsigned int get_uint(struct bitstr *bs, int b) |
5e35941d9 [NETFILTER]: Add ... |
245 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
246 |
unsigned int v = 0; |
5e35941d9 [NETFILTER]: Add ... |
247 248 249 250 251 |
switch (b) { case 4: v |= *bs->cur++; v <<= 8; |
e8542dcec netfilter: mark e... |
252 |
/* fall through */ |
5e35941d9 [NETFILTER]: Add ... |
253 254 255 |
case 3: v |= *bs->cur++; v <<= 8; |
e8542dcec netfilter: mark e... |
256 |
/* fall through */ |
5e35941d9 [NETFILTER]: Add ... |
257 258 259 |
case 2: v |= *bs->cur++; v <<= 8; |
e8542dcec netfilter: mark e... |
260 |
/* fall through */ |
5e35941d9 [NETFILTER]: Add ... |
261 262 263 264 265 266 |
case 1: v |= *bs->cur++; break; } return v; } |
67704c2a0 netfilter: nf_con... |
267 |
static int decode_nul(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
268 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
269 270 271 272 273 274 |
{ PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
275 |
static int decode_bool(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
276 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
277 278 279 280 281 |
{ PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); INC_BIT(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
282 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
283 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
284 285 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
286 |
static int decode_oid(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
287 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
288 289 290 291 292 293 294 |
{ int len; PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
295 |
if (nf_h323_error_boundary(bs, 1, 0)) |
bc7d811ac netfilter: nf_ct_... |
296 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
297 298 |
len = *bs->cur++; bs->cur += len; |
ec8a8f3c3 netfilter: nf_ct_... |
299 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
300 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
301 |
|
5e35941d9 [NETFILTER]: Add ... |
302 303 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
304 |
static int decode_int(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
305 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
306 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
307 |
unsigned int len; |
5e35941d9 [NETFILTER]: Add ... |
308 309 310 311 312 313 314 315 316 317 318 319 320 |
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 */ |
ec8a8f3c3 netfilter: nf_ct_... |
321 322 |
if (nf_h323_error_boundary(bs, 0, 2)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
323 324 325 |
len = get_bits(bs, 2) + 1; BYTE_ALIGN(bs); if (base && (f->attr & DECODE)) { /* timeToLive */ |
1f807d6eb [NETFILTER]: nf_c... |
326 |
unsigned int v = get_uint(bs, len) + f->lb; |
5e35941d9 [NETFILTER]: Add ... |
327 |
PRINT(" = %u", v); |
1f807d6eb [NETFILTER]: nf_c... |
328 |
*((unsigned int *)(base + f->offset)) = v; |
5e35941d9 [NETFILTER]: Add ... |
329 330 331 332 333 |
} bs->cur += len; break; case UNCO: BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
334 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
335 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
336 337 338 339 340 341 342 343 344 345 |
len = get_len(bs); bs->cur += len; break; default: /* 2 <= Range <= 255 */ INC_BITS(bs, f->sz); break; } PRINT(" "); |
ec8a8f3c3 netfilter: nf_ct_... |
346 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
347 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
348 349 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
350 |
static int decode_enum(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
351 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
352 353 354 355 356 357 358 359 360 |
{ 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); } |
ec8a8f3c3 netfilter: nf_ct_... |
361 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
362 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
363 364 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
365 |
static int decode_bitstr(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
366 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
367 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
368 |
unsigned int len; |
5e35941d9 [NETFILTER]: Add ... |
369 370 371 372 373 374 375 376 377 378 |
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 */ |
ec8a8f3c3 netfilter: nf_ct_... |
379 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
380 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
381 382 383 384 |
len = (*bs->cur++) << 8; len += (*bs->cur++) + f->lb; break; case SEMI: |
ec8a8f3c3 netfilter: nf_ct_... |
385 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
386 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
387 388 389 390 391 392 393 394 395 |
len = get_len(bs); break; default: len = 0; break; } bs->cur += len >> 3; bs->bit = len & 7; |
ec8a8f3c3 netfilter: nf_ct_... |
396 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
397 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
398 399 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
400 |
static int decode_numstr(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
401 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
402 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
403 |
unsigned int len; |
5e35941d9 [NETFILTER]: Add ... |
404 405 406 407 408 |
PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); /* 2 <= Range <= 255 */ |
ec8a8f3c3 netfilter: nf_ct_... |
409 410 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
411 412 413 414 |
len = get_bits(bs, f->sz) + f->lb; BYTE_ALIGN(bs); INC_BITS(bs, (len << 2)); |
ec8a8f3c3 netfilter: nf_ct_... |
415 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
416 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
417 418 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
419 |
static int decode_octstr(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
420 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
421 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
422 |
unsigned int len; |
5e35941d9 [NETFILTER]: Add ... |
423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
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 [NETFILTER]: nf_c... |
437 |
*((unsigned int *)(base + f->offset)) = |
5e35941d9 [NETFILTER]: Add ... |
438 439 440 441 442 443 444 |
bs->cur - bs->buf; } } len = f->lb; break; case BYTE: /* Range == 256 */ BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
445 |
if (nf_h323_error_boundary(bs, 1, 0)) |
bc7d811ac netfilter: nf_ct_... |
446 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
447 448 449 450 |
len = (*bs->cur++) + f->lb; break; case SEMI: BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
451 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
452 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
453 454 455 |
len = get_len(bs) + f->lb; break; default: /* 2 <= Range <= 255 */ |
ec8a8f3c3 netfilter: nf_ct_... |
456 457 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
458 459 460 461 462 463 464 465 466 |
len = get_bits(bs, f->sz) + f->lb; BYTE_ALIGN(bs); break; } bs->cur += len; PRINT(" "); |
ec8a8f3c3 netfilter: nf_ct_... |
467 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
468 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
469 470 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
471 |
static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
472 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
473 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
474 |
unsigned int len; |
5e35941d9 [NETFILTER]: Add ... |
475 476 477 478 479 480 481 |
PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); switch (f->sz) { case BYTE: /* Range == 256 */ BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
482 |
if (nf_h323_error_boundary(bs, 1, 0)) |
bc7d811ac netfilter: nf_ct_... |
483 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
484 485 486 |
len = (*bs->cur++) + f->lb; break; default: /* 2 <= Range <= 255 */ |
ec8a8f3c3 netfilter: nf_ct_... |
487 488 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
489 490 491 492 493 494 |
len = get_bits(bs, f->sz) + f->lb; BYTE_ALIGN(bs); break; } bs->cur += len << 1; |
ec8a8f3c3 netfilter: nf_ct_... |
495 |
if (nf_h323_error_boundary(bs, 0, 0)) |
bc7d811ac netfilter: nf_ct_... |
496 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
497 498 |
return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
499 |
static int decode_seq(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
500 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
501 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
502 |
unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len; |
5e35941d9 [NETFILTER]: Add ... |
503 |
int err; |
905e3e8ec [NETFILTER]: nf_c... |
504 |
const struct field_t *son; |
5e35941d9 [NETFILTER]: Add ... |
505 506 507 508 509 510 511 512 513 |
unsigned char *beg = NULL; PRINT("%*.s%s ", level * TAB_SIZE, " ", f->name); /* Decode? */ base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; /* Extensible? */ |
ec8a8f3c3 netfilter: nf_ct_... |
514 515 |
if (nf_h323_error_boundary(bs, 0, 1)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
516 517 518 |
ext = (f->attr & EXT) ? get_bit(bs) : 0; /* Get fields bitmap */ |
ec8a8f3c3 netfilter: nf_ct_... |
519 520 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
521 522 |
bmp = get_bitmap(bs, f->sz); if (base) |
1f807d6eb [NETFILTER]: nf_c... |
523 |
*(unsigned int *)base = bmp; |
5e35941d9 [NETFILTER]: Add ... |
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
/* 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 */ |
ec8a8f3c3 netfilter: nf_ct_... |
541 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
542 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
543 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
544 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
545 |
return H323_ERROR_BOUND; |
25845b515 [NETFILTER]: nf_c... |
546 |
if (!base || !(son->attr & DECODE)) { |
5e35941d9 [NETFILTER]: Add ... |
547 548 549 550 551 552 553 554 555 556 |
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 [NETFILTER]: H.32... |
557 558 |
level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
559 560 561 562 563 |
return err; bs->cur = beg + len; bs->bit = 0; } else if ((err = (Decoders[son->type]) (bs, son, base, |
7185989db [NETFILTER]: H.32... |
564 565 |
level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
566 567 568 569 570 571 572 573 |
return err; } /* No extension? */ if (!ext) return H323_ERROR_NONE; /* Get the extension bitmap */ |
ec8a8f3c3 netfilter: nf_ct_... |
574 575 |
if (nf_h323_error_boundary(bs, 0, 7)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
576 |
bmp2_len = get_bits(bs, 7) + 1; |
ec8a8f3c3 netfilter: nf_ct_... |
577 |
if (nf_h323_error_boundary(bs, 0, bmp2_len)) |
bc7d811ac netfilter: nf_ct_... |
578 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
579 580 581 |
bmp2 = get_bitmap(bs, bmp2_len); bmp |= bmp2 >> f->sz; if (base) |
1f807d6eb [NETFILTER]: nf_c... |
582 |
*(unsigned int *)base = bmp; |
5e35941d9 [NETFILTER]: Add ... |
583 584 585 586 |
BYTE_ALIGN(bs); /* Decode the extension components */ for (opt = 0; opt < bmp2_len; opt++, i++, son++) { |
5e35941d9 [NETFILTER]: Add ... |
587 588 |
/* Check Range */ if (i >= f->ub) { /* Newer Version? */ |
ec8a8f3c3 netfilter: nf_ct_... |
589 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
590 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
591 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
592 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
593 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
594 595 596 |
bs->cur += len; continue; } |
558585aad [NETFILTER]: nf_c... |
597 598 599 600 601 602 603 604 605 |
if (son->attr & STOP) { PRINT("%*.s%s ", (level + 1) * TAB_SIZE, " ", son->name); return H323_ERROR_STOP; } if (!((0x80000000 >> opt) & bmp2)) /* Not present */ continue; |
ec8a8f3c3 netfilter: nf_ct_... |
606 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
607 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
608 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
609 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
610 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
611 612 613 614 615 616 617 618 619 620 |
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 [NETFILTER]: H.32... |
621 622 |
level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
623 624 625 626 627 628 629 |
return err; bs->cur = beg + len; bs->bit = 0; } return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
630 |
static int decode_seqof(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
631 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
632 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
633 |
unsigned int count, effective_count = 0, i, len = 0; |
5e35941d9 [NETFILTER]: Add ... |
634 |
int err; |
905e3e8ec [NETFILTER]: nf_c... |
635 |
const struct field_t *son; |
5e35941d9 [NETFILTER]: Add ... |
636 637 638 639 640 641 642 643 644 645 646 647 |
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); |
ec8a8f3c3 netfilter: nf_ct_... |
648 |
if (nf_h323_error_boundary(bs, 1, 0)) |
bc7d811ac netfilter: nf_ct_... |
649 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
650 651 652 653 |
count = *bs->cur++; break; case WORD: BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
654 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
655 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
656 657 |
count = *bs->cur++; count <<= 8; |
b4232a227 netfilter: h323: ... |
658 |
count += *bs->cur++; |
5e35941d9 [NETFILTER]: Add ... |
659 660 661 |
break; case SEMI: BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
662 |
if (nf_h323_error_boundary(bs, 2, 0)) |
bc7d811ac netfilter: nf_ct_... |
663 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
664 665 666 |
count = get_len(bs); break; default: |
ec8a8f3c3 netfilter: nf_ct_... |
667 668 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
669 670 671 672 673 674 675 676 |
count = get_bits(bs, f->sz); break; } count += f->lb; /* Write Count */ if (base) { effective_count = count > f->ub ? f->ub : count; |
1f807d6eb [NETFILTER]: nf_c... |
677 678 |
*(unsigned int *)base = effective_count; base += sizeof(unsigned int); |
5e35941d9 [NETFILTER]: Add ... |
679 680 681 682 683 684 685 686 687 |
} /* Decode nested field */ son = f->fields; if (base) base -= son->offset; for (i = 0; i < count; i++) { if (son->attr & OPEN) { BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
688 689 |
if (nf_h323_error_boundary(bs, 2, 0)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
690 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
691 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
692 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
693 694 695 696 697 698 699 700 701 702 703 704 705 |
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 [NETFILTER]: H.32... |
706 707 |
level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
708 709 710 711 712 |
return err; bs->cur = beg + len; bs->bit = 0; } else |
7185989db [NETFILTER]: H.32... |
713 714 715 716 717 718 719 |
if ((err = (Decoders[son->type]) (bs, son, i < effective_count ? base : NULL, level + 1)) < H323_ERROR_NONE) return err; |
5e35941d9 [NETFILTER]: Add ... |
720 721 722 723 724 725 726 |
if (base) base += son->offset; } return H323_ERROR_NONE; } |
67704c2a0 netfilter: nf_con... |
727 |
static int decode_choice(struct bitstr *bs, const struct field_t *f, |
905e3e8ec [NETFILTER]: nf_c... |
728 |
char *base, int level) |
5e35941d9 [NETFILTER]: Add ... |
729 |
{ |
1f807d6eb [NETFILTER]: nf_c... |
730 |
unsigned int type, ext, len = 0; |
5e35941d9 [NETFILTER]: Add ... |
731 |
int err; |
905e3e8ec [NETFILTER]: nf_c... |
732 |
const struct field_t *son; |
5e35941d9 [NETFILTER]: Add ... |
733 734 735 736 737 738 739 740 741 |
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 */ |
ec8a8f3c3 netfilter: nf_ct_... |
742 743 |
if (nf_h323_error_boundary(bs, 0, 1)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
744 745 |
if ((f->attr & EXT) && get_bit(bs)) { ext = 1; |
ec8a8f3c3 netfilter: nf_ct_... |
746 747 |
if (nf_h323_error_boundary(bs, 0, 7)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
748 749 750 |
type = get_bits(bs, 7) + f->lb; } else { ext = 0; |
ec8a8f3c3 netfilter: nf_ct_... |
751 752 |
if (nf_h323_error_boundary(bs, 0, f->sz)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
753 |
type = get_bits(bs, f->sz); |
25845b515 [NETFILTER]: nf_c... |
754 755 |
if (type >= f->lb) return H323_ERROR_RANGE; |
5e35941d9 [NETFILTER]: Add ... |
756 |
} |
4228e2a98 [NETFILTER]: H.32... |
757 758 |
/* Write Type */ if (base) |
1f807d6eb [NETFILTER]: nf_c... |
759 |
*(unsigned int *)base = type; |
4228e2a98 [NETFILTER]: H.32... |
760 |
|
5e35941d9 [NETFILTER]: Add ... |
761 762 763 |
/* Check Range */ if (type >= f->ub) { /* Newer version? */ BYTE_ALIGN(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
764 765 |
if (nf_h323_error_boundary(bs, 2, 0)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
766 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
767 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
768 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
769 770 771 |
bs->cur += len; return H323_ERROR_NONE; } |
5e35941d9 [NETFILTER]: Add ... |
772 773 774 775 776 777 778 779 780 781 |
/* 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); |
ec8a8f3c3 netfilter: nf_ct_... |
782 783 |
if (nf_h323_error_boundary(bs, len, 0)) return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
784 |
len = get_len(bs); |
ec8a8f3c3 netfilter: nf_ct_... |
785 |
if (nf_h323_error_boundary(bs, len, 0)) |
bc7d811ac netfilter: nf_ct_... |
786 |
return H323_ERROR_BOUND; |
5e35941d9 [NETFILTER]: Add ... |
787 788 789 790 791 792 793 794 |
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 [NETFILTER]: H.32... |
795 796 |
if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
797 798 799 800 |
return err; bs->cur = beg + len; bs->bit = 0; |
7185989db [NETFILTER]: H.32... |
801 802 |
} else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < H323_ERROR_NONE) |
5e35941d9 [NETFILTER]: Add ... |
803 804 805 806 |
return err; return H323_ERROR_NONE; } |
1f807d6eb [NETFILTER]: nf_c... |
807 |
int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras) |
5e35941d9 [NETFILTER]: Add ... |
808 |
{ |
905e3e8ec [NETFILTER]: nf_c... |
809 |
static const struct field_t ras_message = { |
5e35941d9 [NETFILTER]: Add ... |
810 811 812 |
FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT, 0, _RasMessage }; |
67704c2a0 netfilter: nf_con... |
813 |
struct bitstr bs; |
5e35941d9 [NETFILTER]: Add ... |
814 815 816 817 818 819 820 |
bs.buf = bs.beg = bs.cur = buf; bs.end = buf + sz; bs.bit = 0; return decode_choice(&bs, &ras_message, (char *) ras, 0); } |
5e35941d9 [NETFILTER]: Add ... |
821 |
static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg, |
1f807d6eb [NETFILTER]: nf_c... |
822 |
size_t sz, H323_UserInformation *uuie) |
5e35941d9 [NETFILTER]: Add ... |
823 |
{ |
905e3e8ec [NETFILTER]: nf_c... |
824 |
static const struct field_t h323_userinformation = { |
5e35941d9 [NETFILTER]: Add ... |
825 826 827 |
FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT, 0, _H323_UserInformation }; |
67704c2a0 netfilter: nf_con... |
828 |
struct bitstr bs; |
5e35941d9 [NETFILTER]: Add ... |
829 830 831 832 833 834 835 836 |
bs.buf = buf; bs.beg = bs.cur = beg; bs.end = beg + sz; bs.bit = 0; return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0); } |
5e35941d9 [NETFILTER]: Add ... |
837 838 839 840 |
int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz, MultimediaSystemControlMessage * mscm) { |
905e3e8ec [NETFILTER]: nf_c... |
841 |
static const struct field_t multimediasystemcontrolmessage = { |
5e35941d9 [NETFILTER]: Add ... |
842 843 844 |
FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4, DECODE | EXT, 0, _MultimediaSystemControlMessage }; |
67704c2a0 netfilter: nf_con... |
845 |
struct bitstr bs; |
5e35941d9 [NETFILTER]: Add ... |
846 847 848 849 850 851 852 853 |
bs.buf = bs.beg = bs.cur = buf; bs.end = buf + sz; bs.bit = 0; return decode_choice(&bs, &multimediasystemcontrolmessage, (char *) mscm, 0); } |
1f807d6eb [NETFILTER]: nf_c... |
854 |
int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931) |
5e35941d9 [NETFILTER]: Add ... |
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 |
{ 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 */ |
c2b9b4fee netfilter: nf_con... |
882 |
if (sz < 2) |
5e35941d9 [NETFILTER]: Add ... |
883 884 |
return H323_ERROR_BOUND; q931->MessageType = *p++; |
c2b9b4fee netfilter: nf_con... |
885 |
sz--; |
5e35941d9 [NETFILTER]: Add ... |
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
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++; |
e8daf27c2 netfilter: nf_ct_... |
914 |
sz--; |
5e35941d9 [NETFILTER]: Add ... |
915 916 917 918 919 920 921 922 923 924 925 |
if (sz < len) break; p += len; sz -= len; } PRINT("Q.931 UUIE not found "); return H323_ERROR_BOUND; } |