123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * BER and PER decoding library for H.323 conntrack/NAT module.
- *
- * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net>
- *
- * See nf_conntrack_helper_h323_asn1.h for details.
- */
- #ifdef __KERNEL__
- #include <linux/kernel.h>
- #else
- #include <stdio.h>
- #endif
- #include <linux/netfilter/nf_conntrack_h323_asn1.h>
- /* 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;
- const struct field_t *fields;
- } field_t;
- /* Bit Stream */
- struct bitstr {
- unsigned char *buf;
- unsigned char *beg;
- unsigned char *end;
- unsigned char *cur;
- unsigned int bit;
- };
- /* Tool Functions */
- #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;}
- 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);
- /* Decoder Functions */
- 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);
- /* Decoder Functions Vector */
- typedef int (*decoder_t)(struct bitstr *, const struct field_t *, char *, int);
- static const decoder_t Decoders[] = {
- 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
- */
- #include "nf_conntrack_h323_types.c"
- /*
- * Functions
- */
- /* Assume bs is aligned && v < 16384 */
- static unsigned int get_len(struct bitstr *bs)
- {
- unsigned int v;
- v = *bs->cur++;
- if (v & 0x80) {
- v &= 0x3f;
- v <<= 8;
- v += *bs->cur++;
- }
- return v;
- }
- static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits)
- {
- bits += bs->bit;
- bytes += bits / BITS_PER_BYTE;
- if (bits % BITS_PER_BYTE > 0)
- bytes++;
- if (bs->cur + bytes > bs->end)
- return 1;
- return 0;
- }
- static unsigned int get_bit(struct bitstr *bs)
- {
- unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
- INC_BIT(bs);
- return b;
- }
- /* Assume b <= 8 */
- static unsigned int get_bits(struct bitstr *bs, unsigned int b)
- {
- unsigned int v, l;
- 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 */
- static unsigned int get_bitmap(struct bitstr *bs, unsigned int b)
- {
- unsigned int v, l, shift, bytes;
- if (!b)
- return 0;
- l = bs->bit + b;
- if (l < 8) {
- v = (unsigned int)(*bs->cur) << (bs->bit + 24);
- bs->bit = l;
- } else if (l == 8) {
- v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
- bs->bit = 0;
- } else {
- for (bytes = l >> 3, shift = 24, v = 0; bytes;
- bytes--, shift -= 8)
- v |= (unsigned int)(*bs->cur++) << shift;
- if (l < 32) {
- v |= (unsigned int)(*bs->cur) << shift;
- 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
- */
- static unsigned int get_uint(struct bitstr *bs, int b)
- {
- unsigned int v = 0;
- switch (b) {
- case 4:
- v |= *bs->cur++;
- v <<= 8;
- fallthrough;
- case 3:
- v |= *bs->cur++;
- v <<= 8;
- fallthrough;
- case 2:
- v |= *bs->cur++;
- v <<= 8;
- fallthrough;
- case 1:
- v |= *bs->cur++;
- break;
- }
- return v;
- }
- static int decode_nul(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- return H323_ERROR_NONE;
- }
- static int decode_bool(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- INC_BIT(bs);
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_oid(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- int len;
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 1, 0))
- return H323_ERROR_BOUND;
- len = *bs->cur++;
- bs->cur += len;
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_int(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int len;
- 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 */
- if (nf_h323_error_boundary(bs, 0, 2))
- return H323_ERROR_BOUND;
- len = get_bits(bs, 2) + 1;
- BYTE_ALIGN(bs);
- if (base && (f->attr & DECODE)) { /* timeToLive */
- unsigned int v = get_uint(bs, len) + f->lb;
- PRINT(" = %u", v);
- *((unsigned int *)(base + f->offset)) = v;
- }
- bs->cur += len;
- break;
- case UNCO:
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- bs->cur += len;
- break;
- default: /* 2 <= Range <= 255 */
- INC_BITS(bs, f->sz);
- break;
- }
- PRINT("\n");
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_enum(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- if ((f->attr & EXT) && get_bit(bs)) {
- INC_BITS(bs, 7);
- } else {
- INC_BITS(bs, f->sz);
- }
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_bitstr(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int len;
- PRINT("%*.s%s\n", 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 */
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = (*bs->cur++) << 8;
- len += (*bs->cur++) + f->lb;
- break;
- case SEMI:
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- break;
- default:
- len = 0;
- break;
- }
- bs->cur += len >> 3;
- bs->bit = len & 7;
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_numstr(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int len;
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- /* 2 <= Range <= 255 */
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- len = get_bits(bs, f->sz) + f->lb;
- BYTE_ALIGN(bs);
- INC_BITS(bs, (len << 2));
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_octstr(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int len;
- 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]));
- *((unsigned int *)(base + f->offset)) =
- bs->cur - bs->buf;
- }
- }
- len = f->lb;
- break;
- case BYTE: /* Range == 256 */
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 1, 0))
- return H323_ERROR_BOUND;
- len = (*bs->cur++) + f->lb;
- break;
- case SEMI:
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs) + f->lb;
- break;
- default: /* 2 <= Range <= 255 */
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- len = get_bits(bs, f->sz) + f->lb;
- BYTE_ALIGN(bs);
- break;
- }
- bs->cur += len;
- PRINT("\n");
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_bmpstr(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int len;
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- switch (f->sz) {
- case BYTE: /* Range == 256 */
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 1, 0))
- return H323_ERROR_BOUND;
- len = (*bs->cur++) + f->lb;
- break;
- default: /* 2 <= Range <= 255 */
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- len = get_bits(bs, f->sz) + f->lb;
- BYTE_ALIGN(bs);
- break;
- }
- bs->cur += len << 1;
- if (nf_h323_error_boundary(bs, 0, 0))
- return H323_ERROR_BOUND;
- return H323_ERROR_NONE;
- }
- static int decode_seq(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
- int err;
- const struct field_t *son;
- unsigned char *beg = NULL;
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- /* Decode? */
- base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
- /* Extensible? */
- if (nf_h323_error_boundary(bs, 0, 1))
- return H323_ERROR_BOUND;
- ext = (f->attr & EXT) ? get_bit(bs) : 0;
- /* Get fields bitmap */
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- bmp = get_bitmap(bs, f->sz);
- if (base)
- *(unsigned int *)base = bmp;
- /* Decode the root components */
- for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
- if (son->attr & STOP) {
- PRINT("%*.s%s\n", (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 */
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- if (!base || !(son->attr & DECODE)) {
- PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
- " ", son->name);
- bs->cur += len;
- continue;
- }
- beg = bs->cur;
- /* Decode */
- if ((err = (Decoders[son->type]) (bs, son, base,
- level + 1)) <
- H323_ERROR_NONE)
- return err;
- bs->cur = beg + len;
- bs->bit = 0;
- } else if ((err = (Decoders[son->type]) (bs, son, base,
- level + 1)) <
- H323_ERROR_NONE)
- return err;
- }
- /* No extension? */
- if (!ext)
- return H323_ERROR_NONE;
- /* Get the extension bitmap */
- if (nf_h323_error_boundary(bs, 0, 7))
- return H323_ERROR_BOUND;
- bmp2_len = get_bits(bs, 7) + 1;
- if (nf_h323_error_boundary(bs, 0, bmp2_len))
- return H323_ERROR_BOUND;
- bmp2 = get_bitmap(bs, bmp2_len);
- bmp |= bmp2 >> f->sz;
- if (base)
- *(unsigned int *)base = bmp;
- BYTE_ALIGN(bs);
- /* Decode the extension components */
- for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
- /* Check Range */
- if (i >= f->ub) { /* Newer Version? */
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- bs->cur += len;
- continue;
- }
- if (son->attr & STOP) {
- PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
- son->name);
- return H323_ERROR_STOP;
- }
- if (!((0x80000000 >> opt) & bmp2)) /* Not present */
- continue;
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- if (!base || !(son->attr & DECODE)) {
- PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
- son->name);
- bs->cur += len;
- continue;
- }
- beg = bs->cur;
- if ((err = (Decoders[son->type]) (bs, son, base,
- level + 1)) <
- H323_ERROR_NONE)
- return err;
- bs->cur = beg + len;
- bs->bit = 0;
- }
- return H323_ERROR_NONE;
- }
- static int decode_seqof(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int count, effective_count = 0, i, len = 0;
- int err;
- const struct field_t *son;
- unsigned char *beg = NULL;
- PRINT("%*.s%s\n", 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);
- if (nf_h323_error_boundary(bs, 1, 0))
- return H323_ERROR_BOUND;
- count = *bs->cur++;
- break;
- case WORD:
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- count = *bs->cur++;
- count <<= 8;
- count += *bs->cur++;
- break;
- case SEMI:
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- count = get_len(bs);
- break;
- default:
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- count = get_bits(bs, f->sz);
- break;
- }
- count += f->lb;
- /* Write Count */
- if (base) {
- effective_count = count > f->ub ? f->ub : count;
- *(unsigned int *)base = effective_count;
- base += sizeof(unsigned int);
- }
- /* Decode nested field */
- son = f->fields;
- if (base)
- base -= son->offset;
- for (i = 0; i < count; i++) {
- if (son->attr & OPEN) {
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- if (!base || !(son->attr & DECODE)) {
- PRINT("%*.s%s\n", (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,
- level + 1)) <
- H323_ERROR_NONE)
- return err;
- bs->cur = beg + len;
- bs->bit = 0;
- } else
- if ((err = (Decoders[son->type]) (bs, son,
- i <
- effective_count ?
- base : NULL,
- level + 1)) <
- H323_ERROR_NONE)
- return err;
- if (base)
- base += son->offset;
- }
- return H323_ERROR_NONE;
- }
- static int decode_choice(struct bitstr *bs, const struct field_t *f,
- char *base, int level)
- {
- unsigned int type, ext, len = 0;
- int err;
- const struct field_t *son;
- unsigned char *beg = NULL;
- PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
- /* Decode? */
- base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
- /* Decode the choice index number */
- if (nf_h323_error_boundary(bs, 0, 1))
- return H323_ERROR_BOUND;
- if ((f->attr & EXT) && get_bit(bs)) {
- ext = 1;
- if (nf_h323_error_boundary(bs, 0, 7))
- return H323_ERROR_BOUND;
- type = get_bits(bs, 7) + f->lb;
- } else {
- ext = 0;
- if (nf_h323_error_boundary(bs, 0, f->sz))
- return H323_ERROR_BOUND;
- type = get_bits(bs, f->sz);
- if (type >= f->lb)
- return H323_ERROR_RANGE;
- }
- /* Write Type */
- if (base)
- *(unsigned int *)base = type;
- /* Check Range */
- if (type >= f->ub) { /* Newer version? */
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, 2, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- bs->cur += len;
- return H323_ERROR_NONE;
- }
- /* Transfer to son level */
- son = &f->fields[type];
- if (son->attr & STOP) {
- PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name);
- return H323_ERROR_STOP;
- }
- if (ext || (son->attr & OPEN)) {
- BYTE_ALIGN(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- len = get_len(bs);
- if (nf_h323_error_boundary(bs, len, 0))
- return H323_ERROR_BOUND;
- if (!base || !(son->attr & DECODE)) {
- PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
- son->name);
- bs->cur += len;
- return H323_ERROR_NONE;
- }
- beg = bs->cur;
- if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
- H323_ERROR_NONE)
- return err;
- bs->cur = beg + len;
- bs->bit = 0;
- } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
- H323_ERROR_NONE)
- return err;
- return H323_ERROR_NONE;
- }
- int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
- {
- static const struct field_t ras_message = {
- FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
- 0, _RasMessage
- };
- struct bitstr 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,
- size_t sz, H323_UserInformation *uuie)
- {
- static const struct field_t h323_userinformation = {
- FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
- 0, _H323_UserInformation
- };
- struct bitstr 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)
- {
- static const struct field_t multimediasystemcontrolmessage = {
- FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
- DECODE | EXT, 0, _MultimediaSystemControlMessage
- };
- struct bitstr bs;
- bs.buf = bs.beg = bs.cur = buf;
- bs.end = buf + sz;
- bs.bit = 0;
- return decode_choice(&bs, &multimediasystemcontrolmessage,
- (char *) mscm, 0);
- }
- int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
- {
- unsigned char *p = buf;
- int len;
- if (!p || sz < 1)
- return H323_ERROR_BOUND;
- /* Protocol Discriminator */
- if (*p != 0x08) {
- PRINT("Unknown Protocol Discriminator\n");
- 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 < 2)
- return H323_ERROR_BOUND;
- q931->MessageType = *p++;
- sz--;
- PRINT("MessageType = %02X\n", 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++;
- sz--;
- if (sz < len)
- break;
- p += len;
- sz -= len;
- }
- PRINT("Q.931 UUIE not found\n");
- return H323_ERROR_BOUND;
- }
|