- Embryonic Transaction & Context tracing

svn path=/trunk/; revision=16372
This commit is contained in:
Luis Ontanon 2005-11-01 16:28:13 +00:00
parent aa01054c6a
commit f100a33216
5 changed files with 1611 additions and 258 deletions

View File

@ -16,6 +16,7 @@ PropertyID
SignalName
EventName
ContextID
ErrorCode
#.TYPE_RENAME
IndAudMediaDescriptor/streams indAudMediaDescriptorStreams
@ -75,20 +76,51 @@ ServiceChangeReply/terminationID terminationIDList
offset = dissect_h248_trx_id(implicit_tag, pinfo, tree, tvb, offset);
#.END
#.FN_BODY transactionReply/transactionId
#.FN_BODY TransactionReply/transactionId
offset = dissect_h248_trx_id(implicit_tag, pinfo, tree, tvb, offset);
#.END
#.FN_FTR TransactionRequest
if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "} }");
#.FN_BODY TransactionResponseAck/transactionId
offset = dissect_h248_trx_id(implicit_tag, pinfo, tree, tvb, offset);
#.END
#.FN_FTR TransactionPending
if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "} }");
#.FN_HDR Command
h248_cmdmsg = ep_alloc0(sizeof(h248_cmdmsg_info_t));
h248_cmdmsg->offset = offset;
h248_cmdmsg->transaction_id = transaction_id;
h248_cmdmsg->context_id = context_id;
h248_cmdmsg->cmd_type = H248_CMD_NONE;
h248_cmdmsg->msg_type = H248_TRX_REQUEST;
h248_cmdmsg->term_is_wildcard = FALSE;
#.END
#.FN_FTR TransactionAck
if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, "} }");
#.FN_FTR Command
if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, cmd_str(h248_cmdmsg));
if (keep_persistent_data) {
cmdmsg_tree(h248_cmdmsg);
analyze_h248_cmd(pinfo,h248_cmdmsg);
analysis_tree(pinfo, tvb, h248_tree, h248_cmdmsg);
}
#.END
#.FN_HDR CommandReply
h248_cmdmsg = ep_alloc0(sizeof(h248_cmdmsg_info_t));
h248_cmdmsg->offset = offset;
h248_cmdmsg->transaction_id = transaction_id;
h248_cmdmsg->context_id = context_id;
h248_cmdmsg->cmd_type = H248_CMD_NONE;
h248_cmdmsg->msg_type = H248_TRX_REPLY;
h248_cmdmsg->term_is_wildcard = FALSE;
#.END
#.FN_FTR CommandReply
if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, cmd_str(h248_cmdmsg));
if (keep_persistent_data) {
cmdmsg_tree(h248_cmdmsg);
analyze_h248_cmd(pinfo,h248_cmdmsg);
analysis_tree(pinfo, tvb, h248_tree, h248_cmdmsg);
}
#.END
#.FN_BODY ActionRequest/contextId
@ -100,90 +132,88 @@ ServiceChangeReply/terminationID terminationIDList
#.END
#.FN_HDR Command/addReq
command_string = "addReq {";
h248_cmdmsg->cmd_type = H248_CMD_ADD;
#.END
#.FN_HDR Command/moveReq
command_string = "moveReq {";
h248_cmdmsg->cmd_type = H248_CMD_MOVE;
#.END
#.FN_HDR Command/modReq
command_string = "modReq {";
h248_cmdmsg->cmd_type = H248_CMD_MOD;
#.END
#.FN_HDR Command/subtractReq
command_string = "subtractReq {";
h248_cmdmsg->cmd_type = H248_CMD_SUB;
#.END
#.FN_HDR Command/auditCapRequest
command_string = "auditCapRequest {";
h248_cmdmsg->cmd_type = H248_CMD_AUDITCAP;
#.END
#.FN_HDR Command/auditValueRequest
command_string = "auditValueRequest {";
h248_cmdmsg->cmd_type = H248_CMD_AUDITVAL;
#.END
#.FN_HDR Command/notifyReq
command_string = "notifyReq {";
h248_cmdmsg->cmd_type = H248_CMD_NOTIFY;
#.END
#.FN_HDR Command/ServiceChangeRequest
command_string = "serviceChangeReq {";
h248_cmdmsg->cmd_type = H248_CMD_SVCCHG;
#.END
#.FN_HDR CommandReply/addReply
command_string = "addReply {";
h248_cmdmsg->cmd_type = H248_CMD_ADD;
#.END
#.FN_HDR CommandReply/moveReply
command_string = "moveReply {";
#.END
#.FN_HDR CommandReply/addReply
command_string = "addReply {";
h248_cmdmsg->cmd_type = H248_CMD_MOVE;
#.END
#.FN_HDR CommandReply/modReply
command_string = "modReply {";
#.END
#.FN_HDR CommandReply/notifyReply
command_string = "notifyReply {";
h248_cmdmsg->cmd_type = H248_CMD_MOD;
#.END
#.FN_HDR CommandReply/subtractReply
command_string = "subtractReply {";
h248_cmdmsg->cmd_type = H248_CMD_SUB;
#.END
#.FN_HDR CommandReply/notifyReply
h248_cmdmsg->cmd_type = H248_CMD_NOTIFY;
#.END
#.FN_HDR CommandReply/ServiceChangeReply
h248_cmdmsg->cmd_type = H248_CMD_SVCCHG;
#.END
#.FN_HDR CommandReply/auditCapReply
command_string = "auditCapReply {";
h248_cmdmsg->cmd_type = H248_CMD_AUDITCAP;
#.END
#.FN_HDR CommandReply/auditValueReply
command_string = "auditValueReply {";
#.END
#.FN_HDR TerminationID
if (check_col(pinfo->cinfo, COL_INFO) && command_string != NULL ) col_append_str(pinfo->cinfo, COL_INFO, command_string);
it_is_wildcard = FALSE;
#.END
#.FN_FTR TerminationID
if (check_col(pinfo->cinfo, COL_INFO) && command_string != NULL ) col_append_str(pinfo->cinfo, COL_INFO, "}");
it_is_wildcard = FALSE;
h248_cmdmsg->cmd_type = H248_CMD_AUDITVAL;
#.END
#.FN_HDR WildcardField
if (check_col(pinfo->cinfo, COL_INFO) && command_string != NULL ) col_append_str(pinfo->cinfo, COL_INFO, "*");
it_is_wildcard = TRUE;
h248_cmdmsg->term_is_wildcard = TRUE;
#.END
#.FN_BODY ErrorDescriptor/errorCode
guint32 val;
val = 0;
offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_h248_error_code, &val);
h248_cmdmsg->error_code = val;
return offset;
#.END
#.FN_BODY TerminationID/id
tvbuff_t* new_tvb;
offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index, &new_tvb);
if (command_string != NULL && ! it_is_wildcard && check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO, bytes_to_str(tvb_get_ptr(tvb,0,tvb->length),tvb->length));
h248_cmdmsg->term_id = bytes_to_str(tvb_get_ptr(tvb,0,tvb->length),tvb->length);
if (new_tvb && h248_term_handle) {
call_dissector(h248_term_handle, new_tvb, pinfo, tree);

View File

@ -31,14 +31,17 @@
#include <epan/packet.h>
#include <epan/conversation.h>
#include <epan/strutil.h>
#include <epan/emem.h>
#include <epan/expert.h>
#include <epan/prefs.h>
#include <stdio.h>
#include <string.h>
#include "packet-ber.h"
#include <epan/dissectors/packet-ber.h>
#include "packet-h248.h"
#include "packet-isup.h"
#include "packet-q931.h"
#include <epan/dissectors/packet-isup.h>
#include <epan/dissectors/packet-q931.h>
#include <epan/sctpppids.h>
#define PNAME "H.248 MEGACO"
@ -69,8 +72,25 @@ static int hf_h248_package_3GUP_UPversions = -1;
static int hf_h248_package_3GUP_delerrsdu = -1;
static int hf_h248_package_3GUP_interface = -1;
static int hf_h248_package_3GUP_initdir = -1;
static int hf_h248_contextId_64 = -1;
static int hf_h248_transactionId_64 = -1;
static int hf_h248_context_id = -1;
static int hf_h248_error_code = -1;
static int hf_h248_cmd_trx = -1;
static int hf_h248_cmd_request = -1;
static int hf_h248_cmd_reply = -1;
static int hf_h248_cmd_dup_request = -1;
static int hf_h248_cmd_dup_reply = -1;
static int hf_h248_cmd_start = -1;
static int hf_h248_cmd_error = -1;
static int hf_h248_cmd_ctx = -1;
static int hf_h248_ctx_start = -1;
static int hf_h248_ctx_last = -1;
static int hf_h248_ctx_cmd = -1;
static int hf_h248_ctx_cmd_type = -1;
static int hf_h248_ctx_cmd_request = -1;
static int hf_h248_ctx_cmd_reply = -1;
static int hf_h248_ctx_cmd_error = -1;
#include "packet-h248-hf.c"
@ -80,14 +100,40 @@ static gint ett_mtpaddress = -1;
static gint ett_packagename = -1;
static gint ett_codec = -1;
#include "packet-h248-ett.c"
static const gchar* command_string;
static gboolean it_is_wildcard;
static gint ett_cmd = -1;
static gint ett_ctx = -1;
static gint ett_ctx_cmd = -1;
static gint ett_ctx_cmds = -1;
static gint ett_debug = -1;
#include "packet-h248-ett.c"
static dissector_handle_t h248_term_handle;
#if 0
static GHashTable* h248_package_signals = NULL;
static GHashTable* h248_package_events = NULL;
static GHashTable* h248_package_properties = NULL;
static dissector_table_t h248_package_bin_dissector_table=NULL;
#endif
static GHashTable* transactions = NULL;
static GHashTable* transactions_by_framenum = NULL;
static GHashTable* contexts_creating = NULL;
static GHashTable* contexts = NULL;
static gboolean keep_persistent_data = FALSE;
static h248_cmdmsg_info_t* h248_cmdmsg;
static guint32 transaction_id;
static guint32 context_id;
static proto_tree *h248_tree;
static dissector_handle_t h248_term_handle;
static const value_string package_name_vals[] = {
{ 0x0000, "Media stream properties H.248.1 Annex C" },
@ -290,15 +336,141 @@ static const true_false_string h248_tdmc_ec_vals = {
};
#define NULL_CONTEXT 0
#define CHOOSE_CONTEXT 0xFFFFFFFE
#define ALL_CONTEXTS 0xFFFFFFFF
#if 0
static const value_string context_id_type[] = {
{0x00000000,"0 (Null Context)"},
{0xFFFFFFFE,"$ (Choose Context)"},
{0xFFFFFFFF,"* (All Contexts)"},
{NULL_CONTEXT,"0 (Null Context)"},
{CHOOSE_CONTEXT,"$ (Choose Context)"},
{ALL_CONTEXTS,"* (All Contexts)"},
{0,NULL}
};
#endif
static const value_string h248_reasons[] = {
{ 400, "Syntax error in message"},
{ 401, "Protocol Error"},
{ 402, "Unauthorized"},
{ 403, "Syntax error in transaction request"},
{ 406, "Version Not Supported"},
{ 410, "Incorrect identifier"},
{ 411, "The transaction refers to an unknown ContextId"},
{ 412, "No ContextIDs available"},
{ 421, "Unknown action or illegal combination of actions"},
{ 422, "Syntax Error in Action"},
{ 430, "Unknown TerminationID"},
{ 431, "No TerminationID matched a wildcard"},
{ 432, "Out of TerminationIDs or No TerminationID available"},
{ 433, "TerminationID is already in a Context"},
{ 434, "Max number of Terminations in a Context exceeded"},
{ 435, "Termination ID is not in specified Context"},
{ 440, "Unsupported or unknown Package"},
{ 441, "Missing Remote or Local Descriptor"},
{ 442, "Syntax Error in Command"},
{ 443, "Unsupported or Unknown Command"},
{ 444, "Unsupported or Unknown Descriptor"},
{ 445, "Unsupported or Unknown Property"},
{ 446, "Unsupported or Unknown Parameter"},
{ 447, "Descriptor not legal in this command"},
{ 448, "Descriptor appears twice in a command"},
{ 449, "Unsupported or Unknown Parameter or Property Value"},
{ 450, "No such property in this package"},
{ 451, "No such event in this package"},
{ 452, "No such signal in this package"},
{ 453, "No such statistic in this package"},
{ 454, "No such parameter value in this package"},
{ 455, "Property illegal in this Descriptor"},
{ 456, "Property appears twice in this Descriptor"},
{ 457, "Missing parameter in signal or event"},
{ 458, "Unexpected Event/Request ID"},
{ 459, "Unsupported or Unknown Profile"},
{ 460, "Unable to set statistic on stream"},
{ 471, "Implied Add for Multiplex failure"},
{ 500, "Internal software Failure in MG"},
{ 501, "Not Implemented"},
{ 502, "Not ready"},
{ 503, "Service Unavailable"},
{ 504, "Command Received from unauthorized entity"},
{ 505, "Transaction Request Received before a Service Change Reply has been received"},
{ 506, "Number of Transaction Pendings Exceeded"},
{ 510, "Insufficient resources"},
{ 512, "Media Gateway unequipped to detect requested Event"},
{ 513, "Media Gateway unequipped to generate requested Signals"},
{ 514, "Media Gateway cannot send the specified announcement"},
{ 515, "Unsupported Media Type"},
{ 517, "Unsupported or invalid mode"},
{ 518, "Event buffer full"},
{ 519, "Out of space to store digit map"},
{ 520, "Digit Map undefined in the MG"},
{ 521, "Termination is ServiceChangeing"},
{ 522, "Functionality Requested in Topology Triple Not Supported"},
{ 526, "Insufficient bandwidth"},
{ 529, "Internal hardware failure in MG"},
{ 530, "Temporary Network failure"},
{ 531, "Permanent Network failure"},
{ 532, "Audited Property, Statistic, Event or Signal does not exist"},
{ 533, "Response exceeds maximum transport PDU size"},
{ 534, "Illegal write or read only property"},
{ 540, "Unexpected initial hook state"},
{ 542, "Command is not allowed on this termination"},
{ 581, "Does Not Exist"},
{ 600, "Illegal syntax within an announcement specification"},
{ 601, "Variable type not supported"},
{ 602, "Variable value out of range"},
{ 603, "Category not supported"},
{ 604, "Selector type not supported"},
{ 605, "Selector value not supported"},
{ 606, "Unknown segment ID"},
{ 607, "Mismatch between play specification and provisioned data"},
{ 608, "Provisioning error"},
{ 609, "Invalid offset"},
{ 610, "No free segment IDs"},
{ 611, "Temporary segment not found"},
{ 612, "Segment in use"},
{ 613, "ISP port limit overrun"},
{ 614, "No modems available"},
{ 615, "Calling number unacceptable"},
{ 616, "Called number unacceptable"},
{ 900, "Service Restored"},
{ 901, "Cold Boot"},
{ 902, "Warm Boot"},
{ 903, "MGC Directed Change"},
{ 904, "Termination malfunctioning"},
{ 905, "Termination taken out of service"},
{ 906, "Loss of lower layer connectivity (e.g. downstream sync)"},
{ 907, "Transmission Failure"},
{ 908, "MG Impending Failure"},
{ 909, "MGC Impending Failure"},
{ 910, "Media Capability Failure"},
{ 911, "Modem Capability Failure"},
{ 912, "Mux Capability Failure"},
{ 913, "Signal Capability Failure"},
{ 914, "Event Capability Failure"},
{ 915, "State Loss"},
{ 916, "Packages Change"},
{ 917, "Capabilities Change"},
{ 918, "Cancel Graceful"},
{ 919, "Warm Failover"},
{ 920, "Cold Failover"},
{0,NULL}
};
static const value_string request_types[] = {
{ 0, "unknown" },
{ 1, "add" },
{ 2, "move" },
{ 3, "mod" },
{ 4, "subtract" },
{ 5, "auditCap" },
{ 6, "auditValue" },
{ 7, "notify" },
{ 8, "serviceChange" }
};
static int dissect_h248_trx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
guint64 trx_id = 0;
gint8 class;
@ -323,18 +495,18 @@ static int dissect_h248_trx_id(gboolean implicit_tag, packet_info *pinfo, proto_
offset++;
}
if (trx_id > 0xffffffff) {
proto_tree_add_uint64_format(tree, hf_h248_transactionId_64, tvb, offset-len, len,
trx_id,"transactionId %" PRIu64, trx_id);
proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,"transactionId %" PRIu64, trx_id);
proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
transaction_id = 0;
} else {
proto_tree_add_uint(tree, hf_h248_transactionId, tvb, offset-len, len, (guint32)trx_id);
proto_tree_add_uint(tree, hf_h248_transactionId, tvb, offset-len, len, (guint32)trx_id);
transaction_id = (guint32)trx_id;
}
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "Trx %" PRIu64 " { ", trx_id);
}
return offset;
return offset;
}
static int dissect_h248_ctx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
@ -342,10 +514,8 @@ static int dissect_h248_ctx_id(gboolean implicit_tag, packet_info *pinfo, proto_
gboolean pc;
gint32 tag;
guint32 len;
guint64 context_id = 0;
guint64 ctx_id = 0;
guint32 i;
static gchar context_string[64];
static gchar context_string_long[64];
if(!implicit_tag){
offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
@ -359,38 +529,23 @@ static int dissect_h248_ctx_id(gboolean implicit_tag, packet_info *pinfo, proto_
THROW(BoundsError);
} else {
for(i=1;i<=len;i++){
context_id=(context_id<<8)|tvb_get_guint8(tvb, offset);
ctx_id=(ctx_id<<8)|tvb_get_guint8(tvb, offset);
offset++;
}
if (context_id == 0x0000000 ) {
strncpy(context_string,"Ctx 0",sizeof(context_string));
strncpy(context_string_long,"0 (Null Context)",sizeof(context_string));
} else if (context_id == 0xFFFFFFFF ) {
strncpy(context_string,"Ctx *",sizeof(context_string));
strncpy(context_string_long,"* (All Contexts)",sizeof(context_string));
} else if (context_id == 0xFFFFFFFE ) {
strncpy(context_string,"Ctx $",sizeof(context_string));
strncpy(context_string_long,"$ (Choose One)",sizeof(context_string));
if (ctx_id > 0xffffffff) {
proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,
"contextId: %" PRIu64, ctx_id);
proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
context_id = 0xfffffffd;
} else {
g_snprintf(context_string,sizeof(context_string),"Ctx 0x%" PRIx64, context_id);
g_snprintf(context_string_long,sizeof(context_string),"0x%" PRIx64, context_id);
}
if (context_id > 0xffffffff) {
proto_tree_add_uint64_format(tree, hf_h248_contextId_64,
tvb, offset-len, len,
context_id, "contextId: %s", context_string_long);
} else {
proto_tree_add_uint_format(tree, hf_h248_contextId, tvb, offset-len, len,
(guint32)context_id, "contextId: %s", context_string_long);
proto_tree_add_uint(tree, hf_h248_context_id, tvb, offset-len, len, (guint32)ctx_id);
context_id = (guint32) ctx_id;
}
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s { ", context_string);
}
return offset;
}
@ -705,50 +860,409 @@ dissect_h248_MtpAddress(gboolean implicit_tag, tvbuff_t *tvb, int offset, packet
proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_ni, tvb, old_offset, offset-old_offset, val&0x03);
proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_pc, tvb, old_offset, offset-old_offset, val>>2);
}
return offset;
}
static gchar* cmd_str(h248_cmdmsg_info_t* cmdmsg) {
static gchar* command_strings[][2] = {
{ "unkReq", "unkReply" },
{ "addReq", "addReply" },
{ "moveReq", "moveReply" },
{ "modReq", "modReply" },
{ "subtractReq", "subtractReply" },
{ "auditCapRequest", "auditCapReply" },
{ "auditValueRequest", "auditValueReply" },
{ "notifyReq", "notifyReply" },
{ "serviceChangeReq", "serviceChangeReply" }
};
gchar* ctx_str;
gchar* cmd_str;
gchar* param_str;
switch (cmdmsg->msg_type) {
case H248_TRX_REQUEST:
cmd_str = command_strings[cmdmsg->cmd_type][0];
if (cmdmsg->term_is_wildcard) {
param_str = "Term *";
} else {
param_str = ep_strdup_printf("Term %s",cmdmsg->term_id);
}
break;
case H248_TRX_REPLY:
cmd_str = command_strings[cmdmsg->cmd_type][1];
if ( cmdmsg->error_code ) {
param_str = ep_strdup_printf("Error %u",cmdmsg->error_code);
} else {
if (cmdmsg->term_is_wildcard) {
param_str = "Term *";
} else {
param_str = ep_strdup_printf("Term %s",cmdmsg->term_id);
}
}
break;
case H248_TRX_PENDING:
return ep_strdup_printf("T %x { Pending }", cmdmsg->transaction_id);
case H248_TRX_ACK:
return ep_strdup_printf("T %x { Ack }", cmdmsg->transaction_id);
default:
return "[ Bad Command ]";
};
switch (cmdmsg->context_id) {
case NULL_CONTEXT: ctx_str = "0"; break;
case CHOOSE_CONTEXT: ctx_str = "$"; break;
case ALL_CONTEXTS: ctx_str = "*"; break;
default: ctx_str = ep_strdup_printf("%u",cmdmsg->context_id); break;
}
return ep_strdup_printf("T %x { C %s { %s { %s }}} ",
cmdmsg->transaction_id, ctx_str, cmd_str, param_str );
}
static proto_tree* cmdmsg_tree(h248_cmdmsg_info_t* cmdmsg) {
proto_item* pi = proto_tree_add_text(h248_tree,NULL,0,0,"cmd msg");
proto_tree* debug_tree = proto_item_add_subtree(pi,ett_debug);
proto_tree_add_text(debug_tree,NULL,0,0,"transaction_id = %x",cmdmsg->transaction_id);
proto_tree_add_text(debug_tree,NULL,0,0,"context_id = %x",cmdmsg->context_id);
proto_tree_add_text(debug_tree,NULL,0,0,"cmd_type = %u",cmdmsg->cmd_type);
proto_tree_add_text(debug_tree,NULL,0,0,"msg_type = %u",cmdmsg->msg_type);
proto_tree_add_text(debug_tree,NULL,0,0,"error_code = %u",cmdmsg->error_code);
proto_tree_add_text(debug_tree,NULL,0,0,"term_is_wildcard = %x", cmdmsg->term_is_wildcard);
proto_tree_add_text(debug_tree,NULL,0,0,"term_id = %s", cmdmsg->term_id);
return debug_tree;
}
static void analyze_h248_cmd(packet_info* pinfo, h248_cmdmsg_info_t* cmdmsg) {
h248_cmd_info_t* cmd_info;
static h248_cmd_info_t no_cmd_info = {NULL,0,H248_CMD_NONE,0,0,FALSE,0,NULL,NULL,NULL};
gchar* low_addr;
gchar* high_addr;
guint framenum = pinfo->fd->num;
gchar* cmd_key;
cmd_info = g_hash_table_lookup(transactions_by_framenum,GUINT_TO_POINTER(framenum));
if (cmd_info == &no_cmd_info) {
cmdmsg->cmd_info = NULL;
return;
} else if ( cmd_info == NULL ) {
gboolean dup = FALSE;
if (CMP_ADDRESS(&(pinfo->net_src), &(pinfo->net_dst)) < 0) {
low_addr = address_to_str(&(pinfo->net_src));
high_addr = address_to_str(&(pinfo->net_dst));
} else {
low_addr = address_to_str(&(pinfo->net_dst));
high_addr = address_to_str(&(pinfo->net_src));
}
cmd_key = ep_strdup_printf("%s <-> %s : %x",low_addr,high_addr,cmdmsg->transaction_id);
cmd_info = g_hash_table_lookup(transactions,cmd_key);
if ( cmd_info ) {
switch (cmdmsg->msg_type) {
case H248_TRX_REQUEST:
dup = TRUE;
break;
case H248_TRX_REPLY:
if (cmd_info->response_frame) {
dup = TRUE;
} else {
cmd_info->response_frame = framenum;
cmd_info->error_code = cmdmsg->error_code;
}
break;
default:
break;
}
} else {
switch (cmdmsg->msg_type) {
case H248_TRX_REQUEST:
cmd_info = se_alloc(sizeof(h248_cmd_info_t));
cmd_info->key = se_strdup(cmd_key);
cmd_info->trx_id = cmdmsg->transaction_id;
cmd_info->type = cmdmsg->cmd_type;
cmd_info->request_frame = framenum;
cmd_info->response_frame = 0;
cmd_info->choose_ctx = (cmdmsg->context_id == CHOOSE_CONTEXT);
cmd_info->error_code = 0;
cmd_info->context = NULL;
cmd_info->next = NULL;
cmd_info->last = NULL;
g_hash_table_insert(transactions,cmd_info->key,cmd_info);
break;
default:
cmd_info = &no_cmd_info;
break;
}
}
g_hash_table_insert(transactions_by_framenum,GUINT_TO_POINTER(framenum),cmd_info);
cmdmsg->cmd_info = cmd_info;
if ( cmd_info && (! cmd_info->context || cmd_info->context->ctx_id == 0 ) ) {
h248_context_info_t** ctx_ptr;
gchar* ctx_key;
if (cmd_info->choose_ctx) {
/* the fisrt transaction of a new context */
ctx_key = ep_strdup_printf("%s-%s-%i",low_addr,high_addr,cmdmsg->transaction_id);
switch (cmdmsg->msg_type) {
case H248_TRX_REQUEST: {
cmd_info->context = se_alloc(sizeof(h248_context_info_t));
cmd_info->context->key = NULL;
cmd_info->context->ctx_id = 0;
cmd_info->context->creation_frame = framenum;
cmd_info->context->cmds = cmd_info;
cmd_info->context->prior = NULL;
cmd_info->next = NULL;
cmd_info->last = cmd_info;
/*
* XXX: leak: the "transaction key" of a context should be freed
* as we get the context_id one, there's no need for it afterwards.
*
* We're no using an ep_allocated one because g_hashtables do not
* behave propperly if the key changes.
*
* g_strdup/g_free should be used instead of se_strdup.
*/
g_hash_table_insert(contexts_creating,se_strdup(ctx_key),cmd_info->context);
}
break;
case H248_TRX_REPLY: {
/* XXX: former leak: this one should be an extended lookup to g_free the key */
if (( cmd_info->context = g_hash_table_lookup(contexts_creating,ctx_key) )) {
ctx_key = ep_strdup_printf("%s<->%s : %.8x",low_addr,high_addr,cmdmsg->context_id);
cmd_info->context->ctx_id = cmdmsg->context_id;
if ((ctx_ptr = g_hash_table_lookup(contexts,ctx_key))) {
cmd_info->context->prior = *ctx_ptr;
cmd_info->context->key = cmd_info->context->prior->key;
*ctx_ptr = cmd_info->context;
} else {
ctx_ptr = se_alloc(sizeof(void*));
*ctx_ptr = cmd_info->context;
cmd_info->context->key = se_strdup(ctx_key);
g_hash_table_insert(contexts,cmd_info->context->key,ctx_ptr);
}
}
}
break;
default:
break;
}
} else {
ctx_key = ep_strdup_printf("%s<->%s : %.8x",low_addr,high_addr,cmdmsg->context_id);
if (( ctx_ptr = g_hash_table_lookup(contexts,ctx_key) )) {
cmd_info->context = *ctx_ptr;
cmd_info->context->cmds->last->next = cmd_info;
cmd_info->context->cmds->last = cmd_info;
}
}
if (cmd_info && cmd_info->context) {
cmd_info->context->last_frame = framenum;
}
}
} else {
cmdmsg->cmd_info = cmd_info;
return;
}
}
static void analysis_tree(packet_info* pinfo, tvbuff_t *tvb, proto_tree* tree, h248_cmdmsg_info_t* cmdmsg) {
h248_cmd_info_t* cmd_info = cmdmsg->cmd_info;
guint framenum = pinfo->fd->num;
if (cmd_info) {
proto_item* pi = proto_tree_add_string(tree,hf_h248_cmd_trx,tvb,0,0,cmd_info->key);
proto_tree* cmd_tree = proto_item_add_subtree(pi, ett_cmd);
PROTO_ITEM_SET_GENERATED(pi);
switch (cmdmsg->msg_type) {
case H248_TRX_REQUEST:
if (cmd_info->response_frame) {
pi = proto_tree_add_uint(cmd_tree,hf_h248_cmd_reply,tvb,0,0,cmd_info->response_frame);
} else {
pi = proto_tree_add_text(cmd_tree,tvb,0,0,"No response");
proto_item_set_expert_flags(pi, PI_SEQUENCE, PI_NOTE);
}
PROTO_ITEM_SET_GENERATED(pi);
if (cmd_info->request_frame != framenum) {
pi = proto_tree_add_uint(cmd_tree,hf_h248_cmd_dup_request,tvb,0,0,cmd_info->request_frame);
proto_item_set_expert_flags(pi, PI_SEQUENCE, PI_NOTE);
PROTO_ITEM_SET_GENERATED(pi);
}
break;
case H248_TRX_REPLY:
if (cmd_info->request_frame) {
proto_tree_add_uint(cmd_tree,hf_h248_cmd_request,tvb,0,0,cmd_info->request_frame);
} else {
pi = proto_tree_add_text(cmd_tree,tvb,0,0,"No request");
proto_item_set_expert_flags(pi, PI_SEQUENCE, PI_NOTE);
}
if (cmd_info->response_frame != framenum) {
pi = proto_tree_add_uint(cmd_tree,hf_h248_cmd_dup_reply,tvb,0,0,cmd_info->response_frame);
proto_item_set_expert_flags(pi, PI_SEQUENCE, PI_NOTE);
}
break;
default:
/*
* XXX: TODO Pending and Ack
* We need a list of frames or at least a counter of Pendings; these can be many.
* Pendings are known to be synthoms of problems.
*/
return;
}
if (cmd_info->choose_ctx) {
pi = proto_tree_add_boolean(cmd_tree,hf_h248_cmd_start,tvb,0,0,TRUE);
PROTO_ITEM_SET_GENERATED(pi);
proto_item_set_expert_flags(pi, PI_SEQUENCE, PI_NOTE);
}
if (cmd_info->error_code) {
pi = proto_tree_add_uint(cmd_tree,hf_h248_cmd_error,tvb,0,0,cmd_info->error_code);
PROTO_ITEM_SET_GENERATED(pi);
expert_add_info_format(pinfo, pi, PI_RESPONSE_CODE, PI_WARN, "Errored Command");
}
if (cmd_info->context) {
proto_tree* ctx_tree;
proto_tree* cmds_tree;
h248_cmd_info_t* cmd;
if (cmd_info->context->key) {
pi = proto_tree_add_string(tree,hf_h248_cmd_ctx,tvb,0,0,cmd_info->context->key);
} else {
pi = proto_tree_add_text(tree,tvb,0,0,"Embryonic Context");
}
ctx_tree = proto_item_add_subtree(pi, ett_ctx);
PROTO_ITEM_SET_GENERATED(pi);
pi = proto_tree_add_uint(ctx_tree,hf_h248_ctx_start,tvb,0,0,cmd_info->context->creation_frame);
PROTO_ITEM_SET_GENERATED(pi);
pi = proto_tree_add_uint(ctx_tree,hf_h248_ctx_last,tvb,0,0,cmd_info->context->last_frame);
PROTO_ITEM_SET_GENERATED(pi);
pi = proto_tree_add_text(ctx_tree,tvb,0,0,"[ Commands ]");
cmds_tree = proto_item_add_subtree(pi, ett_ctx_cmds);
for(cmd = cmd_info->context->cmds; cmd; cmd = cmd->next) {
proto_tree* ctx_cmd_tree;
pi = proto_tree_add_uint(cmds_tree,hf_h248_ctx_cmd_type,tvb,0,0,cmd->type);
PROTO_ITEM_SET_GENERATED(pi);
ctx_cmd_tree = proto_item_add_subtree(pi,ett_ctx_cmd);
if (cmd == cmd_info ) {
pi = proto_tree_add_uint_format(ctx_cmd_tree,hf_h248_ctx_cmd,tvb,0,0,cmd->trx_id,"This Transaction: %u",cmd->trx_id);
} else {
pi = proto_tree_add_uint_format(ctx_cmd_tree,hf_h248_ctx_cmd,tvb,0,0,cmd->trx_id,"Transaction: %u",cmd->trx_id);
}
PROTO_ITEM_SET_GENERATED(pi);
pi = proto_tree_add_uint(ctx_cmd_tree,hf_h248_ctx_cmd_request,tvb,0,0,cmd->request_frame);
PROTO_ITEM_SET_GENERATED(pi);
pi = proto_tree_add_uint(ctx_cmd_tree,hf_h248_ctx_cmd_reply,tvb,0,0,cmd->response_frame);
PROTO_ITEM_SET_GENERATED(pi);
if (cmd->error_code) {
pi = proto_tree_add_uint(ctx_cmd_tree,hf_h248_ctx_cmd_error,tvb,0,0,cmd->error_code);
PROTO_ITEM_SET_GENERATED(pi);
expert_add_info_format(pinfo, pi, PI_RESPONSE_CODE, PI_NOTE, "Errored Context");
}
}
}
}
}
#include "packet-h248-fn.c"
static void
dissect_h248(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *h248_item;
proto_tree *h248_tree = NULL;
/* Check if it is actually a text based h248 encoding, which we call
megaco in ehtereal.
*/
if(tvb_length(tvb)>=6){
if(!tvb_strneql(tvb, 0, "MEGACO", 6)){
static dissector_handle_t megaco_handle=NULL;
if(!megaco_handle){
megaco_handle = find_dissector("megaco");
}
if(megaco_handle){
call_dissector(megaco_handle, tvb, pinfo, tree);
return;
}
proto_item *h248_item;
h248_tree = NULL;
/* Check if it is actually a text based h248 encoding, which we call
megaco in ehtereal.
*/
if(tvb_length(tvb)>=6){
if(!tvb_strneql(tvb, 0, "MEGACO", 6)){
static dissector_handle_t megaco_handle=NULL;
if(!megaco_handle){
megaco_handle = find_dissector("megaco");
}
if(megaco_handle){
call_dissector(megaco_handle, tvb, pinfo, tree);
return;
}
}
}
}
/* Make entry in the Protocol column on summary display */
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.248");
if (tree) {
h248_item = proto_tree_add_item(tree, proto_h248, tvb, 0, -1, FALSE);
h248_tree = proto_item_add_subtree(h248_item, ett_h248);
}
dissect_h248_MegacoMessage(FALSE, tvb, 0, pinfo, h248_tree, -1);
/* Make entry in the Protocol column on summary display */
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.248");
if (tree) {
h248_item = proto_tree_add_item(tree, proto_h248, tvb, 0, -1, FALSE);
h248_tree = proto_item_add_subtree(h248_item, ett_h248);
}
dissect_h248_MegacoMessage(FALSE, tvb, 0, pinfo, h248_tree, -1);
}
static void h248_init(void) {
if (transactions) g_hash_table_destroy(transactions);
if (transactions_by_framenum) g_hash_table_destroy(transactions_by_framenum);
if (contexts_creating) g_hash_table_destroy(contexts_creating);
if (contexts) g_hash_table_destroy(contexts);
transactions = g_hash_table_new(g_str_hash,g_str_equal);
transactions_by_framenum = g_hash_table_new(g_direct_hash,g_direct_equal);
contexts_creating = g_hash_table_new(g_str_hash,g_str_equal);
contexts = g_hash_table_new(g_str_hash,g_str_equal);
}
/*--- proto_register_h248 ----------------------------------------------*/
void proto_register_h248(void) {
@ -761,19 +1275,13 @@ void proto_register_h248(void) {
{ &hf_h248_mtpaddress_pc, {
"PC", "h248.mtpaddress.pc", FT_UINT32, BASE_DEC,
NULL, 0, "PC", HFILL }},
{ &hf_h248_transactionId_64, {
"transactionId", "h248.transactionId",
FT_UINT64, BASE_HEX, NULL, 0,"", HFILL }},
{ &hf_h248_contextId_64, {
"contextId", "h248.contextId",
FT_UINT64, BASE_HEX, NULL, 0,"", HFILL }},
{ &hf_h248_package_name, {
"Package", "h248.package_name", FT_UINT16, BASE_HEX,
VALS(package_name_vals), 0, "Package", HFILL }},
{ &hf_h248_event_name, {
"Package and Event name", "h248.event_name", FT_UINT32, BASE_HEX,
VALS(event_name_vals), 0, "Package", HFILL }},
{ &hf_h248_signal_name, {
{ &hf_h248_signal_name, {
"Package and Signal name", "h248.signal_name", FT_UINT32, BASE_HEX,
VALS(signal_name_vals), 0, "Package", HFILL }},
{ &hf_h248_package_bcp_BNCChar_PDU,
@ -832,6 +1340,30 @@ void proto_register_h248(void) {
{ "Initialisation Direction", "h248.package_3GUP.initdir",
FT_UINT32, BASE_DEC, VALS(h248_3GUP_initdir_vals), 0,
"Initialisation Direction", HFILL }},
{ &hf_h248_error_code,
{ "errorCode", "h248.errorCode",
FT_UINT32, BASE_DEC, VALS(h248_reasons), 0,
"ErrorDescriptor/errorCode", HFILL }},
{ &hf_h248_context_id,
{ "contextId", "h248.contextId",
FT_UINT32, BASE_DEC, VALS(h248_reasons), 0,
"Context ID", HFILL }},
{ &hf_h248_cmd_trx, { "Transaction", "h248.trx", FT_STRING, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_request, { "Request for this Reply", "h248.cmd.request", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_reply, { "Reply to this Request", "h248.cmd.reply", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_dup_request, { "This Request is a Duplicate of", "h248.cmd.dup_request", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_dup_reply, { "This Reply is a Duplicate of", "h248.cmd.dup_reply", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_start, { "This Transaction Starts a New Context", "h248.cmd.start", FT_BOOLEAN, BASE_NONE, NULL, 0, "", HFILL }},
{ &hf_h248_cmd_error, { "Error", "h248.cmd.error", FT_UINT32, BASE_DEC, VALS(h248_reasons), 0, "", HFILL }},
{ &hf_h248_cmd_ctx, { "Context", "h248.ctx", FT_STRING, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_start, { "Start", "h248.ctx.start", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_last, { "Last", "h248.ctx.last", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_cmd, { "Command", "h248.ctx.cmd", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_cmd_type, { "Command Type", "h248.ctx.cmd.type", FT_UINT32, BASE_DEC, VALS(request_types), 0, "", HFILL }},
{ &hf_h248_ctx_cmd_request, { "Request", "h248.ctx.cmd.request", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_cmd_reply, { "Reply", "h248.ctx.cmd.reply", FT_FRAMENUM, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_h248_ctx_cmd_error, { "Error", "h248.ctx.cmd.error", FT_UINT32, BASE_DEC, VALS(h248_reasons), 0, "", HFILL }},
#include "packet-h248-hfarr.c"
};
@ -841,9 +1373,18 @@ void proto_register_h248(void) {
&ett_h248,
&ett_mtpaddress,
&ett_packagename,
&ett_codec,
&ett_codec,
&ett_cmd,
&ett_ctx,
&ett_ctx_cmd,
&ett_ctx_cmds,
&ett_debug,
#include "packet-h248-ettarr.c"
};
module_t *h248_module;
/* Register protocol */
proto_h248 = proto_register_protocol(PNAME, PSNAME, PFNAME);
@ -853,11 +1394,23 @@ void proto_register_h248(void) {
proto_register_field_array(proto_h248, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
#if 0
/* register a dissector table packages can attach to */
h248_package_bin_dissector_table = register_dissector_table("h248.package.bin", "Binary H.248 Package Dissectors", FT_UINT16,BASE_HEX);
h248_package_signals = g_hash_table_new(g_hash_direct,g_direct_equal);
h248_package_events = g_hash_table_new(g_hash_direct,g_direct_equal);
h248_package_properties = g_hash_table_new(g_hash_direct,g_direct_equal);
#endif
}
h248_module = prefs_register_protocol(proto_h248, h248_init);
prefs_register_bool_preference(h248_module, "ctx_info",
"Keep Context Information",
"Whether persistent context information is to be kept",
&keep_persistent_data);
register_init_routine( &h248_init );
}
/*--- proto_reg_handoff_h248 -------------------------------------------*/
void proto_reg_handoff_h248(void) {
@ -871,3 +1424,25 @@ void proto_reg_handoff_h248(void) {
dissector_add("sctp.ppi", H248_PAYLOAD_PROTOCOL_ID, h248_handle);
}
#ifndef ENABLE_STATIC
#include <gmodule.h>
G_MODULE_EXPORT const gchar version[] = "0.0.0";
G_MODULE_EXPORT void
plugin_register(void)
{
/* register the new protocol, protocol fields, and subtrees */
if (proto_h248 == -1) { /* execute protocol initialization only once */
proto_register_h248();
}
}
G_MODULE_EXPORT void
plugin_reg_handoff(void){
proto_reg_handoff_h248();
}
#endif

View File

@ -28,5 +28,80 @@
/*#include "packet-h248-exp.h"*/
#endif /* PACKET_H248_H */
typedef enum {
H248_CMD_NONE,
H248_CMD_ADD,
H248_CMD_MOVE,
H248_CMD_MOD,
H248_CMD_SUB,
H248_CMD_AUDITCAP,
H248_CMD_AUDITVAL,
H248_CMD_NOTIFY,
H248_CMD_SVCCHG,
} h248_cmd_type_t;
typedef enum {
H248_TRX_NONE,
H248_TRX_REQUEST,
H248_TRX_PENDING,
H248_TRX_REPLY,
H248_TRX_ACK,
} h248_msg_type_t;
/* per command info */
typedef struct _h248_cmd_info_t h248_cmd_info_t;
/* per context info */
typedef struct _h248_context_info_t h248_context_info_t;
/* per command message info */
typedef struct _h248_cmdmsg_info_t {
guint32 transaction_id;
guint32 context_id;
guint offset;
h248_cmd_type_t cmd_type;
h248_msg_type_t msg_type;
guint error_code;
gboolean term_is_wildcard;
gchar* term_id;
h248_cmd_info_t* cmd_info;
} h248_cmdmsg_info_t;
struct _h248_cmd_info_t {
gchar* key;
guint32 trx_id;
h248_cmd_type_t type;
guint request_frame;
guint response_frame;
gboolean choose_ctx;
guint error_code;
h248_context_info_t* context;
h248_cmd_info_t* next;
h248_cmd_info_t* last;
};
struct _h248_context_info_t {
gchar* key;
guint32 ctx_id;
guint creation_frame;
guint last_frame;
h248_cmd_info_t* cmds;
h248_context_info_t* prior;
};
typedef void (*h248_dissect_pkg_item_t)(gboolean implicit_tag, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
extern void h248_add_package_property(guint package, guint property, h248_dissect_pkg_item_t);
extern void h248_add_package_event(guint package, guint property, h248_dissect_pkg_item_t);
extern void h248_add_package_signal(guint package, guint property, h248_dissect_pkg_item_t);
#endif /* PACKET_H248_H */

File diff suppressed because it is too large Load Diff

View File

@ -35,5 +35,80 @@
/*#include "packet-h248-exp.h"*/
#endif /* PACKET_H248_H */
typedef enum {
H248_CMD_NONE,
H248_CMD_ADD,
H248_CMD_MOVE,
H248_CMD_MOD,
H248_CMD_SUB,
H248_CMD_AUDITCAP,
H248_CMD_AUDITVAL,
H248_CMD_NOTIFY,
H248_CMD_SVCCHG,
} h248_cmd_type_t;
typedef enum {
H248_TRX_NONE,
H248_TRX_REQUEST,
H248_TRX_PENDING,
H248_TRX_REPLY,
H248_TRX_ACK,
} h248_msg_type_t;
/* per command info */
typedef struct _h248_cmd_info_t h248_cmd_info_t;
/* per context info */
typedef struct _h248_context_info_t h248_context_info_t;
/* per command message info */
typedef struct _h248_cmdmsg_info_t {
guint32 transaction_id;
guint32 context_id;
guint offset;
h248_cmd_type_t cmd_type;
h248_msg_type_t msg_type;
guint error_code;
gboolean term_is_wildcard;
gchar* term_id;
h248_cmd_info_t* cmd_info;
} h248_cmdmsg_info_t;
struct _h248_cmd_info_t {
gchar* key;
guint32 trx_id;
h248_cmd_type_t type;
guint request_frame;
guint response_frame;
gboolean choose_ctx;
guint error_code;
h248_context_info_t* context;
h248_cmd_info_t* next;
h248_cmd_info_t* last;
};
struct _h248_context_info_t {
gchar* key;
guint32 ctx_id;
guint creation_frame;
guint last_frame;
h248_cmd_info_t* cmds;
h248_context_info_t* prior;
};
typedef void (*h248_dissect_pkg_item_t)(gboolean implicit_tag, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
extern void h248_add_package_property(guint package, guint property, h248_dissect_pkg_item_t);
extern void h248_add_package_event(guint package, guint property, h248_dissect_pkg_item_t);
extern void h248_add_package_signal(guint package, guint property, h248_dissect_pkg_item_t);
#endif /* PACKET_H248_H */