From 1bf4eed0ba6cabd982a00b6fc4bee9ca5f4213ee Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 9 Dec 2013 05:45:35 -0500 Subject: [PATCH] search for and extract inap data types --- include/libtcap.h | 1 + src/tcap.c | 127 +++++++++++++++++++++++++++++++++++++++------- tests/basic.c | 5 +- 3 files changed, 115 insertions(+), 18 deletions(-) diff --git a/include/libtcap.h b/include/libtcap.h index ddaf2d0..e7f115a 100644 --- a/include/libtcap.h +++ b/include/libtcap.h @@ -10,6 +10,7 @@ TCMessage_t *tcap_decode(const char *buf, size_t len); void *inap_decode(Invoke_t *invoke, asn_TYPE_descriptor_t **); int tcap_extract(const char *buf, size_t len, const char *spec, void *out); +int inap_extract(const char *buf, size_t len, const char *spec, void *out); #endif diff --git a/src/tcap.c b/src/tcap.c index 0eaf1ec..55d54b4 100644 --- a/src/tcap.c +++ b/src/tcap.c @@ -15,6 +15,8 @@ #include "ConnectArg.h" #include "FurnishChargingInformationArg.h" #include "INTEGER.h" +#include "ComponentPortion.h" +#include "Component.h" @@ -79,32 +81,43 @@ nothing: return NULL; } -int tcap_extract(const char *buf, size_t len, const char *spec, void *out) { - void *element; - asn_TYPE_descriptor_t *type; - const char *c; - const char *token; +static inline int next_token_1(const char **token, int *token_len, const char **c) { + *c = strchr(*token, '.'); + if (!*c) + *token_len = strlen(*token); + else + *token_len = *c - *token; + + if (*token_len <= 0) + return -1; + + return 0; +} + +static inline int next_token_2(const char **token, const char **c) { + if (!*c) + return -1; + + *token = *c + 1; + return 0; +} + +static int asn1_extract(const char *spec, void *out, asn_TYPE_descriptor_t *type, void *element) { + const char *token, *c; int token_len, i, num; asn_TYPE_member_t *member; asn_anonymous_set_ *list; asn_CHOICE_specifics_t *choice_spec; - element = tcap_decode(buf, len); if (!element) goto error; - type = &asn_DEF_TCMessage; token = spec; while (1) { - c = strchr(token, '.'); - if (!c) - token_len = strlen(token); - else - token_len = c - token; - - if (token_len <= 0) + if (next_token_1(&token, &token_len, &c)) goto error; + if (type->elements_count <= 0) goto error; /* ? */ @@ -160,10 +173,8 @@ found_member: element = *((void **) element); found_element: - if (!c) + if (next_token_2(&token, &c)) break; - - token = c + 1; } /* found our target value, check for primitive types */ @@ -181,3 +192,85 @@ out: error: return -1; } + + + +int tcap_extract(const char *buf, size_t len, const char *spec, void *out) { + return asn1_extract(spec, out, &asn_DEF_TCMessage, tcap_decode(buf, len)); +} + + + +int inap_extract(const char *buf, size_t len, const char *spec, void *out) { + TCMessage_t *tcm; + ComponentPortion_t *cp; + Component_t *cmp; + Invoke_t *inv; + const char *token, *c; + int token_len, i; + void *parameter; + asn_TYPE_descriptor_t *type; + + tcm = tcap_decode(buf, len); + if (!tcm) + goto error; + + switch (tcm->present) { + case TCMessage_PR_unidirectional: + cp = &tcm->choice.unidirectional.components; + break; + + case TCMessage_PR_begin: + cp = tcm->choice.begin.components; + break; + + case TCMessage_PR_end: + cp = tcm->choice.end.components; + break; + + case TCMessage_PR_continue: + cp = tcm->choice.Continue.components; + break; + + default: + goto error; + } + + if (!cp) + goto error; + + token = spec; + + /* first token is the type we're looking for */ + + if (next_token_1(&token, &token_len, &c)) + goto error; + + for (i = 0; i < cp->list.count; i++) { + cmp = cp->list.array[i]; + if (cmp->present != Component_PR_invoke) + continue; + inv = &cmp->choice.invoke; + + parameter = inap_decode(inv, &type); + if (!parameter) + continue; + + if (!strncmp(type->name, token, token_len)) + goto found_parameter; + } + + goto error; + +found_parameter: + if (next_token_2(&token, &c)) + goto out; + + return asn1_extract(token, out, type, parameter); + +out: + return 0; + +error: + return -1; +} diff --git a/tests/basic.c b/tests/basic.c index 831d3e7..e3b14a3 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -91,7 +91,10 @@ int main() { } i = tcap_extract(tcap, tcap_len, "end.components.1.invoke.opCode.localValue", &l); - printf("extract: returned %i, value %li\n", i, l); + printf("tcap_extract opcode: returned %i, value %li\n", i, l); + + i = inap_extract(tcap, tcap_len, "ConnectArg", NULL); + printf("inap_extract ConnectArg: returned %i\n", i); return 0; }