251 lines
6.8 KiB
C
251 lines
6.8 KiB
C
/* $Id$
|
|
*
|
|
*/
|
|
|
|
#include <linux/mISDNif.h>
|
|
#include "helper.h"
|
|
|
|
#ifndef __ASN1_H__
|
|
#define __ASN1_H__
|
|
|
|
typedef enum {
|
|
invoke = 1,
|
|
returnResult = 2,
|
|
returnError = 3,
|
|
reject = 4,
|
|
} asn1Component;
|
|
|
|
typedef enum {
|
|
GeneralP = 0,
|
|
InvokeP = 1,
|
|
ReturnResultP= 2,
|
|
ReturnErrorP = 3,
|
|
} asn1Problem;
|
|
|
|
struct PublicPartyNumber {
|
|
int publicTypeOfNumber;
|
|
char numberDigits[30];
|
|
};
|
|
|
|
struct PartyNumber {
|
|
int type;
|
|
union {
|
|
char unknown[30];
|
|
struct PublicPartyNumber publicPartyNumber;
|
|
} p;
|
|
};
|
|
|
|
struct Address {
|
|
struct PartyNumber partyNumber;
|
|
char partySubaddress[30];
|
|
};
|
|
|
|
struct ServedUserNr {
|
|
int all;
|
|
struct PartyNumber partyNumber;
|
|
};
|
|
|
|
struct ActDivNotification {
|
|
int procedure;
|
|
int basicService;
|
|
struct ServedUserNr servedUserNr;
|
|
struct Address address;
|
|
};
|
|
|
|
struct DeactDivNotification {
|
|
int procedure;
|
|
int basicService;
|
|
struct ServedUserNr servedUserNr;
|
|
};
|
|
|
|
struct ServedUserNumberList {
|
|
struct PartyNumber partyNumber[10];
|
|
};
|
|
|
|
struct IntResult {
|
|
struct ServedUserNr servedUserNr;
|
|
int procedure;
|
|
int basicService;
|
|
struct Address address;
|
|
};
|
|
|
|
struct IntResultList {
|
|
struct IntResult intResult[10];
|
|
};
|
|
|
|
struct asn1Invoke {
|
|
__u16 invokeId;
|
|
__u16 operationValue;
|
|
union {
|
|
struct ActDivNotification actNot;
|
|
struct DeactDivNotification deactNot;
|
|
} o;
|
|
};
|
|
|
|
struct asn1ReturnResult {
|
|
__u16 invokeId;
|
|
union {
|
|
struct ServedUserNumberList list;
|
|
struct IntResultList resultList;
|
|
} o;
|
|
};
|
|
|
|
struct asn1ReturnError {
|
|
__u16 invokeId;
|
|
__u16 errorValue;
|
|
};
|
|
|
|
struct asn1Reject {
|
|
int invokeId;
|
|
asn1Problem problem;
|
|
__u16 problemValue;
|
|
};
|
|
|
|
struct asn1_parm {
|
|
asn1Component comp;
|
|
union {
|
|
struct asn1Invoke inv;
|
|
struct asn1ReturnResult retResult;
|
|
struct asn1ReturnError retError;
|
|
struct asn1Reject reject;
|
|
} u;
|
|
};
|
|
|
|
|
|
#undef ASN1_DEBUG
|
|
// #define ASN1_DEBUG
|
|
|
|
#ifdef ASN1_DEBUG
|
|
#define print_asn1msg(dummy, fmt, args...) printk(KERN_DEBUG fmt, ## args)
|
|
#else
|
|
#define print_asn1msg(dummy, fmt, args...)
|
|
#endif
|
|
|
|
int ParseASN1(u_char *p, u_char *end, int level);
|
|
|
|
int ParseTag(u_char *p, u_char *end, int *tag);
|
|
int ParseLen(u_char *p, u_char *end, int *len);
|
|
|
|
#define ASN1_TAG_BOOLEAN (0x01) // is that true?
|
|
#define ASN1_TAG_INTEGER (0x02)
|
|
#define ASN1_TAG_BIT_STRING (0x03)
|
|
#define ASN1_TAG_OCTET_STRING (0x04)
|
|
#define ASN1_TAG_NULL (0x05)
|
|
#define ASN1_TAG_OBJECT_IDENTIFIER (0x06)
|
|
#define ASN1_TAG_ENUM (0x0a)
|
|
#define ASN1_TAG_SEQUENCE (0x30)
|
|
#define ASN1_TAG_SET (0x31)
|
|
#define ASN1_TAG_NUMERIC_STRING (0x12)
|
|
#define ASN1_TAG_PRINTABLE_STRING (0x13)
|
|
#define ASN1_TAG_IA5_STRING (0x16)
|
|
#define ASN1_TAG_UTC_TIME (0x17)
|
|
|
|
#define ASN1_TAG_CONSTRUCTED (0x20)
|
|
#define ASN1_TAG_CONTEXT_SPECIFIC (0x80)
|
|
|
|
#define ASN1_TAG_EXPLICIT (0x100)
|
|
#define ASN1_TAG_OPT (0x200)
|
|
#define ASN1_NOT_TAGGED (0x400)
|
|
|
|
#define CallASN1(ret, p, end, todo) do { \
|
|
ret = todo; \
|
|
if (ret < 0) { \
|
|
int_error(); \
|
|
return -1; \
|
|
} \
|
|
p += ret; \
|
|
} while (0)
|
|
|
|
#define INIT \
|
|
int tag, len; \
|
|
int ret; \
|
|
u_char *beg; \
|
|
\
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", __FUNCTION__); \
|
|
beg = p; \
|
|
CallASN1(ret, p, end, ParseTag(p, end, &tag)); \
|
|
CallASN1(ret, p, end, ParseLen(p, end, &len)); \
|
|
if (len >= 0) { \
|
|
if (p + len > end) \
|
|
return -1; \
|
|
end = p + len; \
|
|
}
|
|
|
|
#define XSEQUENCE_1(todo, act_tag, the_tag, arg1) do { \
|
|
if (p < end) { \
|
|
if (((the_tag) &~ ASN1_TAG_OPT) == ASN1_NOT_TAGGED) { \
|
|
if (((u_char)act_tag == *p) || ((act_tag) == ASN1_NOT_TAGGED)) { \
|
|
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
|
} else { \
|
|
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 1 %s:%d\n", __FUNCTION__, __LINE__); \
|
|
return -1; \
|
|
} \
|
|
} \
|
|
} else { \
|
|
if ((the_tag) & ASN1_TAG_EXPLICIT) { \
|
|
if ((u_char)(((the_tag) & 0xff) | (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED)) == *p) { \
|
|
int xtag, xlen; \
|
|
CallASN1(ret, p, end, ParseTag(p, end, &xtag)); \
|
|
CallASN1(ret, p, end, ParseLen(p, end, &xlen)); \
|
|
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
|
} else { \
|
|
if (!(the_tag) & ASN1_TAG_OPT) { \
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 2 %s:%d\n", __FUNCTION__, __LINE__); \
|
|
return -1; \
|
|
} \
|
|
} \
|
|
} else { \
|
|
if ((u_char)(((the_tag) & 0xff) | (ASN1_TAG_CONTEXT_SPECIFIC | (act_tag & ASN1_TAG_CONSTRUCTED))) == *p) { \
|
|
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
|
} else { \
|
|
if (!(the_tag) & ASN1_TAG_OPT) { \
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 3 %s:%d\n", __FUNCTION__, __LINE__); \
|
|
return -1; \
|
|
} \
|
|
} \
|
|
} \
|
|
} \
|
|
} else { \
|
|
if (!(the_tag) & ASN1_TAG_OPT) { \
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 4 %s:%d\n", __FUNCTION__, __LINE__); \
|
|
return -1; \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
#define XSEQUENCE_OPT_1(todo, act_tag, the_tag, arg1) \
|
|
XSEQUENCE_1(todo, act_tag, (the_tag | ASN1_TAG_OPT), arg1)
|
|
|
|
#define XSEQUENCE(todo, act_tag, the_tag) XSEQUENCE_1(todo, act_tag, the_tag, -1)
|
|
#define XSEQUENCE_OPT(todo, act_tag, the_tag) XSEQUENCE_OPT_1(todo, act_tag, the_tag, -1)
|
|
|
|
#define XCHOICE_1(todo, act_tag, the_tag, arg1) \
|
|
if (act_tag == ASN1_NOT_TAGGED) { \
|
|
return todo(pc, beg, end, arg1); \
|
|
} \
|
|
if (the_tag == ASN1_NOT_TAGGED) { \
|
|
if (act_tag == tag) { \
|
|
return todo(pc, beg, end, arg1); \
|
|
} \
|
|
} else { \
|
|
if ((the_tag | (0x80 | (act_tag & 0x20))) == tag) { \
|
|
return todo(pc, beg, end, arg1); \
|
|
} \
|
|
}
|
|
|
|
#define XCHOICE(todo, act_tag, the_tag) XCHOICE_1(todo, act_tag, the_tag, -1)
|
|
|
|
#define XCHOICE_DEFAULT do {\
|
|
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 5 %s:%d\n", __FUNCTION__, __LINE__); \
|
|
return -1; \
|
|
} while (0)
|
|
|
|
#define CHECK_P do { \
|
|
if (p >= end) \
|
|
return -1; \
|
|
} while (0)
|
|
|
|
|
|
#endif
|