diff options
-rw-r--r-- | epan/dissectors/packet-megaco.c | 1259 |
1 files changed, 634 insertions, 625 deletions
diff --git a/epan/dissectors/packet-megaco.c b/epan/dissectors/packet-megaco.c index 4f3f144273..3e99ba50d4 100644 --- a/epan/dissectors/packet-megaco.c +++ b/epan/dissectors/packet-megaco.c @@ -60,12 +60,15 @@ void proto_reg_handoff_megaco(void); static int proto_megaco = -1; /* Define headers for megaco */ +static int hf_megaco_start = -1; static int hf_megaco_version = -1; static int hf_megaco_transaction = -1; static int hf_megaco_transid = -1; static int hf_megaco_Context = -1; /* static int hf_megaco_command_line = -1; */ static int hf_megaco_command = -1; +static int hf_megaco_command_optional = -1; +static int hf_megaco_wildcard_response = -1; static int hf_megaco_termid = -1; @@ -73,22 +76,23 @@ static int hf_megaco_termid = -1; /* Define headers in subtree for megaco */ static int hf_megaco_modem_descriptor = -1; static int hf_megaco_multiplex_descriptor = -1; -/* static int hf_megaco_media_descriptor = -1; */ -/* static int hf_megaco_events_descriptor = -1; */ -/* static int hf_megaco_signal_descriptor = -1; */ +static int hf_megaco_media_descriptor = -1; +static int hf_megaco_Local_descriptor = -1; +static int hf_megaco_events_descriptor = -1; +static int hf_megaco_signal_descriptor = -1; static int hf_megaco_audit_descriptor = -1; /* static int hf_megaco_servicechange_descriptor = -1; */ static int hf_megaco_digitmap_descriptor = -1; static int hf_megaco_statistics_descriptor = -1; -/* static int hf_megaco_observedevents_descriptor = -1; */ +static int hf_megaco_observedevents_descriptor = -1; static int hf_megaco_topology_descriptor = -1; static int hf_megaco_error_descriptor = -1; -/* static int hf_megaco_TerminationState_descriptor= -1; */ +static int hf_megaco_error_code = -1; +static int hf_megaco_error_string = -1; +static int hf_megaco_TerminationState_descriptor= -1; /* static int hf_megaco_Remote_descriptor = -1; */ -/* static int hf_megaco_Local_descriptor = -1; */ -/* static int hf_megaco_LocalControl_descriptor = -1; */ +static int hf_megaco_LocalControl_descriptor = -1; static int hf_megaco_packages_descriptor = -1; -static int hf_megaco_error_Frame = -1; static int hf_megaco_Service_State = -1; static int hf_megaco_Event_Buffer_Control = -1; static int hf_megaco_mode = -1; @@ -96,13 +100,24 @@ static int hf_megaco_reserve_group = -1; static int hf_megaco_h324_muxtbl_in = -1; static int hf_megaco_h324_muxtbl_out = -1; static int hf_megaco_ds_dscp = -1; +static int hf_megaco_gm_saf = -1; +static int hf_megaco_gm_sam = -1; +static int hf_megaco_gm_spf = -1; +static int hf_megaco_gm_spr = -1; +static int hf_megaco_gm_esas = -1; +static int hf_megaco_tman_pol = -1; +static int hf_megaco_tman_sdr = -1; +static int hf_megaco_tman_mbs = -1; +static int hf_megaco_tman_pdr = -1; +static int hf_megaco_tman_dvt = -1; +static int hf_megaco_ipdc_realm = -1; static int hf_megaco_h324_h223capr = -1; static int hf_megaco_reserve_value = -1; static int hf_megaco_streamid = -1; static int hf_megaco_requestid = -1; static int hf_megaco_pkgdname = -1; static int hf_megaco_mId = -1; -/* static int hf_megaco_h245 = -1; */ +static int hf_megaco_h245 = -1; static int hf_megaco_h223Capability = -1; static int hf_megaco_audititem = -1; @@ -114,12 +129,15 @@ static int ett_megaco_context = -1; static int ett_megaco_command_line = -1; static int ett_megaco_mediadescriptor = -1; static int ett_megaco_descriptors = -1; +static int ett_megaco_raw_text = -1; +static int ett_megaco_error_descriptor = -1; static int ett_megaco_TerminationState = -1; static int ett_megaco_Localdescriptor = -1; static int ett_megaco_Remotedescriptor = -1; static int ett_megaco_LocalControldescriptor = -1; static int ett_megaco_auditdescriptor = -1; static int ett_megaco_eventsdescriptor = -1; +static int ett_megaco_statisticsdescriptor = -1; static int ett_megaco_observedeventsdescriptor = -1; static int ett_megaco_observedevent = -1; static int ett_megaco_packagesdescriptor = -1; @@ -131,9 +149,12 @@ static int ett_megaco_h245 = -1; static gcp_hf_ett_t megaco_ctx_ids = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}}; static expert_field ei_megaco_errored_command = EI_INIT; +static expert_field ei_megaco_no_command = EI_INIT; +static expert_field ei_megaco_no_descriptor = EI_INIT; static expert_field ei_megaco_error_descriptor_transaction_list = EI_INIT; static expert_field ei_megaco_parse_error = EI_INIT; static expert_field ei_megaco_audit_descriptor = EI_INIT; +static expert_field ei_megaco_signal_descriptor = EI_INIT; static dissector_handle_t megaco_text_handle; @@ -168,9 +189,18 @@ static guint global_megaco_bin_udp_port = PORT_MEGACO_BIN; static gboolean global_megaco_raw_text = TRUE; static gboolean global_megaco_dissect_tree = TRUE; +static const value_string megaco_context_vals[] = { + { CHOOSE_CONTEXT, "Choose one" }, + { ALL_CONTEXTS, "All" }, + { NULL_CONTEXT, "NULL" }, + + { 0, NULL } +}; + /* Some basic utility functions that are specific to this dissector */ static gint megaco_tvb_skip_wsp(tvbuff_t *tvb, gint offset); static gint megaco_tvb_skip_wsp_return(tvbuff_t *tvb, gint offset); + /* * The various functions that either dissect some * subpart of MEGACO. These aren't really proto dissectors but they @@ -178,28 +208,10 @@ static gint megaco_tvb_skip_wsp_return(tvbuff_t *tvb, gint offset); * */ static void -dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset); -static void -dissect_megaco_modemdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_multiplexdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_servicechangedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); +dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset, proto_tree *top_tree); static void dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); static void -dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void -dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); -static void dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); static void dissect_megaco_errordescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset); @@ -208,7 +220,7 @@ dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *tree, gint static void dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset); static void -dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset); +dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset, proto_tree *top_tree); static void dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset); static void @@ -225,7 +237,6 @@ static dissector_handle_t h248_otp_handle; static gboolean keep_persistent_data = FALSE; -static proto_tree *top_tree; /* * dissect_megaco_text over TCP, there will be a TPKT header there * @@ -304,6 +315,24 @@ my_proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, return(pi); } + +static proto_item * +my_proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, + gint start, gint length, guint32 value) +{ + proto_item *pi; + + pi = proto_tree_add_uint(tree, hfindex, tvb, start, 1, value); + /* String length may be longer than FT_UINT will allow */ + proto_item_set_len(pi, length); + + if (!global_megaco_dissect_tree) { + PROTO_ITEM_SET_HIDDEN(pi); + } + + return(pi); +} + /* * dissect_megaco_text - The dissector for the MEGACO Protocol, using * text encoding. @@ -313,11 +342,11 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint tvb_len, len; gint tvb_offset,tvb_current_offset,tvb_previous_offset,tvb_next_offset,tokenlen; - gint line_start_offset, ver_offset, ver_length, mId_offset, mId_length; + gint context_offset, context_length, save_offset, save_length; gint tvb_command_start_offset, tvb_command_end_offset; gint tvb_descriptors_start_offset, tvb_descriptors_end_offset; gint tvb_transaction_end_offset; - proto_tree *megaco_tree, *message_tree, *message_body_tree, *megaco_context_tree, *megaco_tree_command_line, *ti, *sub_ti; + proto_tree *megaco_tree, *message_body_tree, *megaco_tree_command_line, *ti, *sub_ti; guint8 word[7]; guint8 TermID[30]; @@ -326,7 +355,6 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint token_index=0; guint32 dword; guchar needle; - guint8 first; gcp_msg_t *msg = NULL; gcp_trx_t *trx = NULL; @@ -334,13 +362,12 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) gcp_cmd_t *cmd = NULL; gcp_term_t *term = NULL; gcp_trx_type_t trx_type = GCP_TRX_NONE; - guint32 trx_id = 0; + guint32 trx_id = 0, pending_id; guint32 ctx_id = 0; gcp_cmd_type_t cmd_type = GCP_CMD_NONE; gcp_wildcard_t wild_term = GCP_WILDCARD_NONE; - proto_item *hidden_item; + gboolean short_form; - top_tree=tree; /* Initialize variables */ tvb_len = tvb_reported_length(tvb); megaco_tree = NULL; @@ -370,7 +397,7 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) * binary encodings. Bugfix add skipping of leading spaces. */ tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset); - line_start_offset = tvb_offset; + /* Quick fix for MEGACO not following the RFC, hopefully not breaking any thing * Turned out to be TPKT in case of TCP, added some code to handle that. * @@ -378,10 +405,9 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) */ if(!tvb_get_nstringz0(tvb,tvb_offset,sizeof(word),word)) return; + short_form = (tvb_get_guint8(tvb, tvb_offset ) == '!'); - - - if (g_ascii_strncasecmp(word, "MEGACO", 6) != 0 && tvb_get_guint8(tvb, tvb_offset ) != '!'){ + if (g_ascii_strncasecmp(word, "MEGACO", 6) != 0 && !short_form){ gint8 ber_class; gboolean pc; gint32 tag; @@ -420,6 +446,9 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; } + my_proto_tree_add_string(megaco_tree, hf_megaco_start, tvb, 0, tvb_previous_offset+1, + tvb_get_string_enc(wmem_packet_scope(), tvb, 0, tvb_previous_offset, ENC_UTF_8|ENC_NA)); + /* skip / */ tvb_previous_offset++; @@ -431,9 +460,8 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvb_current_offset++; } - tokenlen = tvb_current_offset - tvb_previous_offset; - ver_offset = tvb_previous_offset; - ver_length = tokenlen; + my_proto_tree_add_string(megaco_tree, hf_megaco_version, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, + tvb_get_string_enc(wmem_packet_scope(), tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, ENC_UTF_8|ENC_NA)); tvb_previous_offset = tvb_current_offset; tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset); @@ -463,32 +491,15 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; } - tokenlen = tvb_current_offset - tvb_previous_offset; tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset); /* At this point we should point to the "\n" ending the mId element * or to the next character after white space SEP */ - mId_offset = tvb_previous_offset; - mId_length = tokenlen; - - /* Add the first line to the tree */ - tokenlen = tvb_next_offset - line_start_offset - 1; - ti = proto_tree_add_format_text(megaco_tree, tvb, line_start_offset, tokenlen); - message_tree = proto_item_add_subtree(ti, ett_megaco_message); - if (tree){ - if(global_megaco_dissect_tree){ - proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, ENC_UTF_8|ENC_NA); - proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, ENC_UTF_8|ENC_NA); - }else{ - hidden_item = proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, ENC_UTF_8|ENC_NA); - PROTO_ITEM_SET_HIDDEN(hidden_item); - hidden_item = proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, ENC_UTF_8|ENC_NA); - PROTO_ITEM_SET_HIDDEN(hidden_item); - } - } + my_proto_tree_add_string(megaco_tree, hf_megaco_mId, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, + tvb_get_string_enc(wmem_packet_scope(), tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, ENC_UTF_8|ENC_NA)); + col_clear(pinfo->cinfo, COL_INFO); - first = 1; do{ tvb_previous_offset = tvb_next_offset; @@ -559,13 +570,11 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) case RESPONSEACKTOKEN: tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{'); tvb_offset = tvb_LBRKT; + save_offset = tvb_previous_offset; + save_length = tvb_current_offset-tvb_previous_offset; - message_body_tree = proto_tree_add_subtree(megaco_tree, tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset, - ett_megaco_message_body, NULL, tvb_format_text(tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset+1)); - - my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb, - tvb_previous_offset, tokenlen, - "TransactionResponseAck" ); + my_proto_tree_add_string(megaco_tree, hf_megaco_transaction, tvb, + save_offset, save_length, "TransactionResponseAck" ); tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1); tvb_current_offset = tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}'); @@ -573,20 +582,14 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset)-1; /* cut last RBRKT */ len = tvb_current_offset - tvb_previous_offset; - if (!first) { - col_append_str(pinfo->cinfo, COL_INFO, " "); - } - col_append_fstr(pinfo->cinfo, COL_INFO, "%s TransactionResponseAck", - tvb_format_text(tvb,tvb_previous_offset,len)); + pending_id = (guint)strtoul(tvb_format_text(tvb,tvb_previous_offset,len),NULL,10); + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d TransactionResponseAck", pending_id); - if(tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, - tvb_previous_offset, len, - tvb_format_text(tvb,tvb_previous_offset,len)); + my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, pending_id); - if(global_megaco_raw_text){ - tvb_raw_text_add(tvb, megaco_tree); - } + if(global_megaco_raw_text){ + tvb_raw_text_add(tvb, megaco_tree); + } return; /* Pe and PN is transactionPending, P+"any char" is transactionReply */ case PENDINGTOKEN: @@ -595,52 +598,40 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset); tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{'); tvb_current_offset = tvb_LBRKT; - message_body_tree = proto_tree_add_subtree(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset, - ett_megaco_message_body, NULL, tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1)); + save_offset = tvb_previous_offset; + save_length = tvb_current_offset-tvb_previous_offset; + + my_proto_tree_add_string(megaco_tree, hf_megaco_transaction, tvb, + save_offset, save_length, "Reply" ); tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1); len = tvb_current_offset - tvb_offset; - if (tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb, - tvb_previous_offset, tokenlen, - "Pending" ); - if (!first) { - col_append_str(pinfo->cinfo, COL_INFO, " "); - } - col_append_fstr(pinfo->cinfo, COL_INFO, "%s Pending", - tvb_format_text(tvb,tvb_offset,len)); + pending_id = (guint)strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10); + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d Pending", pending_id); - if(tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, - tvb_offset, len, - tvb_format_text(tvb,tvb_offset,len)); + my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, pending_id); return; /* transactionReply */ case REPLYTOKEN: trx_type = GCP_TRX_REPLY; tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{'); - message_body_tree = proto_tree_add_subtree(megaco_tree, tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset, - ett_megaco_message_body, NULL, tvb_format_text(tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset+1)); + save_offset = tvb_previous_offset; + save_length = tvb_LBRKT-tvb_previous_offset; - if (tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb, - tvb_previous_offset, tokenlen, - "Reply" ); + my_proto_tree_add_string(megaco_tree, hf_megaco_transaction, tvb, + save_offset, save_length, "Reply" ); tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1; tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset); tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1); len = tvb_current_offset - tvb_offset; - col_add_fstr(pinfo->cinfo, COL_INFO, "%s Reply ", - tvb_format_text(tvb,tvb_offset,len)); trx_id = (guint)strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10); + col_add_fstr(pinfo->cinfo, COL_INFO, "%d Reply ", trx_id); - if(tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, - tvb_offset, len, tvb_format_text(tvb,tvb_offset,len)); + my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, trx_id); /* Find if we have a errorDescriptor or actionReplyList */ tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); @@ -655,33 +646,26 @@ dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) case TRANSTOKEN: /* TransactionRequest */ trx_type = GCP_TRX_REQUEST; - message_body_tree = proto_tree_add_subtree(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset, - ett_megaco_message_body, NULL, tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1)); + save_offset = tvb_previous_offset; + save_length = tvb_current_offset-tvb_previous_offset; + my_proto_tree_add_string(megaco_tree, hf_megaco_transaction, tvb, + save_offset, save_length, "Request" ); - if(tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb, - tvb_previous_offset, tokenlen, - "Request" ); tvb_offset = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '=')+1; tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset); tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1); len = tvb_current_offset - tvb_offset; - if (!first) { - col_append_str(pinfo->cinfo, COL_INFO, " "); - } - col_append_fstr(pinfo->cinfo, COL_INFO, "%s Request", - tvb_format_text(tvb,tvb_offset,len)); + trx_id = (guint)strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10); - if(tree) - my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, tvb_offset,len, - tvb_format_text(tvb,tvb_offset,len)); + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d Request", trx_id); + + my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, trx_id); /* Offset should be at first printable char after { */ tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); break; default : - ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, ENC_NA); - expert_add_info_format(pinfo, ti, &ei_megaco_error_descriptor_transaction_list, + proto_tree_add_expert_format(tree, pinfo, &ei_megaco_error_descriptor_transaction_list, tvb, 0, -1, "Sorry, can't understand errorDescriptor / transactionList = %s, can't parse it pos %u", tvb_format_text(tvb,tvb_previous_offset,2),tvb_previous_offset); return; @@ -708,14 +692,15 @@ nextcontext: tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '{'); - ti = proto_tree_add_format_text(megaco_tree, tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1); - megaco_context_tree = proto_item_add_subtree(ti, ett_megaco_context); + context_offset = tvb_previous_offset; + context_length = tvb_next_offset-tvb_previous_offset+1; - tvb_previous_offset = tvb_find_guint8(tvb, tvb_current_offset, - tvb_transaction_end_offset, '=')+1; + tvb_previous_offset = tvb_find_guint8(tvb, tvb_current_offset, tvb_transaction_end_offset, '=')+1; tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset); + if (tvb_current_offset >= tvb_next_offset) { - expert_add_info_format(pinfo, ti, &ei_megaco_parse_error, "Parse error: Invalid offset"); + proto_tree_add_expert_format(megaco_tree, pinfo, &ei_megaco_parse_error, + tvb, context_offset, context_length, "Parse error: Invalid offset"); return; } tvb_current_offset = tvb_next_offset; @@ -728,37 +713,23 @@ nextcontext: tokenlen--; } - switch ( tempchar ){ case '$': ctx_id = CHOOSE_CONTEXT; - my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb, - tvb_previous_offset, 1, - "Choose one"); - col_append_str(pinfo->cinfo, COL_INFO, " |=Choose one"); break; case '*': ctx_id = ALL_CONTEXTS; - my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb, - tvb_previous_offset, 1, - "All"); - col_append_str(pinfo->cinfo, COL_INFO, " |=All"); break; case '-': ctx_id = NULL_CONTEXT; - proto_tree_add_text(megaco_context_tree, tvb, tvb_previous_offset, tokenlen, "Context: NULL" ); - col_append_str(pinfo->cinfo, COL_INFO, " |=NULL"); break; default: - my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb, - tvb_previous_offset, tokenlen, - tvb_format_text(tvb, tvb_previous_offset, - tokenlen)); ctx_id = (guint)strtoul(tvb_format_text(tvb, tvb_previous_offset, tokenlen),NULL,10); - - col_append_fstr(pinfo->cinfo, COL_INFO, " |=%s",tvb_format_text(tvb, tvb_previous_offset,tokenlen)); } + my_proto_tree_add_uint(megaco_tree, hf_megaco_Context, tvb, context_offset, context_length, ctx_id); + col_append_fstr(pinfo->cinfo, COL_INFO, " |=%s", val_to_str(ctx_id, megaco_context_vals, "%d")); + ctx = gcp_ctx(msg,trx,ctx_id,keep_persistent_data); /* Find Commands */ @@ -864,13 +835,15 @@ nextcontext: goto nextcontext; } - sub_ti = proto_tree_add_format_text(megaco_tree, tvb, tvb_command_start_offset, len+1); - megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line); + megaco_tree_command_line = proto_tree_add_subtree(megaco_tree, tvb, tvb_command_start_offset, len+1, ett_megaco_command_line, &sub_ti, "Command: "); /* creation of the megaco_tree_command_line additionally Command and Transaction ID will be printed in this line */ /* Changed to use the lines above. this code is saved if there is complaints sub_ti = proto_tree_add_item(megaco_tree,hf_megaco_command_line,tvb,tvb_command_start_offset,tokenlen, ENC_UTF_8|ENC_NA); megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line); */ + if (!global_megaco_dissect_tree) { + PROTO_ITEM_SET_HIDDEN(sub_ti); + } tvb_next_offset = tvb_command_start_offset + tokenlen; @@ -918,29 +891,24 @@ nextcontext: } /* Additional value */ - if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'O'){ - proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "O- indicates an optional command" ); + proto_tree_add_item(megaco_tree_command_line, hf_megaco_command_optional, tvb, tvb_command_start_offset, 2, ENC_NA); tvb_command_start_offset = tvb_command_start_offset+2; } /* Additional value */ - if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'W'){ - proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "W- indicates a wildcarded response to a command" ); + proto_tree_add_item(megaco_tree_command_line, hf_megaco_wildcard_response, tvb, tvb_command_start_offset, 2, ENC_NA ); tvb_command_start_offset = tvb_command_start_offset+2; - } - - tvb_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '='); if (tvb_offset == -1 ) { - expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Missing \"=\""); + proto_tree_add_expert_format(megaco_tree, pinfo, &ei_megaco_parse_error, tvb, tvb_command_start_offset, len+1, "Parse error: Missing \"=\""); return; } tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_offset -1); @@ -951,9 +919,8 @@ nextcontext: tempchar = tempchar - 0x20; if ( tempchar != 'E' ){ - /* Short form used */ - if ( tvb_get_guint8(tvb, 0 ) == '!'){ + if (short_form){ switch ( tempchar ){ @@ -972,10 +939,10 @@ nextcontext: default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "AuditValue"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "AuditValue"); col_append_str(pinfo->cinfo, COL_INFO, " AuditValue"); + proto_item_append_text(sub_ti, "AuditValue"); break; case 'C': @@ -984,10 +951,10 @@ nextcontext: case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break; default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "AuditCapability"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "AuditCapability"); col_append_str(pinfo->cinfo, COL_INFO, " AuditCapability"); + proto_item_append_text(sub_ti, "AuditCapability"); break; default: @@ -997,10 +964,10 @@ nextcontext: default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Add"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Add"); col_append_str(pinfo->cinfo, COL_INFO, " Add"); + proto_item_append_text(sub_ti, "Add"); break; } break; @@ -1009,9 +976,10 @@ nextcontext: /* "IEPS" */ tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1); if(tempchar == 'E'){ - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "IEPSCall"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "IEPSCall"); + col_append_str(pinfo->cinfo, COL_INFO, " IEPSCall"); + proto_item_append_text(sub_ti, "IEPSCall"); } cmd_type = GCP_CMD_NONE; break; @@ -1022,10 +990,10 @@ nextcontext: default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Notify"); - col_append_str(pinfo->cinfo, COL_INFO, " Notify"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Notify"); + col_append_str(pinfo->cinfo, COL_INFO, " Notify"); + proto_item_append_text(sub_ti, "Notify"); break; case 'M': @@ -1042,10 +1010,10 @@ nextcontext: default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Modify"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Modify"); col_append_str(pinfo->cinfo, COL_INFO, " Modify"); + proto_item_append_text(sub_ti, "Modify"); break; case 'V': @@ -1054,10 +1022,10 @@ nextcontext: case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break; default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Move"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Move"); col_append_str(pinfo->cinfo, COL_INFO, " Move"); + proto_item_append_text(sub_ti, "Move"); break; } break; @@ -1076,24 +1044,28 @@ nextcontext: switch ( tempchar ){ case 'G': - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Packages"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Packages"); + col_append_str(pinfo->cinfo, COL_INFO, " Packages"); + proto_item_append_text(sub_ti, "Packages"); break; case 'N': - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Pending"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Pending"); + col_append_str(pinfo->cinfo, COL_INFO, " Pending"); + proto_item_append_text(sub_ti, "Pending"); break; case 'R': - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Priority"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Priority"); + col_append_str(pinfo->cinfo, COL_INFO, " Priority"); + proto_item_append_text(sub_ti, "Priority"); break; case 'F': - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Profile"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Profile"); + col_append_str(pinfo->cinfo, COL_INFO, " Profile"); + proto_item_append_text(sub_ti, "Profile"); break; } break; @@ -1111,9 +1083,10 @@ nextcontext: case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break; default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "ServiceChange"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "ServiceChange"); + col_append_str(pinfo->cinfo, COL_INFO, " ServiceChange"); + proto_item_append_text(sub_ti, "ServiceChange"); break; default: @@ -1122,23 +1095,19 @@ nextcontext: case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break; default: cmd_type = GCP_CMD_NONE; break; } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - "Subtract"); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, "Subtract"); col_append_str(pinfo->cinfo, COL_INFO, " Subtract"); + proto_item_append_text(sub_ti, "Subtract"); break; } break; default: { - proto_item *item; - tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; - item = proto_tree_add_string(megaco_tree, hf_megaco_error_Frame, tvb, - tvb_previous_offset, tokenlen, - "No Command detectable !"); - proto_item_append_text(item,"[ tempchar 0x%x ]", tempchar); + proto_item_append_text(sub_ti, "<None> 0x%02x", tempchar); + expert_add_info(pinfo, sub_ti, &ei_megaco_no_command); return; } } @@ -1209,11 +1178,10 @@ nextcontext: } - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, - tvb_command_start_offset, tokenlen, - tvb_format_text(tvb, tvb_command_start_offset, - tokenlen)); - col_append_fstr(pinfo->cinfo, COL_INFO, " %s",command); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb, + tvb_command_start_offset, tokenlen, command); + col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command); + proto_item_append_text(sub_ti, " %s", command); } if (cmd_type == GCP_CMD_NONE && trx_type == GCP_TRX_REPLY) { @@ -1262,9 +1230,8 @@ nextcontext: gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data); /*** TERM ***/ - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, - tvb_offset, tokenlen, - TermID); + proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, + tvb_offset, tokenlen, TermID); break; case '*': @@ -1274,7 +1241,7 @@ nextcontext: gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data); - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, + proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, tvb_offset, tokenlen, "WildCard all"); col_append_str(pinfo->cinfo, COL_INFO, "=*"); @@ -1288,7 +1255,7 @@ nextcontext: gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data); - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, + proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, tvb_offset, tokenlen, "WildCard any"); col_append_str(pinfo->cinfo, COL_INFO, "=$"); @@ -1298,7 +1265,7 @@ nextcontext: default: /*** TERM ***/ - my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, + proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb, tvb_offset, tokenlen, tvb_format_text(tvb, tvb_offset, tokenlen)); @@ -1337,10 +1304,10 @@ nextcontext: tempchar = tvb_get_guint8(tvb, tvb_command_start_offset); if ( tempchar == 'E'|| tempchar == 'e'){ - dissect_megaco_descriptors(tvb, megaco_tree, pinfo, tvb_command_start_offset-1,tvb_descriptors_end_offset); + dissect_megaco_descriptors(tvb, megaco_tree_command_line, pinfo, tvb_command_start_offset-1,tvb_descriptors_end_offset, tree); } else { - dissect_megaco_descriptors(tvb, megaco_tree, pinfo, tvb_descriptors_start_offset,tvb_descriptors_end_offset); + dissect_megaco_descriptors(tvb, megaco_tree_command_line, pinfo, tvb_descriptors_start_offset,tvb_descriptors_end_offset, tree); } } RBRKT_counter = 0; @@ -1359,8 +1326,6 @@ nextcontext: } tvb_next_offset = tvb_transaction_end_offset; - - first = 0; } while( tvb_transaction_end_offset < tvb_len - 2); @@ -1419,144 +1384,6 @@ static gint find_megaco_descriptors_names(tvbuff_t *tvb, int offset, guint heade } static void -dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset) -{ - gint tvb_len, token_index, tvb_offset, temp_offset; - gint tvb_current_offset,tvb_previous_offset,tokenlen; - gint tvb_RBRKT, tvb_LBRKT; - - tvb_len = tvb_reported_length(tvb); - - - tvb_LBRKT = megaco_tvb_skip_wsp(tvb, tvb_descriptors_start_offset +1); - - tvb_previous_offset = tvb_LBRKT; - tvb_RBRKT = tvb_descriptors_start_offset; - - - do { - - tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1, - tvb_len, '}'); - tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT, - tvb_len, '{'); - - tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, - tvb_len, ','); - - if (tvb_current_offset == -1 || tvb_current_offset > tvb_descriptors_end_offset){ - tvb_current_offset = tvb_descriptors_end_offset; - - } - if (tvb_current_offset <= tvb_previous_offset) { - expert_add_info_format(pinfo, megaco_tree_command_line, &ei_megaco_parse_error, "Parse error: Invalid offset"); - return; - } - - - - /* Descriptor includes no parameters */ - - if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){ - - if ( tvb_current_offset > tvb_RBRKT ){ - tvb_current_offset = tvb_RBRKT; - } - - tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1; - } - - /* Descriptor includes Parameters */ - if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){ - - while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){ - - - tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1, - tvb_len, '{'); - if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1) - tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_len, '}'); - } - - } - - /* Find token length */ - for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_descriptors_end_offset -1; tvb_offset++){ - if (!g_ascii_isalpha(tvb_get_guint8(tvb, tvb_offset ))){ - break; - } - } - tokenlen = tvb_offset - tvb_previous_offset; - token_index = find_megaco_descriptors_names(tvb, tvb_previous_offset, tokenlen); - if (tvb_RBRKT > tvb_descriptors_end_offset) tvb_RBRKT = tvb_descriptors_end_offset; - switch ( token_index ){ - case MEGACO_MODEM_TOKEN: - dissect_megaco_modemdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_MUX_TOKEN: - dissect_megaco_multiplexdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_MEDIA_TOKEN: - /*TODO: Move this to the top when all branches fixed !!!*/ - temp_offset = tvb_find_guint8(tvb, tvb_previous_offset,tvb_descriptors_end_offset, '{'); - tokenlen = temp_offset - tvb_previous_offset+1; - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen); - - tvb_previous_offset = megaco_tvb_skip_wsp(tvb, temp_offset +1); - dissect_megaco_mediadescriptor(tvb, megaco_tree_command_line, pinfo, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_SIGNALS_TOKEN: - dissect_megaco_signaldescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_SERVICES_TOKEN: - dissect_megaco_servicechangedescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_STATS_TOKEN: - dissect_megaco_statisticsdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_ERROR_TOKEN: - dissect_megaco_errordescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_EVENTS_TOKEN: - dissect_megaco_eventsdescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_AUDIT_TOKEN: - dissect_megaco_auditdescriptor(tvb, megaco_tree_command_line, pinfo, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_DIGITMAP_TOKEN: - dissect_megaco_digitmapdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_OE_TOKEN: - /* ObservedEventsToken */ - dissect_megaco_observedeventsdescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_TOPOLOGY_TOKEN: - dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - case MEGACO_PACKAGES_TOKEN: - dissect_megaco_Packagesdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset); - break; - default: - tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; - proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_Frame, tvb, - tvb_previous_offset, tokenlen, - "No Descriptor detectable !"); - break; - } - - tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT, tvb_len, ','); - if (tvb_current_offset == -1 || tvb_descriptors_end_offset < tvb_current_offset){ - tvb_current_offset = tvb_descriptors_end_offset; - } - tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1); - tvb_LBRKT = tvb_previous_offset; - tvb_RBRKT = tvb_previous_offset; - - } while ( tvb_current_offset < tvb_descriptors_end_offset ); - -} - -static void dissect_megaco_modemdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset) { @@ -1642,20 +1469,21 @@ static gint find_megaco_mediaParm_names(tvbuff_t *tvb, int offset, guint header_ } static void -dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line,packet_info *pinfo, gint tvb_last_RBRKT, gint tvb_previous_offset) +dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line,packet_info *pinfo, gint tvb_last_RBRKT, + gint tvb_previous_offset, gint start_offset, proto_tree *top_tree) { gint tokenlen, tvb_LBRKT, tvb_RBRKT; - gint tvb_next_offset, tvb_current_offset, tvb_offset, equal_offset; + gint tvb_next_offset, tvb_current_offset, tvb_offset, equal_offset, save_offset; gint mediaParm; + guint streamId; + proto_tree *megaco_mediadescriptor_tree; + proto_item *megaco_mediadescriptor_ti, *ti; - proto_tree *megaco_mediadescriptor_tree, *megaco_mediadescriptor_ti; + megaco_mediadescriptor_ti = proto_tree_add_item(megaco_tree_command_line, hf_megaco_media_descriptor, tvb, start_offset, 1, ENC_NA); + megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor); - /* - megaco_mediadescriptor_tree = proto_tree_add_subtree(megaco_tree_command_line,tvb,tvb_previous_offset,tokenlen, - ett_megaco_mediadescriptor, NULL, "Media Descriptor"); - */ while ( tvb_previous_offset < tvb_last_RBRKT){ /* Start of token */ tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset); @@ -1675,43 +1503,42 @@ dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_li tvb_RBRKT = tvb_next_offset; tokenlen = tvb_LBRKT - tvb_current_offset +1; - megaco_mediadescriptor_ti = proto_tree_add_format_text(megaco_tree_command_line,tvb,tvb_current_offset, - tokenlen); switch ( mediaParm ){ case MEGACO_LOCAL_TOKEN: tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); - dissect_megaco_Localdescriptor(tvb,megaco_tree_command_line , pinfo, + dissect_megaco_Localdescriptor(tvb, megaco_mediadescriptor_tree, pinfo, tvb_RBRKT, tvb_current_offset); tvb_current_offset = tvb_RBRKT; break; case MEGACO_REMOTE_TOKEN: tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); - dissect_megaco_Localdescriptor(tvb,megaco_tree_command_line , pinfo, + dissect_megaco_Localdescriptor(tvb, megaco_mediadescriptor_tree, pinfo, tvb_RBRKT, tvb_current_offset); tvb_current_offset = tvb_RBRKT; break; case MEGACO_LOCAL_CONTROL_TOKEN: tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); - dissect_megaco_LocalControldescriptor(tvb,megaco_tree_command_line, pinfo , - tvb_RBRKT, tvb_current_offset); + dissect_megaco_LocalControldescriptor(tvb, megaco_mediadescriptor_tree, pinfo, + tvb_RBRKT, tvb_current_offset, top_tree); tvb_current_offset = tvb_RBRKT; break; case MEGACO_STREAM_TOKEN: - megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor); - + save_offset = tvb_current_offset; equal_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_last_RBRKT, '='); tvb_current_offset = megaco_tvb_skip_wsp(tvb, equal_offset+1); tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1); tokenlen = tvb_offset - tvb_current_offset; - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_streamid, tvb, - tvb_current_offset, tokenlen, tvb_format_text(tvb, tvb_current_offset,tokenlen)); + streamId = (guint)strtoul(tvb_format_text(tvb, tvb_current_offset,tokenlen),NULL,10); + ti = proto_tree_add_uint(megaco_mediadescriptor_tree, hf_megaco_streamid, tvb, + save_offset, 1, streamId); + proto_item_set_len(ti, tvb_offset-save_offset+tokenlen); tvb_previous_offset = tvb_LBRKT+1; continue; case MEGACO_TERMINATION_STATE_DESC: tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1); - dissect_megaco_TerminationStatedescriptor(tvb,megaco_tree_command_line , + dissect_megaco_TerminationStatedescriptor(tvb, megaco_mediadescriptor_tree, tvb_RBRKT, tvb_current_offset); tvb_current_offset = tvb_RBRKT; break; @@ -1723,28 +1550,28 @@ dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_li if (tvb_next_offset > tvb_last_RBRKT) tvb_next_offset = tvb_last_RBRKT; if ( tvb_next_offset != -1 ){ tokenlen = tvb_next_offset - tvb_RBRKT+1; - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_RBRKT, tokenlen); + /* (raw formatting removed) + proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_RBRKT, tokenlen); */ tvb_previous_offset = tvb_next_offset+1; - }else{ - /* Add the trailing '}'*/ - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_RBRKT, 1); + } else{ + /* Add the trailing '}' (raw formatting removed) */ + /* proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_RBRKT, 1); */ tvb_previous_offset = tvb_last_RBRKT; } } /* End while */ + + proto_item_set_end(megaco_mediadescriptor_ti, tvb, tvb_previous_offset); } static void -dissect_megaco_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, gint offset, gint len, gchar *msg) +dissect_megaco_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, gint offset, gint len, proto_tree *top_tree) { /*proto_item *item;*/ /*proto_tree *tree;*/ + gchar *msg = tvb_format_text(tvb, offset, len); - /*item=proto_tree_add_string(megaco_tree, hf_megaco_h245, tvb, - offset, len, msg ); - */ - /*item = */proto_tree_add_text(megaco_tree, tvb, offset, len, "%s", msg); - + /*item= */proto_tree_add_item(megaco_tree, hf_megaco_h245, tvb, offset, len, ENC_NA); /*tree = proto_item_add_subtree(item, ett_megaco_h245); */ /* arbitrary maximum length */ @@ -1899,27 +1726,21 @@ dissect_megaco_h324_h223caprn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *meg } static void -dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset) +dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset, proto_tree *top_tree) { gint tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset; gint tvb_events_end_offset, tvb_LBRKT; - proto_tree *megaco_eventsdescriptor_tree, *megaco_eventsdescriptor_ti; - + proto_tree *megaco_eventsdescriptor_tree, *megaco_requestedevent_tree; + proto_item *megaco_eventsdescriptor_ti, *megaco_requestedevent_ti, *ti; guint8 tempchar; - gint requested_event_start_offset, requested_event_end_offset; - proto_tree *megaco_requestedevent_tree, *megaco_requestedevent_ti; - requested_event_start_offset = 0; - requested_event_end_offset = 0; + gint requested_event_start_offset = 0, + requested_event_end_offset = 0; tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; - megaco_eventsdescriptor_ti = proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen); - - /* - megaco_eventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_events_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_UTF_8|ENC_NA); - */ + megaco_eventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_events_descriptor,tvb,tvb_previous_offset, tokenlen, ENC_NA); megaco_eventsdescriptor_tree = proto_item_add_subtree(megaco_eventsdescriptor_ti, ett_megaco_eventsdescriptor); tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '='); @@ -1932,10 +1753,10 @@ dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m tokenlen = tvb_help_offset - tvb_current_offset; - proto_tree_add_string(megaco_eventsdescriptor_tree, hf_megaco_requestid, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + ti = proto_tree_add_uint(megaco_eventsdescriptor_tree, hf_megaco_requestid, tvb, + tvb_current_offset, 1, + strtoul(tvb_format_text(tvb, tvb_current_offset, tokenlen), NULL, 10)); + proto_item_set_len(ti, tokenlen); tvb_events_end_offset = tvb_RBRKT; @@ -2012,15 +1833,11 @@ dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m dissect_megaco_digitmapdescriptor(tvb, megaco_requestedevent_tree, requested_event_end_offset, requested_event_start_offset); } else{ - gchar *msg; - tokenlen = requested_event_end_offset - requested_event_start_offset; - msg=tvb_format_text(tvb,requested_event_start_offset, tokenlen); - if(!strncmp("h245", msg, 4)){ - dissect_megaco_h245(tvb, pinfo, megaco_requestedevent_tree, requested_event_start_offset, tokenlen, msg); + if(!tvb_strneql(tvb, requested_event_start_offset, "h245", 4)){ + dissect_megaco_h245(tvb, pinfo, megaco_requestedevent_tree, requested_event_start_offset, tokenlen, top_tree); } else { - proto_tree_add_text(megaco_requestedevent_tree, tvb, requested_event_start_offset, tokenlen, - "%s", msg); + proto_tree_add_format_text(megaco_requestedevent_tree, tvb, requested_event_start_offset, tokenlen); } } @@ -2044,18 +1861,16 @@ dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m } static void -dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset) +dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset, proto_tree *top_tree) { gint tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset; gint tvb_signals_end_offset, tvb_signals_start_offset, tvb_LBRKT; - /*proto_tree *megaco_signalsdescriptor_tree, *megaco_signalsdescriptor_ti;*/ - - gint requested_signal_start_offset, requested_signal_end_offset; - proto_tree *megaco_requestedsignal_tree, *megaco_requestedsignal_ti; + proto_tree *megaco_signalsdescriptor_tree, *megaco_requestedsignal_tree; + proto_item *megaco_signalsdescriptor_ti, *megaco_requestedsignal_ti; - requested_signal_start_offset = 0; - requested_signal_end_offset = 0; + gint requested_signal_start_offset = 0, + requested_signal_end_offset = 0; tvb_signals_end_offset = tvb_RBRKT; tvb_signals_start_offset = tvb_previous_offset; @@ -2069,8 +1884,8 @@ dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m if(tvb_get_guint8(tvb, tvb_current_offset)!='{') { /* {} has been omitted */ - proto_tree_add_text(megaco_tree_command_line, tvb, tvb_signals_start_offset, tokenlen, - "%s", "Empty Signal Descriptor"); + megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line, hf_megaco_signal_descriptor, tvb, tvb_signals_start_offset, tokenlen, ENC_NA); + expert_add_info(pinfo, megaco_signalsdescriptor_ti, &ei_megaco_signal_descriptor); col_append_str(pinfo->cinfo, COL_INFO, " (Signal:none)"); /* then say so */ @@ -2080,12 +1895,8 @@ dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_signals_end_offset, '{'); tokenlen = (tvb_LBRKT+1) - tvb_signals_start_offset; - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_start_offset, tokenlen); - - /* - megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_signal_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_UTF_8|ENC_NA); + megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_signal_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA); megaco_signalsdescriptor_tree = proto_item_add_subtree(megaco_signalsdescriptor_ti, ett_megaco_signalsdescriptor); - */ tvb_current_offset = tvb_LBRKT; tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1); @@ -2154,28 +1965,22 @@ dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m tokenlen = pkg_tokenlen = tvb_RBRKT+1 - tvb_previous_offset; } - megaco_requestedsignal_ti = proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen); + megaco_requestedsignal_ti = proto_tree_add_item(megaco_signalsdescriptor_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, ENC_UTF_8|ENC_NA); megaco_requestedsignal_tree = proto_item_add_subtree(megaco_requestedsignal_ti, ett_megaco_requestedsignal); - proto_tree_add_item(megaco_requestedsignal_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, ENC_UTF_8|ENC_NA); - if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){ - gchar *msg; - requested_signal_start_offset = megaco_tvb_skip_wsp(tvb, requested_signal_start_offset +1); requested_signal_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_signal_end_offset-1); tokenlen = requested_signal_end_offset - requested_signal_start_offset; - msg=tvb_format_text(tvb,requested_signal_start_offset, tokenlen+1); - if(!strncmp("h245", msg, 4)){ - dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, requested_signal_start_offset, tokenlen, msg); + if(!tvb_strneql(tvb, requested_signal_start_offset, "h245", 4)){ + dissect_megaco_h245(tvb, pinfo, megaco_requestedsignal_tree, requested_signal_start_offset, tokenlen, top_tree); } else { - proto_tree_add_text(megaco_tree_command_line, tvb, requested_signal_start_offset, tokenlen, - "%s", msg); + proto_tree_add_format_text( megaco_requestedsignal_tree, tvb, requested_signal_start_offset, tokenlen); } - /* Print the trailing '}' */ - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_RBRKT, 1); + /* Print the trailing '}' (raw formatting removed) */ + /* proto_tree_add_format_text( megaco_requestedsignal_tree, tvb, tvb_RBRKT, 1); */ } tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT, @@ -2189,13 +1994,13 @@ dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *m tvb_LBRKT = tvb_previous_offset; tvb_RBRKT = tvb_previous_offset; - /* Print the trailing '}' */ - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); + /* Print the trailing '}' (raw formatting removed) */ + /* proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); */ } while ( tvb_current_offset < tvb_signals_end_offset ); }else{ - /* signals{}*/ - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); + /* signals{} (raw formatting removed) + proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); */ } @@ -2222,29 +2027,27 @@ dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree, packet_in } tokenlen = (tvb_stop + 1) - tvb_offset; - megaco_auditdescriptor_ti = proto_tree_add_none_format( megaco_tree, hf_megaco_audit_descriptor, - tvb, tvb_offset, tokenlen, "Audit descriptor" ); - + megaco_auditdescriptor_ti = proto_tree_add_item( megaco_tree, hf_megaco_audit_descriptor, tvb, tvb_offset, tokenlen, ENC_NA); megaco_auditdescriptor_tree = proto_item_add_subtree( megaco_auditdescriptor_ti, ett_megaco_auditdescriptor ); tokenlen = tvb_next + 1 - tvb_offset; - proto_tree_add_text( megaco_auditdescriptor_tree, tvb, tvb_offset, tokenlen, "Audit token {" ); - tvb_offset = tvb_next; while( tvb_offset < tvb_stop ) { tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1); /* find start of an auditItem */ - if( tvb_get_guint8(tvb, tvb_offset) != '}' ) /* got something */ - { + if( tvb_get_guint8(tvb, tvb_offset) != '}' ) /* got something */ + { tvb_next = tvb_find_guint8(tvb, tvb_offset, tvb_stop, ','); /* end of an auditItem */ - if (tvb_next == -1) tvb_next = tvb_stop; /* last item doesn't have a comma */ + if (tvb_next == -1) /* last item doesn't have a comma */ + tvb_next = tvb_stop; tvb_end = megaco_tvb_skip_wsp_return(tvb, tvb_next-1); /* trim any trailing whitespace */ tokenlen = tvb_end - tvb_offset; /* get length of token */ token_index = find_megaco_descriptors_names(tvb, tvb_offset, tokenlen); /* lookup the token */ - if( token_index == -1 ) token_index = 0; /* if not found then 0 => Unknown */ + if( token_index == -1 ) /* if not found then 0 => Unknown */ + token_index = 0; proto_tree_add_string(megaco_auditdescriptor_tree, hf_megaco_audititem, tvb, tvb_offset, tokenlen, megaco_descriptors_names[token_index].name); /* and display the long form */ @@ -2252,7 +2055,6 @@ dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree, packet_in tvb_offset = tvb_next; /* advance pointer */ } } - proto_tree_add_text(megaco_auditdescriptor_tree, tvb, tvb_stop, 1, "}"); /* End of auditDescriptor */ } /* @@ -2444,41 +2246,55 @@ dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command static void dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset) { - gint tokenlen; + proto_tree *megaco_statisticsdescriptor_tree; + proto_item *megaco_statisticsdescriptor_ti; + gint tvb_help_offset, param_start_offset, param_end_offset = 0; tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; - proto_tree_add_string(megaco_tree_command_line, hf_megaco_statistics_descriptor, tvb, - tvb_previous_offset, tokenlen, - tvb_format_text(tvb, tvb_previous_offset, - tokenlen)); + megaco_statisticsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_statistics_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA); + megaco_statisticsdescriptor_tree = proto_item_add_subtree(megaco_statisticsdescriptor_ti, ett_megaco_statisticsdescriptor); + + tvb_help_offset = tvb_find_guint8(tvb, tvb_previous_offset+1, tvb_RBRKT, '{'); + do { + param_start_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset+1); + + tvb_help_offset = tvb_find_guint8(tvb, tvb_help_offset+1, tvb_RBRKT, ','); + + if ( tvb_help_offset > tvb_RBRKT || tvb_help_offset == -1){ + tvb_help_offset = tvb_RBRKT; + param_end_offset = megaco_tvb_skip_wsp_return(tvb, tvb_RBRKT-1); + tokenlen = param_end_offset - param_start_offset; + } else { + param_end_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset-1); + tokenlen = param_end_offset - param_start_offset+1; + } + + proto_tree_add_format_text(megaco_statisticsdescriptor_tree, tvb,param_start_offset, tokenlen); + + } while ( tvb_help_offset < tvb_RBRKT ); } + static void -dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset) +dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset, proto_tree *top_tree) { gint tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset; gint tvb_observedevents_end_offset, tvb_LBRKT; - proto_tree *megaco_observedeventsdescriptor_tree, *megaco_observedeventsdescriptor_ti; + proto_tree *megaco_observedeventsdescriptor_tree, *megaco_observedevent_tree; + proto_item *megaco_observedeventsdescriptor_ti, *megaco_observedevent_ti, *ti; gint requested_event_start_offset, requested_event_end_offset, param_start_offset, param_end_offset; - proto_tree *megaco_observedevent_tree, *megaco_observedevent_ti; requested_event_start_offset = 0; requested_event_end_offset = 0; - tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{'); tvb_next_offset = tvb_LBRKT; tokenlen = (tvb_next_offset+1) - tvb_previous_offset; - /* - megaco_observedeventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_observedevents_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_UTF_8|ENC_NA); - megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor); - */ - - megaco_observedeventsdescriptor_ti = proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen); + megaco_observedeventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_observedevents_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA); megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor); tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '='); @@ -2491,10 +2307,10 @@ dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto tokenlen = tvb_help_offset - tvb_current_offset; - proto_tree_add_string(megaco_observedeventsdescriptor_tree, hf_megaco_requestid, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + ti = proto_tree_add_uint(megaco_observedeventsdescriptor_tree, hf_megaco_requestid, tvb, + tvb_current_offset, 1, + strtoul(tvb_format_text(tvb, tvb_current_offset, tokenlen), NULL, 10)); + proto_item_set_len(ti, tokenlen); tvb_observedevents_end_offset = tvb_RBRKT; @@ -2572,8 +2388,6 @@ dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto tvb_help_offset = requested_event_start_offset; do { - gchar *msg; - param_start_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset+1); tvb_help_offset = tvb_find_guint8(tvb, tvb_help_offset+1,requested_event_end_offset, ','); @@ -2585,12 +2399,10 @@ dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto param_end_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset-1); tokenlen = param_end_offset - param_start_offset+1; - msg=tvb_format_text(tvb,param_start_offset, tokenlen); - if(!strncmp("h245", msg, 4)){ - dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, param_start_offset, tokenlen, msg); + if(!tvb_strneql(tvb, param_start_offset, "h245", 4)){ + dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, param_start_offset, tokenlen, top_tree); } else { - proto_tree_add_text(megaco_tree_command_line, tvb, param_start_offset, tokenlen, - "%s", msg); + proto_tree_add_format_text(megaco_tree_command_line, tvb, param_start_offset, tokenlen); } @@ -2613,8 +2425,8 @@ dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto tvb_LBRKT = tvb_previous_offset; tvb_RBRKT = tvb_previous_offset; - /* Print the trailing '}' */ - proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_observedevents_end_offset, 1); + /* Print the trailing '}' (raw formatting removed) */ + /* proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_observedevents_end_offset, 1); */ } while ( tvb_current_offset < tvb_observedevents_end_offset ); } @@ -2638,15 +2450,14 @@ dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command gint tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset; gint tvb_packages_end_offset, tvb_LBRKT; - proto_tree *megaco_packagesdescriptor_tree, *megaco_packagesdescriptor_ti; + proto_tree *megaco_packagesdescriptor_tree; + proto_item *megaco_packagesdescriptor_ti, *ti; tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; megaco_packagesdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_packages_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_UTF_8|ENC_NA); megaco_packagesdescriptor_tree = proto_item_add_subtree(megaco_packagesdescriptor_ti, ett_megaco_packagesdescriptor); - - tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '='); tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{'); @@ -2657,10 +2468,10 @@ dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command tokenlen = tvb_help_offset - tvb_current_offset; - proto_tree_add_string(megaco_packagesdescriptor_tree, hf_megaco_requestid, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + ti = proto_tree_add_uint(megaco_packagesdescriptor_tree, hf_megaco_requestid, tvb, + tvb_current_offset, 1, + strtoul(tvb_format_text(tvb, tvb_current_offset, tokenlen), NULL, 10)); + proto_item_set_len(ti, tokenlen); tvb_packages_end_offset = tvb_RBRKT; @@ -2826,33 +2637,28 @@ dissect_megaco_errordescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_li guint8 error[4]; gint tvb_current_offset; proto_item* item; - proto_item* hidden_item; + proto_tree* error_tree; tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset , tvb_RBRKT, '='); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1); - tvb_get_nstringz0(tvb,tvb_current_offset,4,error); - error_code = atoi(error); - hidden_item = proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_descriptor, tvb, - tvb_current_offset, 3, - tvb_format_text(tvb, tvb_current_offset, - 3)); - PROTO_ITEM_SET_HIDDEN(hidden_item); tokenlen = (tvb_RBRKT) - tvb_previous_offset+1; + item = proto_tree_add_item(megaco_tree_command_line, hf_megaco_error_descriptor, tvb, + tvb_previous_offset, tokenlen, ENC_NA); + error_tree = proto_item_add_subtree(item, ett_megaco_error_descriptor); - proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_descriptor, tvb, - tvb_previous_offset, tokenlen, - tvb_format_text(tvb, tvb_previous_offset, - tokenlen)); - - item = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_current_offset, 3, - "Error code: %s", - val_to_str(error_code, MEGACO_error_code_vals, - "Unknown (%u)")); + /* Get the error code */ + tvb_get_nstringz0(tvb,tvb_current_offset,4,error); + error_code = atoi(error); + proto_tree_add_uint(error_tree, hf_megaco_error_code, tvb, tvb_current_offset, 3, error_code); - PROTO_ITEM_SET_GENERATED(item); + /* Get the error string (even though we have a value_string that should match) */ + tvb_previous_offset = tvb_find_guint8(tvb, tvb_current_offset, tvb_RBRKT, '\"'); + tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset+1, tvb_RBRKT, '\"'); + tokenlen = tvb_current_offset - tvb_previous_offset-1; + proto_tree_add_item(error_tree, hf_megaco_error_string, tvb, tvb_previous_offset+1, tokenlen, ENC_UTF_8|ENC_NA); } static void dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, gint tvb_next_offset, gint tvb_current_offset) @@ -2866,11 +2672,7 @@ dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *megaco_medi tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_next_offset, '='); tokenlen = tvb_next_offset - tvb_current_offset; - /* - megaco_TerminationState_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_TerminationState_descriptor,tvb,tvb_current_offset,tokenlen, ENC_UTF_8|ENC_NA); - megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState); - */ - megaco_TerminationState_ti = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_current_offset, tokenlen); + megaco_TerminationState_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_TerminationState_descriptor,tvb,tvb_current_offset,tokenlen, ENC_NA); megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState); while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){ @@ -2945,7 +2747,8 @@ dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *megaco_medi tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_next_offset, '='); } - proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_next_offset, 1); + /* (raw formatting removed) + proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_next_offset, 1); */ } static void @@ -2954,18 +2757,14 @@ dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor gint tokenlen; tvbuff_t *next_tvb; - proto_tree *megaco_localdescriptor_tree, *megaco_localdescriptor_ti; + proto_tree *megaco_localdescriptor_tree; + proto_item *megaco_localdescriptor_item; tokenlen = tvb_next_offset - tvb_current_offset; + megaco_localdescriptor_item = proto_tree_add_item(megaco_mediadescriptor_tree, hf_megaco_Local_descriptor, tvb, tvb_current_offset, tokenlen, ENC_NA); + megaco_localdescriptor_tree = proto_item_add_subtree(megaco_localdescriptor_item, ett_megaco_Localdescriptor); - /* - megaco_localdescriptor_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_Local_descriptor,tvb,tvb_current_offset,tokenlen, ENC_UTF_8|ENC_NA); - */ - megaco_localdescriptor_ti = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_current_offset, tokenlen); - megaco_localdescriptor_tree = proto_item_add_subtree(megaco_localdescriptor_ti, ett_megaco_Localdescriptor); - - tokenlen = tvb_next_offset - tvb_current_offset; if ( tokenlen > 3 ){ next_tvb = tvb_new_subset_length(tvb, tvb_current_offset, tokenlen); call_dissector(sdp_handle, next_tvb, pinfo, megaco_localdescriptor_tree); @@ -2995,6 +2794,12 @@ dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor #define MEGACO_GM_ESPS 14 #define MEGACO_GM_LSP 15 #define MEGACO_GM_RSB 16 +#define MEGACO_TMAN_POL 17 +#define MEGACO_TMAN_SDR 18 +#define MEGACO_TMAN_MBS 19 +#define MEGACO_TMAN_PDR 20 +#define MEGACO_TMAN_DVT 21 +#define MEGACO_IPDC_REALM 22 static const megaco_tokens_t megaco_localParam_names[] = { { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */ @@ -3018,6 +2823,12 @@ static const megaco_tokens_t megaco_localParam_names[] = { { "gm/esps", NULL }, /* 14 */ { "gm/lsp", NULL }, /* 15 */ { "gm/rsb", NULL }, /* 16 */ + { "tman/pol", NULL }, /* 17 */ + { "tman/sdr", NULL }, /* 18 */ + { "tman/mbs", NULL }, /* 19 */ + { "tman/pdr", NULL }, /* 20 */ + { "tman/dvt", NULL }, /* 21 */ + { "ipdc/realm", NULL }, /* 22 */ }; /* Returns index of megaco_tokens_t */ @@ -3039,26 +2850,24 @@ static gint find_megaco_localParam_names(tvbuff_t *tvb, int offset, guint header } static void -dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset) +dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset, proto_tree *top_tree) { gint tokenlen; guint token_name_len; - gint tvb_offset,tvb_help_offset; + gint tvb_offset = 0,tvb_help_offset; gint token_index = 0; gchar *msg; proto_item* item; guint8 code_str[3]; - /*proto_tree *megaco_LocalControl_tree, *megaco_LocalControl_ti; */ - - tvb_offset = 0; + proto_tree *megaco_LocalControl_tree; + proto_item *megaco_LocalControl_item; - /* tokenlen = tvb_next_offset - tvb_current_offset; - megaco_LocalControl_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_LocalControl_descriptor,tvb,tvb_current_offset,tokenlen, ENC_UTF_8|ENC_NA); - megaco_LocalControl_tree = proto_item_add_subtree(megaco_LocalControl_ti, ett_megaco_LocalControldescriptor); - */ + megaco_LocalControl_item = proto_tree_add_item(megaco_mediadescriptor_tree, hf_megaco_LocalControl_descriptor, tvb, tvb_current_offset, tokenlen, ENC_NA); + megaco_LocalControl_tree = proto_item_add_subtree(megaco_LocalControl_item, ett_megaco_LocalControldescriptor); + while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){ tvb_help_offset = tvb_current_offset; @@ -3106,8 +2915,8 @@ dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediades switch ( token_index ){ case MEGACO_MODETOKEN: /* Mode */ - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_mode, tvb, - tvb_current_offset, tokenlen, + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_mode, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); col_append_fstr(pinfo->cinfo, COL_INFO, " (Mode:%s)",tvb_format_text(tvb, tvb_current_offset,tokenlen)); @@ -3115,26 +2924,23 @@ dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediades break; case MEGACO_RESERVEDVALUETOKEN: /* ReservedValue */ - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_reserve_value, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_reserve_value, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, + tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_RESERVEDGROUPTOKEN: /* ReservedGroup */ - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_reserve_group, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_reserve_group, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, + tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_H324_H223CAPR: /* h324/h223capr */ - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_h223capr, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_h223capr, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, + tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); tokenlen = tvb_offset - tvb_help_offset; @@ -3145,23 +2951,21 @@ dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediades case MEGACO_H324_MUXTBL_IN: /* h324/muxtbl_in */ - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_muxtbl_in, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_muxtbl_in, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, + tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); tokenlen = tvb_offset - tvb_help_offset; - msg=tvb_format_text(tvb,tvb_help_offset, tokenlen); /* Call the existing routine with tree = NULL to avoid an entry to the tree */ - dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, msg); + dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, top_tree); break; case MEGACO_H324_MUXTBL_OUT: - proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_muxtbl_out, tvb, + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_muxtbl_out, tvb, tvb_current_offset, tokenlen, tvb_format_text(tvb, tvb_current_offset, tokenlen)); @@ -3169,81 +2973,242 @@ dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediades tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); tokenlen = tvb_offset - tvb_help_offset; - msg=tvb_format_text(tvb,tvb_help_offset, tokenlen); /* Call the existing routine with tree = NULL to avoid an entry to the tree */ - dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, msg); + dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, top_tree); break; case MEGACO_DS_DSCP: - item = proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_ds_dscp, tvb, - tvb_current_offset, tokenlen, - tvb_format_text(tvb, tvb_current_offset, - tokenlen)); - tvb_get_nstringz0(tvb,tvb_current_offset,3,code_str); - proto_item_append_text(item,"[ %s ]", - val_to_str_ext((guint32)strtoul(code_str,NULL,16), &dscp_vals_ext,"Unknown (%u)")); - + item = proto_tree_add_uint(megaco_LocalControl_tree, hf_megaco_ds_dscp, tvb, + tvb_help_offset, 1, strtoul(code_str,NULL,16)); + proto_item_set_len(item, tvb_offset-tvb_help_offset); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_GM_SAF: - tokenlen = tvb_offset - tvb_help_offset; - item = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); - proto_item_append_text(item," [Remote Source Address Filtering]"); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_saf, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_GM_SAM: - tokenlen = tvb_offset - tvb_help_offset; - item = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); - proto_item_append_text(item," [Remote Source Address Mask]"); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_sam, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_GM_SPF: - tokenlen = tvb_offset - tvb_help_offset; - item = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); - proto_item_append_text(item," [Remote Source Port Filtering]"); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_spf, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_GM_SPR: - tokenlen = tvb_offset - tvb_help_offset; - item = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); - proto_item_append_text(item," [Remote Source Port Range]"); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_spr, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; case MEGACO_GM_ESAS: - tokenlen = tvb_offset - tvb_help_offset; - item = proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); - proto_item_append_text(item," [Explicit Source Address Setting]"); + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_esas, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + case MEGACO_TMAN_POL: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_pol, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + case MEGACO_TMAN_SDR: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_sdr, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + case MEGACO_TMAN_MBS: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_mbs, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + case MEGACO_TMAN_PDR: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_pdr, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + case MEGACO_TMAN_DVT: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_dvt, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; + case MEGACO_IPDC_REALM: + proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_ipdc_realm, tvb, + tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(tvb, tvb_current_offset, tokenlen)); + tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); + break; + default: tokenlen = tvb_offset - tvb_help_offset; - proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen); + proto_tree_add_format_text(megaco_LocalControl_tree, tvb, tvb_help_offset, tokenlen); tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1); break; } } } + +static void +dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *megaco_command_tree, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset, proto_tree *top_tree) +{ + gint tvb_len, token_index, tvb_offset, temp_offset; + gint tvb_current_offset,tvb_previous_offset,save_offset,tokenlen; + gint tvb_RBRKT, tvb_LBRKT; + proto_tree* descriptor_tree; + proto_item* descriptor_item; + + tvb_len = tvb_reported_length(tvb); + + descriptor_tree = proto_tree_add_subtree(megaco_command_tree, tvb, tvb_descriptors_start_offset, + tvb_descriptors_end_offset-tvb_descriptors_start_offset, ett_megaco_descriptors, &descriptor_item, "Descriptors"); + + tvb_LBRKT = megaco_tvb_skip_wsp(tvb, tvb_descriptors_start_offset +1); + + tvb_previous_offset = tvb_LBRKT; + tvb_RBRKT = tvb_descriptors_start_offset; + + + do { + + tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1, + tvb_len, '}'); + tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT, + tvb_len, '{'); + + tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, + tvb_len, ','); + + if (tvb_current_offset == -1 || tvb_current_offset > tvb_descriptors_end_offset){ + tvb_current_offset = tvb_descriptors_end_offset; + + } + if (tvb_current_offset <= tvb_previous_offset) { + expert_add_info_format(pinfo, descriptor_item, &ei_megaco_parse_error, "Parse error: Invalid offset"); + return; + } + + /* Descriptor includes no parameters */ + + if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){ + + if ( tvb_current_offset > tvb_RBRKT ){ + tvb_current_offset = tvb_RBRKT; + } + + tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1; + } + + /* Descriptor includes Parameters */ + if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){ + + while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){ + + + tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1, + tvb_len, '{'); + if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1) + tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_len, '}'); + } + + } + + /* Find token length */ + for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_descriptors_end_offset -1; tvb_offset++){ + if (!g_ascii_isalpha(tvb_get_guint8(tvb, tvb_offset ))){ + break; + } + } + tokenlen = tvb_offset - tvb_previous_offset; + token_index = find_megaco_descriptors_names(tvb, tvb_previous_offset, tokenlen); + if (tvb_RBRKT > tvb_descriptors_end_offset) + tvb_RBRKT = tvb_descriptors_end_offset; + switch ( token_index ){ + case MEGACO_MODEM_TOKEN: + dissect_megaco_modemdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_MUX_TOKEN: + dissect_megaco_multiplexdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_MEDIA_TOKEN: + /*TODO: Move this to the top when all branches fixed !!!*/ + temp_offset = tvb_find_guint8(tvb, tvb_previous_offset,tvb_descriptors_end_offset, '{'); + tokenlen = temp_offset - tvb_previous_offset+1; + save_offset = tvb_previous_offset; + + tvb_previous_offset = megaco_tvb_skip_wsp(tvb, temp_offset +1); + dissect_megaco_mediadescriptor(tvb, descriptor_tree, pinfo, tvb_RBRKT, tvb_previous_offset, save_offset, top_tree); + break; + case MEGACO_SIGNALS_TOKEN: + dissect_megaco_signaldescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree); + break; + case MEGACO_SERVICES_TOKEN: + dissect_megaco_servicechangedescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_STATS_TOKEN: + dissect_megaco_statisticsdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_ERROR_TOKEN: + dissect_megaco_errordescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_EVENTS_TOKEN: + dissect_megaco_eventsdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree); + break; + case MEGACO_AUDIT_TOKEN: + dissect_megaco_auditdescriptor(tvb, descriptor_tree, pinfo, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_DIGITMAP_TOKEN: + dissect_megaco_digitmapdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_OE_TOKEN: + /* ObservedEventsToken */ + dissect_megaco_observedeventsdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree); + break; + case MEGACO_TOPOLOGY_TOKEN: + dissect_megaco_topologydescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + case MEGACO_PACKAGES_TOKEN: + dissect_megaco_Packagesdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset); + break; + default: + tokenlen = (tvb_RBRKT+1) - tvb_previous_offset; + proto_tree_add_expert(descriptor_tree, pinfo, &ei_megaco_no_descriptor, tvb, tvb_previous_offset, tokenlen); + break; + } + + tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT, tvb_len, ','); + if (tvb_current_offset == -1 || tvb_descriptors_end_offset < tvb_current_offset){ + tvb_current_offset = tvb_descriptors_end_offset; + } + tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1); + tvb_LBRKT = tvb_previous_offset; + tvb_RBRKT = tvb_previous_offset; + + } while ( tvb_current_offset < tvb_descriptors_end_offset ); + +} + /* Copied from MGCP dissector, prints whole message in raw text */ static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree){ gint tvb_linebegin,tvb_lineend,linelen; + proto_tree* text_tree; tvb_linebegin = 0; - proto_tree_add_text(tree, tvb, 0, -1,"-------------- (RAW text output) ---------------"); + if (tree) { + text_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_megaco_raw_text, NULL, "-------------- (RAW text output) ---------------"); - do { - linelen = tvb_find_line_end(tvb,tvb_linebegin,-1,&tvb_lineend,FALSE); - proto_tree_add_text(tree, tvb, tvb_linebegin, linelen, - "%s", tvb_format_text_wsp(tvb,tvb_linebegin, - linelen)); - tvb_linebegin = tvb_lineend; - } while (tvb_offset_exists(tvb, tvb_lineend) && linelen > 0); + do { + linelen = tvb_find_line_end(tvb,tvb_linebegin,-1,&tvb_lineend,FALSE); + proto_tree_add_format_wsp_text(text_tree, tvb, tvb_linebegin, linelen); + tvb_linebegin = tvb_lineend; + } while (tvb_offset_exists(tvb, tvb_lineend) && linelen > 0); + } } /* @@ -3259,26 +3224,19 @@ static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree){ */ static gint megaco_tvb_skip_wsp(tvbuff_t* tvb, gint offset ){ gint counter = offset; - gint end,tvb_len; - guint8 tempchar; - tvb_len = tvb_reported_length(tvb); - end = tvb_len; + gint end = tvb_reported_length(tvb); for(counter = offset; counter < end && - ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' || - tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter++); + (g_ascii_isspace(tvb_get_guint8(tvb,counter))); counter++); return (counter); } static gint megaco_tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){ gint counter = offset; - gint end; - guint8 tempchar; - end = 0; + gint end = 0; for(counter = offset; counter > end && - ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' || - tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--); + (g_ascii_isspace(tvb_get_guint8(tvb,counter))); counter--); counter++; return (counter); } @@ -3312,6 +3270,21 @@ static gint megaco_tvb_find_token(tvbuff_t* tvb, gint offset, gint maxlength){ } } +static void +megaco_fmt_content( gchar *result, guint32 context ) +{ + switch(context) + { + case CHOOSE_CONTEXT: + case ALL_CONTEXTS: + case NULL_CONTEXT: + g_strlcpy(result, val_to_str_const(context, megaco_context_vals, "Unknown"), ITEM_LABEL_LENGTH); + break; + default: + g_snprintf( result, ITEM_LABEL_LENGTH, "%d", context); + } +} + void proto_register_megaco(void) { @@ -3329,42 +3302,44 @@ proto_register_megaco(void) #endif { &hf_megaco_command, { "Command", "megaco.command", FT_STRING, BASE_NONE, NULL, 0x0, - "Command of this message", HFILL }}, + NULL, HFILL }}, + { &hf_megaco_command_optional, + { "Optional Command", "megaco.command_optional", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_wildcard_response, + { "Wildcarded response to a command", "megaco.wildcard_response", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_Context, - { "Context", "megaco.context", FT_STRING, BASE_NONE, NULL, 0x0, + { "Context", "megaco.context", FT_UINT32, BASE_CUSTOM, CF_FUNC(megaco_fmt_content), 0x0, "Context ID of this message", HFILL }}, { &hf_megaco_digitmap_descriptor, { "DigitMap Descriptor", "megaco.digitmap", FT_STRING, BASE_NONE, NULL, 0x0, "DigitMap Descriptor of the megaco Command", HFILL }}, { &hf_megaco_error_descriptor, - { "ERROR Descriptor", "megaco.error", FT_STRING, BASE_NONE, NULL, 0x0, + { "ERROR Descriptor", "megaco.error", FT_NONE, BASE_NONE, NULL, 0x0, "Error Descriptor of the megaco Command", HFILL }}, - { &hf_megaco_error_Frame, - { "ERROR frame", "megaco.error_frame", FT_STRING, BASE_NONE, NULL, 0x0, - "Syntax error", HFILL }}, + { &hf_megaco_error_code, + { "ERROR Code", "megaco.error_code", FT_UINT32, BASE_DEC, VALS(MEGACO_error_code_vals), 0x0, + "Error Code of the megaco Command", HFILL }}, + { &hf_megaco_error_string, + { "ERROR String", "megaco.error_string", FT_STRING, BASE_NONE, NULL, 0x0, + "Error String of the megaco Command", HFILL }}, { &hf_megaco_Event_Buffer_Control, { "Event Buffer Control", "megaco.eventbuffercontrol", FT_STRING, BASE_NONE, NULL, 0x0, "Event Buffer Control in Termination State Descriptor", HFILL }}, -#if 0 { &hf_megaco_events_descriptor, - { "Events Descriptor", "megaco.events", FT_STRING, BASE_NONE, NULL, 0x0, + { "Events Descriptor", "megaco.events", FT_NONE, BASE_NONE, NULL, 0x0, "Events Descriptor of the megaco Command", HFILL }}, -#endif -#if 0 { &hf_megaco_Local_descriptor, - { "Local Descriptor", "megaco.localdescriptor", FT_STRING, BASE_NONE, NULL, 0x0, + { "Local Descriptor", "megaco.localdescriptor", FT_NONE, BASE_NONE, NULL, 0x0, "Local Descriptor in Media Descriptor", HFILL }}, -#endif -#if 0 { &hf_megaco_LocalControl_descriptor, - { "Local Control Descriptor", "megaco.localcontroldescriptor", FT_STRING, BASE_NONE, NULL, 0x0, + { "Local Control Descriptor", "megaco.localcontroldescriptor", FT_NONE, BASE_NONE, NULL, 0x0, "Local Control Descriptor in Media Descriptor", HFILL }}, -#endif -#if 0 { &hf_megaco_media_descriptor, - { "Media Descriptor", "megaco.media", FT_STRING, BASE_NONE, NULL, 0x0, + { "Media Descriptor", "megaco.media", FT_NONE, BASE_NONE, NULL, 0x0, "Media Descriptor of the megaco Command", HFILL }}, -#endif { &hf_megaco_modem_descriptor, { "Modem Descriptor", "megaco.modem", FT_STRING, BASE_NONE, NULL, 0x0, "Modem Descriptor of the megaco Command", HFILL }}, @@ -3374,11 +3349,9 @@ proto_register_megaco(void) { &hf_megaco_multiplex_descriptor, { "Multiplex Descriptor", "megaco.multiplex", FT_STRING, BASE_NONE, NULL, 0x0, "Multiplex Descriptor of the megaco Command", HFILL }}, -#if 0 { &hf_megaco_observedevents_descriptor, - { "Observed Events Descriptor", "megaco.observedevents", FT_STRING, BASE_NONE, NULL, 0x0, + { "Observed Events Descriptor", "megaco.observedevents", FT_NONE, BASE_NONE, NULL, 0x0, "Observed Events Descriptor of the megaco Command", HFILL }}, -#endif { &hf_megaco_packages_descriptor, { "Packages Descriptor", "megaco.packagesdescriptor", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, @@ -3400,8 +3373,41 @@ proto_register_megaco(void) { "h324/muxtbl_out", "megaco.h324_muxtbl_out", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_megaco_ds_dscp, - { "ds/dscp", "megaco.ds_dscp", FT_STRING, BASE_NONE, NULL, 0x0, - "ds/dscp Differentiated Services Code Point", HFILL }}, + { "Differentiated Services Code Point", "megaco.ds_dscp", FT_UINT32, BASE_HEX|BASE_EXT_STRING, &dscp_vals_ext, 0x0, + NULL, HFILL }}, + { &hf_megaco_gm_saf, + { "Remote Source Address Filtering", "megaco.gm_saf", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_gm_sam, + { "Remote Source Address Mask", "megaco.gm_sam", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_gm_spf, + { "Remote Source Port Filtering", "megaco.gm_spf", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_gm_spr, + { "Remote Source Port Range", "megaco.gm_spr", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_gm_esas, + { "Explicit Source Address Setting", "megaco.gm_esas", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_tman_pol, + { "Policing", "megaco.tman_pol", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_tman_sdr, + { "Sustainable Data Rate", "megaco.tman_sdr", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_tman_mbs, + { "Maximum Burst Rate", "megaco.tman_mbs", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_tman_pdr, + { "Peak Data Rate", "megaco.tman_pdr", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_tman_dvt, + { "Delay Variation Tolerance", "megaco.tman_dvt", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_megaco_ipdc_realm, + { "IP Realm Identifier", "megaco.ipdc_realm", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, { &hf_megaco_h324_h223capr, { "h324/h223capr", "megaco.h324_h223capr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, @@ -3409,7 +3415,7 @@ proto_register_megaco(void) { "Reserve Value", "megaco.reservevalue", FT_STRING, BASE_NONE, NULL, 0x0, "Reserve Value on or off", HFILL }}, { &hf_megaco_requestid, - { "RequestID", "megaco.requestid", FT_STRING, BASE_NONE, NULL, 0x0, + { "RequestID", "megaco.requestid", FT_UINT32, BASE_DEC, NULL, 0x0, "RequestID in Events or Observedevents Descriptor", HFILL }}, #if 0 { &hf_megaco_servicechange_descriptor, @@ -3419,25 +3425,21 @@ proto_register_megaco(void) { &hf_megaco_Service_State, { "Service State", "megaco.servicestates", FT_STRING, BASE_NONE, NULL, 0x0, "Service States in Termination State Descriptor", HFILL }}, -#if 0 { &hf_megaco_signal_descriptor, - { "Signal Descriptor", "megaco.signal", FT_STRING, BASE_NONE, NULL, 0x0, + { "Signal Descriptor", "megaco.signal", FT_NONE, BASE_NONE, NULL, 0x0, "Signal Descriptor of the megaco Command", HFILL }}, -#endif { &hf_megaco_statistics_descriptor, - { "Statistics Descriptor", "megaco.statistics", FT_STRING, BASE_NONE, NULL, 0x0, + { "Statistics Descriptor", "megaco.statistics", FT_NONE, BASE_NONE, NULL, 0x0, "Statistics Descriptor of the megaco Command", HFILL }}, { &hf_megaco_streamid, - { "StreamID", "megaco.streamid", FT_STRING, BASE_NONE, NULL, 0x0, + { "StreamID", "megaco.streamid", FT_UINT32, BASE_DEC, NULL, 0x0, "StreamID in the Media Descriptor", HFILL }}, { &hf_megaco_termid, { "Termination ID", "megaco.termid", FT_STRING, BASE_NONE, NULL, 0x0, "Termination ID of this Command", HFILL }}, -#if 0 { &hf_megaco_TerminationState_descriptor, - { "Termination State Descriptor", "megaco.terminationstate", FT_STRING, BASE_NONE, NULL, 0x0, + { "Termination State Descriptor", "megaco.terminationstate", FT_NONE, BASE_NONE, NULL, 0x0, "Termination State Descriptor in Media Descriptor", HFILL }}, -#endif { &hf_megaco_topology_descriptor, { "Topology Descriptor", "megaco.topology", FT_STRING, BASE_NONE, NULL, 0x0, "Topology Descriptor of the megaco Command", HFILL }}, @@ -3445,7 +3447,7 @@ proto_register_megaco(void) { "Transaction", "megaco.transaction", FT_STRING, BASE_NONE, NULL, 0x0, "Message Originator", HFILL }}, { &hf_megaco_transid, - { "Transaction ID", "megaco.transid", FT_STRING, BASE_NONE, NULL, 0x0, + { "Transaction ID", "megaco.transid", FT_UINT32, BASE_DEC, NULL, 0x0, "Transaction ID of this message", HFILL }}, { &hf_megaco_mId, { "MediagatewayID", "megaco.mId", FT_STRING, BASE_NONE, NULL, 0x0, @@ -3453,11 +3455,12 @@ proto_register_megaco(void) { &hf_megaco_version, { "Version", "megaco.version", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, -#if 0 + { &hf_megaco_start, + { "Start token", "megaco.start_token", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, { &hf_megaco_h245, - { "h245", "megaco.h245", FT_STRING, BASE_NONE, NULL, 0x0, + { "h245", "megaco.h245", FT_NONE, BASE_NONE, NULL, 0x0, "Embedded H.245 message", HFILL }}, -#endif { &hf_megaco_h223Capability, { "h223Capability", "megaco.h245.h223Capability", FT_NONE, BASE_NONE, NULL, 0, "megaco.h245.H223Capability", HFILL }}, @@ -3473,6 +3476,8 @@ proto_register_megaco(void) &ett_megaco_context, &ett_megaco_command_line, &ett_megaco_descriptors, + &ett_megaco_raw_text, + &ett_megaco_error_descriptor, &ett_megaco_mediadescriptor, &ett_megaco_TerminationState, &ett_megaco_Remotedescriptor, @@ -3480,6 +3485,7 @@ proto_register_megaco(void) &ett_megaco_LocalControldescriptor, &ett_megaco_auditdescriptor, &ett_megaco_eventsdescriptor, + &ett_megaco_statisticsdescriptor, &ett_megaco_observedeventsdescriptor, &ett_megaco_observedevent, &ett_megaco_packagesdescriptor, @@ -3495,6 +3501,9 @@ proto_register_megaco(void) { &ei_megaco_parse_error, { "megaco.parse_error", PI_MALFORMED, PI_ERROR, "Parse error", EXPFILL }}, { &ei_megaco_error_descriptor_transaction_list, { "megaco.error_descriptor_transaction_list.invalid", PI_MALFORMED, PI_ERROR, "Sorry, can't understand errorDescriptor / transactionList", EXPFILL }}, { &ei_megaco_audit_descriptor, { "megaco.audit.malformed", PI_MALFORMED, PI_ERROR, "Badly constructed audit descriptor (no { )", EXPFILL }}, + { &ei_megaco_signal_descriptor, { "megaco.signal_descriptor.empty", PI_PROTOCOL, PI_NOTE, "Empty Signal Descriptor", EXPFILL }}, + { &ei_megaco_no_command, { "megaco.no_command", PI_PROTOCOL, PI_WARN, "No Command detectable", EXPFILL }}, + { &ei_megaco_no_descriptor, { "megaco.no_descriptor", PI_PROTOCOL, PI_WARN, "No Descriptor detectable", EXPFILL }}, }; module_t *megaco_module; |