summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-h248.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-06-10 00:00:39 -0400
committerMichael Mann <mmann78@netscape.net>2016-06-12 11:21:52 +0000
commit2d095de05328a7209fefa31d5b3c26713f4b5ad2 (patch)
treeb49fb8041db8777aadf2df1bdf0f45929cb178d4 /epan/dissectors/packet-h248.c
parent68ef5dbf2fff83f8ed1c718ec83a1c1145ac5239 (diff)
downloadwireshark-2d095de05328a7209fefa31d5b3c26713f4b5ad2.tar.gz
Move Gateway Control Protocol (Context Tracking) into packet-h248.h
The Gateway Control Protocol (Context Tracking) is used by both H248 and MEGACO, so the functionality was refactored to epan, but should really be kept in the dissector directory to minimize (and eventually completely remove) the epan directory's dependence on it. Change-Id: I387b46aecde97234086bfdb7d8c546854fa301cd Reviewed-on: https://code.wireshark.org/review/15798 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-h248.c')
-rw-r--r--epan/dissectors/packet-h248.c755
1 files changed, 739 insertions, 16 deletions
diff --git a/epan/dissectors/packet-h248.c b/epan/dissectors/packet-h248.c
index 38bdc079b7..f6d3fe1f49 100644
--- a/epan/dissectors/packet-h248.c
+++ b/epan/dissectors/packet-h248.c
@@ -33,10 +33,14 @@
#include "config.h"
-#include <packet.h>
+#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/tap.h>
+#include <epan/asn1.h>
+#include <epan/prefs.h>
#include <epan/exported_pdu.h>
+#include "packet-alcap.h"
+#include "packet-ber.h"
#include "packet-tpkt.h"
#include "packet-mtp3.h"
#include "packet-h248.h"
@@ -398,7 +402,7 @@ static int hf_h248_NotifyCompletion_otherReason = -1;
static int hf_h248_NotifyCompletion_onIteration = -1;
/*--- End of included file: packet-h248-hf.c ---*/
-#line 75 "./asn1/h248/packet-h248-template.c"
+#line 79 "./asn1/h248/packet-h248-template.c"
/* Initialize the subtree pointers */
static gint ett_h248 = -1;
@@ -566,7 +570,7 @@ static gint ett_h248_EventParameterV1 = -1;
static gint ett_h248_SigParameterV1 = -1;
/*--- End of included file: packet-h248-ett.c ---*/
-#line 95 "./asn1/h248/packet-h248-template.c"
+#line 99 "./asn1/h248/packet-h248-template.c"
static expert_field ei_h248_errored_command = EI_INIT;
static expert_field ei_h248_transactionId64 = EI_INIT;
@@ -575,10 +579,731 @@ static expert_field ei_h248_octet_string_expected = EI_INIT;
static dissector_table_t subdissector_table;
-static wmem_tree_t* msgs = NULL;
-static wmem_tree_t* trxs = NULL;
-static wmem_tree_t* ctxs_by_trx = NULL;
-static wmem_tree_t* ctxs = NULL;
+/* Gateway Control Protocol -- Context Tracking */
+
+const value_string gcp_cmd_type[] = {
+ { GCP_CMD_NONE, "NoCommand"},
+ { GCP_CMD_ADD_REQ, "addReq"},
+ { GCP_CMD_MOVE_REQ, "moveReq"},
+ { GCP_CMD_MOD_REQ, "modReq"},
+ { GCP_CMD_SUB_REQ, "subtractReq"},
+ { GCP_CMD_AUDITCAP_REQ, "auditCapRequest"},
+ { GCP_CMD_AUDITVAL_REQ, "auditValueRequest"},
+ { GCP_CMD_NOTIFY_REQ, "notifyReq"},
+ { GCP_CMD_SVCCHG_REQ, "serviceChangeReq"},
+ { GCP_CMD_TOPOLOGY_REQ, "topologyReq"},
+ { GCP_CMD_CTX_ATTR_AUDIT_REQ, "ctxAttrAuditReq"},
+ { GCP_CMD_ADD_REPLY, "addReply"},
+ { GCP_CMD_MOVE_REPLY, "moveReply"},
+ { GCP_CMD_MOD_REPLY, "modReply"},
+ { GCP_CMD_SUB_REPLY, "subtractReply"},
+ { GCP_CMD_AUDITCAP_REPLY, "auditCapReply"},
+ { GCP_CMD_AUDITVAL_REPLY, "auditValReply"},
+ { GCP_CMD_NOTIFY_REPLY, "notifyReply"},
+ { GCP_CMD_SVCCHG_REPLY, "serviceChangeReply"},
+ { GCP_CMD_TOPOLOGY_REPLY, "topologyReply"},
+ { 0, NULL }
+};
+
+const value_string gcp_term_types[] = {
+ { GCP_TERM_TYPE_AAL1, "aal1" },
+ { GCP_TERM_TYPE_AAL2, "aal2" },
+ { GCP_TERM_TYPE_AAL1_STRUCT, "aal1struct" },
+ { GCP_TERM_TYPE_IP_RTP, "ipRtp" },
+ { GCP_TERM_TYPE_TDM, "tdm" },
+ { 0, NULL }
+};
+
+static wmem_tree_t* gcp_msgs = NULL;
+static wmem_tree_t* gcp_trxs = NULL;
+static wmem_tree_t* gcp_ctxs_by_trx = NULL;
+static wmem_tree_t* gcp_ctxs = NULL;
+
+gcp_msg_t* gcp_msg(packet_info* pinfo, int o, gboolean keep_persistent_data) {
+ gcp_msg_t* m;
+ guint32 framenum = (guint32)pinfo->num;
+ guint32 offset = (guint32)o;
+ address* src = &(pinfo->src);
+ address* dst = &(pinfo->dst);
+ address* lo_addr;
+ address* hi_addr;
+
+ if (keep_persistent_data) {
+ wmem_tree_key_t key[3];
+
+ key[0].length = 1;
+ key[0].key = &(framenum);
+ key[1].length = 1;
+ key[1].key = &offset;
+ key[2].length = 0;
+ key[2].key =NULL;
+
+ if (( m = (gcp_msg_t *)wmem_tree_lookup32_array(gcp_msgs,key) )) {
+ m->committed = TRUE;
+ return m;
+ } else {
+ m = wmem_new(wmem_file_scope(), gcp_msg_t);
+ m->framenum = framenum;
+ m->time = pinfo->abs_ts;
+ m->trxs = NULL;
+ m->committed = FALSE;
+
+ wmem_tree_insert32_array(gcp_msgs,key,m);
+ }
+ } else {
+ m = wmem_new0(wmem_packet_scope(), gcp_msg_t);
+ m->framenum = framenum;
+ m->trxs = NULL;
+ m->committed = FALSE;
+ }
+
+ if (cmp_address(src, dst) < 0) {
+ lo_addr = src;
+ hi_addr = dst;
+ } else {
+ lo_addr = dst;
+ hi_addr = src;
+ }
+
+ switch(lo_addr->type) {
+ case AT_NONE:
+ m->lo_addr = 0;
+ m->hi_addr = 0;
+ break;
+ case AT_IPv4:
+ memcpy((guint8*)&(m->hi_addr),hi_addr->data,4);
+ memcpy((guint8*)&(m->lo_addr),lo_addr->data,4);
+ break;
+ case AT_SS7PC:
+ m->hi_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)hi_addr->data);
+ m->lo_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)lo_addr->data);
+ break;
+ default:
+ /* XXX: heuristic and error prone */
+ m->hi_addr = g_str_hash(address_to_str(wmem_packet_scope(), hi_addr));
+ m->lo_addr = g_str_hash(address_to_str(wmem_packet_scope(), lo_addr));
+ break;
+ }
+
+ return m;
+}
+
+gcp_trx_t* gcp_trx(gcp_msg_t* m ,guint32 t_id , gcp_trx_type_t type, gboolean keep_persistent_data) {
+ gcp_trx_t* t = NULL;
+ gcp_trx_msg_t* trxmsg;
+
+ if ( !m ) return NULL;
+
+ if (keep_persistent_data) {
+ if (m->committed) {
+
+ for ( trxmsg = m->trxs; trxmsg; trxmsg = trxmsg->next) {
+ if (trxmsg->trx && trxmsg->trx->id == t_id) {
+ return trxmsg->trx;
+ }
+ }
+ DISSECTOR_ASSERT_NOT_REACHED();
+ } else {
+ wmem_tree_key_t key[4];
+
+ key[0].length = 1;
+ key[0].key = &(m->hi_addr);
+ key[1].length = 1;
+ key[1].key = &(m->lo_addr);
+ key[2].length = 1;
+ key[2].key = &(t_id);
+ key[3].length = 0;
+ key[3].key = NULL;
+
+ trxmsg = wmem_new(wmem_file_scope(), gcp_trx_msg_t);
+ t = (gcp_trx_t *)wmem_tree_lookup32_array(gcp_trxs,key);
+
+ if (!t) {
+ t = wmem_new(wmem_file_scope(), gcp_trx_t);
+ t->initial = m;
+ t->id = t_id;
+ t->type = type;
+ t->pendings = 0;
+ t->error = 0;
+ t->cmds = NULL;
+
+ wmem_tree_insert32_array(gcp_trxs,key,t);
+ }
+
+ /* XXX: request, reply and ack + point to frames where they are */
+ switch ( type ) {
+ case GCP_TRX_PENDING:
+ t->pendings++;
+ break;
+ default:
+ break;
+ }
+
+ }
+ } else {
+ t = wmem_new(wmem_packet_scope(), gcp_trx_t);
+ trxmsg = wmem_new(wmem_packet_scope(), gcp_trx_msg_t);
+ t->initial = NULL;
+ t->id = t_id;
+ t->type = type;
+ t->pendings = 0;
+ t->error = 0;
+ t->cmds = NULL;
+ }
+
+ DISSECTOR_ASSERT(trxmsg);
+
+ trxmsg->trx = t;
+ trxmsg->next = NULL;
+ trxmsg->last = trxmsg;
+
+ if (m->trxs) {
+ m->trxs->last = m->trxs->last->next = trxmsg;
+ } else {
+ m->trxs = trxmsg;
+ }
+
+ return t;
+}
+
+
+gcp_ctx_t* gcp_ctx(gcp_msg_t* m, gcp_trx_t* t, guint32 c_id, gboolean persistent) {
+ gcp_ctx_t* context = NULL;
+ gcp_ctx_t** context_p = NULL;
+
+ if ( !m || !t ) return NULL;
+
+ if (persistent) {
+
+ wmem_tree_key_t ctx_key[4];
+ wmem_tree_key_t trx_key[4];
+
+ ctx_key[0].length = 1;
+ ctx_key[0].key = &(m->hi_addr);
+ ctx_key[1].length = 1;
+ ctx_key[1].key = &(m->lo_addr);
+ ctx_key[2].length = 1;
+ ctx_key[2].key = &(c_id);
+ ctx_key[3].length = 0;
+ ctx_key[3].key = NULL;
+
+ trx_key[0].length = 1;
+ trx_key[0].key = &(m->hi_addr);
+ trx_key[1].length = 1;
+ trx_key[1].key = &(m->lo_addr);
+ trx_key[2].length = 1;
+ trx_key[2].key = &(t->id);
+ trx_key[3].length = 0;
+ trx_key[3].key = NULL;
+
+ if (m->committed) {
+ if (( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key) )) {
+ return context;
+ } if ((context_p = (gcp_ctx_t **)wmem_tree_lookup32_array(gcp_ctxs,ctx_key))) {
+ context = *context_p;
+
+ do {
+ if (context->initial->framenum <= m->framenum) {
+ return context;
+ }
+ } while(( context = context->prev ));
+
+ DISSECTOR_ASSERT(! "a context should exist");
+ }
+ } else {
+ if (c_id == CHOOSE_CONTEXT) {
+ if (! ( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key))) {
+ context = wmem_new(wmem_file_scope(), gcp_ctx_t);
+ context->initial = m;
+ context->cmds = NULL;
+ context->id = c_id;
+ context->terms.last = &(context->terms);
+ context->terms.next = NULL;
+ context->terms.term = NULL;
+
+ wmem_tree_insert32_array(gcp_ctxs_by_trx,trx_key,context);
+ }
+ } else {
+ if (( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key) )) {
+ if (( context_p = (gcp_ctx_t **)wmem_tree_lookup32_array(gcp_ctxs,ctx_key) )) {
+ if (context != *context_p) {
+ if(context->id != CHOOSE_CONTEXT) {
+ context = wmem_new(wmem_file_scope(), gcp_ctx_t);
+ }
+ context->initial = m;
+ context->id = c_id;
+ context->cmds = NULL;
+ context->terms.last = &(context->terms);
+ context->terms.next = NULL;
+ context->terms.term = NULL;
+
+ context->prev = *context_p;
+ *context_p = context;
+ }
+ } else {
+ context_p = wmem_new(wmem_file_scope(), gcp_ctx_t*);
+ *context_p = context;
+ context->initial = m;
+ context->id = c_id;
+ wmem_tree_insert32_array(gcp_ctxs,ctx_key,context_p);
+ }
+ } else if (! ( context_p = (gcp_ctx_t**)wmem_tree_lookup32_array(gcp_ctxs,ctx_key) )) {
+ context = wmem_new(wmem_file_scope(), gcp_ctx_t);
+ context->initial = m;
+ context->id = c_id;
+ context->cmds = NULL;
+ context->terms.last = &(context->terms);
+ context->terms.next = NULL;
+ context->terms.term = NULL;
+
+ context_p = wmem_new(wmem_file_scope(), gcp_ctx_t*);
+ *context_p = context;
+ wmem_tree_insert32_array(gcp_ctxs,ctx_key,context_p);
+ } else {
+ context = *context_p;
+ }
+ }
+ }
+ } else {
+ context = wmem_new(wmem_packet_scope(), gcp_ctx_t);
+ context->initial = m;
+ context->cmds = NULL;
+ context->id = c_id;
+ context->terms.last = &(context->terms);
+ context->terms.next = NULL;
+ context->terms.term = NULL;
+ }
+
+ return context;
+}
+
+gcp_cmd_t* gcp_cmd(gcp_msg_t* m, gcp_trx_t* t, gcp_ctx_t* c, gcp_cmd_type_t type, guint offset, gboolean persistent) {
+ gcp_cmd_t* cmd;
+ gcp_cmd_msg_t* cmdtrx;
+ gcp_cmd_msg_t* cmdctx;
+
+ if ( !m || !t || !c ) return NULL;
+
+ if (persistent) {
+ if (m->committed) {
+ DISSECTOR_ASSERT(t->cmds != NULL);
+
+ for (cmdctx = t->cmds; cmdctx; cmdctx = cmdctx->next) {
+ cmd = cmdctx->cmd;
+ if (cmd->msg == m && cmd->offset == offset) {
+ return cmd;
+ }
+ }
+
+ DISSECTOR_ASSERT(!"called for a command that does not exist!");
+
+ return NULL;
+ } else {
+ cmd = wmem_new(wmem_file_scope(), gcp_cmd_t);
+ cmdtrx = wmem_new(wmem_file_scope(), gcp_cmd_msg_t);
+ cmdctx = wmem_new(wmem_file_scope(), gcp_cmd_msg_t);
+ }
+ } else {
+ cmd = wmem_new(wmem_packet_scope(), gcp_cmd_t);
+ cmdtrx = wmem_new(wmem_packet_scope(), gcp_cmd_msg_t);
+ cmdctx = wmem_new(wmem_packet_scope(), gcp_cmd_msg_t);
+ }
+
+ cmd->type = type;
+ cmd->offset = offset;
+ cmd->terms.term = NULL;
+ cmd->terms.next = NULL;
+ cmd->terms.last = &(cmd->terms);
+ cmd->str = NULL;
+ cmd->msg = m;
+ if ((type != GCP_CMD_NONE) && (!persistent)){
+ cmd->str = val_to_str_const(type, gcp_cmd_type, "Unknown");
+ }
+ cmd->trx = t;
+ cmd->ctx = c;
+ cmd->error = 0;
+
+ cmdctx->cmd = cmdtrx->cmd = cmd;
+ cmdctx->next = cmdtrx->next = NULL;
+ cmdctx->last = cmdtrx->last = NULL;
+
+ if (t->cmds) {
+ t->cmds->last->next = cmdtrx;
+ t->cmds->last = cmdtrx;
+ } else {
+ t->cmds = cmdtrx;
+ t->cmds->last = cmdtrx;
+ }
+
+ if (c->cmds) {
+ c->cmds->last->next = cmdctx;
+ c->cmds->last = cmdctx;
+ } else {
+ c->cmds = cmdctx;
+ c->cmds->last = cmdctx;
+ }
+
+ return cmd;
+}
+
+gcp_term_t* gcp_cmd_add_term(gcp_msg_t* m, gcp_trx_t* tr, gcp_cmd_t* c, gcp_term_t* t, gcp_wildcard_t wildcard, gboolean persistent) {
+ gcp_terms_t* ct;
+ gcp_terms_t* ct2;
+
+ static gcp_term_t all_terms = {"$",(const guint8*)"",1,GCP_TERM_TYPE_UNKNOWN,NULL,NULL,NULL};
+
+ if ( !c ) return NULL;
+
+ if ( wildcard == GCP_WILDCARD_CHOOSE) {
+ return &all_terms;
+ }
+
+ if (persistent) {
+ if ( c->msg->committed ) {
+ if (wildcard == GCP_WILDCARD_ALL) {
+ for (ct = c->ctx->terms.next; ct; ct = ct->next) {
+ /* XXX not handling more wilcards in one msg */
+ if ( ct->term->start == m ) {
+ return ct->term;
+ }
+ }
+ return NULL;
+ } else {
+ for (ct = c->ctx->terms.next; ct; ct = ct->next) {
+ if ( g_str_equal(ct->term->str,t->str) ) {
+ return ct->term;
+ }
+ }
+ return NULL;
+ }
+ } else {
+
+ for (ct = c->ctx->terms.next; ct; ct = ct->next) {
+ if ( g_str_equal(ct->term->str,t->str) || ct->term->start == m) {
+ break;
+ }
+ }
+
+ if ( ! ct ) {
+
+ if (wildcard == GCP_WILDCARD_ALL) {
+ ct = wmem_new(wmem_file_scope(), gcp_terms_t);
+ ct->next = NULL;
+ ct->term = wmem_new0(wmem_file_scope(), gcp_term_t);
+
+ ct->term->start = m;
+ ct->term->str = "*";
+ ct->term->buffer = NULL;
+ ct->term->len = 0;
+
+ c->terms.last = c->terms.last->next = ct;
+
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->ctx->terms.last->next = ct2;
+ c->ctx->terms.last = ct2;
+
+ return ct->term;
+ } else {
+ for (ct = c->ctx->terms.next; ct; ct = ct->next) {
+ /* XXX not handling more wilcards in one msg */
+ if ( ct->term->buffer == NULL && tr->cmds->cmd->msg == ct->term->start ) {
+ ct->term->str = wmem_strdup(wmem_file_scope(), t->str);
+ ct->term->buffer = (const guint8 *)wmem_memdup(wmem_file_scope(), t->buffer,t->len);
+ ct->term->len = t->len;
+
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->terms.last = c->terms.last->next = ct2;
+
+ return ct->term;
+ }
+
+ if ( g_str_equal(ct->term->str,t->str) ) {
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->terms.last = c->terms.last->next = ct2;
+
+ return ct->term;
+ }
+ }
+
+ ct = wmem_new(wmem_file_scope(), gcp_terms_t);
+ ct->next = NULL;
+ ct->term = wmem_new0(wmem_file_scope(), gcp_term_t);
+
+ ct->term->start = m;
+ ct->term->str = wmem_strdup(wmem_file_scope(), t->str);
+ ct->term->buffer = (const guint8 *)wmem_memdup(wmem_file_scope(), t->buffer,t->len);
+ ct->term->len = t->len;
+
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->terms.last = c->terms.last->next = ct2;
+
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->ctx->terms.last = c->ctx->terms.last->next = ct2;
+
+ return ct->term;
+ }
+ } else {
+ ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t);
+ ct2->term = ct->term;
+
+ c->terms.last = c->terms.last->next = ct2;
+ return ct->term;
+ }
+
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+ } else {
+ ct = wmem_new(wmem_packet_scope(), gcp_terms_t);
+ ct->term = t;
+ ct->next = NULL;
+ c->terms.last = c->terms.last->next = ct;
+
+ return t;
+ }
+
+}
+
+static const gchar* gcp_cmd_to_str(gcp_cmd_t* c, gboolean persistent) {
+ const gchar* s;
+ gcp_terms_t* term;
+
+ if ( !c ) return "-";
+
+ switch (c->type) {
+ case GCP_CMD_NONE:
+ return "-";
+ break;
+ case GCP_CMD_ADD_REQ:
+ s = "AddReq {";
+ break;
+ case GCP_CMD_MOVE_REQ:
+ s = "MoveReq {";
+ break;
+ case GCP_CMD_MOD_REQ:
+ s = "ModReq {";
+ break;
+ case GCP_CMD_SUB_REQ:
+ s = "SubReq {";
+ break;
+ case GCP_CMD_AUDITCAP_REQ:
+ s = "AuditCapReq {";
+ break;
+ case GCP_CMD_AUDITVAL_REQ:
+ s = "AuditValReq {";
+ break;
+ case GCP_CMD_NOTIFY_REQ:
+ s = "NotifyReq {";
+ break;
+ case GCP_CMD_SVCCHG_REQ:
+ s = "SvcChgReq {";
+ break;
+ case GCP_CMD_TOPOLOGY_REQ:
+ s = "TopologyReq {";
+ break;
+ case GCP_CMD_CTX_ATTR_AUDIT_REQ:
+ s = "CtxAttribAuditReq {";
+ break;
+ case GCP_CMD_ADD_REPLY:
+ s = "AddReply {";
+ break;
+ case GCP_CMD_MOVE_REPLY:
+ s = "MoveReply {";
+ break;
+ case GCP_CMD_MOD_REPLY:
+ s = "ModReply {";
+ break;
+ case GCP_CMD_SUB_REPLY:
+ s = "SubReply {";
+ break;
+ case GCP_CMD_AUDITCAP_REPLY:
+ s = "AuditCapReply {";
+ break;
+ case GCP_CMD_AUDITVAL_REPLY:
+ s = "AuditValReply {";
+ break;
+ case GCP_CMD_NOTIFY_REPLY:
+ s = "NotifyReply {";
+ break;
+ case GCP_CMD_SVCCHG_REPLY:
+ s = "SvcChgReply {";
+ break;
+ case GCP_CMD_TOPOLOGY_REPLY:
+ s = "TopologyReply {";
+ break;
+ case GCP_CMD_REPLY:
+ s = "ActionReply {";
+ break;
+ case GCP_CMD_OTHER_REQ:
+ s = "Request {";
+ break;
+ default:
+ s = "-";
+ break;
+ }
+
+ for (term = c->terms.next; term; term = term->next) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s %s",s,term->term->str);
+ }
+
+ if (c->error) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s Error=%i",s,c->error);
+ }
+
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s }", s);
+
+ if (persistent) {
+ if (! c->str) c->str = wmem_strdup(wmem_file_scope(), s);
+ } else {
+ c->str = s;
+ }
+
+ return s;
+}
+
+static const gchar* gcp_trx_to_str(gcp_msg_t* m, gcp_trx_t* t, gboolean persistent) {
+ gchar* s;
+ gcp_cmd_msg_t* c;
+
+ if ( !m || !t ) return "-";
+
+ s = wmem_strdup_printf(wmem_packet_scope(), "T %x { ",t->id);
+
+ if (t->cmds) {
+ if (t->cmds->cmd->ctx) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s C %x {",s,t->cmds->cmd->ctx->id);
+
+ for (c = t->cmds; c; c = c->next) {
+ if (c->cmd->msg == m) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s %s",s,gcp_cmd_to_str(c->cmd,persistent));
+ }
+ }
+
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s %s",s,"}");
+ }
+ }
+
+ if (t->error) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s Error=%i",s,t->error);
+ }
+
+ return wmem_strdup_printf(wmem_packet_scope(), "%s %s",s,"}");
+}
+
+const gchar* gcp_msg_to_str(gcp_msg_t* m, gboolean persistent) {
+ gcp_trx_msg_t* t;
+ const gchar* s = "";
+
+ if ( !m ) return "-";
+
+ for (t = m->trxs; t; t = t->next) {
+ s = wmem_strdup_printf(wmem_packet_scope(), "%s %s",s,gcp_trx_to_str(m,t->trx, persistent));
+ }
+
+ return s;
+}
+
+typedef struct _gcp_ctxs_t {
+ struct _gcp_ctx_t* ctx;
+ struct _gcp_ctxs_t* next;
+} gcp_ctxs_t;
+
+/*static const gchar* trx_types[] = {"None","Req","Reply","Pending","Ack"};*/
+
+void gcp_analyze_msg(proto_tree* gcp_tree, packet_info* pinfo, tvbuff_t* gcp_tvb, gcp_msg_t* m, gcp_hf_ett_t* ids, expert_field* command_err) {
+ gcp_trx_msg_t* t;
+ gcp_ctxs_t contexts = {NULL,NULL};
+ gcp_ctxs_t* ctx_node;
+ gcp_cmd_msg_t* c;
+
+
+ for (t = m->trxs; t; t = t->next) {
+ for (c = t->trx->cmds; c; c = c->next) {
+ gcp_ctx_t* ctx = c->cmd->ctx;
+
+ for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) {
+ if (ctx_node->ctx->id == ctx->id) {
+ break;
+ }
+ }
+
+ if (! ctx_node) {
+ ctx_node = wmem_new(wmem_packet_scope(), gcp_ctxs_t);
+ ctx_node->ctx = ctx;
+ ctx_node->next = contexts.next;
+ contexts.next = ctx_node;
+ }
+ }
+ }
+
+ for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) {
+ gcp_ctx_t* ctx = ctx_node->ctx;
+ proto_item* ctx_item = proto_tree_add_uint(gcp_tree,ids->hf.ctx,gcp_tvb,0,0,ctx->id);
+ proto_tree* ctx_tree = proto_item_add_subtree(ctx_item,ids->ett.ctx);
+ gcp_terms_t *ctx_term;
+
+ PROTO_ITEM_SET_GENERATED(ctx_item);
+
+ if (ctx->cmds) {
+ proto_tree* history_tree = proto_tree_add_subtree(ctx_tree,gcp_tvb,0,0,ids->ett.ctx_cmds,NULL,"[ Command History ]");
+
+ for (c = ctx->cmds; c; c = c->next) {
+ proto_item* cmd_item = proto_tree_add_uint(history_tree,ids->hf.ctx_cmd,gcp_tvb,0,0,c->cmd->msg->framenum);
+ if (c->cmd->str) proto_item_append_text(cmd_item," %s ",c->cmd->str);
+ PROTO_ITEM_SET_GENERATED(cmd_item);
+ if (c->cmd->error) {
+ expert_add_info(pinfo, cmd_item, command_err);
+ }
+ }
+ }
+
+ if (( ctx_term = ctx->terms.next )) {
+ proto_tree* terms_tree = proto_tree_add_subtree(ctx_tree,gcp_tvb,0,0,ids->ett.ctx_terms,NULL,"[ Terminations Used ]");
+
+ for (; ctx_term; ctx_term = ctx_term->next ) {
+ if ( ctx_term->term && ctx_term->term->str) {
+ proto_item* pi = proto_tree_add_string(terms_tree,ids->hf.ctx_term,gcp_tvb,0,0,ctx_term->term->str);
+ proto_tree* term_tree = proto_item_add_subtree(pi,ids->ett.ctx_term);
+
+ PROTO_ITEM_SET_GENERATED(pi);
+
+ if (ctx_term->term->type) {
+ pi = proto_tree_add_uint(term_tree,ids->hf.ctx_term_type,gcp_tvb,0,0,ctx_term->term->type);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
+ if (ctx_term->term->bir) {
+ pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_bir,gcp_tvb,0,0,ctx_term->term->bir);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
+ if (ctx_term->term->nsap) {
+ pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_nsap,gcp_tvb,0,0,ctx_term->term->nsap);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
+ if (ctx_term->term->bir && ctx_term->term->nsap) {
+ gchar* tmp_key = wmem_strdup_printf(wmem_packet_scope(), "%s:%s",ctx_term->term->nsap,ctx_term->term->bir);
+ gchar* key = g_ascii_strdown(tmp_key, -1);
+ alcap_tree_from_bearer_key(term_tree, gcp_tvb, pinfo, key);
+ g_free(key);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* END Gateway Control Protocol -- Context Tracking */
static gboolean keep_persistent_data = FALSE;
static guint global_udp_port = 2945;
@@ -5365,7 +6090,7 @@ dissect_h248_SigParameterV1(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
/*--- End of included file: packet-h248-fn.c ---*/
-#line 1443 "./asn1/h248/packet-h248-template.c"
+#line 2168 "./asn1/h248/packet-h248-template.c"
static int dissect_h248_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
dissect_tpkt_encap(tvb, pinfo, tree, h248_desegment, h248_handle);
@@ -6791,7 +7516,7 @@ void proto_register_h248(void) {
NULL, HFILL }},
/*--- End of included file: packet-h248-hfarr.c ---*/
-#line 1612 "./asn1/h248/packet-h248-template.c"
+#line 2337 "./asn1/h248/packet-h248-template.c"
GCP_HF_ARR_ELEMS("h248",h248_arrel)
@@ -6957,7 +7682,7 @@ void proto_register_h248(void) {
&ett_h248_SigParameterV1,
/*--- End of included file: packet-h248-ettarr.c ---*/
-#line 1630 "./asn1/h248/packet-h248-template.c"
+#line 2355 "./asn1/h248/packet-h248-template.c"
};
static ei_register_info ei[] = {
@@ -7003,14 +7728,12 @@ void proto_register_h248(void) {
"Desegment H.248 messages that span more TCP segments",
&h248_desegment);
- msgs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
- trxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
- ctxs_by_trx = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
- ctxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
+ gcp_msgs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
+ gcp_trxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
+ gcp_ctxs_by_trx = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
+ gcp_ctxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
h248_tap = register_tap("h248");
-
- gcp_init();
}
/*--- proto_reg_handoff_h248 -------------------------------------------*/