aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/asn1/h248
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/asn1/h248
parent68ef5dbf2fff83f8ed1c718ec83a1c1145ac5239 (diff)
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/asn1/h248')
-rw-r--r--epan/dissectors/asn1/h248/packet-h248-template.c745
-rw-r--r--epan/dissectors/asn1/h248/packet-h248-template.h177
2 files changed, 909 insertions, 13 deletions
diff --git a/epan/dissectors/asn1/h248/packet-h248-template.c b/epan/dissectors/asn1/h248/packet-h248-template.c
index c2fa50b963..b8d23aacb9 100644
--- a/epan/dissectors/asn1/h248/packet-h248-template.c
+++ b/epan/dissectors/asn1/h248/packet-h248-template.c
@@ -25,10 +25,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"
@@ -100,10 +104,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;
@@ -1672,14 +2397,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 -------------------------------------------*/
diff --git a/epan/dissectors/asn1/h248/packet-h248-template.h b/epan/dissectors/asn1/h248/packet-h248-template.h
index 1783bf27c9..80af626e31 100644
--- a/epan/dissectors/asn1/h248/packet-h248-template.h
+++ b/epan/dissectors/asn1/h248/packet-h248-template.h
@@ -24,10 +24,183 @@
*/
#ifndef PACKET_H248_H
+#define PACKET_H248_H
-#include <epan/gcp.h>
#include "ws_symbol_export.h"
-/*#include "packet-h248-exp.h"*/
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <wsutil/nstime.h>
+
+/* Gateway Control Protocol -- Context Tracking */
+
+typedef struct _gcp_hf_ett_t {
+ struct {
+ int ctx;
+ int ctx_cmd;
+ int ctx_term;
+ int ctx_term_type;
+ int ctx_term_bir;
+ int ctx_term_nsap;
+ } hf;
+
+ struct {
+ gint ctx;
+ gint ctx_cmds;
+ gint ctx_terms;
+ gint ctx_term;
+ } ett;
+} gcp_hf_ett_t;
+
+#define NULL_CONTEXT 0
+#define CHOOSE_CONTEXT 0xFFFFFFFE
+#define ALL_CONTEXTS 0xFFFFFFFF
+
+
+typedef enum {
+ GCP_CMD_NONE,
+ GCP_CMD_ADD_REQ,
+ GCP_CMD_MOVE_REQ,
+ GCP_CMD_MOD_REQ,
+ GCP_CMD_SUB_REQ,
+ GCP_CMD_AUDITCAP_REQ,
+ GCP_CMD_AUDITVAL_REQ,
+ GCP_CMD_NOTIFY_REQ,
+ GCP_CMD_SVCCHG_REQ,
+ GCP_CMD_TOPOLOGY_REQ,
+ GCP_CMD_CTX_ATTR_AUDIT_REQ,
+ GCP_CMD_OTHER_REQ,
+ GCP_CMD_ADD_REPLY,
+ GCP_CMD_MOVE_REPLY,
+ GCP_CMD_MOD_REPLY,
+ GCP_CMD_SUB_REPLY,
+ GCP_CMD_AUDITCAP_REPLY,
+ GCP_CMD_AUDITVAL_REPLY,
+ GCP_CMD_NOTIFY_REPLY,
+ GCP_CMD_SVCCHG_REPLY,
+ GCP_CMD_TOPOLOGY_REPLY,
+ GCP_CMD_REPLY
+} gcp_cmd_type_t;
+
+typedef enum {
+ GCP_TRX_NONE,
+ GCP_TRX_REQUEST,
+ GCP_TRX_PENDING,
+ GCP_TRX_REPLY,
+ GCP_TRX_ACK
+} gcp_trx_type_t;
+
+
+typedef struct _gcp_msg_t {
+ guint32 lo_addr;
+ guint32 hi_addr;
+ guint32 framenum;
+ nstime_t time;
+ struct _gcp_trx_msg_t* trxs;
+ gboolean committed;
+} gcp_msg_t;
+
+typedef struct _gcp_trx_msg_t {
+ struct _gcp_trx_t* trx;
+ struct _gcp_trx_msg_t* next;
+ struct _gcp_trx_msg_t* last;
+} gcp_trx_msg_t;
+
+typedef struct _gcp_cmd_msg_t {
+ struct _gcp_cmd_t* cmd;
+ struct _gcp_cmd_msg_t* next;
+ struct _gcp_cmd_msg_t* last;
+} gcp_cmd_msg_t;
+
+typedef struct _gcp_trx_t {
+ gcp_msg_t* initial;
+ guint32 id;
+ gcp_trx_type_t type;
+ guint pendings;
+ struct _gcp_cmd_msg_t* cmds;
+ struct _gcp_trx_ctx_t* ctxs;
+ guint error;
+} gcp_trx_t;
+
+#define GCP_TERM_TYPE_UNKNOWN 0
+#define GCP_TERM_TYPE_AAL1 1
+#define GCP_TERM_TYPE_AAL2 2
+#define GCP_TERM_TYPE_AAL1_STRUCT 3
+#define GCP_TERM_TYPE_IP_RTP 4
+#define GCP_TERM_TYPE_TDM 5
+
+typedef enum _gcp_wildcard_t {
+ GCP_WILDCARD_NONE,
+ GCP_WILDCARD_CHOOSE,
+ GCP_WILDCARD_ALL
+} gcp_wildcard_t;
+
+typedef struct _gcp_term_t {
+ const gchar* str;
+
+ const guint8* buffer;
+ guint len;
+
+ guint type;
+ gchar* bir;
+ gchar* nsap;
+
+ gcp_msg_t* start;
+
+} gcp_term_t;
+
+typedef struct _gcp_terms_t {
+ gcp_term_t* term;
+ struct _gcp_terms_t* next;
+ struct _gcp_terms_t* last;
+} gcp_terms_t;
+
+typedef struct _gcp_cmd_t {
+ guint offset;
+ const gchar* str;
+ gcp_cmd_type_t type;
+ gcp_terms_t terms;
+ struct _gcp_msg_t* msg;
+ struct _gcp_trx_t* trx;
+ struct _gcp_ctx_t* ctx;
+ guint error;
+} gcp_cmd_t;
+
+
+typedef struct _gcp_ctx_t {
+ gcp_msg_t* initial;
+ guint32 id;
+ struct _gcp_cmd_msg_t* cmds;
+ struct _gcp_ctx_t* prev;
+ gcp_terms_t terms;
+} gcp_ctx_t;
+
+extern gcp_msg_t* gcp_msg(packet_info* pinfo, int o, gboolean persistent);
+extern gcp_trx_t* gcp_trx(gcp_msg_t* m ,guint32 t_id , gcp_trx_type_t type, gboolean persistent);
+extern gcp_ctx_t* gcp_ctx(gcp_msg_t* m, gcp_trx_t* t, guint32 c_id, gboolean persistent);
+extern 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);
+extern 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);
+extern 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);
+
+#define GCP_ETT_ARR_ELEMS(gi) &(gi.ett.ctx),&(gi.ett.ctx_cmds),&(gi.ett.ctx_terms),&(gi.ett.ctx_term)
+
+#define GCP_HF_ARR_ELEMS(n,gi) \
+ { &(gi.hf.ctx), { "Context", n ".ctx", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, \
+ { &(gi.hf.ctx_term), { "Termination", n ".ctx.term", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \
+ { &(gi.hf.ctx_term_type), { "Type", n ".ctx.term.type", FT_UINT32, BASE_HEX, VALS(gcp_term_types), 0, NULL, HFILL }}, \
+ { &(gi.hf.ctx_term_bir), { "BIR", n ".ctx.term.bir", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \
+ { &(gi.hf.ctx_term_nsap), { "NSAP", n ".ctx.term.nsap", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \
+ { &(gi.hf.ctx_cmd), { "Command in Frame", n ".ctx.cmd", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }}
+
+WS_DLL_PUBLIC const value_string gcp_cmd_type[];
+WS_DLL_PUBLIC const value_string gcp_term_types[];
+
+extern const gchar* gcp_msg_to_str(gcp_msg_t* m, gboolean persistent);
+
+#define gcp_cmd_set_error(c,e) (c->error = e)
+#define gcp_trx_set_error(t,e) (t->error = e)
+
+/* END Gateway Control Protocol -- Context Tracking */
typedef struct _h248_curr_info_t h248_curr_info_t;