2 * Routines for megaco packet disassembly
7 * Christian Falckenberg, 2002/10/17
8 * Copyright (c) 2002 by Christian Falckenberg
9 * <christian.falckenberg@nortelnetworks.com>
11 * Christoph Wiest, 2003/06/28
12 * Modified 2003 by Christoph Wiest
13 * <ch.wiest@tesionmail.de>
14 * Modifyed 2004 by Anders Broman
15 * <anders.broman@ericsson.com>
16 * To handle TPKT headers if over TCP
17 * Modified 2005 by Karl Knoebl
18 * <karl.knoebl@siemens.com>
19 * provide info to COL_INFO and some "prettification"
21 * Copyright (c) 2006 Anders Broman <anders.broman@ericsson.com>
23 * Wireshark - Network traffic analyzer
24 * By Gerald Combs <gerald@wireshark.org>
25 * Copyright 1999 Gerald Combs
27 * This program is free software; you can redistribute it and/or
28 * modify it under the terms of the GNU General Public License
29 * as published by the Free Software Foundation; either version 2
30 * of the License, or (at your option) any later version.
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
54 #include <epan/packet.h>
55 #include <epan/emem.h>
56 #include <epan/addr_resolv.h>
57 #include <epan/prefs.h>
58 #include <epan/strutil.h>
59 #include <epan/sctpppids.h>
60 #include <epan/dissectors/packet-tpkt.h>
61 #include <epan/asn1.h>
62 #include <epan/dissectors/packet-per.h>
63 #include <epan/dissectors/packet-h245.h>
64 #include <epan/dissectors/packet-ip.h>
65 #include <epan/dissectors/packet-ber.h>
70 #define PORT_MEGACO_TXT 2944
71 #define PORT_MEGACO_BIN 2945
73 /* Define the megaco proto */
74 static int proto_megaco = -1;
76 /* Define headers for megaco */
77 static int hf_megaco_version = -1;
78 static int hf_megaco_transaction = -1;
79 static int hf_megaco_transid = -1;
80 static int hf_megaco_Context = -1;
81 static int hf_megaco_command_line = -1;
82 static int hf_megaco_command = -1;
83 static int hf_megaco_termid = -1;
87 /* Define headers in subtree for megaco */
88 static int hf_megaco_modem_descriptor = -1;
89 static int hf_megaco_multiplex_descriptor = -1;
90 static int hf_megaco_media_descriptor = -1;
91 static int hf_megaco_events_descriptor = -1;
92 static int hf_megaco_signal_descriptor = -1;
93 static int hf_megaco_audit_descriptor = -1;
94 static int hf_megaco_servicechange_descriptor = -1;
95 static int hf_megaco_digitmap_descriptor = -1;
96 static int hf_megaco_statistics_descriptor = -1;
97 static int hf_megaco_observedevents_descriptor = -1;
98 static int hf_megaco_topology_descriptor = -1;
99 static int hf_megaco_error_descriptor = -1;
100 static int hf_megaco_TerminationState_descriptor= -1;
101 static int hf_megaco_Remote_descriptor = -1;
102 static int hf_megaco_Local_descriptor = -1;
103 static int hf_megaco_LocalControl_descriptor = -1;
104 static int hf_megaco_packages_descriptor = -1;
105 static int hf_megaco_error_Frame = -1;
106 static int hf_megaco_Service_State = -1;
107 static int hf_megaco_Event_Buffer_Control = -1;
108 static int hf_megaco_mode = -1;
109 static int hf_megaco_reserve_group = -1;
110 static int hf_megaco_h324_muxtbl_in = -1;
111 static int hf_megaco_h324_muxtbl_out = -1;
112 static int hf_megaco_ds_dscp = -1;
113 static int hf_megaco_h324_h223capr = -1;
114 static int hf_megaco_reserve_value = -1;
115 static int hf_megaco_streamid = -1;
116 static int hf_megaco_requestid = -1;
117 static int hf_megaco_pkgdname = -1;
118 static int hf_megaco_mId = -1;
119 static int hf_megaco_h245 = -1;
120 static int hf_megaco_h223Capability = -1;
121 static int hf_megaco_audititem = -1;
123 /* Define the trees for megaco */
124 static int ett_megaco = -1;
125 static int ett_megaco_message = -1;
126 static int ett_megaco_message_body = -1;
127 static int ett_megaco_context = -1;
128 static int ett_megaco_command_line = -1;
129 static int ett_megaco_mediadescriptor = -1;
130 static int ett_megaco_descriptors = -1;
131 static int ett_megaco_TerminationState = -1;
132 static int ett_megaco_Localdescriptor = -1;
133 static int ett_megaco_Remotedescriptor = -1;
134 static int ett_megaco_LocalControldescriptor = -1;
135 static int ett_megaco_auditdescriptor = -1;
136 static int ett_megaco_eventsdescriptor = -1;
137 static int ett_megaco_observedeventsdescriptor = -1;
138 static int ett_megaco_observedevent = -1;
139 static int ett_megaco_packagesdescriptor = -1;
140 static int ett_megaco_requestedevent = -1;
141 static int ett_megaco_signalsdescriptor = -1;
142 static int ett_megaco_requestedsignal = -1;
143 static int ett_megaco_h245 = -1;
145 static gcp_hf_ett_t megaco_ctx_ids = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}};
147 static dissector_handle_t megaco_text_handle;
149 static int megaco_tap = -1;
152 * Here are the global variables associated with
153 * the various user definable characteristics of the dissection
155 * MEGACO has two kinds of message formats: text and binary
157 * global_megaco_raw_text determines whether we are going to display
158 * the raw text of the megaco message, much like the HTTP dissector does.
160 * global_megaco_dissect_tree determines whether we are going to display
161 * a detailed tree that expresses a somewhat more semantically meaningful
164 static guint global_megaco_txt_tcp_port = PORT_MEGACO_TXT;
165 static guint global_megaco_txt_udp_port = PORT_MEGACO_TXT;
167 static guint global_megaco_bin_tcp_port = PORT_MEGACO_BIN;
168 static guint global_megaco_bin_udp_port = PORT_MEGACO_BIN;
170 static gboolean global_megaco_raw_text = TRUE;
171 static gboolean global_megaco_dissect_tree = TRUE;
173 /* Some basic utility functions that are specific to this dissector */
174 static gint megaco_tvb_skip_wsp(tvbuff_t* tvb, gint offset);
175 static gint megaco_tvb_skip_wsp_return(tvbuff_t* tvb, gint offset);
177 * The various functions that either dissect some
178 * subpart of MEGACO. These aren't really proto dissectors but they
179 * are written in the same style.
183 dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset);
185 dissect_megaco_modemdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
187 dissect_megaco_multiplexdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
189 dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset);
191 dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
193 dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
195 dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset);
197 dissect_megaco_servicechangedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
199 dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
201 dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
203 dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
205 dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
207 dissect_megaco_errordescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
209 dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
211 dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset);
213 dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset);
215 dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
217 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
219 dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
221 static dissector_handle_t data_handle;
222 static dissector_handle_t sdp_handle;
223 static dissector_handle_t h245_handle;
224 static dissector_handle_t h248_handle;
225 static dissector_handle_t h248_otp_handle;
227 static gboolean keep_persistent_data = FALSE;
229 static proto_tree *top_tree;
231 * dissect_megaco_text over TCP, there will be a TPKT header there
234 static void dissect_megaco_text_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
238 /* This code is copied from the Q.931 dissector, some parts skipped.
239 * Check whether this looks like a TPKT-encapsulated
242 * The minimum length of a MEGACO message is 6?:
245 lv_tpkt_len = is_tpkt(tvb, 6);
246 if (lv_tpkt_len == -1) {
248 * It's not a TPKT packet;
251 dissect_megaco_text(tvb, pinfo, tree);
253 dissect_tpkt_encap(tvb, pinfo, tree, TRUE,
260 #define PENDINGTOKEN 4
261 #define RESPONSEACKTOKEN 5
265 const char *compact_name;
268 static const megaco_tokens_t megaco_messageBody_names[] = {
269 { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
270 { "Error", "ER" }, /* 1 */
271 { "Transaction", "T" }, /* 2 */
272 { "Reply", "P" }, /* 3 */
273 { "Pending", "PN" }, /* 4 */
274 { "TransactionResponseAck", "K" }, /* 5 */
277 /* Returns index of megaco_tokens_t */
278 static gint find_megaco_messageBody_names(tvbuff_t *tvb, int offset, guint header_len)
282 for (i = 1; i < array_length(megaco_messageBody_names); i++) {
283 if (header_len == strlen(megaco_messageBody_names[i].name) &&
284 tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].name, header_len) == 0)
286 if (megaco_messageBody_names[i].compact_name != NULL &&
287 header_len == strlen(megaco_messageBody_names[i].compact_name) &&
288 tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].compact_name, header_len) == 0)
296 my_proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
297 gint start, gint length, const char *value)
301 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
302 if (!global_megaco_dissect_tree) {
303 PROTO_ITEM_SET_HIDDEN(pi);
309 * dissect_megaco_text - The dissector for the MEGACO Protocol, using
313 dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
316 gint tvb_offset,tvb_current_offset,tvb_previous_offset,tvb_next_offset,tokenlen;
317 gint line_start_offset, ver_offset, ver_length, mId_offset, mId_length;
318 gint tvb_command_start_offset, tvb_command_end_offset;
319 gint tvb_descriptors_start_offset, tvb_descriptors_end_offset;
320 proto_tree *megaco_tree, *message_tree, *message_body_tree, *megaco_context_tree, *megaco_tree_command_line, *ti, *sub_ti;
325 gint tvb_RBRKT, tvb_LBRKT, RBRKT_counter, LBRKT_counter;
329 gcp_msg_t* msg = NULL;
330 gcp_trx_t* trx = NULL;
331 gcp_ctx_t* ctx = NULL;
332 gcp_cmd_t* cmd = NULL;
333 gcp_term_t* term = NULL;
334 gcp_trx_type_t trx_type = GCP_TRX_NONE;
337 gcp_cmd_type_t cmd_type = GCP_CMD_NONE;
338 gcp_wildcard_t wild_term = GCP_WILDCARD_NONE;
339 proto_item *hidden_item;
342 /* Initialize variables */
343 tvb_len = tvb_length(tvb);
346 tvb_previous_offset = 0;
347 tvb_current_offset = 0;
350 tvb_command_start_offset = 0;
351 tvb_command_end_offset = 0;
357 /* Check if H.248 in otp(Erlang) internal format
358 * XXX Needs improvment?
360 * http://www.erlang.org/doc/apps/megaco/part_frame.html
361 * 4.1 Internal form of messages
362 * 4.2 The different encodings
364 dword = tvb_get_ntoh24(tvb,0);
365 if ((dword == 0x836803)&&(h248_otp_handle)){
366 call_dissector(h248_otp_handle, tvb, pinfo, tree);
370 msg = gcp_msg(pinfo, TVB_RAW_OFFSET(tvb), keep_persistent_data);
373 * Check to see whether we're really dealing with MEGACO by looking
374 * for the "MEGACO" string or a "!".This needs to be improved when supporting
375 * binary encodings. Bugfix add skipping of leading spaces.
377 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
378 line_start_offset = tvb_offset;
379 /* Quick fix for MEGACO not following the RFC, hopfully not breaking any thing
380 * Turned out to be TPKT in case of TCP, added some code to handle that.
382 * tvb_offset = tvb_find_guint8(tvb, tvb_offset, 5, 'M');
384 if(!tvb_get_nstringz0(tvb,tvb_offset,sizeof(word),word)) return;
389 if (g_ascii_strncasecmp(word, "MEGACO", 6) != 0 && tvb_get_guint8(tvb, tvb_offset ) != '!'){
393 dissector_handle_t handle = data_handle;
395 get_ber_identifier(tvb, 0, &class, &pc, &tag);
397 if (class == BER_CLASS_UNI && pc && tag == BER_UNI_TAG_SEQUENCE ) {
398 handle = h248_handle;
401 call_dissector(handle,tvb,pinfo,tree);
407 /* Display MEGACO in protocol column */
408 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MEGACO");
410 /* Build the info tree if we've been given a root */
411 /* Create megaco subtree */
412 ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, FALSE);
413 megaco_tree = proto_item_add_subtree(ti, ett_megaco);
415 /* Format of 'message' is = MegacopToken SLASH Version SEP mId SEP messageBody */
416 /* MegacopToken = "MEGACO" or "!" */
417 /* According to H248.1-200205 Annex B Text encoding ( protocol version 2 ) */
420 tvb_previous_offset = tvb_find_guint8(tvb, 0,
422 if (tvb_previous_offset == -1) {
423 proto_tree_add_text(megaco_tree, tvb, 0, -1,
424 "Sorry, no \"/\" in the MEGACO header, I can't parse this packet");
427 tvb_previous_offset = tvb_previous_offset + 1;
428 /* As version should follow /, just add 1, works till ver 9 */
429 tvb_current_offset = tvb_previous_offset + 1;
432 tokenlen = tvb_current_offset - tvb_previous_offset;
433 ver_offset = tvb_previous_offset;
434 ver_length = tokenlen;
436 /* Pos of version + 2 should take us past version + SEP */
438 tvb_previous_offset = tvb_previous_offset + 2;
439 /* in case of CRLF */
440 if (tvb_get_guint8(tvb, tvb_current_offset ) == '\n')
441 tvb_previous_offset++;
442 if (tvb_get_guint8(tvb, tvb_current_offset ) == '\r')
443 tvb_previous_offset++;
445 /* mId should follow here,
446 * mId = (( domainAddress / domainName ) [":" portNumber]) / mtpAddress / deviceName
447 * domainAddress = "[" (IPv4address / IPv6address) "]"
448 * domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /".") ">"
449 * mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT
451 * deviceName = pathNAME
452 * pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )["@" pathDomainName ]
455 tokenlen = tvb_find_line_end( tvb, tvb_previous_offset, -1, &tvb_next_offset, FALSE);
456 /* accept white spaces as SEParator too */
457 if ( (tvb_current_offset=tvb_find_guint8(tvb, tvb_previous_offset, tokenlen, ' ')) != -1 ) {
458 /* SEP after mID might be spaces only */
459 tokenlen = tvb_current_offset-tvb_previous_offset;
460 tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset);
463 /* Att this point we should point to the "\n" ending the mId element
464 * or to the next character after white space SEP
466 mId_offset = tvb_previous_offset;
467 mId_length = tokenlen;
469 /* Add the first line to the tree */
470 tokenlen = tvb_next_offset - line_start_offset;
471 ti = proto_tree_add_text(megaco_tree, tvb, line_start_offset, tokenlen,
472 "%s",tvb_format_text(tvb,line_start_offset,tokenlen));
473 message_tree = proto_item_add_subtree(ti, ett_megaco_message);
475 if(global_megaco_dissect_tree){
476 proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, FALSE);
477 proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, FALSE);
479 hidden_item = proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, FALSE);
480 PROTO_ITEM_SET_HIDDEN(hidden_item);
481 hidden_item = proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, FALSE);
482 PROTO_ITEM_SET_HIDDEN(hidden_item);
486 tvb_previous_offset = tvb_next_offset;
489 * : messageBody = ( errorDescriptor / transactionList )
490 * errorDescriptor = ErrorToken EQUAL ErrorCode LBRKT [quotedString] RBRKT
491 * ErrorToken = ("Error" / "ER")
493 * transactionList = 1*( transactionRequest / transactionReply /
494 * transactionPending / transactionResponseAck )
496 * transactionResponseAck = ResponseAckToken LBRKT
497 * transactionAck*(COMMA transactionAck) RBRKT
498 * ResponseAckToken = ("TransactionResponseAck"/ "K")
500 * transactionPending = PendingToken EQUAL TransactionID LBRKT RBRKT
501 * PendingToken = ("Pending" / "PN")
503 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
504 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
505 * ReplyToken = ("Reply" / "P")
507 * transactionRequest = TransToken EQUAL TransactionID LBRKT
508 * actionRequest *(COMMA actionRequest) RBRKT
509 * TransToken = ("Transaction" / "T")
511 tempchar = tvb_get_guint8(tvb, tvb_previous_offset);
512 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
513 tempchar = tempchar - 0x20;
515 /* Find token length */
516 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_len-1; tvb_offset++){
517 if (!isalpha(tvb_get_guint8(tvb, tvb_offset ))){
521 tokenlen = tvb_offset - tvb_previous_offset;
522 token_index = find_megaco_messageBody_names(tvb, tvb_previous_offset, tokenlen);
524 g_warning("token_index %u",token_index);
527 switch ( token_index ){
528 /* errorDescriptor */
530 if (check_col(pinfo->cinfo, COL_INFO) )
531 col_set_str(pinfo->cinfo, COL_INFO, "Error ");
533 tvb_current_offset = tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');
535 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
536 "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
537 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
540 my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
541 tvb_previous_offset, tokenlen,
544 tvb_command_start_offset = tvb_previous_offset;
545 dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_len-1, tvb_command_start_offset);
548 /* transactionResponseAck
549 * transactionResponseAck = ResponseAckToken LBRKT transactionAck
550 * *(COMMA transactionAck) RBRKT
551 * transactionAck = transactionID / (transactionID "-" transactionID)
553 case RESPONSEACKTOKEN:
554 trx_type = GCP_TRX_ACK;
555 tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
556 tvb_offset = tvb_LBRKT;
557 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset,
558 "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset+1));
559 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
561 my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
562 tvb_previous_offset, tokenlen,
563 "TransactionResponseAck" );
565 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
566 tvb_current_offset = tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');
567 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset)-1; /* cut last RBRKT */
568 len = tvb_current_offset - tvb_previous_offset;
570 if (check_col(pinfo->cinfo, COL_INFO) )
571 col_add_fstr(pinfo->cinfo, COL_INFO, "%s TransactionResponseAck",
572 tvb_format_text(tvb,tvb_previous_offset,len));
574 trx_id = strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
577 my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
578 tvb_previous_offset, len,
579 tvb_format_text(tvb,tvb_previous_offset,len));
581 if(global_megaco_raw_text){
582 tvb_raw_text_add(tvb, megaco_tree);
584 tvb_previous_offset = tvb_LBRKT +1;
586 /* Pe and PN is transactionPending, P+"any char" is transactionReply */
588 trx_type = GCP_TRX_PENDING;
590 tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_len, '=')+1;
591 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
592 tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
593 tvb_current_offset = tvb_LBRKT;
594 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
595 "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
596 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
598 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
599 len = tvb_current_offset - tvb_offset;
601 my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
602 tvb_previous_offset, tokenlen,
605 if (check_col(pinfo->cinfo, COL_INFO) )
606 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Pending",
607 tvb_format_text(tvb,tvb_offset,len));
608 trx_id = strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
611 my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
613 tvb_format_text(tvb,tvb_offset,len));
616 /* transactionReply */
618 trx_type = GCP_TRX_REPLY;
619 tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
620 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset,
621 "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset+1));
622 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
625 my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
626 tvb_previous_offset, tokenlen,
629 tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_len, '=')+1;
630 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
631 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1);
632 len = tvb_current_offset - tvb_offset;
634 if (check_col(pinfo->cinfo, COL_INFO) )
635 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Reply ",
636 tvb_format_text(tvb,tvb_offset,len));
637 trx_id = strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
640 my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
641 tvb_offset, len, tvb_format_text(tvb,tvb_offset,len));
643 /* Find if we have a errorDescriptor or actionReplyList */
644 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
645 tempchar = tvb_get_guint8(tvb,tvb_offset);
646 if ((tempchar == 'E')||(tempchar == 'e')){
647 dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_len-1, tvb_offset);
650 /* Offset should be at first printarable char after { */
651 tvb_previous_offset = tvb_offset;
654 /* TransactionRequest */
655 trx_type = GCP_TRX_REQUEST;
656 tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
657 tvb_current_offset = tvb_LBRKT;
658 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
659 "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
660 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
663 my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
664 tvb_previous_offset, tokenlen,
666 tvb_offset = tvb_find_guint8(tvb, tvb_offset, tvb_len, '=')+1;
667 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
668 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
669 len = tvb_current_offset - tvb_offset;
670 if (check_col(pinfo->cinfo, COL_INFO) )
671 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request",
672 tvb_format_text(tvb,tvb_offset,len));
673 trx_id = strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
675 my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, tvb_offset,len,
676 tvb_format_text(tvb,tvb_offset,len));
677 /* Offset should be at first printarable char after { */
678 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
682 ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, FALSE);
683 megaco_tree = proto_item_add_subtree(ti, ett_megaco);
684 proto_tree_add_text(megaco_tree, tvb, 0, -1,
685 "Sorry, can't understand errorDescriptor / transactionList = %s, can't parse it pos %u",
686 tvb_format_text(tvb,tvb_previous_offset,2),tvb_previous_offset);
689 /* Only these remains now
690 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
691 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
692 * ReplyToken = ("Reply" / "P")
694 * errorDescriptor = ErrorToken EQUAL ErrorCode
695 * LBRKT [quotedString] RBRKT
697 * transactionRequest = TransToken EQUAL TransactionID LBRKT
698 * actionRequest *(COMMA actionRequest) RBRKT
699 * TransToken = ("Transaction" / "T")
702 trx = gcp_trx(msg , trx_id , trx_type, keep_persistent_data);
710 tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_len, '{');
711 ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1,
712 "%s", tvb_format_text(tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1));
713 megaco_context_tree = proto_item_add_subtree(ti, ett_megaco_context);
715 tvb_previous_offset = tvb_find_guint8(tvb, tvb_current_offset,
717 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
718 if (tvb_current_offset >= tvb_next_offset) {
719 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Invalid offset ]");
722 tvb_current_offset = tvb_next_offset;
725 tokenlen = tvb_current_offset - tvb_previous_offset;
726 tempchar = tvb_get_guint8(tvb, tvb_previous_offset );
728 if (tvb_get_guint8(tvb, tvb_current_offset-1 ) == ' '){
735 ctx_id = CHOOSE_CONTEXT;
736 my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
737 tvb_previous_offset, 1,
739 if (check_col(pinfo->cinfo, COL_INFO) )
740 col_append_str(pinfo->cinfo, COL_INFO, " |=Choose one");
743 ctx_id = ALL_CONTEXTS;
744 my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
745 tvb_previous_offset, 1,
747 if (check_col(pinfo->cinfo, COL_INFO) )
748 col_append_str(pinfo->cinfo, COL_INFO, " |=All");
751 ctx_id = NULL_CONTEXT;
752 proto_tree_add_text(megaco_context_tree, tvb, tvb_previous_offset, tokenlen, "Context: NULL" );
753 if (check_col(pinfo->cinfo, COL_INFO) )
754 col_append_str(pinfo->cinfo, COL_INFO, " |=NULL");
757 my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
758 tvb_previous_offset, tokenlen,
759 tvb_format_text(tvb, tvb_previous_offset,
761 ctx_id = strtoul(tvb_format_text(tvb, tvb_previous_offset, tokenlen),NULL,10);
763 if (check_col(pinfo->cinfo, COL_INFO) )
764 col_append_fstr(pinfo->cinfo, COL_INFO, " |=%s",tvb_format_text(tvb, tvb_previous_offset,tokenlen));
767 ctx = gcp_ctx(msg,trx,ctx_id,keep_persistent_data);
771 /* If Transaction is is Request, Reply or Pending */
772 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
773 tvb_command_end_offset = tvb_command_start_offset;
775 tvb_LBRKT = tvb_command_start_offset;
776 tvb_RBRKT = tvb_command_start_offset;
778 /* The following loop find the individual contexts, commands and call the for every Descriptor a subroutine */
781 tvb_command_end_offset = tvb_find_guint8(tvb, tvb_command_end_offset +1,
784 if ( tvb_command_end_offset == -1 ){
785 tvb_command_end_offset = tvb_len;
789 /* checking how many left brackets are before the next comma */
791 while ( tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_len, '{') != -1
792 && (tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_len, '{') < tvb_command_end_offset)){
794 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
800 /* checking how many right brackets are before the next comma */
802 while ( (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_len, '}') != -1 )
803 && (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_len, '}') < tvb_command_end_offset)
804 && LBRKT_counter != 0){
806 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
813 /* If equal or more right brackets before the comma, one command is complete */
815 if ( LBRKT_counter <= RBRKT_counter ){
817 tvb_current_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
821 /* includes no descriptors */
823 if ( LBRKT_counter == 0 ){
825 tvb_current_offset = tvb_command_end_offset;
827 /* the last command in a context */
829 if ( tvb_find_guint8(tvb, tvb_command_start_offset, tvb_len, '}') < tvb_current_offset
830 && tvb_find_guint8(tvb, tvb_command_start_offset, tvb_len, '}') != -1){
832 tvb_previous_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
835 len = tvb_previous_offset - tvb_command_start_offset;
837 tvb_previous_offset = megaco_tvb_skip_wsp_return(tvb, tvb_previous_offset -1);
839 tokenlen = tvb_previous_offset - tvb_command_start_offset;
843 /* not the last command in a context*/
846 len = tvb_current_offset - tvb_command_start_offset;
847 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
849 tokenlen = tvb_current_offset - tvb_command_start_offset;
853 /* command includes descriptors */
856 len = tvb_current_offset - tvb_command_start_offset;
857 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
859 tokenlen = tvb_current_offset - tvb_command_start_offset;
862 /* if a next context is specified */
864 if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'C'){
865 tvb_current_offset = tvb_command_start_offset;
866 tvb_previous_offset = tvb_command_start_offset;
872 sub_ti = proto_tree_add_text(megaco_tree, tvb, tvb_command_start_offset, len+1,
873 "%s", tvb_format_text(tvb, tvb_command_start_offset, len+1));
874 megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
875 /* creation of the megaco_tree_command_line additionally Command and Transaction ID will be printed in this line */
876 /* Changed to use the lines above. this code is saved if there is complaints
877 sub_ti = proto_tree_add_item(megaco_tree,hf_megaco_command_line,tvb,tvb_command_start_offset,tokenlen, FALSE);
878 megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
881 tvb_next_offset = tvb_command_start_offset + tokenlen;
883 /* Try to dissect Topology Descriptor before the command */
884 if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'T') {
885 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
887 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
888 tempchar = tempchar - 0x20;
890 if ( tempchar == 'P' || tempchar == 'O'){
891 gint tvb_topology_end_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_len, '}');
892 if ( tvb_topology_end_offset == -1 ){
893 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Missing \"}\" ]");
897 tvb_command_start_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_len, '{');
898 if ( tvb_command_start_offset == -1 ){
899 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Missing \"{\" ]");
902 dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_topology_end_offset-1, tvb_command_start_offset+1);
904 /* Command after Topology Descriptor */
905 tvb_command_start_offset = tvb_find_guint8(tvb, tvb_topology_end_offset + 1,
908 if ( tvb_command_start_offset == -1 ){
909 /* No Command present after Topology Descriptor */
913 /* Try to find the first char of the command */
914 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_start_offset + 1);
915 tvb_next_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_len, '{');
922 /* Additional value */
924 if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'O'){
926 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "O- indicates an optional command" );
927 tvb_command_start_offset = tvb_command_start_offset+2;
931 /* Additional value */
933 if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'W'){
935 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "W- indicates a wildcarded response to a command" );
936 tvb_command_start_offset = tvb_command_start_offset+2;
942 tvb_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
944 if (tvb_offset == -1 ) {
945 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Missing \"=\" ]");
948 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_offset -1);
949 tokenlen = tvb_offset - tvb_command_start_offset;
951 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
952 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
953 tempchar = tempchar - 0x20;
955 if ( tempchar != 'E' ){
957 if ( tvb_get_guint8(tvb, 0 ) == '!'){
963 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
964 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
965 tempchar = tempchar - 0x20;
971 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
972 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; break;
973 default: cmd_type = GCP_CMD_NONE; break;
976 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
977 tvb_command_start_offset, tokenlen,
979 if (check_col(pinfo->cinfo, COL_INFO) )
980 col_append_str(pinfo->cinfo, COL_INFO, " AuditValue");
985 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
986 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break;
987 default: cmd_type = GCP_CMD_NONE; break;
989 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
990 tvb_command_start_offset, tokenlen,
992 if (check_col(pinfo->cinfo, COL_INFO) )
993 col_append_str(pinfo->cinfo, COL_INFO, " AuditCapability");
998 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
999 case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_REPLY; break;
1000 default: cmd_type = GCP_CMD_NONE; break;
1003 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1004 tvb_command_start_offset, tokenlen,
1006 if (check_col(pinfo->cinfo, COL_INFO) )
1007 col_append_str(pinfo->cinfo, COL_INFO, " Add");
1014 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
1015 case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_REPLY; break;
1016 default: cmd_type = GCP_CMD_NONE; break;
1019 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1020 tvb_command_start_offset, tokenlen,
1022 if (check_col(pinfo->cinfo, COL_INFO) )
1023 col_append_str(pinfo->cinfo, COL_INFO, " Notify");
1028 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
1029 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1030 tempchar = tempchar - 0x20;
1032 switch ( tempchar ){
1035 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
1036 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_REPLY; break;
1037 default: cmd_type = GCP_CMD_NONE; break;
1040 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1041 tvb_command_start_offset, tokenlen,
1043 if (check_col(pinfo->cinfo, COL_INFO) )
1044 col_append_str(pinfo->cinfo, COL_INFO, " Modify");
1049 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
1050 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break;
1051 default: cmd_type = GCP_CMD_NONE; break;
1053 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1054 tvb_command_start_offset, tokenlen,
1056 if (check_col(pinfo->cinfo, COL_INFO) )
1057 col_append_str(pinfo->cinfo, COL_INFO, " Move");
1063 cmd_type = GCP_CMD_NONE;
1065 PackagesToken = ("Packages" / "PG")
1066 PendingToken = ("Pending" / "PN")
1067 PriorityToken = ("Priority" / "PR")
1068 ProfileToken = ("Profile" / "PF")
1070 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
1071 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1072 tempchar = tempchar - 0x20;
1074 switch ( tempchar ){
1076 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1077 tvb_command_start_offset, tokenlen,
1081 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1082 tvb_command_start_offset, tokenlen,
1086 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1087 tvb_command_start_offset, tokenlen,
1091 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1092 tvb_command_start_offset, tokenlen,
1099 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
1100 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1101 tempchar = tempchar - 0x20;
1103 switch ( tempchar ){
1107 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
1108 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break;
1109 default: cmd_type = GCP_CMD_NONE; break;
1111 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1112 tvb_command_start_offset, tokenlen,
1118 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
1119 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
1120 default: cmd_type = GCP_CMD_NONE; break;
1122 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1123 tvb_command_start_offset, tokenlen,
1125 if (check_col(pinfo->cinfo, COL_INFO) )
1126 col_append_str(pinfo->cinfo, COL_INFO, " Subtract");
1132 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1133 tvb_ensure_bytes_exist(tvb, tvb_previous_offset, tokenlen);
1134 proto_tree_add_string(megaco_tree, hf_megaco_error_Frame, tvb,
1135 tvb_previous_offset, tokenlen,
1136 "No Command detectable !");
1141 gchar* command = tvb_format_text(tvb, tvb_command_start_offset, tokenlen);
1143 if ( g_str_equal(command,"Subtract") ) {
1145 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
1146 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
1147 default: cmd_type = GCP_CMD_NONE; break;
1149 } else if ( g_str_equal(command,"AuditValue") ) {
1151 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
1152 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; break;
1153 default: cmd_type = GCP_CMD_NONE; break;
1155 } else if ( g_str_equal(command,"AuditCapability") ) {
1157 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
1158 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break;
1159 default: cmd_type = GCP_CMD_NONE; break;
1161 } else if ( g_str_equal(command,"Add") ) {
1163 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
1164 case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_REPLY; break;
1165 default: cmd_type = GCP_CMD_NONE; break;
1167 } else if ( g_str_equal(command,"Notify") ) {
1169 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
1170 case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_REPLY; break;
1171 default: cmd_type = GCP_CMD_NONE; break;
1173 } else if ( g_str_equal(command,"Modify") ) {
1175 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
1176 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_REPLY; break;
1177 default: cmd_type = GCP_CMD_NONE; break;
1179 } else if ( g_str_equal(command,"Move") ) {
1181 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
1182 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break;
1183 default: cmd_type = GCP_CMD_NONE; break;
1185 } else if ( g_str_equal(command,"ServiceChange") ) {
1187 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
1188 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break;
1189 default: cmd_type = GCP_CMD_NONE; break;
1191 } else if ( g_str_equal(command,"Subtract") ) {
1193 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
1194 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
1195 default: cmd_type = GCP_CMD_NONE; break;
1199 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_OTHER_REQ; break;
1200 case GCP_TRX_REPLY: cmd_type = GCP_CMD_REPLY; break;
1201 default: cmd_type = GCP_CMD_NONE; break;
1206 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1207 tvb_command_start_offset, tokenlen,
1208 tvb_format_text(tvb, tvb_command_start_offset,
1210 if (check_col(pinfo->cinfo, COL_INFO) )
1211 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",command);
1214 if (cmd_type == GCP_CMD_NONE && trx_type == GCP_TRX_REPLY) {
1215 cmd_type = GCP_CMD_REPLY;
1218 if (cmd_type != GCP_CMD_NONE) {
1219 cmd = gcp_cmd(msg, trx, ctx, cmd_type, tvb_command_start_offset, keep_persistent_data);
1220 tap_queue_packet(megaco_tap, pinfo, cmd);
1223 tvb_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
1225 if (tvb_offset == -1 ) {
1226 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Missing \"=\" ]");
1229 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
1230 tokenlen = tvb_next_offset - tvb_offset;
1231 if (tokenlen+1 <= 0) {
1232 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Invalid token length (%d) ]", tokenlen+1);
1236 tempchar = tvb_get_guint8(tvb, tvb_offset);
1237 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1238 tempchar = tempchar - 0x20;
1240 term = ep_new0(gcp_term_t);
1241 wild_term = GCP_WILDCARD_NONE;
1242 term->type = GCP_TERM_TYPE_UNKNOWN;
1244 switch ( tempchar ){
1247 if ((tokenlen+1 > (int) sizeof(TermID))) {
1248 proto_tree_add_text(megaco_tree, tvb, 0, 0, "[ Parse error: Invalid TermID length (%d) ]", tokenlen+1);
1251 tvb_get_nstringz0(tvb,tvb_offset,tokenlen+1,TermID);
1254 term->len = tokenlen;
1255 term->str = (gchar*)(term->buffer = TermID);
1257 term = gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data);
1260 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1261 tvb_offset, tokenlen,
1266 wild_term = GCP_WILDCARD_ALL;
1268 term->buffer = (guint8*)(term->str = "*");
1270 term = gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data);
1272 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1273 tvb_offset, tokenlen,
1275 if (check_col(pinfo->cinfo, COL_INFO) )
1276 col_append_str(pinfo->cinfo, COL_INFO, "=*");
1280 wild_term = GCP_WILDCARD_CHOOSE;
1283 term->buffer = (term->str = "$");
1285 term = gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data);
1287 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1288 tvb_offset, tokenlen,
1290 if (check_col(pinfo->cinfo, COL_INFO) )
1291 col_append_str(pinfo->cinfo, COL_INFO, "=$");
1296 my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1297 tvb_offset, tokenlen,
1298 tvb_format_text(tvb, tvb_offset,
1301 term->len = tokenlen;
1302 term->buffer = (guint8*)(term->str = tvb_format_text(tvb, tvb_offset, tokenlen));
1304 term = gcp_cmd_add_term(msg, trx, cmd, term, wild_term, keep_persistent_data);
1306 if (check_col(pinfo->cinfo, COL_INFO) )
1307 col_append_fstr(pinfo->cinfo, COL_INFO, "=%s",tvb_format_text(tvb, tvb_offset,tokenlen));
1312 /* Dissect the Descriptors */
1315 if ( LBRKT_counter != 0 && tvb_current_offset != tvb_command_end_offset){
1317 tvb_descriptors_start_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
1320 tvb_descriptors_end_offset = tvb_descriptors_start_offset;
1323 while ( LBRKT_counter > 0 ){
1325 tvb_descriptors_end_offset = tvb_find_guint8(tvb, tvb_descriptors_end_offset+1,
1332 tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
1334 if ( tempchar == 'E'|| tempchar == 'e'){
1335 dissect_megaco_descriptors(tvb, megaco_tree, pinfo, tvb_command_start_offset-1,tvb_descriptors_end_offset);
1338 dissect_megaco_descriptors(tvb, megaco_tree, pinfo, tvb_descriptors_start_offset,tvb_descriptors_end_offset);
1343 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_end_offset +1);
1344 tvb_LBRKT = tvb_command_start_offset;
1345 tvb_RBRKT = tvb_command_start_offset;
1348 } while ( tvb_command_end_offset < tvb_len );
1350 if (keep_persistent_data) {
1351 gcp_msg_to_str(msg,keep_persistent_data);
1352 gcp_analyze_msg(megaco_tree, tvb, msg, &megaco_ctx_ids );
1355 if(global_megaco_raw_text){
1356 tvb_raw_text_add(tvb, megaco_tree);
1360 #define MEGACO_MODEM_TOKEN 1
1361 #define MEGACO_MUX_TOKEN 2
1362 #define MEGACO_MEDIA_TOKEN 3
1363 #define MEGACO_SIGNALS_TOKEN 4
1364 #define MEGACO_SERVICES_TOKEN 5
1365 #define MEGACO_STATS_TOKEN 6
1366 #define MEGACO_ERROR_TOKEN 7
1367 #define MEGACO_EVENTS_TOKEN 8
1368 #define MEGACO_AUDIT_TOKEN 9
1369 #define MEGACO_DIGITMAP_TOKEN 10
1370 #define MEGACO_OE_TOKEN 11
1371 #define MEGACO_TOPOLOGY_TOKEN 12
1372 #define MEGACO_PACKAGES_TOKEN 13
1374 static const megaco_tokens_t megaco_descriptors_names[] = {
1375 { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
1376 { "Modem", "MD" }, /* 1 */
1377 { "Mux", "MX" }, /* 2 */
1378 { "Media", "M" }, /* 3 */
1379 { "Signals", "SG" }, /* 4 */
1380 { "Services", "SV" }, /* 5 */
1381 { "Statistics", "SA" }, /* 6 */
1382 { "Error", "ER" }, /* 7 */
1383 { "Events", "E" }, /* 8 */
1384 { "Audit", "AT" }, /* 9 */
1385 { "DigitMap", "DM" }, /* 10 */
1386 { "ObservedEvents", "OE" }, /* 11 */
1387 { "Topology", "TP" }, /* 12 */
1388 { "Packages", "PG" }, /* 13 */
1391 /* Returns index of megaco_tokens_t */
1392 /* note - also called by dissect_megaco_auditdescriptor */
1393 static gint find_megaco_descriptors_names(tvbuff_t *tvb, int offset, guint header_len)
1397 for (i = 1; i < array_length(megaco_descriptors_names); i++) {
1398 if (header_len == strlen(megaco_descriptors_names[i].name) &&
1399 tvb_strncaseeql(tvb, offset, megaco_descriptors_names[i].name, header_len) == 0)
1401 if (megaco_descriptors_names[i].compact_name != NULL &&
1402 header_len == strlen(megaco_descriptors_names[i].compact_name) &&
1403 tvb_strncaseeql(tvb, offset, megaco_descriptors_names[i].compact_name, header_len) == 0)
1410 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)
1412 gint tvb_len, len, token_index, tvb_offset, temp_offset;
1413 gint tvb_current_offset,tvb_previous_offset,tokenlen;
1414 gint tvb_RBRKT, tvb_LBRKT, RBRKT_counter, LBRKT_counter;
1415 tvb_len = tvb_length(tvb);
1425 tvb_LBRKT = megaco_tvb_skip_wsp(tvb, tvb_descriptors_start_offset +1);
1427 tvb_previous_offset = tvb_LBRKT;
1428 tvb_RBRKT = tvb_descriptors_start_offset;
1433 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
1435 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT,
1438 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset,
1441 if (tvb_current_offset == -1 ){
1442 tvb_current_offset = tvb_descriptors_end_offset;
1445 if (tvb_current_offset <= tvb_previous_offset) {
1446 proto_tree_add_text(megaco_tree_command_line, tvb, 0, 0, "[ Parse error: Invalid offset ]");
1452 /* Descriptor includes no parameters */
1454 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
1456 if ( tvb_current_offset > tvb_RBRKT ){
1457 tvb_current_offset = tvb_RBRKT;
1460 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
1463 /* Descriptor includes Parameters */
1464 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
1466 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
1469 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
1471 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
1472 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_len, '}');
1477 /* Find token length */
1478 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_len-1; tvb_offset++){
1479 if (!isalpha(tvb_get_guint8(tvb, tvb_offset ))){
1483 tokenlen = tvb_offset - tvb_previous_offset;
1484 token_index = find_megaco_descriptors_names(tvb, tvb_previous_offset, tokenlen);
1485 switch ( token_index ){
1486 case MEGACO_MODEM_TOKEN:
1487 dissect_megaco_modemdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1489 case MEGACO_MUX_TOKEN:
1490 dissect_megaco_multiplexdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1492 case MEGACO_MEDIA_TOKEN:
1493 /*TODO: Move tis to the top when all branches fixed !!!*/
1494 temp_offset = tvb_find_guint8(tvb, tvb_previous_offset,tvb_len, '{');
1495 tokenlen = temp_offset - tvb_previous_offset+1;
1496 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen,
1497 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
1499 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, temp_offset +1);
1500 dissect_megaco_mediadescriptor(tvb, megaco_tree_command_line, pinfo, tvb_RBRKT, tvb_previous_offset);
1502 case MEGACO_SIGNALS_TOKEN:
1503 dissect_megaco_signaldescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1505 case MEGACO_SERVICES_TOKEN:
1506 dissect_megaco_servicechangedescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1508 case MEGACO_STATS_TOKEN:
1509 dissect_megaco_statisticsdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1511 case MEGACO_ERROR_TOKEN:
1512 dissect_megaco_errordescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1514 case MEGACO_EVENTS_TOKEN:
1515 dissect_megaco_eventsdescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1517 case MEGACO_AUDIT_TOKEN:
1518 dissect_megaco_auditdescriptor(tvb, megaco_tree_command_line, pinfo, tvb_RBRKT, tvb_previous_offset);
1520 case MEGACO_DIGITMAP_TOKEN:
1521 dissect_megaco_digitmapdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1523 case MEGACO_OE_TOKEN:
1524 /* ObservedEventsToken */
1525 dissect_megaco_observedeventsdescriptor(tvb, pinfo, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1527 case MEGACO_TOPOLOGY_TOKEN:
1528 dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1530 case MEGACO_PACKAGES_TOKEN:
1531 dissect_megaco_Packagesdescriptor(tvb, megaco_tree_command_line, tvb_RBRKT, tvb_previous_offset);
1534 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1535 proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_Frame, tvb,
1536 tvb_previous_offset, tokenlen,
1537 "No Descriptor detectable !");
1541 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1543 tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT, tvb_len, ',');
1544 if (tvb_current_offset == -1 ){
1545 tvb_current_offset = tvb_descriptors_end_offset;
1547 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
1548 tvb_LBRKT = tvb_previous_offset;
1549 tvb_RBRKT = tvb_previous_offset;
1551 } while ( tvb_current_offset < tvb_descriptors_end_offset );
1556 dissect_megaco_modemdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
1565 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1566 proto_tree_add_string(megaco_tree_command_line, hf_megaco_modem_descriptor, tvb,
1567 tvb_previous_offset, tokenlen,
1568 tvb_format_text(tvb, tvb_previous_offset,
1573 dissect_megaco_multiplexdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
1580 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1581 proto_tree_add_string(megaco_tree_command_line, hf_megaco_multiplex_descriptor, tvb,
1582 tvb_previous_offset, tokenlen,
1583 tvb_format_text(tvb, tvb_previous_offset,
1588 /* mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
1589 * MediaToken = ("Media" / "M")
1591 * mediaParm = (streamParm / streamDescriptor /terminationStateDescriptor)
1593 * ; at-most one terminationStateDescriptor
1594 * ; and either streamParm(s) or streamDescriptor(s) but not both
1595 * streamParm = ( localDescriptor / remoteDescriptor /localControlDescriptor )
1596 * localDescriptor = LocalToken LBRKT octetString RBRKT
1597 * LocalToken = ("Local" / "L")
1598 * octetString = *(nonEscapeChar)
1599 * nonEscapeChar = ( "\}" / %x01-7C / %x7E-FF )
1600 * remoteDescriptor = RemoteToken LBRKT octetString RBRKT
1601 * RemoteToken = ("Remote" / "R")
1602 * localControlDescriptor = LocalControlToken LBRKT localParm*(COMMA localParm) RBRKT
1603 * LocalControlToken = ("LocalControl" / "O")
1604 * localParm = ( streamMode / propertyParm / reservedValueMode
1605 * streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm*(COMMA streamParm) RBRKT
1606 * StreamToken = ("Stream" / "ST")
1607 * terminationStateDescriptor = TerminationStateToken LBRKTterminationStateParm
1608 * *( COMMA terminationStateParm ) RBRKT
1609 * TerminationStateToken = ("TerminationState" / "TS")
1610 * terminationStateParm =(propertyParm / serviceStates / eventBufferControl )
1613 #define MEGACO_LOCAL_TOKEN 1
1614 #define MEGACO_REMOTE_TOKEN 2
1615 #define MEGACO_LOCAL_CONTROL_TOKEN 3
1616 #define MEGACO_STREAM_TOKEN 4
1617 #define MEGACO_TERMINATION_STATE_DESC 5
1619 static const megaco_tokens_t megaco_mediaParm_names[] = {
1620 { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
1621 { "Local", "L" }, /* 1 */
1622 { "Remote", "R" }, /* 2 */
1623 { "LocalControl", "O" }, /* 3 */
1624 { "Stream", "ST" }, /* 4 */
1625 { "TerminationState", "TS" }, /* 5 */
1628 /* Returns index of megaco_tokens_t */
1629 static gint find_megaco_mediaParm_names(tvbuff_t *tvb, int offset, guint header_len)
1633 for (i = 1; i < array_length(megaco_mediaParm_names); i++) {
1634 if (header_len == strlen(megaco_mediaParm_names[i].name) &&
1635 tvb_strncaseeql(tvb, offset, megaco_mediaParm_names[i].name, header_len) == 0)
1637 if (megaco_mediaParm_names[i].compact_name != NULL &&
1638 header_len == strlen(megaco_mediaParm_names[i].compact_name) &&
1639 tvb_strncaseeql(tvb, offset, megaco_mediaParm_names[i].compact_name, header_len) == 0)
1647 dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line,packet_info *pinfo, gint tvb_last_RBRKT, gint tvb_previous_offset)
1650 gint tokenlen, tvb_LBRKT, tvb_RBRKT;
1651 gint tvb_next_offset, tvb_current_offset, tvb_offset, equal_offset;
1655 proto_tree *megaco_mediadescriptor_tree, *megaco_mediadescriptor_ti;
1658 tvb_next_offset = 0;
1659 tvb_current_offset = 0;
1663 megaco_mediadescriptor_ti = proto_tree_add_text(megaco_tree_command_line,tvb,tvb_previous_offset,tokenlen,"Media Descriptor");
1664 megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor);
1666 while ( tvb_previous_offset < tvb_last_RBRKT){
1667 /* Start of token */
1668 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
1670 /* Find token length */
1671 for (tvb_next_offset=tvb_current_offset; tvb_next_offset < tvb_last_RBRKT; tvb_next_offset++){
1672 if (!isalpha(tvb_get_guint8(tvb, tvb_next_offset ))){
1676 tokenlen = tvb_next_offset - tvb_current_offset;
1678 mediaParm = find_megaco_mediaParm_names(tvb, tvb_current_offset, tokenlen);
1680 tvb_LBRKT = tvb_find_guint8(tvb, tvb_next_offset , tvb_last_RBRKT, '{');
1681 tvb_next_offset = tvb_find_guint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, '}');
1682 tvb_RBRKT = tvb_next_offset;
1684 tokenlen = tvb_LBRKT - tvb_current_offset +1;
1685 megaco_mediadescriptor_ti = proto_tree_add_text(megaco_tree_command_line,tvb,tvb_current_offset,
1686 tokenlen,"%s",tvb_format_text(tvb, tvb_current_offset,tokenlen));
1688 switch ( mediaParm ){
1689 case MEGACO_LOCAL_TOKEN:
1690 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1691 dissect_megaco_Localdescriptor(tvb,megaco_tree_command_line , pinfo,
1692 tvb_RBRKT, tvb_current_offset);
1693 tvb_current_offset = tvb_RBRKT;
1695 case MEGACO_REMOTE_TOKEN:
1696 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1697 dissect_megaco_Localdescriptor(tvb,megaco_tree_command_line , pinfo,
1698 tvb_RBRKT, tvb_current_offset);
1699 tvb_current_offset = tvb_RBRKT;
1701 case MEGACO_LOCAL_CONTROL_TOKEN:
1702 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1703 dissect_megaco_LocalControldescriptor(tvb,megaco_tree_command_line, pinfo ,
1704 tvb_RBRKT, tvb_current_offset);
1705 tvb_current_offset = tvb_RBRKT;
1707 case MEGACO_STREAM_TOKEN:
1708 megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor);
1710 equal_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_last_RBRKT, '=');
1711 tvb_current_offset = megaco_tvb_skip_wsp(tvb, equal_offset+1);
1712 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1);
1713 tokenlen = tvb_offset - tvb_current_offset;
1715 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_streamid, tvb,
1716 tvb_current_offset, tokenlen, tvb_format_text(tvb, tvb_current_offset,tokenlen));
1717 tvb_previous_offset = tvb_LBRKT+1;
1719 case MEGACO_TERMINATION_STATE_DESC:
1720 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1721 dissect_megaco_TerminationStatedescriptor(tvb,megaco_tree_command_line ,
1722 tvb_RBRKT, tvb_current_offset);
1723 tvb_current_offset = tvb_RBRKT;
1728 /* more parameters ? */
1729 tvb_next_offset = tvb_find_guint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, ',');
1730 if ( tvb_next_offset != -1){
1731 tokenlen = tvb_next_offset - tvb_RBRKT+1;
1732 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_RBRKT, tokenlen,
1733 "%s", tvb_format_text(tvb, tvb_RBRKT, tokenlen));
1734 tvb_previous_offset = tvb_next_offset+1;
1736 /* Add the trailing '}'*/
1737 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_RBRKT, 1,
1738 "%s", tvb_format_text(tvb, tvb_RBRKT, 1));
1739 tvb_previous_offset = tvb_last_RBRKT;
1746 dissect_megaco_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, gint offset, gint len, gchar *msg)
1750 guint8 *buf = ep_alloc(10240);
1752 /*item=proto_tree_add_string(megaco_tree, hf_megaco_h245, tvb,
1755 item = proto_tree_add_text(megaco_tree, tvb, offset, len,
1758 tree = proto_item_add_subtree(item, ett_megaco_h245);
1760 /* arbitrary maximum length */
1765 /* first, skip to where the encoded pdu starts, this is
1766 the first hex digit after the '=' char.
1769 if((*msg==0)||(*msg=='\n')){
1779 if((*msg==0)||(*msg=='\n')){
1782 if( ((*msg>='0')&&(*msg<='9'))
1783 || ((*msg>='a')&&(*msg<='f'))
1784 || ((*msg>='A')&&(*msg<='F'))){
1790 while( ((*msg>='0')&&(*msg<='9'))
1791 ||((*msg>='a')&&(*msg<='f'))
1792 ||((*msg>='A')&&(*msg<='F')) ){
1794 if((*msg>='0')&&(*msg<='9')){
1796 } else if((*msg>='a')&&(*msg<='f')){
1798 } else if((*msg>='A')&&(*msg<='F')){
1805 if((*msg>='0')&&(*msg<='9')){
1807 } else if((*msg>='a')&&(*msg<='f')){
1809 } else if((*msg>='A')&&(*msg<='F')){
1822 h245_tvb = tvb_new_child_real_data(tvb, buf,i,i);
1823 add_new_data_source(pinfo, h245_tvb, "H.245 over MEGACO");
1824 /* should go through a handle, however, the two h245 entry
1825 points are different, one is over tpkt and the other is raw
1827 call_dissector(h245_handle, h245_tvb, pinfo, top_tree);
1828 /* dissect_h245_MultimediaSystemControlMessage(h245_tvb, pinfo, tree);*/
1833 dissect_megaco_h324_h223caprn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, gint offset _U_, gint len, gchar *msg)
1835 guint8 *buf = ep_alloc(10240);
1838 /* arbitrary maximum length */
1843 /* first, skip to where the encoded pdu starts, this is
1844 the first hex digit after the '=' char.
1847 if((*msg==0)||(*msg=='\n')){
1857 if((*msg==0)||(*msg=='\n')){
1860 if( ((*msg>='0')&&(*msg<='9'))
1861 || ((*msg>='a')&&(*msg<='f'))
1862 || ((*msg>='A')&&(*msg<='F'))){
1868 while( ((*msg>='0')&&(*msg<='9'))
1869 ||((*msg>='a')&&(*msg<='f'))
1870 ||((*msg>='A')&&(*msg<='F')) ){
1872 if((*msg>='0')&&(*msg<='9')){
1874 } else if((*msg>='a')&&(*msg<='f')){
1876 } else if((*msg>='A')&&(*msg<='F')){
1883 if((*msg>='0')&&(*msg<='9')){
1885 } else if((*msg>='a')&&(*msg<='f')){
1887 } else if((*msg>='A')&&(*msg<='F')){
1900 h245_tvb = tvb_new_child_real_data(tvb, buf,i,i);
1901 add_new_data_source(pinfo, h245_tvb, "H.245 over MEGACO");
1902 /* should go through a handle, however, the two h245 entry
1903 points are different, one is over tpkt and the other is raw
1905 asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo);
1906 dissect_h245_H223Capability(h245_tvb, 0, &actx, megaco_tree, hf_megaco_h223Capability);
1911 dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
1914 gint tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
1915 gint tvb_events_end_offset, tvb_events_start_offset, tvb_LBRKT;
1916 proto_tree *megaco_eventsdescriptor_tree, *megaco_eventsdescriptor_ti;
1919 gint requested_event_start_offset, requested_event_end_offset;
1920 proto_tree *megaco_requestedevent_tree, *megaco_requestedevent_ti;
1923 tvb_current_offset = 0;
1924 tvb_next_offset = 0;
1925 tvb_help_offset = 0;
1926 tvb_events_end_offset = 0;
1927 tvb_events_start_offset = 0;
1928 tvb_help_offset = 0;
1929 requested_event_start_offset = 0;
1930 requested_event_end_offset = 0;
1932 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1934 megaco_eventsdescriptor_ti = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen,
1935 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
1938 megaco_eventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_events_descriptor,tvb,tvb_previous_offset,tokenlen, FALSE);
1940 megaco_eventsdescriptor_tree = proto_item_add_subtree(megaco_eventsdescriptor_ti, ett_megaco_eventsdescriptor);
1942 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
1943 tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
1945 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
1947 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
1948 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
1950 tokenlen = tvb_help_offset - tvb_current_offset;
1952 proto_tree_add_string(megaco_eventsdescriptor_tree, hf_megaco_requestid, tvb,
1953 tvb_current_offset, tokenlen,
1954 tvb_format_text(tvb, tvb_current_offset,
1957 tvb_events_end_offset = tvb_RBRKT;
1958 tvb_events_start_offset = tvb_previous_offset;
1960 tvb_RBRKT = tvb_next_offset+1;
1961 tvb_LBRKT = tvb_next_offset+1;
1962 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
1967 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
1968 tvb_events_end_offset, '}');
1969 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT,
1970 tvb_events_end_offset, '{');
1972 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset,
1973 tvb_events_end_offset, ',');
1975 if (tvb_current_offset == -1 || tvb_current_offset > tvb_events_end_offset){
1976 tvb_current_offset = tvb_events_end_offset;
1980 /* Descriptor includes no parameters */
1982 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
1984 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
1987 /* Descriptor includes Parameters */
1989 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
1991 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
1993 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
1994 tvb_events_end_offset, '{');
1995 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
1996 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
1997 tvb_events_end_offset, '}');
2002 tvb_help_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_events_end_offset, '{');
2004 /* if there are eventparameter */
2006 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2008 requested_event_start_offset = tvb_help_offset;
2009 requested_event_end_offset = tvb_RBRKT;
2010 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2011 tokenlen = tvb_help_offset - tvb_previous_offset;
2015 tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2018 megaco_requestedevent_ti = proto_tree_add_item(megaco_eventsdescriptor_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,tokenlen, FALSE);
2019 megaco_requestedevent_tree = proto_item_add_subtree(megaco_requestedevent_ti, ett_megaco_requestedevent);
2021 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2023 tvb_help_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1);
2024 tempchar = tvb_get_guint8(tvb, tvb_help_offset);
2026 requested_event_start_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1);
2027 requested_event_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_event_end_offset-1);
2029 if ( tempchar == 'D' || tempchar == 'd'){
2030 dissect_megaco_digitmapdescriptor(tvb, megaco_requestedevent_tree, requested_event_end_offset, requested_event_start_offset);
2035 tokenlen = requested_event_end_offset - requested_event_start_offset;
2036 msg=tvb_format_text(tvb,requested_event_start_offset, tokenlen);
2037 if(!strncmp("h245", msg, 4)){
2038 dissect_megaco_h245(tvb, pinfo, megaco_requestedevent_tree, requested_event_start_offset, tokenlen, msg);
2040 proto_tree_add_text(megaco_requestedevent_tree, tvb, requested_event_start_offset, tokenlen,
2047 tvb_previous_offset = tvb_current_offset;
2048 tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT,
2049 tvb_events_end_offset, ',');
2051 if (tvb_current_offset == -1 || tvb_current_offset > tvb_events_end_offset || tvb_current_offset < tvb_previous_offset ) {
2052 tvb_current_offset = tvb_events_end_offset;
2055 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2057 tvb_LBRKT = tvb_previous_offset;
2058 tvb_RBRKT = tvb_previous_offset;
2060 } while ( tvb_current_offset < tvb_events_end_offset );
2065 dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2068 gint tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2069 gint tvb_signals_end_offset, tvb_signals_start_offset, tvb_LBRKT;
2070 /*proto_tree *megaco_signalsdescriptor_tree, *megaco_signalsdescriptor_ti;*/
2072 gint requested_signal_start_offset, requested_signal_end_offset;
2073 proto_tree *megaco_requestedsignal_tree, *megaco_requestedsignal_ti;
2076 tvb_current_offset = 0;
2077 tvb_next_offset = 0;
2078 tvb_help_offset = 0;
2079 tvb_signals_end_offset = 0;
2080 tvb_signals_start_offset = 0;
2082 requested_signal_start_offset = 0;
2083 requested_signal_end_offset = 0;
2085 tvb_signals_end_offset = tvb_RBRKT;
2086 tvb_signals_start_offset = tvb_previous_offset;
2088 if(toupper(tvb_get_guint8(tvb, tvb_previous_offset+1))=='G')
2089 tokenlen = 2; /* token is compact text (SG) */
2091 tokenlen = 7; /* token must be verbose text (Signals) */
2093 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset+tokenlen);
2095 if(tvb_get_guint8(tvb, tvb_current_offset)!='{') { /* {} has been omitted */
2097 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_signals_start_offset, tokenlen,
2098 "%s", "Empty Signal Descriptor");
2100 if(check_col(pinfo->cinfo, COL_INFO))
2101 col_append_str(pinfo->cinfo, COL_INFO, " (Signal:none)"); /* then say so */
2103 return; /* and return */
2106 tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_signals_end_offset, '{');
2107 tokenlen = (tvb_LBRKT+1) - tvb_signals_start_offset;
2109 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_signals_start_offset, tokenlen,
2110 "%s", tvb_format_text(tvb, tvb_signals_start_offset, tokenlen));
2113 megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_signal_descriptor,tvb,tvb_previous_offset,tokenlen, FALSE);
2114 megaco_signalsdescriptor_tree = proto_item_add_subtree(megaco_signalsdescriptor_ti, ett_megaco_signalsdescriptor);
2117 tvb_current_offset = tvb_LBRKT;
2118 tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2119 if (check_col(pinfo->cinfo, COL_INFO) )
2120 col_append_fstr(pinfo->cinfo, COL_INFO, " (Signal:%s)",tvb_format_text(tvb, tvb_current_offset,tokenlen-tvb_current_offset+tvb_previous_offset));
2123 if ( tvb_current_offset < tvb_signals_end_offset && tvb_current_offset != -1 && tvb_next_offset != tvb_signals_end_offset){
2126 tvb_RBRKT = tvb_next_offset+1;
2127 tvb_LBRKT = tvb_next_offset+1;
2128 tvb_previous_offset = tvb_next_offset;
2133 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2134 tvb_signals_end_offset, '}');
2135 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT,
2136 tvb_signals_end_offset, '{');
2138 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset,
2139 tvb_signals_end_offset, ',');
2141 if (tvb_current_offset == -1 || tvb_current_offset > tvb_signals_end_offset){
2142 tvb_current_offset = tvb_signals_end_offset;
2146 /* Descriptor includes no parameters */
2148 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2150 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2153 /* Descriptor includes Parameters */
2155 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2157 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2159 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
2160 tvb_signals_end_offset, '{');
2161 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
2162 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2163 tvb_signals_end_offset, '}');
2168 tvb_help_offset = tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_signals_end_offset, '{');
2170 /* if there are signalparameter */
2172 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2174 requested_signal_start_offset = tvb_help_offset;
2175 requested_signal_end_offset = tvb_RBRKT;
2176 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2177 pkg_tokenlen = tvb_help_offset - tvb_previous_offset;
2178 tokenlen = tvb_LBRKT+1 - tvb_previous_offset;
2182 tokenlen = pkg_tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2185 megaco_requestedsignal_ti = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen,
2186 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2187 megaco_requestedsignal_tree = proto_item_add_subtree(megaco_requestedsignal_ti, ett_megaco_requestedsignal);
2189 proto_tree_add_item(megaco_requestedsignal_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, FALSE);
2191 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2194 requested_signal_start_offset = megaco_tvb_skip_wsp(tvb, requested_signal_start_offset +1);
2195 requested_signal_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_signal_end_offset-1);
2197 tokenlen = requested_signal_end_offset - requested_signal_start_offset;
2199 msg=tvb_format_text(tvb,requested_signal_start_offset, tokenlen+1);
2200 if(!strncmp("h245", msg, 4)){
2201 dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, requested_signal_start_offset, tokenlen, msg);
2203 proto_tree_add_text(megaco_tree_command_line, tvb, requested_signal_start_offset, tokenlen,
2206 /* Print the trailing '}' */
2207 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_RBRKT, 1,
2208 "%s", tvb_format_text(tvb, tvb_RBRKT, 1));
2211 tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT,
2212 tvb_signals_end_offset, ',');
2214 if (tvb_current_offset == -1 || tvb_current_offset > tvb_signals_end_offset || tvb_current_offset < tvb_previous_offset){
2215 tvb_current_offset = tvb_signals_end_offset;
2218 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2220 tvb_LBRKT = tvb_previous_offset;
2221 tvb_RBRKT = tvb_previous_offset;
2222 /* Print the trailing '}' */
2223 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1,
2224 "%s", tvb_format_text(tvb, tvb_signals_end_offset, 1));
2226 } while ( tvb_current_offset < tvb_signals_end_offset );
2229 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1,
2230 "%s", tvb_format_text(tvb, tvb_signals_end_offset, 1));
2237 auditDescriptor = AuditToken LBRKT [ auditItem *(COMMA auditItem) ] RBRKT
2239 auditItem = ( MuxToken / ModemToken / MediaToken /
2240 SignalsToken / EventBufferToken /
2241 DigitMapToken / StatsToken / EventsToken /
2242 ObservedEventsToken / PackagesToken ) */
2244 dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree, packet_info *pinfo _U_, gint tvb_stop, gint tvb_offset)
2246 gint tokenlen, tvb_end, tvb_next, token_index;
2247 proto_tree *megaco_auditdescriptor_tree, *megaco_auditdescriptor_ti;
2249 tvb_next = tvb_find_guint8(tvb, tvb_offset, tvb_stop, '{'); /* find opening LBRKT - is this already checked by caller?*/
2250 if( tvb_next == -1 ) /* complain and give up if not there */
2252 proto_tree_add_text(megaco_tree, tvb, tvb_offset, tvb_stop+1-tvb_offset, "Badly constructed audit descriptor (no { )");
2255 tokenlen = (tvb_stop + 1) - tvb_offset;
2257 megaco_auditdescriptor_ti = proto_tree_add_none_format( megaco_tree, hf_megaco_audit_descriptor,
2258 tvb, tvb_offset, tokenlen, "Audit descriptor" );
2260 megaco_auditdescriptor_tree = proto_item_add_subtree( megaco_auditdescriptor_ti, ett_megaco_auditdescriptor );
2262 tokenlen = tvb_next + 1 - tvb_offset;
2264 proto_tree_add_text( megaco_auditdescriptor_tree, tvb, tvb_offset, tokenlen, "Audit token {" );
2266 tvb_offset = tvb_next;
2268 while( tvb_offset < tvb_stop )
2270 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1); /* find start of an auditItem */
2271 if( tvb_get_guint8(tvb, tvb_offset) != '}' ) /* got something */
2273 tvb_next = tvb_find_guint8(tvb, tvb_offset, tvb_stop, ','); /* end of an auditItem */
2274 if (tvb_next == -1) tvb_next = tvb_stop; /* last item doesn't have a comma */
2275 tvb_end = megaco_tvb_skip_wsp_return(tvb, tvb_next-1); /* trim any trailing whitespace */
2276 tokenlen = tvb_end - tvb_offset; /* get length of token */
2278 token_index = find_megaco_descriptors_names(tvb, tvb_offset, tokenlen); /* lookup the token */
2279 if( token_index == -1 ) token_index = 0; /* if not found then 0 => Unknown */
2281 proto_tree_add_string(megaco_auditdescriptor_tree, hf_megaco_audititem, tvb,
2282 tvb_offset, tokenlen, megaco_descriptors_names[token_index].name); /* and display the long form */
2284 tvb_offset = tvb_next; /* advance pointer */
2287 proto_tree_add_text(megaco_auditdescriptor_tree, tvb, tvb_stop, 1, "}"); /* End of auditDescriptor */
2291 * serviceChangeDescriptor = ServicesToken LBRKT serviceChangeParm
2292 * *(COMMA serviceChangeParm) RBRKT
2294 * ServicesToken = ("Services" / "SV")
2296 * serviceChangeParm = (serviceChangeMethod / serviceChangeReason /
2297 * serviceChangeDelay / serviceChangeAddress /
2298 * serviceChangeProfile / extension / TimeStamp /
2299 * serviceChangeMgcId / serviceChangeVersion )
2302 #define MEGACO_REASON_TOKEN 1
2303 #define MEGACO_DELAY_TOKEN 2
2304 #define MEGACO_SC_ADDR_TOKEN 3
2305 #define MEGACO_MGC_ID_TOKEN 4
2306 #define MEGACO_PROFILE_TOKEN 5
2307 #define MEGACO_VERSION_TOKEN 6
2308 #define MEGACO_METHOD_TOKEN 7
2310 static const megaco_tokens_t megaco_serviceChangeParm_names[] = {
2311 { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
2313 { "Reason", "RE" }, /* 1 ReasonToken*/
2314 { "Delay", "DL" }, /* 2 DelayToken */
2315 { "ServiceChangeAddress", "AD" }, /* 3 ServiceChangeAddressToken */
2316 { "MgcIdToTry", "MG" }, /* 4 MgcIdToken */
2317 { "Profile", "PF" }, /* 5 ProfileToken */
2318 { "Version", "V" }, /* 6 VersionToken */
2319 { "Method", "MT" }, /* 7 MethodToken */
2322 /* Returns index of megaco_tokens_t */
2323 static gint find_megaco_megaco_serviceChangeParm_names(tvbuff_t *tvb, int offset, guint header_len)
2327 for (i = 1; i < array_length(megaco_serviceChangeParm_names); i++) {
2328 if (header_len == strlen(megaco_serviceChangeParm_names[i].name) &&
2329 tvb_strncaseeql(tvb, offset, megaco_serviceChangeParm_names[i].name, header_len) == 0)
2331 if (megaco_serviceChangeParm_names[i].compact_name != NULL &&
2332 header_len == strlen(megaco_serviceChangeParm_names[i].compact_name) &&
2333 tvb_strncaseeql(tvb, offset, megaco_serviceChangeParm_names[i].compact_name, header_len) == 0)
2340 * ServiceChangeReasons References
2341 * -------------------- ----------
2343 static const value_string MEGACO_ServiceChangeReasons_vals[] = {
2344 {900, "Service Restored"},
2347 {903, "MGC Directed Change"},
2348 {904, "Termination malfunctioning"},
2349 {905, "Termination taken out of service"},
2350 {906, "Loss of lower layer connectivity (e.g. downstream sync)"},
2351 {907, "Transmission Failure"},
2352 {908, "MG Impending Failure"},
2353 {909, "MGC Impending Failure"},
2354 {910, "Media Capability Failure"},
2355 {911, "Modem Capability Failure"},
2356 {912, "Mux Capability Failure"},
2357 {913, "Signal Capability Failure"},
2358 {914, "Event Capability Failure"},
2359 {915, "State Loss"},
2360 {916, "Packages Change"},
2361 {917, "Capabilities Change"},
2362 {918, "Cancel Graceful"},
2363 {919, "Warm Failover"},
2364 {920, "Cold Failover"},
2369 dissect_megaco_servicechangedescriptor(tvbuff_t *tvb, proto_tree *megaco_tree, gint tvb_RBRKT, gint tvb_previous_offset)
2372 gint tokenlen, tvb_LBRKT, tvb_offset;
2374 gint tvb_current_offset;
2375 gboolean more_params = TRUE;
2378 guint8 ServiceChangeReason_str[4];
2380 tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2382 if (tvb_LBRKT == -1)
2385 tokenlen = (tvb_LBRKT + 1) - tvb_previous_offset;
2386 proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tokenlen,
2387 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2390 /* Start dissecting serviceChangeParm */
2391 tvb_previous_offset = tvb_LBRKT + 1;
2392 while (more_params){
2393 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
2394 /* Find token length */
2395 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_RBRKT; tvb_offset++){
2396 if (!isalpha(tvb_get_guint8(tvb, tvb_offset ))){
2400 tokenlen = tvb_offset - tvb_previous_offset;
2401 token_index = find_megaco_megaco_serviceChangeParm_names(tvb, tvb_previous_offset, tokenlen);
2403 tvb_offset = tvb_find_guint8(tvb, tvb_offset, tvb_RBRKT, ',');
2404 if ((tvb_offset == -1)||(tvb_offset >=tvb_RBRKT)){
2405 more_params = FALSE;
2406 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_RBRKT-1);
2408 tokenlen = tvb_offset - tvb_previous_offset;
2409 if (more_params == TRUE )
2412 switch(token_index){
2413 case MEGACO_REASON_TOKEN:
2414 /* ReasonToken EQUAL VALUE
2415 * VALUE = quotedString / 1*(SafeChar)
2417 item = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tokenlen,
2418 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2420 /* As the reason code ( if a digit ) can be in quoted string or 'just' digit
2421 * look for a nine and hope for the best.
2423 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '9');
2424 if ( tvb_current_offset == -1)
2427 tvb_get_nstringz0(tvb,tvb_current_offset,4,ServiceChangeReason_str);
2428 reason = atoi(ServiceChangeReason_str);
2430 proto_item_append_text(item,"[ %s ]", val_to_str(reason, MEGACO_ServiceChangeReasons_vals,"Unknown (%u)"));
2432 case MEGACO_DELAY_TOKEN:
2433 case MEGACO_SC_ADDR_TOKEN:
2434 case MEGACO_MGC_ID_TOKEN:
2435 case MEGACO_PROFILE_TOKEN:
2436 case MEGACO_VERSION_TOKEN:
2437 case MEGACO_METHOD_TOKEN:
2438 /* No special dissection: fall trough */
2441 * extension = extensionParameter parmValue
2442 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2444 proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tokenlen,
2445 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2449 tvb_previous_offset = tvb_offset +1;
2453 /* extension = extensionParameter parmValue
2454 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2458 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2459 proto_tree_add_string(megaco_tree_command_line, hf_megaco_servicechange_descriptor, tvb,
2460 tvb_previous_offset, tokenlen,
2461 tvb_format_text(tvb, tvb_previous_offset,
2464 proto_tree_add_text(megaco_tree, tvb, tvb_RBRKT, 1,"%s", tvb_format_text(tvb, tvb_RBRKT, 1));
2468 dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2475 tokenlen = tvb_RBRKT - tvb_previous_offset;
2476 proto_tree_add_string(megaco_tree_command_line, hf_megaco_digitmap_descriptor, tvb,
2477 tvb_previous_offset, tokenlen,
2478 tvb_format_text(tvb, tvb_previous_offset,
2483 dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2490 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2491 proto_tree_add_string(megaco_tree_command_line, hf_megaco_statistics_descriptor, tvb,
2492 tvb_previous_offset, tokenlen,
2493 tvb_format_text(tvb, tvb_previous_offset,
2498 dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2501 gint tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2502 gint tvb_observedevents_end_offset, tvb_observedevents_start_offset, tvb_LBRKT;
2503 proto_tree *megaco_observedeventsdescriptor_tree, *megaco_observedeventsdescriptor_ti;
2506 gint requested_event_start_offset, requested_event_end_offset, param_start_offset, param_end_offset;
2507 proto_tree *megaco_observedevent_tree, *megaco_observedevent_ti;
2510 tvb_current_offset = 0;
2511 tvb_next_offset = 0;
2512 tvb_help_offset = 0;
2513 tvb_observedevents_end_offset = 0;
2514 tvb_observedevents_start_offset = 0;
2516 requested_event_start_offset = 0;
2517 requested_event_end_offset = 0;
2520 tvb_LBRKT = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2521 tvb_next_offset = tvb_LBRKT;
2522 tokenlen = (tvb_next_offset+1) - tvb_previous_offset;
2525 megaco_observedeventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_observedevents_descriptor,tvb,tvb_previous_offset,tokenlen, FALSE);
2526 megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor);
2529 megaco_observedeventsdescriptor_ti = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen,
2530 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2531 megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor);
2533 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
2534 tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2536 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
2538 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2539 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
2541 tokenlen = tvb_help_offset - tvb_current_offset;
2543 proto_tree_add_string(megaco_observedeventsdescriptor_tree, hf_megaco_requestid, tvb,
2544 tvb_current_offset, tokenlen,
2545 tvb_format_text(tvb, tvb_current_offset,
2548 tvb_observedevents_end_offset = tvb_RBRKT;
2549 tvb_observedevents_start_offset = tvb_previous_offset;
2551 tvb_RBRKT = tvb_next_offset+1;
2552 tvb_LBRKT = tvb_next_offset+1;
2553 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
2558 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2559 tvb_observedevents_end_offset, '}');
2560 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT,
2561 tvb_observedevents_end_offset, '{');
2563 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset,
2564 tvb_observedevents_end_offset, ',');
2566 if (tvb_current_offset == -1 || tvb_current_offset > tvb_observedevents_end_offset){
2567 tvb_current_offset = tvb_observedevents_end_offset;
2571 /* Descriptor includes no parameters */
2573 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2575 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2578 /* Descriptor includes Parameters */
2580 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2582 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2584 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
2585 tvb_observedevents_end_offset, '{');
2586 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1){
2587 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2588 tvb_observedevents_end_offset, '}');
2594 tvb_LBRKT = tvb_help_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_observedevents_end_offset, '{');
2596 /* if there are eventparameter */
2598 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2600 requested_event_start_offset = tvb_help_offset;
2601 requested_event_end_offset = tvb_RBRKT;
2602 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2603 pkg_tokenlen = tvb_help_offset - tvb_previous_offset;
2604 tokenlen = tvb_LBRKT+1 - tvb_previous_offset;
2608 tokenlen = pkg_tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2611 megaco_observedevent_ti = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen,
2612 "%s", tvb_format_text(tvb, tvb_previous_offset, tokenlen));
2614 megaco_observedevent_tree = proto_item_add_subtree(megaco_observedevent_ti, ett_megaco_observedevent);
2616 proto_tree_add_item(megaco_observedevent_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, FALSE);
2618 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2620 tvb_help_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1);
2621 tempchar = tvb_get_guint8(tvb, tvb_help_offset);
2622 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
2623 tempchar = tempchar - 0x20;
2625 requested_event_start_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1)-1;
2626 requested_event_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_event_end_offset-1);
2628 tvb_help_offset = requested_event_start_offset;
2633 param_start_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset+1);
2635 tvb_help_offset = tvb_find_guint8(tvb, tvb_help_offset+1,requested_event_end_offset, ',');
2637 if ( tvb_help_offset > requested_event_end_offset || tvb_help_offset == -1){
2638 tvb_help_offset = requested_event_end_offset;
2641 param_end_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset-1);
2643 tokenlen = param_end_offset - param_start_offset+1;
2644 msg=tvb_format_text(tvb,param_start_offset, tokenlen);
2645 if(!strncmp("h245", msg, 4)){
2646 dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, param_start_offset, tokenlen, msg);
2648 proto_tree_add_text(megaco_tree_command_line, tvb, param_start_offset, tokenlen,
2653 } while ( tvb_help_offset < requested_event_end_offset );
2656 tvb_previous_offset = tvb_current_offset;
2657 tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT,
2658 tvb_observedevents_end_offset, ',');
2660 if (tvb_current_offset == -1 || tvb_current_offset > tvb_observedevents_end_offset ){
2661 tvb_current_offset = tvb_observedevents_end_offset;
2663 if (tvb_current_offset < tvb_previous_offset) {
2664 proto_tree_add_text(megaco_observedevent_tree, tvb, 0, 0, "[ Parse error: Invalid offset ]");
2668 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2670 tvb_LBRKT = tvb_previous_offset;
2671 tvb_RBRKT = tvb_previous_offset;
2672 /* Print the trailing '}' */
2673 proto_tree_add_text(megaco_tree_command_line, tvb, tvb_observedevents_end_offset, 1,
2674 "%s", tvb_format_text(tvb, tvb_observedevents_end_offset, 1));
2676 } while ( tvb_current_offset < tvb_observedevents_end_offset );
2680 dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2687 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2688 proto_tree_add_string(megaco_tree_command_line, hf_megaco_topology_descriptor, tvb,
2689 tvb_previous_offset, tokenlen,
2690 tvb_format_text_wsp(tvb, tvb_previous_offset,
2695 dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2698 gint tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2699 gint tvb_packages_end_offset, tvb_packages_start_offset, tvb_LBRKT;
2700 proto_tree *megaco_packagesdescriptor_tree, *megaco_packagesdescriptor_ti;
2703 tvb_current_offset = 0;
2704 tvb_next_offset = 0;
2705 tvb_help_offset = 0;
2706 tvb_packages_end_offset = 0;
2707 tvb_packages_start_offset = 0;
2710 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2712 megaco_packagesdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_packages_descriptor,tvb,tvb_previous_offset,tokenlen, FALSE);
2713 megaco_packagesdescriptor_tree = proto_item_add_subtree(megaco_packagesdescriptor_ti, ett_megaco_packagesdescriptor);
2717 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
2718 tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2720 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
2722 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2723 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
2725 tokenlen = tvb_help_offset - tvb_current_offset;
2727 proto_tree_add_string(megaco_packagesdescriptor_tree, hf_megaco_requestid, tvb,
2728 tvb_current_offset, tokenlen,
2729 tvb_format_text(tvb, tvb_current_offset,
2732 tvb_packages_end_offset = tvb_RBRKT;
2733 tvb_packages_start_offset = tvb_previous_offset;
2735 tvb_RBRKT = tvb_next_offset+1;
2736 tvb_LBRKT = tvb_next_offset+1;
2737 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
2742 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2743 tvb_packages_end_offset, '}');
2744 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT,
2745 tvb_packages_end_offset, '{');
2747 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset,
2748 tvb_packages_end_offset, ',');
2750 if (tvb_current_offset == -1 || tvb_current_offset > tvb_packages_end_offset){
2751 tvb_current_offset = tvb_packages_end_offset;
2755 /* Descriptor includes no parameters */
2757 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2759 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2762 /* Descriptor includes Parameters */
2764 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2766 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2768 tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
2769 tvb_packages_end_offset, '{');
2770 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
2771 tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
2772 tvb_packages_end_offset, '}');
2777 tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2779 proto_tree_add_text(megaco_packagesdescriptor_tree, tvb, tvb_previous_offset, tokenlen,
2780 "%s", tvb_format_text(tvb,tvb_previous_offset,
2784 tvb_current_offset = tvb_find_guint8(tvb, tvb_RBRKT,
2785 tvb_packages_end_offset, ',');
2787 if (tvb_current_offset == -1 || tvb_current_offset > tvb_packages_end_offset ){
2788 tvb_current_offset = tvb_packages_end_offset;
2791 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2793 tvb_LBRKT = tvb_previous_offset;
2794 tvb_RBRKT = tvb_previous_offset;
2796 } while ( tvb_current_offset < tvb_packages_end_offset );
2800 /* The list of error code values is fetched from http://www.iana.org/assignments/megaco-h248 */
2803 static const value_string MEGACO_error_code_vals[] = {
2805 {400, "Syntax error in message"},
2806 {401, "Protocol Error"},
2807 {402, "Unauthorized"},
2808 {403, "Syntax error in transaction request"},
2809 {406, "Version Not Supported"},
2810 {410, "Incorrect identifier"},
2811 {411, "The transaction refers to an unknown ContextId"},
2812 {412, "No ContextIDs available"},
2813 {421, "Unknown action or illegal combination of actions"},
2814 {422, "Syntax Error in Action"},
2815 {430, "Unknown TerminationID"},
2816 {431, "No TerminationID matched a wildcard"},
2817 {432, "Out of TerminationIDs or No TerminationID available"},
2818 {433, "TerminationID is already in a Context"},
2819 {434, "Max number of Terminations in a Context exceeded"},
2820 {435, "Termination ID is not in specified Context"},
2821 {440, "Unsupported or unknown Package"},
2822 {441, "Missing Remote or Local Descriptor"},
2823 {442, "Syntax Error in Command"},
2824 {443, "Unsupported or Unknown Command"},
2825 {444, "Unsupported or Unknown Descriptor"},
2826 {445, "Unsupported or Unknown Property"},
2827 {446, "Unsupported or Unknown Parameter"},
2828 {447, "Descriptor not legal in this command"},
2829 {448, "Descriptor appears twice in a command"},
2830 {450, "No such property in this package"},
2831 {451, "No such event in this package"},
2832 {452, "No such signal in this package"},
2833 {453, "No such statistic in this package"},
2834 {454, "No such parameter value in this package"},
2835 {455, "Property illegal in this Descriptor"},
2836 {456, "Property appears twice in this Descriptor"},
2837 {457, "Missing parameter in signal or event"},
2838 {458, "Unexpected Event/Request ID"},
2839 {459, "Unsupported or Unknown Profile"},
2840 {471, "Implied Add for Multiplex failure"},
2842 {500, "Internal software Failure in MG"},
2843 {501, "Not Implemented"},
2844 {502, "Not ready."},
2845 {503, "Service Unavailable"},
2846 {504, "Command Received from unauthorized entity"},
2847 {505, "Transaction Request Received before a Service Change Reply has been received"},
2848 {506, "Number of Transaction Pendings Exceeded"},
2849 {510, "Insufficient resources"},
2850 {512, "Media Gateway unequipped to detect requested Event"},
2851 {513, "Media Gateway unequipped to generate requested Signals"},
2852 {514, "Media Gateway cannot send the specified announcement"},
2853 {515, "Unsupported Media Type"},
2854 {517, "Unsupported or invalid mode"},
2855 {518, "Event buffer full"},
2856 {519, "Out of space to store digit map"},
2857 {520, "Digit Map undefined in the MG"},
2858 {521, "Termination is ServiceChanging"},
2859 {526, "Insufficient bandwidth"},
2860 {529, "Internal hardware failure in MG"},
2861 {530, "Temporary Network failure"},
2862 {531, "Permanent Network failure"},
2863 {532, "Audited Property, Statistic, Event or Signal does not exist"},
2864 {533, "Response exceeds maximum transport PDU size"},
2865 {534, "Illegal write or read only property"},
2866 {540, "Unexpected initial hook state"},
2867 {581, "Does Not Exist"},
2869 {600, "Illegal syntax within an announcement specification"},
2870 {601, "Variable type not supported"},
2871 {602, "Variable value out of range"},
2872 {603, "Category not supported"},
2873 {604, "Selector type not supported"},
2874 {605, "Selector value not supported"},
2875 {606, "Unknown segment ID"},
2876 {607, "Mismatch between play specification and provisioned data"},
2877 {608, "Provisioning error"},
2878 {609, "Invalid offset"},
2879 {610, "No free segment IDs"},
2880 {611, "Temporary segment not found"},
2881 {612, "Segment in use"},
2882 {613, "ISP port limit overrun"},
2883 {614, "No modems available"},
2884 {615, "Calling number unacceptable"},
2885 {616, "Called number unacceptable"},
2892 dissect_megaco_errordescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, gint tvb_RBRKT, gint tvb_previous_offset)
2898 gint tvb_next_offset, tvb_current_offset,tvb_len;
2900 proto_item* hidden_item;
2902 tvb_len = tvb_length(tvb);
2904 tvb_next_offset = 0;
2905 tvb_current_offset = 0;
2908 tvb_current_offset = tvb_find_guint8(tvb, tvb_previous_offset , tvb_RBRKT, '=');
2909 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2910 tvb_get_nstringz0(tvb,tvb_current_offset,4,error);
2911 error_code = atoi(error);
2912 hidden_item = proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_descriptor, tvb,
2913 tvb_current_offset, 3,
2914 tvb_format_text(tvb, tvb_current_offset,
2916 PROTO_ITEM_SET_HIDDEN(hidden_item);
2918 tokenlen = (tvb_RBRKT) - tvb_previous_offset+1;
2921 proto_tree_add_string(megaco_tree_command_line, hf_megaco_error_descriptor, tvb,
2922 tvb_previous_offset, tokenlen,
2923 tvb_format_text(tvb, tvb_previous_offset,
2926 item = proto_tree_add_text(megaco_tree_command_line, tvb, tvb_current_offset, 3,
2928 val_to_str(error_code, MEGACO_error_code_vals,
2931 PROTO_ITEM_SET_GENERATED(item);
2935 dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, gint tvb_next_offset, gint tvb_current_offset)
2941 proto_tree *megaco_TerminationState_tree, *megaco_TerminationState_ti;
2946 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_next_offset, '=');
2948 tokenlen = tvb_next_offset - tvb_current_offset;
2950 megaco_TerminationState_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_TerminationState_descriptor,tvb,tvb_current_offset,tokenlen, FALSE);
2951 megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState);
2953 megaco_TerminationState_ti = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_current_offset, tokenlen,
2954 "%s", tvb_format_text(tvb, tvb_current_offset, tokenlen));
2955 megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState);
2957 while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){
2959 tempchar = tvb_get_guint8(tvb, tvb_current_offset);
2960 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
2961 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
2962 tempchar = tempchar - 0x20;
2964 switch ( tempchar ){
2967 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_offset, ',');
2968 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
2969 tvb_offset = tvb_next_offset;
2972 tempchar = tvb_get_guint8(tvb, tvb_current_offset);
2973 tokenlen = tvb_offset - tvb_current_offset;
2974 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
2975 tempchar = tempchar - 0x20;
2977 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Service_State, tvb,
2978 tvb_current_offset, tokenlen,
2979 tvb_format_text(tvb, tvb_current_offset,
2986 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_offset, ',');
2987 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
2988 tvb_offset = tvb_next_offset;
2991 tempchar = tvb_get_guint8(tvb, tvb_current_offset);
2992 tokenlen = tvb_offset - tvb_current_offset;
2993 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
2994 tempchar = tempchar - 0x20;
2996 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Event_Buffer_Control, tvb,
2997 tvb_current_offset, tokenlen,
2998 tvb_format_text(tvb, tvb_current_offset,
3004 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_offset, ',');
3005 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3006 tvb_offset = tvb_next_offset;
3009 tempchar = tvb_get_guint8(tvb, tvb_current_offset);
3010 tokenlen = tvb_offset - tvb_current_offset;
3011 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
3012 tempchar = tempchar - 0x20;
3014 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Event_Buffer_Control, tvb,
3015 tvb_current_offset, tokenlen,
3016 tvb_format_text(tvb, tvb_current_offset,
3022 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_offset, ',');
3023 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3024 tvb_offset = tvb_next_offset;
3027 tokenlen = tvb_offset - tvb_current_offset;
3029 proto_tree_add_text(megaco_TerminationState_tree, tvb, tvb_current_offset, tokenlen,
3030 "%s", tvb_format_text(tvb,tvb_current_offset,tokenlen));
3035 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3036 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_next_offset, '=');
3039 proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_next_offset, 1,
3040 "%s", tvb_format_text(tvb, tvb_next_offset, 1));
3045 dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree,packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset)
3050 proto_tree *megaco_localdescriptor_tree, *megaco_localdescriptor_ti;
3054 tokenlen = tvb_next_offset - tvb_current_offset;
3058 megaco_localdescriptor_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_Local_descriptor,tvb,tvb_current_offset,tokenlen, FALSE);
3060 megaco_localdescriptor_ti = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_current_offset, tokenlen,
3061 "%s", tvb_format_text(tvb, tvb_current_offset, tokenlen));
3062 megaco_localdescriptor_tree = proto_item_add_subtree(megaco_localdescriptor_ti, ett_megaco_Localdescriptor);
3064 tokenlen = tvb_next_offset - tvb_current_offset;
3065 if ( tokenlen > 3 ){
3066 next_tvb = tvb_new_subset(tvb, tvb_current_offset, tokenlen, tokenlen);
3067 call_dissector(sdp_handle, next_tvb, pinfo, megaco_localdescriptor_tree);
3072 * localControlDescriptor = LocalControlToken LBRKT localParm
3073 * *(COMMA localParm) RBRKT
3074 * ; at-most-once per item
3075 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3078 #define MEGACO_MODETOKEN 1
3079 #define MEGACO_RESERVEDVALUETOKEN 2
3080 #define MEGACO_RESERVEDGROUPTOKEN 3
3081 #define MEGACO_H324_H223CAPR 4
3082 #define MEGACO_H324_MUXTBL_IN 5
3083 #define MEGACO_H324_MUXTBL_OUT 6
3084 #define MEGACO_DS_DSCP 7
3085 #define MEGACO_GM_SAF 8
3086 #define MEGACO_GM_SAM 9
3087 #define MEGACO_GM_SPF 10
3088 #define MEGACO_GM_SPR 11
3089 #define MEGACO_GM_ESAS 12
3090 #define MEGACO_GM_LSA 13
3091 #define MEGACO_GM_ESPS 14
3092 #define MEGACO_GM_LSP 15
3093 #define MEGACO_GM_RSB 16
3095 static const megaco_tokens_t megaco_localParam_names[] = {
3096 { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
3098 { "Mode", "MO" }, /* 1 */
3099 { "ReservedValue", "RV" }, /* 2 */
3100 { "ReservedGroup", "RG" }, /* 3 */
3101 /* propertyParm = pkgdName parmValue
3102 * Add more package names as needed.
3104 { "h324/h223capr", NULL }, /* 4 */
3105 { "h324/muxtbl_in", NULL }, /* 5 */
3106 { "h324/muxtbl_out", NULL }, /* 6 */
3107 { "ds/dscp", NULL }, /* 7 */
3108 { "gm/saf", NULL }, /* 8 */
3109 { "gm/sam", NULL }, /* 9 */
3110 { "gm/spf", NULL }, /* 10 */
3111 { "gm/spr", NULL }, /* 11 */
3112 { "gm/esas", NULL }, /* 12 */
3113 { "gm/lsa", NULL }, /* 13 */
3114 { "gm/esps", NULL }, /* 14 */
3115 { "gm/lsp", NULL }, /* 15 */
3116 { "gm/rsb", NULL }, /* 16 */
3119 /* Returns index of megaco_tokens_t */
3120 static gint find_megaco_localParam_names(tvbuff_t *tvb, int offset, guint header_len)
3124 for (i = 1; i < array_length(megaco_localParam_names); i++) {
3125 if (header_len == strlen(megaco_localParam_names[i].name) &&
3126 tvb_strncaseeql(tvb, offset, megaco_localParam_names[i].name, header_len) == 0)
3128 if (megaco_localParam_names[i].compact_name != NULL &&
3129 header_len == strlen(megaco_localParam_names[i].compact_name) &&
3130 tvb_strncaseeql(tvb, offset, megaco_localParam_names[i].compact_name, header_len) == 0)
3138 dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset)
3141 guint token_name_len;
3142 gint tvb_offset,tvb_help_offset;
3143 gint token_index = 0;
3148 /*proto_tree *megaco_LocalControl_tree, *megaco_LocalControl_ti; */
3152 tvb_help_offset = 0;
3155 tokenlen = tvb_next_offset - tvb_current_offset;
3157 megaco_LocalControl_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_LocalControl_descriptor,tvb,tvb_current_offset,tokenlen, FALSE);
3158 megaco_LocalControl_tree = proto_item_add_subtree(megaco_LocalControl_ti, ett_megaco_LocalControldescriptor);
3160 while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){
3162 tvb_help_offset = tvb_current_offset;
3165 * Find local parameter name
3166 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3167 * pkgdName = (PackageName SLASH ItemID) ;specific item
3168 * / (PackageName SLASH "*") ;all events in package
3169 * / ("*" SLASH "*") ; all events supported by the MG
3171 /* Find token length */
3172 for (tvb_offset=tvb_current_offset; tvb_offset < tvb_next_offset; tvb_offset++){
3174 octet = tvb_get_guint8(tvb, tvb_offset);
3175 if (!isalnum(octet)){
3176 if ((octet!='/')&&(octet!='_')){
3181 token_name_len = tvb_offset - tvb_current_offset;
3183 proto_tree_add_text(megaco_LocalControl_tree, tvb, tvb_current_offset, token_name_len,
3184 "%s", tvb_format_text(tvb,tvb_current_offset,token_name_len));
3187 token_index = find_megaco_localParam_names(tvb, tvb_current_offset, token_name_len);
3188 /* Find start of parameter value */
3189 tvb_offset = tvb_find_guint8(tvb, tvb_offset , tvb_next_offset, '=');
3190 if (tvb_offset == -1)
3191 THROW(ReportedBoundsError);
3192 /* Start search after '=' in case there is no SP*/
3194 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
3196 /* find if there are more parameters or not */
3197 tvb_offset = tvb_find_guint8(tvb, tvb_current_offset , tvb_offset, ',');
3198 if ( tvb_offset < 0 || tvb_offset > tvb_next_offset ){
3199 tvb_offset = tvb_next_offset;
3202 tokenlen = megaco_tvb_skip_wsp_return(tvb,tvb_offset-1) - tvb_current_offset;
3204 proto_tree_add_text(megaco_LocalControl_tree, tvb, tvb_current_offset, tokenlen,
3205 "%s", tvb_format_text(tvb,tvb_current_offset,tokenlen));
3208 switch ( token_index ){
3210 case MEGACO_MODETOKEN: /* Mode */
3211 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_mode, tvb,
3212 tvb_current_offset, tokenlen,
3213 tvb_format_text(tvb, tvb_current_offset,
3215 if (check_col(pinfo->cinfo, COL_INFO) )
3216 col_append_fstr(pinfo->cinfo, COL_INFO, " (Mode:%s)",tvb_format_text(tvb, tvb_current_offset,tokenlen));
3217 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3220 case MEGACO_RESERVEDVALUETOKEN: /* ReservedValue */
3221 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_reserve_value, tvb,
3222 tvb_current_offset, tokenlen,
3223 tvb_format_text(tvb, tvb_current_offset,
3226 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3228 case MEGACO_RESERVEDGROUPTOKEN: /* ReservedGroup */
3229 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_reserve_group, tvb,
3230 tvb_current_offset, tokenlen,
3231 tvb_format_text(tvb, tvb_current_offset,
3233 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3236 case MEGACO_H324_H223CAPR: /* h324/h223capr */
3237 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_h223capr, tvb,
3238 tvb_current_offset, tokenlen,
3239 tvb_format_text(tvb, tvb_current_offset,
3242 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3243 tokenlen = tvb_offset - tvb_help_offset;
3244 msg=tvb_format_text(tvb,tvb_help_offset, tokenlen);
3245 dissect_megaco_h324_h223caprn(tvb, pinfo, megaco_mediadescriptor_tree, tvb_help_offset, tokenlen, msg);
3249 case MEGACO_H324_MUXTBL_IN: /* h324/muxtbl_in */
3251 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_muxtbl_in, tvb,
3252 tvb_current_offset, tokenlen,
3253 tvb_format_text(tvb, tvb_current_offset,
3256 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3258 tokenlen = tvb_offset - tvb_help_offset;
3259 msg=tvb_format_text(tvb,tvb_help_offset, tokenlen);
3260 /* Call the existing rotine with tree = NULL to avoid an entry to the tree */
3261 dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, msg);
3265 case MEGACO_H324_MUXTBL_OUT:
3267 proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_h324_muxtbl_out, tvb,
3268 tvb_current_offset, tokenlen,
3269 tvb_format_text(tvb, tvb_current_offset,
3272 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3274 tokenlen = tvb_offset - tvb_help_offset;
3275 msg=tvb_format_text(tvb,tvb_help_offset, tokenlen);
3276 /* Call the existing rotine with tree = NULL to avoid an entry to the tree */
3277 dissect_megaco_h245(tvb, pinfo, NULL, tvb_help_offset, tokenlen, msg);
3281 case MEGACO_DS_DSCP:
3282 item = proto_tree_add_string(megaco_mediadescriptor_tree, hf_megaco_ds_dscp, tvb,
3283 tvb_current_offset, tokenlen,
3284 tvb_format_text(tvb, tvb_current_offset,
3287 tvb_get_nstringz0(tvb,tvb_current_offset,3,code_str);
3288 proto_item_append_text(item,"[ %s ]", val_to_str(strtoul(code_str,NULL,16), dscp_vals,"Unknown (%u)"));
3290 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3294 tokenlen = tvb_offset - tvb_help_offset;
3295 item = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3296 "%s", tvb_format_text(tvb,tvb_help_offset,
3298 proto_item_append_text(item," [Remote Source Address Filtering]");
3299 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3302 tokenlen = tvb_offset - tvb_help_offset;
3303 item = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3304 "%s", tvb_format_text(tvb,tvb_help_offset,
3306 proto_item_append_text(item," [Remote Source Address Mask]");
3307 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3310 tokenlen = tvb_offset - tvb_help_offset;
3311 item = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3312 "%s", tvb_format_text(tvb,tvb_help_offset,
3314 proto_item_append_text(item," [Remote Source Port Filtering]");
3315 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3318 tokenlen = tvb_offset - tvb_help_offset;
3319 item = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3320 "%s", tvb_format_text(tvb,tvb_help_offset,
3322 proto_item_append_text(item," [Remote Source Port Range]");
3323 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3325 case MEGACO_GM_ESAS:
3326 tokenlen = tvb_offset - tvb_help_offset;
3327 item = proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3328 "%s", tvb_format_text(tvb,tvb_help_offset,
3330 proto_item_append_text(item," [Explicit Source Address Setting]");
3331 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3334 tokenlen = tvb_offset - tvb_help_offset;
3335 proto_tree_add_text(megaco_mediadescriptor_tree, tvb, tvb_help_offset, tokenlen,
3336 "%s", tvb_format_text(tvb,tvb_help_offset,
3338 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3344 /* Copied from MGCP dissector, prints whole message in raw text */
3346 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree){
3348 gint tvb_linebegin,tvb_lineend,tvb_len,linelen;
3351 tvb_len = tvb_length(tvb);
3353 proto_tree_add_text(tree, tvb, 0, -1,"-------------- (RAW text output) ---------------");
3356 linelen = tvb_find_line_end(tvb,tvb_linebegin,-1,&tvb_lineend,FALSE);
3357 proto_tree_add_text(tree, tvb, tvb_linebegin, linelen,
3358 "%s", tvb_format_text_wsp(tvb,tvb_linebegin,
3360 tvb_linebegin = tvb_lineend;
3361 } while ( tvb_lineend < tvb_len );
3364 /* Register all the bits needed with the filtering engine */
3365 /* The registration hand-off routine */
3367 proto_reg_handoff_megaco(void)
3369 static gboolean megaco_prefs_initialized = FALSE;
3370 static dissector_handle_t megaco_text_tcp_handle;
3372 * Variables to allow for proper deletion of dissector registration when
3373 * the user changes port from the gui.
3375 static guint txt_tcp_port;
3376 static guint txt_udp_port;
3378 static guint bin_tcp_port;
3379 static guint bin_udp_port;
3382 if (!megaco_prefs_initialized) {
3383 sdp_handle = find_dissector("sdp");
3384 h245_handle = find_dissector("h245dg");
3385 h248_handle = find_dissector("h248");
3386 h248_otp_handle = find_dissector("h248_otp");
3387 data_handle = find_dissector("data");
3389 megaco_text_handle = find_dissector("megaco");
3390 megaco_text_tcp_handle = create_dissector_handle(dissect_megaco_text_tcp, proto_megaco);
3392 dissector_add("sctp.ppi", H248_PAYLOAD_PROTOCOL_ID, megaco_text_handle);
3394 megaco_prefs_initialized = TRUE;
3397 dissector_delete("tcp.port", txt_tcp_port, megaco_text_tcp_handle);
3398 dissector_delete("udp.port", txt_udp_port, megaco_text_handle);
3401 /* Set our port number for future use */
3403 txt_tcp_port = global_megaco_txt_tcp_port;
3404 txt_udp_port = global_megaco_txt_udp_port;
3406 dissector_add("tcp.port", global_megaco_txt_tcp_port, megaco_text_tcp_handle);
3407 dissector_add("udp.port", global_megaco_txt_udp_port, megaco_text_handle);
3412 proto_register_megaco(void)
3414 static hf_register_info hf[] = {
3415 { &hf_megaco_audititem,
3416 { "Audit Item", "megaco.audititem", FT_STRING, BASE_NONE, NULL, 0x0,
3417 "Identity of item to be audited", HFILL }},
3418 { &hf_megaco_audit_descriptor,
3419 { "Audit Descriptor", "megaco.audit", FT_NONE, BASE_NONE, NULL, 0x0,
3420 "Audit Descriptor of the megaco Command", HFILL }},
3421 { &hf_megaco_command_line,
3422 { "Command line", "megaco.command_line", FT_STRING, BASE_NONE, NULL, 0x0,
3423 "Commands of this message", HFILL }},
3424 { &hf_megaco_command,
3425 { "Command", "megaco.command", FT_STRING, BASE_NONE, NULL, 0x0,
3426 "Command of this message", HFILL }},
3427 { &hf_megaco_Context,
3428 { "Context", "megaco.context", FT_STRING, BASE_NONE, NULL, 0x0,
3429 "Context ID of this massage", HFILL }},
3430 { &hf_megaco_digitmap_descriptor,
3431 { "DigitMap Descriptor", "megaco.digitmap", FT_STRING, BASE_NONE, NULL, 0x0,
3432 "DigitMap Descriptor of the megaco Command", HFILL }},
3433 { &hf_megaco_error_descriptor,
3434 { "ERROR Descriptor", "megaco.error", FT_STRING, BASE_NONE, NULL, 0x0,
3435 "Error Descriptor of the megaco Command", HFILL }},
3436 { &hf_megaco_error_Frame,
3437 { "ERROR frame", "megaco.error_frame", FT_STRING, BASE_NONE, NULL, 0x0,
3438 "Syntax error", HFILL }},
3439 { &hf_megaco_Event_Buffer_Control,
3440 { "Event Buffer Control", "megaco.eventbuffercontrol", FT_STRING, BASE_NONE, NULL, 0x0,
3441 "Event Buffer Control in Termination State Descriptor", HFILL }},
3442 { &hf_megaco_events_descriptor,
3443 { "Events Descriptor", "megaco.events", FT_STRING, BASE_NONE, NULL, 0x0,
3444 "Events Descriptor of the megaco Command", HFILL }},
3445 { &hf_megaco_Local_descriptor,
3446 { "Local Descriptor", "megaco.localdescriptor", FT_STRING, BASE_NONE, NULL, 0x0,
3447 "Local Descriptor in Media Descriptor", HFILL }},
3448 { &hf_megaco_LocalControl_descriptor,
3449 { "Local Control Descriptor", "megaco.localcontroldescriptor", FT_STRING, BASE_NONE, NULL, 0x0,
3450 "Local Control Descriptor in Media Descriptor", HFILL }},
3451 { &hf_megaco_media_descriptor,
3452 { "Media Descriptor", "megaco.media", FT_STRING, BASE_NONE, NULL, 0x0,
3453 "Media Descriptor of the megaco Command", HFILL }},
3454 { &hf_megaco_modem_descriptor,
3455 { "Modem Descriptor", "megaco.modem", FT_STRING, BASE_NONE, NULL, 0x0,
3456 "Modem Descriptor of the megaco Command", HFILL }},
3458 { "Mode", "megaco.mode", FT_STRING, BASE_NONE, NULL, 0x0,
3459 "Mode sendonly/receiveonly/inactive/loopback", HFILL }},
3460 { &hf_megaco_multiplex_descriptor,
3461 { "Multiplex Descriptor", "megaco.multiplex", FT_STRING, BASE_NONE, NULL, 0x0,
3462 "Multiplex Descriptor of the megaco Command", HFILL }},
3463 { &hf_megaco_observedevents_descriptor,
3464 { "Observed Events Descriptor", "megaco.observedevents", FT_STRING, BASE_NONE, NULL, 0x0,
3465 "Observed Events Descriptor of the megaco Command", HFILL }},
3466 { &hf_megaco_packages_descriptor,
3467 { "Packages Descriptor", "megaco.packagesdescriptor", FT_STRING, BASE_NONE, NULL, 0x0,
3469 { &hf_megaco_pkgdname,
3470 { "pkgdName", "megaco.pkgdname", FT_STRING, BASE_NONE, NULL, 0x0,
3471 "PackageName SLASH ItemID", HFILL }},
3472 { &hf_megaco_Remote_descriptor,
3473 { "Remote Descriptor", "megaco.remotedescriptor", FT_STRING, BASE_NONE, NULL, 0x0,
3474 "Remote Descriptor in Media Descriptor", HFILL }},
3475 { &hf_megaco_reserve_group,
3476 { "Reserve Group", "megaco.reservegroup", FT_STRING, BASE_NONE, NULL, 0x0,
3477 "Reserve Group on or off", HFILL }},
3478 { &hf_megaco_h324_muxtbl_in,
3479 { "h324/muxtbl_in", "megaco.h324_muxtbl_in", FT_STRING, BASE_NONE, NULL, 0x0,
3481 { &hf_megaco_h324_muxtbl_out,
3482 { "h324/muxtbl_out", "megaco.h324_muxtbl_out", FT_STRING, BASE_NONE, NULL, 0x0,
3484 { &hf_megaco_ds_dscp,
3485 { "ds/dscp", "megaco.ds_dscp", FT_STRING, BASE_NONE, NULL, 0x0,
3486 "ds/dscp Differentiated Services Code Point", HFILL }},
3487 { &hf_megaco_h324_h223capr,
3488 { "h324/h223capr", "megaco._h324_h223capr", FT_STRING, BASE_NONE, NULL, 0x0,
3490 { &hf_megaco_reserve_value,
3491 { "Reserve Value", "megaco.reservevalue", FT_STRING, BASE_NONE, NULL, 0x0,
3492 "Reserve Value on or off", HFILL }},
3493 { &hf_megaco_requestid,
3494 { "RequestID", "megaco.requestid", FT_STRING, BASE_NONE, NULL, 0x0,
3495 "RequestID in Events or Observedevents Descriptor", HFILL }},
3496 { &hf_megaco_servicechange_descriptor,
3497 { "Service Change Descriptor", "megaco.servicechange", FT_STRING, BASE_NONE, NULL, 0x0,
3498 "Service Change Descriptor of the megaco Command", HFILL }},
3499 { &hf_megaco_Service_State,
3500 { "Service State", "megaco.servicestates", FT_STRING, BASE_NONE, NULL, 0x0,
3501 "Service States in Termination State Descriptor", HFILL }},
3502 { &hf_megaco_signal_descriptor,
3503 { "Signal Descriptor", "megaco.signal", FT_STRING, BASE_NONE, NULL, 0x0,
3504 "Signal Descriptor of the megaco Command", HFILL }},
3505 { &hf_megaco_statistics_descriptor,
3506 { "Statistics Descriptor", "megaco.statistics", FT_STRING, BASE_NONE, NULL, 0x0,
3507 "Statistics Descriptor of the megaco Command", HFILL }},
3508 { &hf_megaco_streamid,
3509 { "StreamID", "megaco.streamid", FT_STRING, BASE_NONE, NULL, 0x0,
3510 "StreamID in the Media Descriptor", HFILL }},
3511 { &hf_megaco_termid,
3512 { "Termination ID", "megaco.termid", FT_STRING, BASE_NONE, NULL, 0x0,
3513 "Termination ID of this Command", HFILL }},
3514 { &hf_megaco_TerminationState_descriptor,
3515 { "Termination State Descriptor", "megaco.terminationstate", FT_STRING, BASE_NONE, NULL, 0x0,
3516 "Termination State Descriptor in Media Descriptor", HFILL }},
3517 { &hf_megaco_topology_descriptor,
3518 { "Topology Descriptor", "megaco.topology", FT_STRING, BASE_NONE, NULL, 0x0,
3519 "Topology Descriptor of the megaco Command", HFILL }},
3520 { &hf_megaco_transaction,
3521 { "Transaction", "megaco.transaction", FT_STRING, BASE_NONE, NULL, 0x0,
3522 "Message Originator", HFILL }},
3523 { &hf_megaco_transid,
3524 { "Transaction ID", "megaco.transid", FT_STRING, BASE_NONE, NULL, 0x0,
3525 "Transaction ID of this message", HFILL }},
3527 { "MediagatewayID", "megaco.mId", FT_STRING, BASE_NONE, NULL, 0x0,
3528 "Mediagateway ID", HFILL }},
3529 { &hf_megaco_version,
3530 { "Version", "megaco.version", FT_STRING, BASE_NONE, NULL, 0x0,
3533 { "h245", "megaco.h245", FT_STRING, BASE_NONE, NULL, 0x0,
3534 "Embedded H.245 message", HFILL }},
3535 { &hf_megaco_h223Capability,
3536 { "h223Capability", "megaco.h245.h223Capability", FT_NONE, BASE_NONE, NULL, 0,
3537 "megaco.h245.H223Capability", HFILL }},
3539 GCP_HF_ARR_ELEMS("megaco",megaco_ctx_ids),
3541 /* Add more fields here */
3543 static gint *ett[] = {
3545 &ett_megaco_message,
3546 &ett_megaco_message_body,
3547 &ett_megaco_context,
3548 &ett_megaco_command_line,
3549 &ett_megaco_descriptors,
3550 &ett_megaco_mediadescriptor,
3551 &ett_megaco_TerminationState,
3552 &ett_megaco_Remotedescriptor,
3553 &ett_megaco_Localdescriptor,
3554 &ett_megaco_LocalControldescriptor,
3555 &ett_megaco_auditdescriptor,
3556 &ett_megaco_eventsdescriptor,
3557 &ett_megaco_observedeventsdescriptor,
3558 &ett_megaco_observedevent,
3559 &ett_megaco_packagesdescriptor,
3560 &ett_megaco_requestedevent,
3561 &ett_megaco_signalsdescriptor,
3562 &ett_megaco_requestedsignal,
3564 GCP_ETT_ARR_ELEMS(megaco_ctx_ids),
3567 module_t *megaco_module;
3569 proto_megaco = proto_register_protocol("MEGACO",
3570 "MEGACO", "megaco");
3572 register_dissector("megaco", dissect_megaco_text, proto_megaco);
3574 proto_register_field_array(proto_megaco, hf, array_length(hf));
3575 proto_register_subtree_array(ett, array_length(ett));
3577 /* Register our configuration options, particularly our ports */
3579 megaco_module = prefs_register_protocol(proto_megaco, proto_reg_handoff_megaco);
3581 prefs_register_uint_preference(megaco_module, "tcp.txt_port",
3582 "MEGACO Text TCP Port",
3583 "Set the TCP port for MEGACO text messages",
3584 10, &global_megaco_txt_tcp_port);
3586 prefs_register_uint_preference(megaco_module, "udp.txt_port",
3587 "MEGACO Text UDP Port",
3588 "Set the UDP port for MEGACO text messages",
3589 10, &global_megaco_txt_udp_port);
3592 prefs_register_uint_preference(megaco_module, "tcp.bin_port",
3593 "MEGACO Binary TCP Port",
3594 "Set the TCP port for MEGACO binary messages",
3595 10, &global_megaco_bin_tcp_port);
3597 prefs_register_uint_preference(megaco_module, "udp.bin_port",
3598 "MEGACO Binary UDP Port",
3599 "Set the UDP port for MEGACO binary messages",
3600 10, &global_megaco_bin_udp_port);
3603 prefs_register_bool_preference(megaco_module, "display_raw_text",
3604 "Display raw text for MEGACO message",
3605 "Specifies that the raw text of the "
3606 "MEGACO message should be displayed "
3607 "instead of (or in addition to) the "
3609 &global_megaco_raw_text);
3611 prefs_register_bool_preference(megaco_module, "display_dissect_tree",
3612 "Display tree dissection for MEGACO message",
3613 "Specifies that the dissection tree of the "
3614 "MEGACO message should be displayed "
3615 "instead of (or in addition to) the "
3617 &global_megaco_dissect_tree);
3618 prefs_register_bool_preference(megaco_module, "ctx_info",
3620 "Mantain relationships between transactions and contexts "
3621 "and display an extra tree showing context data",
3622 &keep_persistent_data);
3624 megaco_tap = register_tap("megaco");
3630 * megaco_tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3631 * character following offset or offset + maxlength -1 whichever
3635 * tvb - The tvbuff in which we are skipping whitespaces, tab and end_of_line characters.
3636 * offset - The offset in tvb from which we begin trying to skip whitespace.
3638 * Returns: The position in tvb of the first non-whitespace
3640 static gint megaco_tvb_skip_wsp(tvbuff_t* tvb, gint offset ){
3641 gint counter = offset;
3644 tvb_len = tvb_length(tvb);
3647 for(counter = offset; counter < end &&
3648 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3649 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter++);
3652 static gint megaco_tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
3653 gint counter = offset;
3658 for(counter = offset; counter > end &&
3659 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3660 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);