/epan/dissectors/packet-megaco.c
C | 3664 lines | 2589 code | 639 blank | 436 comment | 452 complexity | d1120d55ed35d3d68e137e2bcfb78ea8 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /* packet-megaco.c
- * Routines for megaco packet disassembly
- * RFC 3015
- *
- * $Id$
- *
- * Christian Falckenberg, 2002/10/17
- * Copyright (c) 2002 by Christian Falckenberg
- * <christian.falckenberg@nortelnetworks.com>
- *
- * Christoph Wiest, 2003/06/28
- * Modified 2003 by Christoph Wiest
- * <ch.wiest@tesionmail.de>
- * Modified 2004 by Anders Broman
- * <anders.broman@ericsson.com>
- * To handle TPKT headers if over TCP
- * Modified 2005 by Karl Knoebl
- * <karl.knoebl@siemens.com>
- * provide info to COL_INFO and some "prettification"
- *
- * Copyright (c) 2006 Anders Broman <anders.broman@ericsson.com>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1999 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #include "config.h"
- #include <stdlib.h>
- #include <ctype.h>
- #include <glib.h>
- #include <epan/packet.h>
- #include <epan/wmem/wmem.h>
- #include <epan/addr_resolv.h>
- #include <epan/prefs.h>
- #include <epan/strutil.h>
- #include <epan/sctpppids.h>
- #include <epan/dissectors/packet-tpkt.h>
- #include <epan/asn1.h>
- #include <epan/dissectors/packet-per.h>
- #include <epan/dissectors/packet-h245.h>
- #include <epan/dissectors/packet-ip.h>
- #include <epan/dissectors/packet-ber.h>
- #include <epan/gcp.h>
- #include <epan/tap.h>
- #define PORT_MEGACO_TXT 2944
- #define PORT_MEGACO_BIN 2945
- /* Define the megaco proto */
- static int proto_megaco = -1;
- /* Define headers for megaco */
- 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_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_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_topology_descriptor = -1;
- static int hf_megaco_error_descriptor = -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_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;
- 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_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_h223Capability = -1;
- static int hf_megaco_audititem = -1;
- /* Define the trees for megaco */
- static int ett_megaco = -1;
- static int ett_megaco_message = -1;
- static int ett_megaco_message_body = -1;
- 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_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_observedeventsdescriptor = -1;
- static int ett_megaco_observedevent = -1;
- static int ett_megaco_packagesdescriptor = -1;
- static int ett_megaco_requestedevent = -1;
- static int ett_megaco_signalsdescriptor = -1;
- static int ett_megaco_requestedsignal = -1;
- 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 dissector_handle_t megaco_text_handle;
- static int megaco_tap = -1;
- /*
- * Here are the global variables associated with
- * the various user definable characteristics of the dissection
- *
- * MEGACO has two kinds of message formats: text and binary
- *
- * global_megaco_raw_text determines whether we are going to display
- * the raw text of the megaco message, much like the HTTP dissector does.
- *
- * global_megaco_dissect_tree determines whether we are going to display
- * a detailed tree that expresses a somewhat more semantically meaningful
- * decode.
- */
- static guint global_megaco_txt_sctp_port = PORT_MEGACO_TXT;
- static guint global_megaco_txt_tcp_port = PORT_MEGACO_TXT;
- static guint global_megaco_txt_udp_port = PORT_MEGACO_TXT;
- #if 0
- static guint global_megaco_bin_sctp_port = PORT_MEGACO_BIN;
- static guint global_megaco_bin_tcp_port = PORT_MEGACO_BIN;
- static guint global_megaco_bin_udp_port = PORT_MEGACO_BIN;
- #endif
- static gboolean global_megaco_raw_text = TRUE;
- static gboolean global_megaco_dissect_tree = TRUE;
- /* 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
- * are written in the same style.
- *
- */
- 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);
- 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);
- static void
- dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
- 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);
- static void
- dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
- static void
- tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
- static void
- dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
- static gint
- megaco_tvb_find_token(tvbuff_t* tvb, gint offset, gint maxlenght);
- static dissector_handle_t data_handle;
- static dissector_handle_t sdp_handle;
- static dissector_handle_t h245_handle;
- static dissector_handle_t h248_handle;
- 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
- *
- */
- static void dissect_megaco_text_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
- {
- int lv_tpkt_len;
- /* This code is copied from the Q.931 dissector, some parts skipped.
- * Check whether this looks like a TPKT-encapsulated
- * MEGACO packet.
- *
- * The minimum length of a MEGACO message is 6?:
- * Re-assembly ?
- */
- lv_tpkt_len = is_tpkt(tvb, 6);
- if (lv_tpkt_len == -1) {
- /*
- * It's not a TPKT packet;
- * Is in MEGACO ?
- */
- dissect_megaco_text(tvb, pinfo, tree);
- }
- dissect_tpkt_encap(tvb, pinfo, tree, TRUE,
- megaco_text_handle);
- }
- #define ERRORTOKEN 1
- #define TRANSTOKEN 2
- #define REPLYTOKEN 3
- #define PENDINGTOKEN 4
- #define RESPONSEACKTOKEN 5
- typedef struct {
- const char *name;
- const char *compact_name;
- } megaco_tokens_t;
- static const megaco_tokens_t megaco_messageBody_names[] = {
- { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
- { "Error", "ER" }, /* 1 */
- { "Transaction", "T" }, /* 2 */
- { "Reply", "P" }, /* 3 */
- { "Pending", "PN" }, /* 4 */
- { "TransactionResponseAck", "K" }, /* 5 */
- };
- /* Returns index of megaco_tokens_t */
- static gint find_megaco_messageBody_names(tvbuff_t *tvb, int offset, guint header_len)
- {
- guint i;
- for (i = 1; i < array_length(megaco_messageBody_names); i++) {
- if (header_len == strlen(megaco_messageBody_names[i].name) &&
- tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].name, header_len) == 0)
- return i;
- if (megaco_messageBody_names[i].compact_name != NULL &&
- header_len == strlen(megaco_messageBody_names[i].compact_name) &&
- tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].compact_name, header_len) == 0)
- return i;
- }
- return -1;
- }
- static proto_item *
- my_proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
- gint start, gint length, const char *value)
- {
- proto_item *pi;
- pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
- if (!global_megaco_dissect_tree) {
- PROTO_ITEM_SET_HIDDEN(pi);
- }
- return(pi);
- }
- /*
- * dissect_megaco_text - The dissector for the MEGACO Protocol, using
- * text encoding.
- */
- static void
- 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 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;
- guint8 word[7];
- guint8 TermID[30];
- guint8 tempchar;
- gint tvb_RBRKT, tvb_LBRKT, RBRKT_counter, LBRKT_counter;
- guint token_index=0;
- guint32 dword;
- guchar needle;
- guint8 first;
- gcp_msg_t* msg = NULL;
- gcp_trx_t* trx = NULL;
- gcp_ctx_t* ctx = NULL;
- gcp_cmd_t* cmd = NULL;
- gcp_term_t* term = NULL;
- gcp_trx_type_t trx_type = GCP_TRX_NONE;
- guint32 trx_id = 0;
- 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;
- top_tree=tree;
- /* Initialize variables */
- tvb_len = tvb_length(tvb);
- megaco_tree = NULL;
- ti = NULL;
- tvb_offset = 0;
- tvb_next_offset = 0;
- RBRKT_counter = 0;
- LBRKT_counter = 0;
- /* Check if H.248 in otp(Erlang) internal format
- * XXX Needs improvement?
- * Ref:
- * http://www.erlang.org/doc/apps/megaco/part_frame.html
- * 4.1 Internal form of messages
- * 4.2 The different encodings
- */
- dword = tvb_get_ntoh24(tvb,0);
- if ((dword == 0x836803)&&(h248_otp_handle)){
- call_dissector(h248_otp_handle, tvb, pinfo, tree);
- return;
- }
- msg = gcp_msg(pinfo, tvb_raw_offset(tvb), keep_persistent_data);
- /*
- * Check to see whether we're really dealing with MEGACO by looking
- * for the "MEGACO" string or a "!".This needs to be improved when supporting
- * 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.
- *
- * tvb_offset = tvb_find_guint8(tvb, tvb_offset, 5, 'M');
- */
- if(!tvb_get_nstringz0(tvb,tvb_offset,sizeof(word),word)) return;
- if (g_ascii_strncasecmp(word, "MEGACO", 6) != 0 && tvb_get_guint8(tvb, tvb_offset ) != '!'){
- gint8 ber_class;
- gboolean pc;
- gint32 tag;
- dissector_handle_t handle = data_handle;
- get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
- if (ber_class == BER_CLASS_UNI && pc && tag == BER_UNI_TAG_SEQUENCE ) {
- handle = h248_handle;
- }
- call_dissector(handle,tvb,pinfo,tree);
- return;
- }
- /* Display MEGACO in protocol column */
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "MEGACO");
- /* Build the info tree if we've been given a root */
- /* Create megaco subtree */
- ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, ENC_NA);
- megaco_tree = proto_item_add_subtree(ti, ett_megaco);
- /* Format of 'message' is = MegacopToken SLASH Version SEP mId SEP messageBody */
- /* MegacopToken = "MEGACO" or "!" */
- /* According to H248.1-200205 Annex B Text encoding ( protocol version 2 ) */
- /* Find version */
- tvb_previous_offset = tvb_find_guint8(tvb, 0,
- tvb_len, '/');
- if (tvb_previous_offset == -1) {
- expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
- "Sorry, no \"/\" in the MEGACO header, I can't parse this packet");
- return;
- }
- /* skip / */
- tvb_previous_offset++;
- /* assume at least one digit in version */
- tvb_current_offset = tvb_previous_offset + 1;
- if (isdigit(tvb_get_guint8(tvb, tvb_current_offset))) {
- /* 2-digit version */
- tvb_current_offset++;
- }
- tokenlen = tvb_current_offset - tvb_previous_offset;
- ver_offset = tvb_previous_offset;
- ver_length = tokenlen;
- tvb_previous_offset = tvb_current_offset;
- tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
- if (tvb_previous_offset == tvb_current_offset) {
- expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
- "[ Parse error: missing SEP in MEGACO header ]");
- return;
- }
- tvb_previous_offset = tvb_current_offset;
- /* mId should follow here,
- * mId = (( domainAddress / domainName ) [":" portNumber]) / mtpAddress / deviceName
- * domainAddress = "[" (IPv4address / IPv6address) "]"
- * domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /".") ">"
- * mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT
- * MTPToken = ("MTP")
- * deviceName = pathNAME
- * pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )["@" pathDomainName ]
- */
- tvb_current_offset = tvb_pbrk_guint8(tvb, tvb_current_offset, -1, " \t\r\n", &needle);
- if (tvb_current_offset == -1) {
- expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
- "[ Parse error: no body in MEGACO message (missing SEP after mId) ]");
- 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_text(megaco_tree, tvb, line_start_offset, tokenlen,
- "%s",tvb_format_text(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_ASCII|ENC_NA);
- proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, ENC_ASCII|ENC_NA);
- }else{
- hidden_item = proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, ENC_ASCII|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_ASCII|ENC_NA);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- }
- }
- col_clear(pinfo->cinfo, COL_INFO);
- first = 1;
- do{
- tvb_previous_offset = tvb_next_offset;
- /* Next part is
- * : messageBody = ( errorDescriptor / transactionList )
- * errorDescriptor = ErrorToken EQUAL ErrorCode LBRKT [quotedString] RBRKT
- * ErrorToken = ("Error" / "ER")
- *
- * transactionList = 1*( transactionRequest / transactionReply /
- * transactionPending / transactionResponseAck )
- *
- * transactionResponseAck = ResponseAckToken LBRKT
- * transactionAck*(COMMA transactionAck) RBRKT
- * ResponseAckToken = ("TransactionResponseAck"/ "K")
- *
- * transactionPending = PendingToken EQUAL TransactionID LBRKT RBRKT
- * PendingToken = ("Pending" / "PN")
- *
- * transactionReply = ReplyToken EQUAL TransactionID LBRKT
- * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
- * ReplyToken = ("Reply" / "P")
- *
- * transactionRequest = TransToken EQUAL TransactionID LBRKT
- * actionRequest *(COMMA actionRequest) RBRKT
- * TransToken = ("Transaction" / "T")
- */
- /* Find token length */
- for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_len-1; tvb_offset++){
- if (!isalpha(tvb_get_guint8(tvb, tvb_offset ))){
- break;
- }
- }
- tokenlen = tvb_offset - tvb_previous_offset;
- token_index = find_megaco_messageBody_names(tvb, tvb_previous_offset, tokenlen);
- /* Debug code
- g_warning("token_index %u",token_index);
- */
- tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
- tvb_current_offset = tvb_LBRKT;
- tvb_transaction_end_offset = megaco_tvb_find_token(tvb, tvb_LBRKT - 1, tvb_len);
- switch ( token_index ){
- /* errorDescriptor */
- case ERRORTOKEN:
- col_set_str(pinfo->cinfo, COL_INFO, "Error ");
- tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_len); /*tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');*/
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
- "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset));
- message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
- if (tree) {
- my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
- tvb_previous_offset, tokenlen,
- "Error" );
- tvb_command_start_offset = tvb_previous_offset;
- dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_len-1, tvb_command_start_offset);
- }
- return;
- /* transactionResponseAck
- * transactionResponseAck = ResponseAckToken LBRKT transactionAck
- * *(COMMA transactionAck) RBRKT
- * transactionAck = transactionID / (transactionID "-" transactionID)
- */
- case RESPONSEACKTOKEN:
- tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
- tvb_offset = tvb_LBRKT;
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset,
- "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset+1));
- message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
- my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
- tvb_previous_offset, tokenlen,
- "TransactionResponseAck" );
- tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
- tvb_current_offset = tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');
- /*tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_transaction_end_offset);*/
- 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));
- 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));
- 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:
- tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1;
- 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;
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
- "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
- message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
- 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));
- if(tree)
- my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
- tvb_offset, len,
- tvb_format_text(tvb,tvb_offset,len));
- return;
- /* transactionReply */
- case REPLYTOKEN:
- trx_type = GCP_TRX_REPLY;
- tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset,
- "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset+1));
- message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
- if (tree)
- my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
- tvb_previous_offset, tokenlen,
- "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);
- if(tree)
- my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
- tvb_offset, len, tvb_format_text(tvb,tvb_offset,len));
- /* Find if we have a errorDescriptor or actionReplyList */
- tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
- tempchar = tvb_get_guint8(tvb,tvb_offset);
- if ((tempchar == 'E')||(tempchar == 'e')){
- dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_transaction_end_offset-1, tvb_offset);
- return;
- }
- /* Offset should be at first printable char after { */
- tvb_previous_offset = tvb_offset;
- break;
- case TRANSTOKEN:
- /* TransactionRequest */
- trx_type = GCP_TRX_REQUEST;
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
- "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
- message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
- 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));
- /* 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, PI_MALFORMED, PI_ERROR,
- "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;
- } /* end switch */
- /* Only these remains now
- * transactionReply = ReplyToken EQUAL TransactionID LBRKT
- * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
- * ReplyToken = ("Reply" / "P")
- *
- * errorDescriptor = ErrorToken EQUAL ErrorCode
- * LBRKT [quotedString] RBRKT
- *
- * transactionRequest = TransToken EQUAL TransactionID LBRKT
- * actionRequest *(COMMA actionRequest) RBRKT
- * TransToken = ("Transaction" / "T")
- */
- trx = gcp_trx(msg , trx_id , trx_type, keep_persistent_data);
- /* Find Context */
- nextcontext:
- tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '{');
- ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1,
- "%s", tvb_format_text(tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1));
- megaco_context_tree = proto_item_add_subtree(ti, ett_megaco_context);
- 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, PI_MALFORMED, PI_ERROR, "[ Parse error: Invalid offset ]");
- return;
- }
- tvb_current_offset = tvb_next_offset;
- tokenlen = tvb_current_offset - tvb_previous_offset;
- tempchar = tvb_get_guint8(tvb, tvb_previous_offset );
- if (tvb_get_guint8(tvb, tvb_current_offset-1 ) == ' '){
- 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));
- }
- ctx = gcp_ctx(msg,trx,ctx_id,keep_persistent_data);
- /* Find Commands */
- /* If Transaction is is Request, Reply or Pending */
- tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
- tvb_command_end_offset = tvb_command_start_offset;
- tvb_LBRKT = tvb_command_start_offset;
- tvb_RBRKT = tvb_command_start_offset;
- /* The following loop find the individual contexts, commands and call the for every Descriptor a subroutine */
- do {
- tvb_command_end_offset = tvb_find_guint8(tvb, tvb_command_end_offset +1,
- tvb_transaction_end_offset, ',');
- if ( tvb_command_end_offset == -1 || tvb_command_end_offset > tvb_transaction_end_offset){
- tvb_command_end_offset = tvb_transaction_end_offset ;
- }
- /* checking how many left brackets are before the next comma */
- while ( tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') != -1
- && (tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') < tvb_command_end_offset)){
- tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
- tvb_transaction_end_offset, '{');
- LBRKT_counter++;
- }
- /* checking how many right brackets are before the next comma */
- while ( (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') != -1 )
- && (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') <= tvb_command_end_offset)
- && LBRKT_counter != 0){
- tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
- tvb_transaction_end_offset, '}');
- RBRKT_counter++;
- }
- /* If equal or more right brackets before the comma, one command is complete */
- if ( LBRKT_counter <= RBRKT_counter ){
- tvb_current_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
- tvb_transaction_end_offset, '{');
- /* includes no descriptors */
- if ( LBRKT_counter == 0 ){
- tvb_current_offset = tvb_command_end_offset;
- /* the last command in a context */
- if ( tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') < tvb_current_offset
- && tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') != -1){
- tvb_previous_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
- tvb_transaction_end_offset, '}');
- len = tvb_previous_offset - tvb_command_start_offset;
- tvb_previous_offset = megaco_tvb_skip_wsp_return(tvb, tvb_previous_offset -1);
- tokenlen = tvb_previous_offset - tvb_command_start_offset;
- }
- /* not the last command in a context*/
- else{
- len = tvb_current_offset - tvb_command_start_offset;
- tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
- tokenlen = tvb_current_offset - tvb_command_start_offset;
- }
- }
- /* command includes descriptors */
- else{
- len = tvb_current_offset - tvb_command_start_offset;
- tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
- tokenlen = tvb_current_offset - tvb_command_start_offset;
- }
- /* if a next context is specified */
- if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'C'){
- tvb_current_offset = tvb_command_start_offset;
- tvb_previous_offset = tvb_command_start_offset;
- LBRKT_counter = 0;
- RBRKT_counter = 0;
- goto nextcontext;
- }
- sub_ti = proto_tree_add_text(megaco_tree, tvb, tvb_command_start_offset, len+1,
- "%s", tvb_format_text(tvb, tvb_command_start_offset, len+1));
- megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
- /* 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_ASCII|ENC_NA);
- megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
- */
- tvb_next_offset = tvb_command_start_offset + tokenlen;
- /* Try to dissect Topology Descriptor before the command */
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
- if ( (tempchar >= 'a')&& (tempchar <= 'z')){
- tempchar = tempchar - 0x20;
- }
- if ( tempchar == 'T') {
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- if ( tempchar == 'P' || tempchar == 'O'){
- gint tvb_topology_end_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}');
- if ( tvb_topology_end_offset == -1 ){
- expert_add_info_format(pinfo, sub_ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"}\" ]");
- return;
- }
- tvb_command_start_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');
- if ( tvb_command_start_offset == -1 ){
- expert_add_info_format(pinfo, sub_ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"{\" ]");
- return;
- }
- dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_topology_end_offset-1, tvb_command_start_offset+1);
- /* Command after Topology Descriptor */
- tvb_command_start_offset = tvb_find_guint8(tvb, tvb_topology_end_offset + 1,
- tvb_transaction_end_offset, ',');
- if ( tvb_command_start_offset == -1 ){
- /* No Command present after Topology Descriptor */
- break;
- } else {
- /* Try to find the first char of the command */
- tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_start_offset + 1);
- tvb_next_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');
- continue;
- }
- }
- }
- /* 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" );
- 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" );
- 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, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"=\" ]");
- return;
- }
- tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_offset -1);
- tokenlen = tvb_offset - tvb_command_start_offset;
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- if ( tempchar != 'E' ){
- /* Short form used */
- if ( tvb_get_guint8(tvb, 0 ) == '!'){
- switch ( tempchar ){
- case 'A':
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- switch ( tempchar ){
- case 'V':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
- case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; 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,
- "AuditValue");
- col_append_str(pinfo->cinfo, COL_INFO, " AuditValue");
- break;
- case 'C':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
- 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");
- col_append_str(pinfo->cinfo, COL_INFO, " AuditCapability");
- break;
- default:
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
- case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_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,
- "Add");
- col_append_str(pinfo->cinfo, COL_INFO, " Add");
- break;
- }
- break;
- case 'N':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
- case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_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,
- "Notify");
- col_append_str(pinfo->cinfo, COL_INFO, " Notify");
- break;
- case 'M':
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- switch ( tempchar ){
- case 'F':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
- case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_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,
- "Modify");
- col_append_str(pinfo->cinfo, COL_INFO, " Modify");
- break;
- case 'V':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
- 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");
- col_append_str(pinfo->cinfo, COL_INFO, " Move");
- break;
- }
- break;
- case 'P':
- cmd_type = GCP_CMD_NONE;
- /*
- PackagesToken = ("Packages" / "PG")
- PendingToken = ("Pending" / "PN")
- PriorityToken = ("Priority" / "PR")
- ProfileToken = ("Profile" / "PF")
- */
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- switch ( tempchar ){
- case 'G':
- my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
- tvb_command_start_offset, tokenlen,
- "Packages");
- break;
- case 'N':
- my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
- tvb_command_start_offset, tokenlen,
- "Pending");
- break;
- case 'R':
- my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
- tvb_command_start_offset, tokenlen,
- "Priority");
- break;
- case 'F':
- my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
- tvb_command_start_offset, tokenlen,
- "Profile");
- break;
- }
- break;
- case 'S':
- tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
- if ( (tempchar >= 'a')&& (tempchar <= 'z'))
- tempchar = tempchar - 0x20;
- switch ( tempchar ){
- case 'C':
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
- 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");
- break;
- default:
- switch(trx_type) {
- case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
- 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");
- col_append_str(pinfo->cinfo, COL_INFO, " Subtract");
- break;
- }
- break;
- default:
- {
- proto_item *item;
- tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
- tvb_ensure_bytes_exist(tvb, tvb_previous_offset, tokenlen);
- item = proto_tree_add_string(m…
Large files files are truncated, but you can click here to view the full file