📄 nf_conntrack_h323_asn1.c
字号:
/**************************************************************************** * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 * conntrack/NAT module. * * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> * * 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#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; struct field_t *fields;} field_t;/* Bit Stream */typedef struct { unsigned char *buf; unsigned char *beg; unsigned char *end; unsigned char *cur; unsigned bit;} bitstr_t;/* 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;}#define CHECK_BOUND(bs,n) if(bs->cur+(n)>bs->end)return(H323_ERROR_BOUND)static unsigned get_len(bitstr_t * bs);static unsigned get_bit(bitstr_t * bs);static unsigned get_bits(bitstr_t * bs, unsigned b);static unsigned get_bitmap(bitstr_t * bs, unsigned b);static unsigned get_uint(bitstr_t * bs, int b);/* Decoder Functions */static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);/* Decoder Functions Vector */typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);static 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 */unsigned get_len(bitstr_t * bs){ unsigned v; v = *bs->cur++; if (v & 0x80) { v &= 0x3f; v <<= 8; v += *bs->cur++; } return v;}/****************************************************************************/unsigned get_bit(bitstr_t * bs){ unsigned b = (*bs->cur) & (0x80 >> bs->bit); INC_BIT(bs); return b;}/****************************************************************************//* Assume b <= 8 */unsigned get_bits(bitstr_t * bs, unsigned b){ unsigned 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 */unsigned get_bitmap(bitstr_t * bs, unsigned b){ unsigned v, l, shift, bytes; if (!b) return 0; l = bs->bit + b; if (l < 8) { v = (unsigned) (*bs->cur) << (bs->bit + 24); bs->bit = l; } else if (l == 8) { v = (unsigned) (*bs->cur++) << (bs->bit + 24); bs->bit = 0; } else { for (bytes = l >> 3, shift = 24, v = 0; bytes; bytes--, shift -= 8) v |= (unsigned) (*bs->cur++) << shift; if (l < 32) { v |= (unsigned) (*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 ****************************************************************************/unsigned get_uint(bitstr_t * bs, int b){ unsigned v = 0; 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;}/****************************************************************************/int decode_nul(bitstr_t * bs, field_t * f, char *base, int level){ PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); return H323_ERROR_NONE;}/****************************************************************************/int decode_bool(bitstr_t * bs, field_t * f, char *base, int level){ PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); INC_BIT(bs); CHECK_BOUND(bs, 0); return H323_ERROR_NONE;}/****************************************************************************/int decode_oid(bitstr_t * bs, field_t * f, char *base, int level){ int len; PRINT("%*.s%s\n", 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;}/****************************************************************************/int decode_int(bitstr_t * bs, field_t * f, char *base, int level){ unsigned 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 */ len = get_bits(bs, 2) + 1; BYTE_ALIGN(bs); if (base && (f->attr & DECODE)) { /* timeToLive */ unsigned v = get_uint(bs, len) + f->lb; PRINT(" = %u", v); *((unsigned *) (base + f->offset)) = v; } 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("\n"); CHECK_BOUND(bs, 0); return H323_ERROR_NONE;}/****************************************************************************/int decode_enum(bitstr_t * bs, 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); } CHECK_BOUND(bs, 0); return H323_ERROR_NONE;}/****************************************************************************/int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level){ unsigned 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 */ 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;}/****************************************************************************/int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level){ unsigned len; PRINT("%*.s%s\n", 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;}/****************************************************************************/int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level){ unsigned 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 *) (base + f->offset)) = 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -