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 * Modified 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
50 #include <epan/packet.h>
51 #include <epan/exceptions.h>
52 #include <epan/wmem/wmem.h>
53 #include <epan/addr_resolv.h>
54 #include <epan/prefs.h>
55 #include <epan/strutil.h>
56 #include <epan/sctpppids.h>
57 #include <epan/dissectors/packet-tpkt.h>
58 #include <epan/asn1.h>
59 #include <epan/dissectors/packet-per.h>
60 #include <epan/dissectors/packet-h245.h>
61 #include <epan/dissectors/packet-ip.h>
62 #include <epan/dissectors/packet-ber.h>
67 #define PORT_MEGACO_TXT 2944
68 #define PORT_MEGACO_BIN 2945
70 /* Define the megaco proto */
71 static int proto_megaco
= -1;
73 /* Define headers for megaco */
74 static int hf_megaco_version
= -1;
75 static int hf_megaco_transaction
= -1;
76 static int hf_megaco_transid
= -1;
77 static int hf_megaco_Context
= -1;
78 /* static int hf_megaco_command_line = -1; */
79 static int hf_megaco_command
= -1;
80 static int hf_megaco_termid
= -1;
84 /* Define headers in subtree for megaco */
85 static int hf_megaco_modem_descriptor
= -1;
86 static int hf_megaco_multiplex_descriptor
= -1;
87 /* static int hf_megaco_media_descriptor = -1; */
88 /* static int hf_megaco_events_descriptor = -1; */
89 /* static int hf_megaco_signal_descriptor = -1; */
90 static int hf_megaco_audit_descriptor
= -1;
91 /* static int hf_megaco_servicechange_descriptor = -1; */
92 static int hf_megaco_digitmap_descriptor
= -1;
93 static int hf_megaco_statistics_descriptor
= -1;
94 /* static int hf_megaco_observedevents_descriptor = -1; */
95 static int hf_megaco_topology_descriptor
= -1;
96 static int hf_megaco_error_descriptor
= -1;
97 /* static int hf_megaco_TerminationState_descriptor= -1; */
98 /* static int hf_megaco_Remote_descriptor = -1; */
99 /* static int hf_megaco_Local_descriptor = -1; */
100 /* static int hf_megaco_LocalControl_descriptor = -1; */
101 static int hf_megaco_packages_descriptor
= -1;
102 static int hf_megaco_error_Frame
= -1;
103 static int hf_megaco_Service_State
= -1;
104 static int hf_megaco_Event_Buffer_Control
= -1;
105 static int hf_megaco_mode
= -1;
106 static int hf_megaco_reserve_group
= -1;
107 static int hf_megaco_h324_muxtbl_in
= -1;
108 static int hf_megaco_h324_muxtbl_out
= -1;
109 static int hf_megaco_ds_dscp
= -1;
110 static int hf_megaco_h324_h223capr
= -1;
111 static int hf_megaco_reserve_value
= -1;
112 static int hf_megaco_streamid
= -1;
113 static int hf_megaco_requestid
= -1;
114 static int hf_megaco_pkgdname
= -1;
115 static int hf_megaco_mId
= -1;
116 /* static int hf_megaco_h245 = -1; */
117 static int hf_megaco_h223Capability
= -1;
118 static int hf_megaco_audititem
= -1;
120 /* Define the trees for megaco */
121 static int ett_megaco
= -1;
122 static int ett_megaco_message
= -1;
123 static int ett_megaco_message_body
= -1;
124 static int ett_megaco_context
= -1;
125 static int ett_megaco_command_line
= -1;
126 static int ett_megaco_mediadescriptor
= -1;
127 static int ett_megaco_descriptors
= -1;
128 static int ett_megaco_TerminationState
= -1;
129 static int ett_megaco_Localdescriptor
= -1;
130 static int ett_megaco_Remotedescriptor
= -1;
131 static int ett_megaco_LocalControldescriptor
= -1;
132 static int ett_megaco_auditdescriptor
= -1;
133 static int ett_megaco_eventsdescriptor
= -1;
134 static int ett_megaco_observedeventsdescriptor
= -1;
135 static int ett_megaco_observedevent
= -1;
136 static int ett_megaco_packagesdescriptor
= -1;
137 static int ett_megaco_requestedevent
= -1;
138 static int ett_megaco_signalsdescriptor
= -1;
139 static int ett_megaco_requestedsignal
= -1;
140 static int ett_megaco_h245
= -1;
142 static gcp_hf_ett_t megaco_ctx_ids
= {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}};
144 static expert_field ei_megaco_errored_command
= EI_INIT
;
145 static expert_field ei_megaco_error_descriptor_transaction_list
= EI_INIT
;
146 static expert_field ei_megaco_parse_error
= EI_INIT
;
147 static expert_field ei_megaco_audit_descriptor
= EI_INIT
;
149 static dissector_handle_t megaco_text_handle
;
151 static int megaco_tap
= -1;
154 * Here are the global variables associated with
155 * the various user definable characteristics of the dissection
157 * MEGACO has two kinds of message formats: text and binary
159 * global_megaco_raw_text determines whether we are going to display
160 * the raw text of the megaco message, much like the HTTP dissector does.
162 * global_megaco_dissect_tree determines whether we are going to display
163 * a detailed tree that expresses a somewhat more semantically meaningful
166 static guint global_megaco_txt_sctp_port
= PORT_MEGACO_TXT
;
167 static guint global_megaco_txt_tcp_port
= PORT_MEGACO_TXT
;
168 static guint global_megaco_txt_udp_port
= PORT_MEGACO_TXT
;
170 static guint global_megaco_bin_sctp_port
= PORT_MEGACO_BIN
;
171 static guint global_megaco_bin_tcp_port
= PORT_MEGACO_BIN
;
172 static guint global_megaco_bin_udp_port
= PORT_MEGACO_BIN
;
174 static gboolean global_megaco_raw_text
= TRUE
;
175 static gboolean global_megaco_dissect_tree
= TRUE
;
177 /* Some basic utility functions that are specific to this dissector */
178 static gint
megaco_tvb_skip_wsp(tvbuff_t
* tvb
, gint offset
);
179 static gint
megaco_tvb_skip_wsp_return(tvbuff_t
* tvb
, gint offset
);
181 * The various functions that either dissect some
182 * subpart of MEGACO. These aren't really proto dissectors but they
183 * are written in the same style.
187 dissect_megaco_descriptors(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, gint tvb_descriptors_start_offset
, gint tvb_descriptors_end_offset
);
189 dissect_megaco_modemdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
191 dissect_megaco_multiplexdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
193 dissect_megaco_mediadescriptor(tvbuff_t
*tvb
, proto_tree
*tree
,packet_info
*pinfo
, gint tvb_RBRKT
, gint tvb_previous_offset
);
195 dissect_megaco_eventsdescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
197 dissect_megaco_signaldescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
199 dissect_megaco_auditdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
,packet_info
*pinfo
, gint tvb_RBRKT
, gint tvb_previous_offset
);
201 dissect_megaco_servicechangedescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
203 dissect_megaco_digitmapdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
205 dissect_megaco_statisticsdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
207 dissect_megaco_observedeventsdescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
209 dissect_megaco_topologydescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
211 dissect_megaco_errordescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_RBRKT
, gint tvb_previous_offset
);
213 dissect_megaco_TerminationStatedescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_next_offset
, gint tvb_current_offset
);
215 dissect_megaco_Localdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, gint tvb_next_offset
, gint tvb_current_offset
);
217 dissect_megaco_LocalControldescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, gint tvb_next_offset
, gint tvb_current_offset
);
219 dissect_megaco_Packagesdescriptor(tvbuff_t
*tvb
, proto_tree
*tree
, gint tvb_next_offset
, gint tvb_current_offset
);
221 tvb_raw_text_add(tvbuff_t
*tvb
, proto_tree
*tree
);
223 dissect_megaco_text(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
225 megaco_tvb_find_token(tvbuff_t
* tvb
, gint offset
, gint maxlenght
);
226 static dissector_handle_t data_handle
;
227 static dissector_handle_t sdp_handle
;
228 static dissector_handle_t h245_handle
;
229 static dissector_handle_t h248_handle
;
230 static dissector_handle_t h248_otp_handle
;
232 static gboolean keep_persistent_data
= FALSE
;
234 static proto_tree
*top_tree
;
236 * dissect_megaco_text over TCP, there will be a TPKT header there
239 static void dissect_megaco_text_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
243 /* This code is copied from the Q.931 dissector, some parts skipped.
244 * Check whether this looks like a TPKT-encapsulated
247 * The minimum length of a MEGACO message is 6?:
250 lv_tpkt_len
= is_tpkt(tvb
, 6);
251 if (lv_tpkt_len
== -1) {
253 * It's not a TPKT packet;
256 dissect_megaco_text(tvb
, pinfo
, tree
);
258 dissect_tpkt_encap(tvb
, pinfo
, tree
, TRUE
,
265 #define PENDINGTOKEN 4
266 #define RESPONSEACKTOKEN 5
270 const char *compact_name
;
273 static const megaco_tokens_t megaco_messageBody_names
[] = {
274 { "Unknown-token", NULL
}, /* 0 Pad so that the real headers start at index 1 */
275 { "Error", "ER" }, /* 1 */
276 { "Transaction", "T" }, /* 2 */
277 { "Reply", "P" }, /* 3 */
278 { "Pending", "PN" }, /* 4 */
279 { "TransactionResponseAck", "K" }, /* 5 */
282 /* Returns index of megaco_tokens_t */
283 static gint
find_megaco_messageBody_names(tvbuff_t
*tvb
, int offset
, guint header_len
)
287 for (i
= 1; i
< array_length(megaco_messageBody_names
); i
++) {
288 if (header_len
== strlen(megaco_messageBody_names
[i
].name
) &&
289 tvb_strncaseeql(tvb
, offset
, megaco_messageBody_names
[i
].name
, header_len
) == 0)
291 if (megaco_messageBody_names
[i
].compact_name
!= NULL
&&
292 header_len
== strlen(megaco_messageBody_names
[i
].compact_name
) &&
293 tvb_strncaseeql(tvb
, offset
, megaco_messageBody_names
[i
].compact_name
, header_len
) == 0)
301 my_proto_tree_add_string(proto_tree
*tree
, int hfindex
, tvbuff_t
*tvb
,
302 gint start
, gint length
, const char *value
)
306 pi
= proto_tree_add_string(tree
, hfindex
, tvb
, start
, length
, value
);
307 if (!global_megaco_dissect_tree
) {
308 PROTO_ITEM_SET_HIDDEN(pi
);
314 * dissect_megaco_text - The dissector for the MEGACO Protocol, using
318 dissect_megaco_text(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
321 gint tvb_offset
,tvb_current_offset
,tvb_previous_offset
,tvb_next_offset
,tokenlen
;
322 gint line_start_offset
, ver_offset
, ver_length
, mId_offset
, mId_length
;
323 gint tvb_command_start_offset
, tvb_command_end_offset
;
324 gint tvb_descriptors_start_offset
, tvb_descriptors_end_offset
;
325 gint tvb_transaction_end_offset
;
326 proto_tree
*megaco_tree
, *message_tree
, *message_body_tree
, *megaco_context_tree
, *megaco_tree_command_line
, *ti
, *sub_ti
;
331 gint tvb_RBRKT
, tvb_LBRKT
, RBRKT_counter
, LBRKT_counter
;
337 gcp_msg_t
* msg
= NULL
;
338 gcp_trx_t
* trx
= NULL
;
339 gcp_ctx_t
* ctx
= NULL
;
340 gcp_cmd_t
* cmd
= NULL
;
341 gcp_term_t
* term
= NULL
;
342 gcp_trx_type_t trx_type
= GCP_TRX_NONE
;
345 gcp_cmd_type_t cmd_type
= GCP_CMD_NONE
;
346 gcp_wildcard_t wild_term
= GCP_WILDCARD_NONE
;
347 proto_item
*hidden_item
;
350 /* Initialize variables */
351 tvb_len
= tvb_length(tvb
);
358 /* Check if H.248 in otp(Erlang) internal format
359 * XXX Needs improvement?
361 * http://www.erlang.org/doc/apps/megaco/part_frame.html
362 * 4.1 Internal form of messages
363 * 4.2 The different encodings
365 dword
= tvb_get_ntoh24(tvb
,0);
366 if ((dword
== 0x836803)&&(h248_otp_handle
)){
367 call_dissector(h248_otp_handle
, tvb
, pinfo
, tree
);
371 msg
= gcp_msg(pinfo
, tvb_raw_offset(tvb
), keep_persistent_data
);
374 * Check to see whether we're really dealing with MEGACO by looking
375 * for the "MEGACO" string or a "!".This needs to be improved when supporting
376 * binary encodings. Bugfix add skipping of leading spaces.
378 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
);
379 line_start_offset
= tvb_offset
;
380 /* Quick fix for MEGACO not following the RFC, hopefully not breaking any thing
381 * Turned out to be TPKT in case of TCP, added some code to handle that.
383 * tvb_offset = tvb_find_guint8(tvb, tvb_offset, 5, 'M');
385 if(!tvb_get_nstringz0(tvb
,tvb_offset
,sizeof(word
),word
)) return;
390 if (g_ascii_strncasecmp(word
, "MEGACO", 6) != 0 && tvb_get_guint8(tvb
, tvb_offset
) != '!'){
394 dissector_handle_t handle
= data_handle
;
396 get_ber_identifier(tvb
, 0, &ber_class
, &pc
, &tag
);
398 if (ber_class
== BER_CLASS_UNI
&& pc
&& tag
== BER_UNI_TAG_SEQUENCE
) {
399 handle
= h248_handle
;
402 call_dissector(handle
,tvb
,pinfo
,tree
);
408 /* Display MEGACO in protocol column */
409 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MEGACO");
411 /* Build the info tree if we've been given a root */
412 /* Create megaco subtree */
413 ti
= proto_tree_add_item(tree
,proto_megaco
,tvb
, 0, -1, ENC_NA
);
414 megaco_tree
= proto_item_add_subtree(ti
, ett_megaco
);
416 /* Format of 'message' is = MegacopToken SLASH Version SEP mId SEP messageBody */
417 /* MegacopToken = "MEGACO" or "!" */
418 /* According to H248.1-200205 Annex B Text encoding ( protocol version 2 ) */
421 tvb_previous_offset
= tvb_find_guint8(tvb
, 0,
423 if (tvb_previous_offset
== -1) {
424 expert_add_info_format(pinfo
, ti
, &ei_megaco_parse_error
,
425 "Sorry, no \"/\" in the MEGACO header, I can't parse this packet");
430 tvb_previous_offset
++;
432 /* assume at least one digit in version */
433 tvb_current_offset
= tvb_previous_offset
+ 1;
435 if (isdigit(tvb_get_guint8(tvb
, tvb_current_offset
))) {
436 /* 2-digit version */
437 tvb_current_offset
++;
440 tokenlen
= tvb_current_offset
- tvb_previous_offset
;
441 ver_offset
= tvb_previous_offset
;
442 ver_length
= tokenlen
;
444 tvb_previous_offset
= tvb_current_offset
;
445 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_previous_offset
);
447 if (tvb_previous_offset
== tvb_current_offset
) {
448 expert_add_info_format(pinfo
, ti
, &ei_megaco_parse_error
,
449 "[ Parse error: missing SEP in MEGACO header ]");
453 tvb_previous_offset
= tvb_current_offset
;
455 /* mId should follow here,
456 * mId = (( domainAddress / domainName ) [":" portNumber]) / mtpAddress / deviceName
457 * domainAddress = "[" (IPv4address / IPv6address) "]"
458 * domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /".") ">"
459 * mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT
461 * deviceName = pathNAME
462 * pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )["@" pathDomainName ]
465 tvb_current_offset
= tvb_pbrk_guint8(tvb
, tvb_current_offset
, -1, " \t\r\n", &needle
);
466 if (tvb_current_offset
== -1) {
467 expert_add_info_format(pinfo
, ti
, &ei_megaco_parse_error
,
468 "[ Parse error: no body in MEGACO message (missing SEP after mId) ]");
472 tokenlen
= tvb_current_offset
- tvb_previous_offset
;
473 tvb_next_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
);
475 /* At this point we should point to the "\n" ending the mId element
476 * or to the next character after white space SEP
478 mId_offset
= tvb_previous_offset
;
479 mId_length
= tokenlen
;
481 /* Add the first line to the tree */
482 tokenlen
= tvb_next_offset
- line_start_offset
- 1;
483 ti
= proto_tree_add_text(megaco_tree
, tvb
, line_start_offset
, tokenlen
,
484 "%s",tvb_format_text(tvb
,line_start_offset
,tokenlen
));
485 message_tree
= proto_item_add_subtree(ti
, ett_megaco_message
);
487 if(global_megaco_dissect_tree
){
488 proto_tree_add_item(message_tree
, hf_megaco_version
,tvb
, ver_offset
, ver_length
, ENC_ASCII
|ENC_NA
);
489 proto_tree_add_item(message_tree
, hf_megaco_mId
,tvb
, mId_offset
, mId_length
, ENC_ASCII
|ENC_NA
);
491 hidden_item
= proto_tree_add_item(message_tree
, hf_megaco_version
,tvb
, ver_offset
, ver_length
, ENC_ASCII
|ENC_NA
);
492 PROTO_ITEM_SET_HIDDEN(hidden_item
);
493 hidden_item
= proto_tree_add_item(message_tree
, hf_megaco_mId
,tvb
, mId_offset
, mId_length
, ENC_ASCII
|ENC_NA
);
494 PROTO_ITEM_SET_HIDDEN(hidden_item
);
497 col_clear(pinfo
->cinfo
, COL_INFO
);
500 tvb_previous_offset
= tvb_next_offset
;
503 * : messageBody = ( errorDescriptor / transactionList )
504 * errorDescriptor = ErrorToken EQUAL ErrorCode LBRKT [quotedString] RBRKT
505 * ErrorToken = ("Error" / "ER")
507 * transactionList = 1*( transactionRequest / transactionReply /
508 * transactionPending / transactionResponseAck )
510 * transactionResponseAck = ResponseAckToken LBRKT
511 * transactionAck*(COMMA transactionAck) RBRKT
512 * ResponseAckToken = ("TransactionResponseAck"/ "K")
514 * transactionPending = PendingToken EQUAL TransactionID LBRKT RBRKT
515 * PendingToken = ("Pending" / "PN")
517 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
518 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
519 * ReplyToken = ("Reply" / "P")
521 * transactionRequest = TransToken EQUAL TransactionID LBRKT
522 * actionRequest *(COMMA actionRequest) RBRKT
523 * TransToken = ("Transaction" / "T")
526 /* Find token length */
527 for (tvb_offset
=tvb_previous_offset
; tvb_offset
< tvb_len
-1; tvb_offset
++){
528 if (!isalpha(tvb_get_guint8(tvb
, tvb_offset
))){
532 tokenlen
= tvb_offset
- tvb_previous_offset
;
533 token_index
= find_megaco_messageBody_names(tvb
, tvb_previous_offset
, tokenlen
);
535 g_warning("token_index %u",token_index);
538 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_offset
, tvb_len
, '{');
539 tvb_current_offset
= tvb_LBRKT
;
540 tvb_transaction_end_offset
= megaco_tvb_find_token(tvb
, tvb_LBRKT
- 1, tvb_len
);
542 switch ( token_index
){
543 /* errorDescriptor */
545 col_set_str(pinfo
->cinfo
, COL_INFO
, "Error ");
547 tvb_current_offset
= megaco_tvb_find_token(tvb
, tvb_offset
, tvb_len
); /*tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');*/
549 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
,
550 "%s",tvb_format_text(tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
));
551 message_body_tree
= proto_item_add_subtree(ti
, ett_megaco_message_body
);
554 my_proto_tree_add_string(message_body_tree
, hf_megaco_transaction
, tvb
,
555 tvb_previous_offset
, tokenlen
,
558 tvb_command_start_offset
= tvb_previous_offset
;
559 dissect_megaco_errordescriptor(tvb
, megaco_tree
, tvb_len
-1, tvb_command_start_offset
);
562 /* transactionResponseAck
563 * transactionResponseAck = ResponseAckToken LBRKT transactionAck
564 * *(COMMA transactionAck) RBRKT
565 * transactionAck = transactionID / (transactionID "-" transactionID)
567 case RESPONSEACKTOKEN
:
568 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_offset
, tvb_transaction_end_offset
, '{');
569 tvb_offset
= tvb_LBRKT
;
571 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_offset
-tvb_previous_offset
,
572 "%s",tvb_format_text(tvb
, tvb_previous_offset
, tvb_offset
-tvb_previous_offset
+1));
573 message_body_tree
= proto_item_add_subtree(ti
, ett_megaco_message_body
);
575 my_proto_tree_add_string(message_body_tree
, hf_megaco_transaction
, tvb
,
576 tvb_previous_offset
, tokenlen
,
577 "TransactionResponseAck" );
579 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
580 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_offset
+1, tvb_len
, '}');
581 /*tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_transaction_end_offset);*/
582 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
)-1; /* cut last RBRKT */
583 len
= tvb_current_offset
- tvb_previous_offset
;
586 col_append_str(pinfo
->cinfo
, COL_INFO
, " ");
588 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s TransactionResponseAck",
589 tvb_format_text(tvb
,tvb_previous_offset
,len
));
592 my_proto_tree_add_string(message_body_tree
, hf_megaco_transid
, tvb
,
593 tvb_previous_offset
, len
,
594 tvb_format_text(tvb
,tvb_previous_offset
,len
));
596 if(global_megaco_raw_text
){
597 tvb_raw_text_add(tvb
, megaco_tree
);
600 /* Pe and PN is transactionPending, P+"any char" is transactionReply */
603 tvb_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_transaction_end_offset
, '=')+1;
604 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
);
605 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_offset
, tvb_transaction_end_offset
, '{');
606 tvb_current_offset
= tvb_LBRKT
;
607 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
,
608 "%s",tvb_format_text(tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
+1));
609 message_body_tree
= proto_item_add_subtree(ti
, ett_megaco_message_body
);
611 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1);
612 len
= tvb_current_offset
- tvb_offset
;
614 my_proto_tree_add_string(message_body_tree
, hf_megaco_transaction
, tvb
,
615 tvb_previous_offset
, tokenlen
,
619 col_append_str(pinfo
->cinfo
, COL_INFO
, " ");
621 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s Pending",
622 tvb_format_text(tvb
,tvb_offset
,len
));
625 my_proto_tree_add_string(message_body_tree
, hf_megaco_transid
, tvb
,
627 tvb_format_text(tvb
,tvb_offset
,len
));
630 /* transactionReply */
632 trx_type
= GCP_TRX_REPLY
;
633 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_offset
, tvb_transaction_end_offset
, '{');
634 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_LBRKT
-tvb_previous_offset
,
635 "%s",tvb_format_text(tvb
, tvb_previous_offset
, tvb_LBRKT
-tvb_previous_offset
+1));
636 message_body_tree
= proto_item_add_subtree(ti
, ett_megaco_message_body
);
639 my_proto_tree_add_string(message_body_tree
, hf_megaco_transaction
, tvb
,
640 tvb_previous_offset
, tokenlen
,
643 tvb_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_transaction_end_offset
, '=')+1;
644 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
);
645 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_LBRKT
-1);
646 len
= tvb_current_offset
- tvb_offset
;
648 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s Reply ",
649 tvb_format_text(tvb
,tvb_offset
,len
));
650 trx_id
= (guint
)strtoul(tvb_format_text(tvb
,tvb_offset
,len
),NULL
,10);
653 my_proto_tree_add_string(message_body_tree
, hf_megaco_transid
, tvb
,
654 tvb_offset
, len
, tvb_format_text(tvb
,tvb_offset
,len
));
656 /* Find if we have a errorDescriptor or actionReplyList */
657 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
658 tempchar
= tvb_get_guint8(tvb
,tvb_offset
);
659 if ((tempchar
== 'E')||(tempchar
== 'e')){
660 dissect_megaco_errordescriptor(tvb
, megaco_tree
, tvb_transaction_end_offset
-1, tvb_offset
);
663 /* Offset should be at first printable char after { */
664 tvb_previous_offset
= tvb_offset
;
667 /* TransactionRequest */
668 trx_type
= GCP_TRX_REQUEST
;
669 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
,
670 "%s",tvb_format_text(tvb
, tvb_previous_offset
, tvb_current_offset
-tvb_previous_offset
+1));
671 message_body_tree
= proto_item_add_subtree(ti
, ett_megaco_message_body
);
674 my_proto_tree_add_string(message_body_tree
, hf_megaco_transaction
, tvb
,
675 tvb_previous_offset
, tokenlen
,
677 tvb_offset
= tvb_find_guint8(tvb
, tvb_offset
, tvb_transaction_end_offset
, '=')+1;
678 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
);
679 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1);
680 len
= tvb_current_offset
- tvb_offset
;
682 col_append_str(pinfo
->cinfo
, COL_INFO
, " ");
684 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s Request",
685 tvb_format_text(tvb
,tvb_offset
,len
));
686 trx_id
= (guint
)strtoul(tvb_format_text(tvb
,tvb_offset
,len
),NULL
,10);
688 my_proto_tree_add_string(message_body_tree
, hf_megaco_transid
, tvb
, tvb_offset
,len
,
689 tvb_format_text(tvb
,tvb_offset
,len
));
690 /* Offset should be at first printable char after { */
691 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
695 ti
= proto_tree_add_item(tree
,proto_megaco
,tvb
, 0, -1, ENC_NA
);
696 expert_add_info_format(pinfo
, ti
, &ei_megaco_error_descriptor_transaction_list
,
697 "Sorry, can't understand errorDescriptor / transactionList = %s, can't parse it pos %u",
698 tvb_format_text(tvb
,tvb_previous_offset
,2),tvb_previous_offset
);
701 /* Only these remains now
702 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
703 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
704 * ReplyToken = ("Reply" / "P")
706 * errorDescriptor = ErrorToken EQUAL ErrorCode
707 * LBRKT [quotedString] RBRKT
709 * transactionRequest = TransToken EQUAL TransactionID LBRKT
710 * actionRequest *(COMMA actionRequest) RBRKT
711 * TransToken = ("Transaction" / "T")
714 trx
= gcp_trx(msg
, trx_id
, trx_type
, keep_persistent_data
);
722 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_transaction_end_offset
, '{');
723 ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tvb_next_offset
-tvb_previous_offset
+1,
724 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tvb_next_offset
-tvb_previous_offset
+1));
725 megaco_context_tree
= proto_item_add_subtree(ti
, ett_megaco_context
);
727 tvb_previous_offset
= tvb_find_guint8(tvb
, tvb_current_offset
,
728 tvb_transaction_end_offset
, '=')+1;
729 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_previous_offset
);
730 if (tvb_current_offset
>= tvb_next_offset
) {
731 expert_add_info_format(pinfo
, ti
, &ei_megaco_parse_error
, "Parse error: Invalid offset");
734 tvb_current_offset
= tvb_next_offset
;
737 tokenlen
= tvb_current_offset
- tvb_previous_offset
;
738 tempchar
= tvb_get_guint8(tvb
, tvb_previous_offset
);
740 if (tvb_get_guint8(tvb
, tvb_current_offset
-1 ) == ' '){
747 ctx_id
= CHOOSE_CONTEXT
;
748 my_proto_tree_add_string(megaco_context_tree
, hf_megaco_Context
, tvb
,
749 tvb_previous_offset
, 1,
751 col_append_str(pinfo
->cinfo
, COL_INFO
, " |=Choose one");
754 ctx_id
= ALL_CONTEXTS
;
755 my_proto_tree_add_string(megaco_context_tree
, hf_megaco_Context
, tvb
,
756 tvb_previous_offset
, 1,
758 col_append_str(pinfo
->cinfo
, COL_INFO
, " |=All");
761 ctx_id
= NULL_CONTEXT
;
762 proto_tree_add_text(megaco_context_tree
, tvb
, tvb_previous_offset
, tokenlen
, "Context: NULL" );
763 col_append_str(pinfo
->cinfo
, COL_INFO
, " |=NULL");
766 my_proto_tree_add_string(megaco_context_tree
, hf_megaco_Context
, tvb
,
767 tvb_previous_offset
, tokenlen
,
768 tvb_format_text(tvb
, tvb_previous_offset
,
770 ctx_id
= (guint
)strtoul(tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
),NULL
,10);
772 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " |=%s",tvb_format_text(tvb
, tvb_previous_offset
,tokenlen
));
775 ctx
= gcp_ctx(msg
,trx
,ctx_id
,keep_persistent_data
);
779 /* If Transaction is is Request, Reply or Pending */
780 tvb_command_start_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
781 tvb_command_end_offset
= tvb_command_start_offset
;
783 tvb_LBRKT
= tvb_command_start_offset
;
784 tvb_RBRKT
= tvb_command_start_offset
;
786 /* The following loop find the individual contexts, commands and call the for every Descriptor a subroutine */
789 tvb_command_end_offset
= tvb_find_guint8(tvb
, tvb_command_end_offset
+1,
790 tvb_transaction_end_offset
, ',');
792 if ( tvb_command_end_offset
== -1 || tvb_command_end_offset
> tvb_transaction_end_offset
){
793 tvb_command_end_offset
= tvb_transaction_end_offset
;
797 /* checking how many left brackets are before the next comma */
799 while ( tvb_find_guint8(tvb
, tvb_LBRKT
+1,tvb_transaction_end_offset
, '{') != -1
800 && (tvb_find_guint8(tvb
, tvb_LBRKT
+1,tvb_transaction_end_offset
, '{') < tvb_command_end_offset
)){
802 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
803 tvb_transaction_end_offset
, '{');
808 /* checking how many right brackets are before the next comma */
810 while ( (tvb_find_guint8(tvb
, tvb_RBRKT
+1,tvb_transaction_end_offset
, '}') != -1 )
811 && (tvb_find_guint8(tvb
, tvb_RBRKT
+1,tvb_transaction_end_offset
, '}') <= tvb_command_end_offset
)
812 && LBRKT_counter
!= 0){
814 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
815 tvb_transaction_end_offset
, '}');
821 /* If equal or more right brackets before the comma, one command is complete */
823 if ( LBRKT_counter
<= RBRKT_counter
){
825 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
,
826 tvb_transaction_end_offset
, '{');
829 /* includes no descriptors */
831 if ( LBRKT_counter
== 0 ){
833 tvb_current_offset
= tvb_command_end_offset
;
835 /* the last command in a context */
837 if ( tvb_find_guint8(tvb
, tvb_command_start_offset
, tvb_transaction_end_offset
, '}') < tvb_current_offset
838 && tvb_find_guint8(tvb
, tvb_command_start_offset
, tvb_transaction_end_offset
, '}') != -1){
840 tvb_previous_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
,
841 tvb_transaction_end_offset
, '}');
843 len
= tvb_previous_offset
- tvb_command_start_offset
;
845 tvb_previous_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_previous_offset
-1);
847 tokenlen
= tvb_previous_offset
- tvb_command_start_offset
;
851 /* not the last command in a context*/
854 len
= tvb_current_offset
- tvb_command_start_offset
;
855 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1);
857 tokenlen
= tvb_current_offset
- tvb_command_start_offset
;
861 /* command includes descriptors */
864 len
= tvb_current_offset
- tvb_command_start_offset
;
865 tvb_current_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1);
867 tokenlen
= tvb_current_offset
- tvb_command_start_offset
;
870 /* if a next context is specified */
872 if ( tvb_get_guint8(tvb
, tvb_command_start_offset
) == 'C'){
873 tvb_current_offset
= tvb_command_start_offset
;
874 tvb_previous_offset
= tvb_command_start_offset
;
880 sub_ti
= proto_tree_add_text(megaco_tree
, tvb
, tvb_command_start_offset
, len
+1,
881 "%s", tvb_format_text(tvb
, tvb_command_start_offset
, len
+1));
882 megaco_tree_command_line
= proto_item_add_subtree(sub_ti
, ett_megaco_command_line
);
883 /* creation of the megaco_tree_command_line additionally Command and Transaction ID will be printed in this line */
884 /* Changed to use the lines above. this code is saved if there is complaints
885 sub_ti = proto_tree_add_item(megaco_tree,hf_megaco_command_line,tvb,tvb_command_start_offset,tokenlen, ENC_ASCII|ENC_NA);
886 megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
889 tvb_next_offset
= tvb_command_start_offset
+ tokenlen
;
891 /* Try to dissect Topology Descriptor before the command */
892 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
);
893 if ( (tempchar
>= 'a')&& (tempchar
<= 'z')){
894 tempchar
= tempchar
- 0x20;
896 if ( tempchar
== 'T') {
897 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
+1);
899 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
900 tempchar
= tempchar
- 0x20;
902 if ( tempchar
== 'P' || tempchar
== 'O'){
903 gint tvb_topology_end_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
, tvb_transaction_end_offset
, '}');
904 if ( tvb_topology_end_offset
== -1 ){
905 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Missing \"}\"");
909 tvb_command_start_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
, tvb_transaction_end_offset
, '{');
910 if ( tvb_command_start_offset
== -1 ){
911 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Missing \"{\"");
914 dissect_megaco_topologydescriptor(tvb
, megaco_tree_command_line
, tvb_topology_end_offset
-1, tvb_command_start_offset
+1);
916 /* Command after Topology Descriptor */
917 tvb_command_start_offset
= tvb_find_guint8(tvb
, tvb_topology_end_offset
+ 1,
918 tvb_transaction_end_offset
, ',');
920 if ( tvb_command_start_offset
== -1 ){
921 /* No Command present after Topology Descriptor */
925 /* Try to find the first char of the command */
926 tvb_command_start_offset
= megaco_tvb_skip_wsp(tvb
, tvb_command_start_offset
+ 1);
927 /*tvb_next_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');*/
934 /* Additional value */
936 if ( tvb_get_guint8(tvb
, tvb_command_start_offset
) == 'O'){
938 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_command_start_offset
, 2, "O- indicates an optional command" );
939 tvb_command_start_offset
= tvb_command_start_offset
+2;
943 /* Additional value */
945 if ( tvb_get_guint8(tvb
, tvb_command_start_offset
) == 'W'){
947 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_command_start_offset
, 2, "W- indicates a wildcarded response to a command" );
948 tvb_command_start_offset
= tvb_command_start_offset
+2;
954 tvb_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
,
955 tvb_transaction_end_offset
, '=');
956 if (tvb_offset
== -1 ) {
957 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Missing \"=\"");
960 tvb_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_offset
-1);
961 tokenlen
= tvb_offset
- tvb_command_start_offset
;
963 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
);
964 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
965 tempchar
= tempchar
- 0x20;
967 if ( tempchar
!= 'E' ){
969 /* Short form used */
970 if ( tvb_get_guint8(tvb
, 0 ) == '!'){
976 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
+1);
977 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
978 tempchar
= tempchar
- 0x20;
984 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_AUDITVAL_REPLY
; break;
985 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_AUDITVAL_REQ
; break;
986 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 col_append_str(pinfo
->cinfo
, COL_INFO
, " AuditValue");
997 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_AUDITCAP_REQ
; break;
998 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_AUDITCAP_REPLY
; break;
999 default: cmd_type
= GCP_CMD_NONE
; break;
1001 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1002 tvb_command_start_offset
, tokenlen
,
1004 col_append_str(pinfo
->cinfo
, COL_INFO
, " AuditCapability");
1009 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_ADD_REQ
; break;
1010 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_ADD_REPLY
; break;
1011 default: cmd_type
= GCP_CMD_NONE
; break;
1014 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1015 tvb_command_start_offset
, tokenlen
,
1017 col_append_str(pinfo
->cinfo
, COL_INFO
, " Add");
1024 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_NOTIFY_REQ
; break;
1025 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_NOTIFY_REPLY
; break;
1026 default: cmd_type
= GCP_CMD_NONE
; break;
1029 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1030 tvb_command_start_offset
, tokenlen
,
1032 col_append_str(pinfo
->cinfo
, COL_INFO
, " Notify");
1037 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
+1);
1038 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
1039 tempchar
= tempchar
- 0x20;
1041 switch ( tempchar
){
1044 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_MOD_REQ
; break;
1045 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_MOD_REPLY
; break;
1046 default: cmd_type
= GCP_CMD_NONE
; break;
1049 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1050 tvb_command_start_offset
, tokenlen
,
1052 col_append_str(pinfo
->cinfo
, COL_INFO
, " Modify");
1057 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_MOVE_REQ
; break;
1058 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_MOVE_REPLY
; break;
1059 default: cmd_type
= GCP_CMD_NONE
; break;
1061 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1062 tvb_command_start_offset
, tokenlen
,
1064 col_append_str(pinfo
->cinfo
, COL_INFO
, " Move");
1070 cmd_type
= GCP_CMD_NONE
;
1072 PackagesToken = ("Packages" / "PG")
1073 PendingToken = ("Pending" / "PN")
1074 PriorityToken = ("Priority" / "PR")
1075 ProfileToken = ("Profile" / "PF")
1077 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
+1);
1078 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
1079 tempchar
= tempchar
- 0x20;
1081 switch ( tempchar
){
1083 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1084 tvb_command_start_offset
, tokenlen
,
1088 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1089 tvb_command_start_offset
, tokenlen
,
1093 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1094 tvb_command_start_offset
, tokenlen
,
1098 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1099 tvb_command_start_offset
, tokenlen
,
1106 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
+1);
1107 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
1108 tempchar
= tempchar
- 0x20;
1110 switch ( tempchar
){
1114 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_SVCCHG_REQ
; break;
1115 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_SVCCHG_REPLY
; break;
1116 default: cmd_type
= GCP_CMD_NONE
; break;
1118 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1119 tvb_command_start_offset
, tokenlen
,
1125 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_SUB_REQ
; break;
1126 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_SUB_REPLY
; break;
1127 default: cmd_type
= GCP_CMD_NONE
; break;
1129 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1130 tvb_command_start_offset
, tokenlen
,
1132 col_append_str(pinfo
->cinfo
, COL_INFO
, " Subtract");
1141 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
1142 tvb_ensure_bytes_exist(tvb
, tvb_previous_offset
, tokenlen
);
1143 item
= proto_tree_add_string(megaco_tree
, hf_megaco_error_Frame
, tvb
,
1144 tvb_previous_offset
, tokenlen
,
1145 "No Command detectable !");
1146 proto_item_append_text(item
,"[ tempchar 0x%x ]", tempchar
);
1152 gchar
* command
= tvb_format_text(tvb
, tvb_command_start_offset
, tokenlen
);
1154 if ( g_str_equal(command
,"Subtract") ) {
1156 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_SUB_REQ
; break;
1157 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_SUB_REPLY
; break;
1158 default: cmd_type
= GCP_CMD_NONE
; break;
1160 } else if ( g_str_equal(command
,"AuditValue") ) {
1162 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_AUDITVAL_REPLY
; break;
1163 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_AUDITVAL_REQ
; break;
1164 default: cmd_type
= GCP_CMD_NONE
; break;
1166 } else if ( g_str_equal(command
,"AuditCapability") ) {
1168 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_AUDITCAP_REQ
; break;
1169 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_AUDITCAP_REPLY
; break;
1170 default: cmd_type
= GCP_CMD_NONE
; break;
1172 } else if ( g_str_equal(command
,"Add") ) {
1174 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_ADD_REQ
; break;
1175 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_ADD_REPLY
; break;
1176 default: cmd_type
= GCP_CMD_NONE
; break;
1178 } else if ( g_str_equal(command
,"Notify") ) {
1180 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_NOTIFY_REQ
; break;
1181 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_NOTIFY_REPLY
; break;
1182 default: cmd_type
= GCP_CMD_NONE
; break;
1184 } else if ( g_str_equal(command
,"Modify") ) {
1186 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_MOD_REQ
; break;
1187 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_MOD_REPLY
; break;
1188 default: cmd_type
= GCP_CMD_NONE
; break;
1190 } else if ( g_str_equal(command
,"Move") ) {
1192 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_MOVE_REQ
; break;
1193 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_MOVE_REPLY
; break;
1194 default: cmd_type
= GCP_CMD_NONE
; break;
1196 } else if ( g_str_equal(command
,"ServiceChange") ) {
1198 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_SVCCHG_REQ
; break;
1199 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_SVCCHG_REPLY
; break;
1200 default: cmd_type
= GCP_CMD_NONE
; break;
1202 } else if ( g_str_equal(command
,"Subtract") ) {
1204 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_SUB_REQ
; break;
1205 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_SUB_REPLY
; break;
1206 default: cmd_type
= GCP_CMD_NONE
; break;
1210 case GCP_TRX_REQUEST
: cmd_type
= GCP_CMD_OTHER_REQ
; break;
1211 case GCP_TRX_REPLY
: cmd_type
= GCP_CMD_REPLY
; break;
1212 default: cmd_type
= GCP_CMD_NONE
; break;
1217 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_command
, tvb
,
1218 tvb_command_start_offset
, tokenlen
,
1219 tvb_format_text(tvb
, tvb_command_start_offset
,
1221 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",command
);
1224 if (cmd_type
== GCP_CMD_NONE
&& trx_type
== GCP_TRX_REPLY
) {
1225 cmd_type
= GCP_CMD_REPLY
;
1228 if (cmd_type
!= GCP_CMD_NONE
) {
1229 cmd
= gcp_cmd(msg
, trx
, ctx
, cmd_type
, tvb_command_start_offset
, keep_persistent_data
);
1230 tap_queue_packet(megaco_tap
, pinfo
, cmd
);
1233 tvb_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
,
1234 tvb_transaction_end_offset
, '=');
1235 if (tvb_offset
== -1 ) {
1236 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Missing \"=\"");
1239 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
1240 tokenlen
= tvb_next_offset
- tvb_offset
;
1241 if (tokenlen
+1 <= 0) {
1242 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Invalid token length (%d)", tokenlen
+1);
1246 tempchar
= tvb_get_guint8(tvb
, tvb_offset
);
1247 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
1248 tempchar
= tempchar
- 0x20;
1250 term
= wmem_new0(wmem_packet_scope(), gcp_term_t
);
1251 wild_term
= GCP_WILDCARD_NONE
;
1252 term
->type
= GCP_TERM_TYPE_UNKNOWN
;
1254 switch ( tempchar
){
1257 if ((tokenlen
+1 > (int) sizeof(TermID
))) {
1258 expert_add_info_format(pinfo
, sub_ti
, &ei_megaco_parse_error
, "Parse error: Invalid TermID length (%d)", tokenlen
+1);
1261 tvb_get_nstringz0(tvb
,tvb_offset
,tokenlen
+1,TermID
);
1264 term
->len
= tokenlen
;
1265 term
->str
= (const gchar
*)(term
->buffer
= TermID
);
1267 gcp_cmd_add_term(msg
, trx
, cmd
, term
, wild_term
, keep_persistent_data
);
1270 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_termid
, tvb
,
1271 tvb_offset
, tokenlen
,
1276 wild_term
= GCP_WILDCARD_ALL
;
1278 term
->buffer
= (const guint8
*)(term
->str
= "*");
1280 gcp_cmd_add_term(msg
, trx
, cmd
, term
, wild_term
, keep_persistent_data
);
1282 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_termid
, tvb
,
1283 tvb_offset
, tokenlen
,
1285 col_append_str(pinfo
->cinfo
, COL_INFO
, "=*");
1289 wild_term
= GCP_WILDCARD_CHOOSE
;
1292 term
->buffer
= (term
->str
= "$");
1294 gcp_cmd_add_term(msg
, trx
, cmd
, term
, wild_term
, keep_persistent_data
);
1296 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_termid
, tvb
,
1297 tvb_offset
, tokenlen
,
1299 col_append_str(pinfo
->cinfo
, COL_INFO
, "=$");
1304 my_proto_tree_add_string(megaco_tree_command_line
, hf_megaco_termid
, tvb
,
1305 tvb_offset
, tokenlen
,
1306 tvb_format_text(tvb
, tvb_offset
,
1309 term
->len
= tokenlen
;
1310 term
->buffer
= (const guint8
*)(term
->str
= tvb_format_text(tvb
, tvb_offset
, tokenlen
));
1312 gcp_cmd_add_term(msg
, trx
, cmd
, term
, wild_term
, keep_persistent_data
);
1314 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "=%s",tvb_format_text(tvb
, tvb_offset
,tokenlen
));
1319 /* Dissect the Descriptors */
1322 if ( LBRKT_counter
!= 0 && tvb_current_offset
!= tvb_command_end_offset
){
1324 tvb_descriptors_start_offset
= tvb_find_guint8(tvb
, tvb_command_start_offset
,
1325 tvb_transaction_end_offset
, '{');
1327 tvb_descriptors_end_offset
= tvb_descriptors_start_offset
;
1328 if ( tvb_descriptors_end_offset
> tvb_transaction_end_offset
)
1329 tvb_descriptors_end_offset
= tvb_transaction_end_offset
;
1331 while ( LBRKT_counter
> 0 ){
1333 tvb_descriptors_end_offset
= tvb_find_guint8(tvb
, tvb_descriptors_end_offset
+1,
1334 tvb_transaction_end_offset
, '}');
1340 tempchar
= tvb_get_guint8(tvb
, tvb_command_start_offset
);
1342 if ( tempchar
== 'E'|| tempchar
== 'e'){
1343 dissect_megaco_descriptors(tvb
, megaco_tree
, pinfo
, tvb_command_start_offset
-1,tvb_descriptors_end_offset
);
1346 dissect_megaco_descriptors(tvb
, megaco_tree
, pinfo
, tvb_descriptors_start_offset
,tvb_descriptors_end_offset
);
1351 tvb_command_start_offset
= megaco_tvb_skip_wsp(tvb
, tvb_command_end_offset
+1);
1352 tvb_LBRKT
= tvb_command_start_offset
;
1353 tvb_RBRKT
= tvb_command_start_offset
;
1357 } while ( tvb_command_end_offset
< tvb_transaction_end_offset
);
1359 if (keep_persistent_data
) {
1360 gcp_msg_to_str(msg
,keep_persistent_data
);
1361 gcp_analyze_msg(megaco_tree
, pinfo
, tvb
, msg
, &megaco_ctx_ids
, &ei_megaco_errored_command
);
1364 tvb_next_offset
= tvb_transaction_end_offset
;
1368 while( tvb_transaction_end_offset
< tvb_len
- 2);
1370 if(global_megaco_raw_text
){
1371 tvb_raw_text_add(tvb
, megaco_tree
);
1375 #define MEGACO_MODEM_TOKEN 1
1376 #define MEGACO_MUX_TOKEN 2
1377 #define MEGACO_MEDIA_TOKEN 3
1378 #define MEGACO_SIGNALS_TOKEN 4
1379 #define MEGACO_SERVICES_TOKEN 5
1380 #define MEGACO_STATS_TOKEN 6
1381 #define MEGACO_ERROR_TOKEN 7
1382 #define MEGACO_EVENTS_TOKEN 8
1383 #define MEGACO_AUDIT_TOKEN 9
1384 #define MEGACO_DIGITMAP_TOKEN 10
1385 #define MEGACO_OE_TOKEN 11
1386 #define MEGACO_TOPOLOGY_TOKEN 12
1387 #define MEGACO_PACKAGES_TOKEN 13
1389 static const megaco_tokens_t megaco_descriptors_names
[] = {
1390 { "Unknown-token", NULL
}, /* 0 Pad so that the real headers start at index 1 */
1391 { "Modem", "MD" }, /* 1 */
1392 { "Mux", "MX" }, /* 2 */
1393 { "Media", "M" }, /* 3 */
1394 { "Signals", "SG" }, /* 4 */
1395 { "Services", "SV" }, /* 5 */
1396 { "Statistics", "SA" }, /* 6 */
1397 { "Error", "ER" }, /* 7 */
1398 { "Events", "E" }, /* 8 */
1399 { "Audit", "AT" }, /* 9 */
1400 { "DigitMap", "DM" }, /* 10 */
1401 { "ObservedEvents", "OE" }, /* 11 */
1402 { "Topology", "TP" }, /* 12 */
1403 { "Packages", "PG" }, /* 13 */
1406 /* Returns index of megaco_tokens_t */
1407 /* note - also called by dissect_megaco_auditdescriptor */
1408 static gint
find_megaco_descriptors_names(tvbuff_t
*tvb
, int offset
, guint header_len
)
1412 for (i
= 1; i
< array_length(megaco_descriptors_names
); i
++) {
1413 if (header_len
== strlen(megaco_descriptors_names
[i
].name
) &&
1414 tvb_strncaseeql(tvb
, offset
, megaco_descriptors_names
[i
].name
, header_len
) == 0)
1416 if (megaco_descriptors_names
[i
].compact_name
!= NULL
&&
1417 header_len
== strlen(megaco_descriptors_names
[i
].compact_name
) &&
1418 tvb_strncaseeql(tvb
, offset
, megaco_descriptors_names
[i
].compact_name
, header_len
) == 0)
1425 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
)
1427 gint tvb_len
, token_index
, tvb_offset
, temp_offset
;
1428 gint tvb_current_offset
,tvb_previous_offset
,tokenlen
;
1429 gint tvb_RBRKT
, tvb_LBRKT
;
1431 tvb_len
= tvb_length(tvb
);
1434 tvb_LBRKT
= megaco_tvb_skip_wsp(tvb
, tvb_descriptors_start_offset
+1);
1436 tvb_previous_offset
= tvb_LBRKT
;
1437 tvb_RBRKT
= tvb_descriptors_start_offset
;
1442 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
1444 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
,
1447 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,
1450 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_descriptors_end_offset
){
1451 tvb_current_offset
= tvb_descriptors_end_offset
;
1454 if (tvb_current_offset
<= tvb_previous_offset
) {
1455 expert_add_info_format(pinfo
, megaco_tree_command_line
, &ei_megaco_parse_error
, "Parse error: Invalid offset");
1461 /* Descriptor includes no parameters */
1463 if ( tvb_LBRKT
> tvb_current_offset
|| tvb_LBRKT
== -1 ){
1465 if ( tvb_current_offset
> tvb_RBRKT
){
1466 tvb_current_offset
= tvb_RBRKT
;
1469 tvb_RBRKT
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1)-1;
1472 /* Descriptor includes Parameters */
1473 if ( (tvb_current_offset
> tvb_LBRKT
&& tvb_LBRKT
!= -1)){
1475 while ( tvb_LBRKT
!= -1 && tvb_RBRKT
> tvb_LBRKT
){
1478 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
1480 if ( tvb_LBRKT
< tvb_RBRKT
&& tvb_LBRKT
!= -1)
1481 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,tvb_len
, '}');
1486 /* Find token length */
1487 for (tvb_offset
=tvb_previous_offset
; tvb_offset
< tvb_descriptors_end_offset
-1; tvb_offset
++){
1488 if (!isalpha(tvb_get_guint8(tvb
, tvb_offset
))){
1492 tokenlen
= tvb_offset
- tvb_previous_offset
;
1493 token_index
= find_megaco_descriptors_names(tvb
, tvb_previous_offset
, tokenlen
);
1494 if (tvb_RBRKT
> tvb_descriptors_end_offset
) tvb_RBRKT
= tvb_descriptors_end_offset
;
1495 switch ( token_index
){
1496 case MEGACO_MODEM_TOKEN
:
1497 dissect_megaco_modemdescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1499 case MEGACO_MUX_TOKEN
:
1500 dissect_megaco_multiplexdescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1502 case MEGACO_MEDIA_TOKEN
:
1503 /*TODO: Move this to the top when all branches fixed !!!*/
1504 temp_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,tvb_descriptors_end_offset
, '{');
1505 tokenlen
= temp_offset
- tvb_previous_offset
+1;
1506 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_previous_offset
, tokenlen
,
1507 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
1509 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, temp_offset
+1);
1510 dissect_megaco_mediadescriptor(tvb
, megaco_tree_command_line
, pinfo
, tvb_RBRKT
, tvb_previous_offset
);
1512 case MEGACO_SIGNALS_TOKEN
:
1513 dissect_megaco_signaldescriptor(tvb
, pinfo
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1515 case MEGACO_SERVICES_TOKEN
:
1516 dissect_megaco_servicechangedescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1518 case MEGACO_STATS_TOKEN
:
1519 dissect_megaco_statisticsdescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1521 case MEGACO_ERROR_TOKEN
:
1522 dissect_megaco_errordescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1524 case MEGACO_EVENTS_TOKEN
:
1525 dissect_megaco_eventsdescriptor(tvb
, pinfo
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1527 case MEGACO_AUDIT_TOKEN
:
1528 dissect_megaco_auditdescriptor(tvb
, megaco_tree_command_line
, pinfo
, tvb_RBRKT
, tvb_previous_offset
);
1530 case MEGACO_DIGITMAP_TOKEN
:
1531 dissect_megaco_digitmapdescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1533 case MEGACO_OE_TOKEN
:
1534 /* ObservedEventsToken */
1535 dissect_megaco_observedeventsdescriptor(tvb
, pinfo
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1537 case MEGACO_TOPOLOGY_TOKEN
:
1538 dissect_megaco_topologydescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1540 case MEGACO_PACKAGES_TOKEN
:
1541 dissect_megaco_Packagesdescriptor(tvb
, megaco_tree_command_line
, tvb_RBRKT
, tvb_previous_offset
);
1544 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
1545 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_error_Frame
, tvb
,
1546 tvb_previous_offset
, tokenlen
,
1547 "No Descriptor detectable !");
1551 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_RBRKT
, tvb_len
, ',');
1552 if (tvb_current_offset
== -1 || tvb_descriptors_end_offset
< tvb_current_offset
){
1553 tvb_current_offset
= tvb_descriptors_end_offset
;
1555 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
1556 tvb_LBRKT
= tvb_previous_offset
;
1557 tvb_RBRKT
= tvb_previous_offset
;
1559 } while ( tvb_current_offset
< tvb_descriptors_end_offset
);
1564 dissect_megaco_modemdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
1569 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
1570 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_modem_descriptor
, tvb
,
1571 tvb_previous_offset
, tokenlen
,
1572 tvb_format_text(tvb
, tvb_previous_offset
,
1577 dissect_megaco_multiplexdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
1582 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
1583 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_multiplex_descriptor
, tvb
,
1584 tvb_previous_offset
, tokenlen
,
1585 tvb_format_text(tvb
, tvb_previous_offset
,
1590 /* mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
1591 * MediaToken = ("Media" / "M")
1593 * mediaParm = (streamParm / streamDescriptor /terminationStateDescriptor)
1595 * ; at-most one terminationStateDescriptor
1596 * ; and either streamParm(s) or streamDescriptor(s) but not both
1597 * streamParm = ( localDescriptor / remoteDescriptor /localControlDescriptor )
1598 * localDescriptor = LocalToken LBRKT octetString RBRKT
1599 * LocalToken = ("Local" / "L")
1600 * octetString = *(nonEscapeChar)
1601 * nonEscapeChar = ( "\}" / %x01-7C / %x7E-FF )
1602 * remoteDescriptor = RemoteToken LBRKT octetString RBRKT
1603 * RemoteToken = ("Remote" / "R")
1604 * localControlDescriptor = LocalControlToken LBRKT localParm*(COMMA localParm) RBRKT
1605 * LocalControlToken = ("LocalControl" / "O")
1606 * localParm = ( streamMode / propertyParm / reservedValueMode
1607 * streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm*(COMMA streamParm) RBRKT
1608 * StreamToken = ("Stream" / "ST")
1609 * terminationStateDescriptor = TerminationStateToken LBRKTterminationStateParm
1610 * *( COMMA terminationStateParm ) RBRKT
1611 * TerminationStateToken = ("TerminationState" / "TS")
1612 * terminationStateParm =(propertyParm / serviceStates / eventBufferControl )
1615 #define MEGACO_LOCAL_TOKEN 1
1616 #define MEGACO_REMOTE_TOKEN 2
1617 #define MEGACO_LOCAL_CONTROL_TOKEN 3
1618 #define MEGACO_STREAM_TOKEN 4
1619 #define MEGACO_TERMINATION_STATE_DESC 5
1621 static const megaco_tokens_t megaco_mediaParm_names
[] = {
1622 { "Unknown-token", NULL
}, /* 0 Pad so that the real headers start at index 1 */
1623 { "Local", "L" }, /* 1 */
1624 { "Remote", "R" }, /* 2 */
1625 { "LocalControl", "O" }, /* 3 */
1626 { "Stream", "ST" }, /* 4 */
1627 { "TerminationState", "TS" }, /* 5 */
1630 /* Returns index of megaco_tokens_t */
1631 static gint
find_megaco_mediaParm_names(tvbuff_t
*tvb
, int offset
, guint header_len
)
1635 for (i
= 1; i
< array_length(megaco_mediaParm_names
); i
++) {
1636 if (header_len
== strlen(megaco_mediaParm_names
[i
].name
) &&
1637 tvb_strncaseeql(tvb
, offset
, megaco_mediaParm_names
[i
].name
, header_len
) == 0)
1639 if (megaco_mediaParm_names
[i
].compact_name
!= NULL
&&
1640 header_len
== strlen(megaco_mediaParm_names
[i
].compact_name
) &&
1641 tvb_strncaseeql(tvb
, offset
, megaco_mediaParm_names
[i
].compact_name
, header_len
) == 0)
1649 dissect_megaco_mediadescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
,packet_info
*pinfo
, gint tvb_last_RBRKT
, gint tvb_previous_offset
)
1652 gint tokenlen
, tvb_LBRKT
, tvb_RBRKT
;
1653 gint tvb_next_offset
, tvb_current_offset
, tvb_offset
, equal_offset
;
1657 proto_tree
*megaco_mediadescriptor_tree
, *megaco_mediadescriptor_ti
;
1660 megaco_mediadescriptor_ti = proto_tree_add_text(megaco_tree_command_line,tvb,tvb_previous_offset,tokenlen,"Media Descriptor");
1661 megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor);
1663 while ( tvb_previous_offset
< tvb_last_RBRKT
){
1664 /* Start of token */
1665 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_previous_offset
);
1667 /* Find token length */
1668 for (tvb_next_offset
=tvb_current_offset
; tvb_next_offset
< tvb_last_RBRKT
; tvb_next_offset
++){
1669 if (!isalpha(tvb_get_guint8(tvb
, tvb_next_offset
))){
1673 tokenlen
= tvb_next_offset
- tvb_current_offset
;
1675 mediaParm
= find_megaco_mediaParm_names(tvb
, tvb_current_offset
, tokenlen
);
1677 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_next_offset
, tvb_last_RBRKT
, '{');
1678 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_current_offset
+1 , tvb_last_RBRKT
, '}');
1679 tvb_RBRKT
= tvb_next_offset
;
1681 tokenlen
= tvb_LBRKT
- tvb_current_offset
+1;
1682 megaco_mediadescriptor_ti
= proto_tree_add_text(megaco_tree_command_line
,tvb
,tvb_current_offset
,
1683 tokenlen
,"%s",tvb_format_text(tvb
, tvb_current_offset
,tokenlen
));
1685 switch ( mediaParm
){
1686 case MEGACO_LOCAL_TOKEN
:
1687 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
1688 dissect_megaco_Localdescriptor(tvb
,megaco_tree_command_line
, pinfo
,
1689 tvb_RBRKT
, tvb_current_offset
);
1690 tvb_current_offset
= tvb_RBRKT
;
1692 case MEGACO_REMOTE_TOKEN
:
1693 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
1694 dissect_megaco_Localdescriptor(tvb
,megaco_tree_command_line
, pinfo
,
1695 tvb_RBRKT
, tvb_current_offset
);
1696 tvb_current_offset
= tvb_RBRKT
;
1698 case MEGACO_LOCAL_CONTROL_TOKEN
:
1699 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
1700 dissect_megaco_LocalControldescriptor(tvb
,megaco_tree_command_line
, pinfo
,
1701 tvb_RBRKT
, tvb_current_offset
);
1702 tvb_current_offset
= tvb_RBRKT
;
1704 case MEGACO_STREAM_TOKEN
:
1705 megaco_mediadescriptor_tree
= proto_item_add_subtree(megaco_mediadescriptor_ti
, ett_megaco_mediadescriptor
);
1707 equal_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_last_RBRKT
, '=');
1708 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, equal_offset
+1);
1709 tvb_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_LBRKT
-1);
1710 tokenlen
= tvb_offset
- tvb_current_offset
;
1712 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_streamid
, tvb
,
1713 tvb_current_offset
, tokenlen
, tvb_format_text(tvb
, tvb_current_offset
,tokenlen
));
1714 tvb_previous_offset
= tvb_LBRKT
+1;
1716 case MEGACO_TERMINATION_STATE_DESC
:
1717 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_LBRKT
+1);
1718 dissect_megaco_TerminationStatedescriptor(tvb
,megaco_tree_command_line
,
1719 tvb_RBRKT
, tvb_current_offset
);
1720 tvb_current_offset
= tvb_RBRKT
;
1725 /* more parameters ? */
1726 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_current_offset
+1 , tvb_last_RBRKT
, ',');
1727 if (tvb_next_offset
> tvb_last_RBRKT
) tvb_next_offset
= tvb_last_RBRKT
;
1728 if ( tvb_next_offset
!= -1 ){
1729 tokenlen
= tvb_next_offset
- tvb_RBRKT
+1;
1730 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_RBRKT
, tokenlen
,
1731 "%s", tvb_format_text(tvb
, tvb_RBRKT
, tokenlen
));
1732 tvb_previous_offset
= tvb_next_offset
+1;
1734 /* Add the trailing '}'*/
1735 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_RBRKT
, 1,
1736 "%s", tvb_format_text(tvb
, tvb_RBRKT
, 1));
1737 tvb_previous_offset
= tvb_last_RBRKT
;
1744 dissect_megaco_h245(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*megaco_tree
, gint offset
, gint len
, gchar
*msg
)
1746 /*proto_item *item;*/
1747 /*proto_tree *tree;*/
1749 /*item=proto_tree_add_string(megaco_tree, hf_megaco_h245, tvb,
1752 /*item = */proto_tree_add_text(megaco_tree
, tvb
, offset
, len
, "%s", msg
);
1754 /*tree = proto_item_add_subtree(item, ett_megaco_h245); */
1756 /* arbitrary maximum length */
1760 guint8
*buf
= (guint8
*)wmem_alloc(pinfo
->pool
, 10240);
1762 /* first, skip to where the encoded pdu starts, this is
1763 the first hex digit after the '=' char.
1766 if((*msg
==0)||(*msg
=='\n')){
1776 if((*msg
==0)||(*msg
=='\n')){
1779 if( ((*msg
>='0')&&(*msg
<='9'))
1780 || ((*msg
>='a')&&(*msg
<='f'))
1781 || ((*msg
>='A')&&(*msg
<='F'))){
1787 while( ((*msg
>='0')&&(*msg
<='9'))
1788 ||((*msg
>='a')&&(*msg
<='f'))
1789 ||((*msg
>='A')&&(*msg
<='F')) ){
1791 if((*msg
>='0')&&(*msg
<='9')){
1793 } else if((*msg
>='a')&&(*msg
<='f')){
1795 } else if((*msg
>='A')&&(*msg
<='F')){
1802 if((*msg
>='0')&&(*msg
<='9')){
1804 } else if((*msg
>='a')&&(*msg
<='f')){
1806 } else if((*msg
>='A')&&(*msg
<='F')){
1819 h245_tvb
= tvb_new_child_real_data(tvb
, buf
,i
,i
);
1820 add_new_data_source(pinfo
, h245_tvb
, "H.245 over MEGACO");
1821 /* should go through a handle, however, the two h245 entry
1822 points are different, one is over tpkt and the other is raw
1824 call_dissector(h245_handle
, h245_tvb
, pinfo
, top_tree
);
1825 /* dissect_h245_MultimediaSystemControlMessage(h245_tvb, pinfo, tree);*/
1830 dissect_megaco_h324_h223caprn(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*megaco_tree
, gint offset _U_
, gint len
, gchar
*msg
)
1834 /* arbitrary maximum length */
1838 guint8
*buf
= (guint8
*)wmem_alloc(pinfo
->pool
, 10240);
1840 /* first, skip to where the encoded pdu starts, this is
1841 the first hex digit after the '=' char.
1844 if((*msg
==0)||(*msg
=='\n')){
1854 if((*msg
==0)||(*msg
=='\n')){
1857 if( ((*msg
>='0')&&(*msg
<='9'))
1858 || ((*msg
>='a')&&(*msg
<='f'))
1859 || ((*msg
>='A')&&(*msg
<='F'))){
1865 while( ((*msg
>='0')&&(*msg
<='9'))
1866 ||((*msg
>='a')&&(*msg
<='f'))
1867 ||((*msg
>='A')&&(*msg
<='F')) ){
1869 if((*msg
>='0')&&(*msg
<='9')){
1871 } else if((*msg
>='a')&&(*msg
<='f')){
1873 } else if((*msg
>='A')&&(*msg
<='F')){
1880 if((*msg
>='0')&&(*msg
<='9')){
1882 } else if((*msg
>='a')&&(*msg
<='f')){
1884 } else if((*msg
>='A')&&(*msg
<='F')){
1897 h245_tvb
= tvb_new_child_real_data(tvb
, buf
,i
,i
);
1898 add_new_data_source(pinfo
, h245_tvb
, "H.245 over MEGACO");
1899 /* should go through a handle, however, the two h245 entry
1900 points are different, one is over tpkt and the other is raw
1902 asn1_ctx_init(&actx
, ASN1_ENC_PER
, TRUE
, pinfo
);
1903 dissect_h245_H223Capability(h245_tvb
, 0, &actx
, megaco_tree
, hf_megaco_h223Capability
);
1908 dissect_megaco_eventsdescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
1911 gint tokenlen
, tvb_current_offset
, tvb_next_offset
, tvb_help_offset
;
1912 gint tvb_events_end_offset
, tvb_LBRKT
;
1913 proto_tree
*megaco_eventsdescriptor_tree
, *megaco_eventsdescriptor_ti
;
1916 gint requested_event_start_offset
, requested_event_end_offset
;
1917 proto_tree
*megaco_requestedevent_tree
, *megaco_requestedevent_ti
;
1919 requested_event_start_offset
= 0;
1920 requested_event_end_offset
= 0;
1922 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
1924 megaco_eventsdescriptor_ti
= proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_previous_offset
, tokenlen
,
1925 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
1928 megaco_eventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_events_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_ASCII|ENC_NA);
1930 megaco_eventsdescriptor_tree
= proto_item_add_subtree(megaco_eventsdescriptor_ti
, ett_megaco_eventsdescriptor
);
1932 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '=');
1933 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '{');
1935 if ( tvb_current_offset
< tvb_RBRKT
&& tvb_current_offset
!= -1 ){
1937 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
1938 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_next_offset
-1);
1940 tokenlen
= tvb_help_offset
- tvb_current_offset
;
1942 proto_tree_add_string(megaco_eventsdescriptor_tree
, hf_megaco_requestid
, tvb
,
1943 tvb_current_offset
, tokenlen
,
1944 tvb_format_text(tvb
, tvb_current_offset
,
1947 tvb_events_end_offset
= tvb_RBRKT
;
1949 tvb_RBRKT
= tvb_next_offset
+1;
1950 tvb_LBRKT
= tvb_next_offset
+1;
1951 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_next_offset
+1);
1956 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
1957 tvb_events_end_offset
, '}');
1958 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
,
1959 tvb_events_end_offset
, '{');
1961 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,
1962 tvb_events_end_offset
, ',');
1964 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_events_end_offset
){
1965 tvb_current_offset
= tvb_events_end_offset
;
1969 /* Descriptor includes no parameters */
1971 if ( tvb_LBRKT
> tvb_current_offset
|| tvb_LBRKT
== -1 ){
1973 tvb_RBRKT
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1)-1;
1976 /* Descriptor includes Parameters */
1978 if ( (tvb_current_offset
> tvb_LBRKT
&& tvb_LBRKT
!= -1)){
1980 while ( tvb_LBRKT
!= -1 && tvb_RBRKT
> tvb_LBRKT
){
1982 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
1983 tvb_events_end_offset
, '{');
1984 if ( tvb_LBRKT
< tvb_RBRKT
&& tvb_LBRKT
!= -1)
1985 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
1986 tvb_events_end_offset
, '}');
1991 tvb_help_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_events_end_offset
, '{');
1993 /* if there are eventparameter */
1995 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
1997 requested_event_start_offset
= tvb_help_offset
;
1998 requested_event_end_offset
= tvb_RBRKT
;
1999 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_help_offset
-1);
2000 tokenlen
= tvb_help_offset
- tvb_previous_offset
;
2004 tokenlen
= tvb_RBRKT
+1 - tvb_previous_offset
;
2007 megaco_requestedevent_ti
= proto_tree_add_item(megaco_eventsdescriptor_tree
,hf_megaco_pkgdname
,tvb
,tvb_previous_offset
,tokenlen
, ENC_ASCII
|ENC_NA
);
2008 megaco_requestedevent_tree
= proto_item_add_subtree(megaco_requestedevent_ti
, ett_megaco_requestedevent
);
2010 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
2012 tvb_help_offset
= megaco_tvb_skip_wsp(tvb
, requested_event_start_offset
+1);
2013 tempchar
= tvb_get_guint8(tvb
, tvb_help_offset
);
2015 requested_event_start_offset
= megaco_tvb_skip_wsp(tvb
, requested_event_start_offset
+1);
2016 requested_event_end_offset
= megaco_tvb_skip_wsp_return(tvb
, requested_event_end_offset
-1);
2018 if ( tempchar
== 'D' || tempchar
== 'd'){
2019 dissect_megaco_digitmapdescriptor(tvb
, megaco_requestedevent_tree
, requested_event_end_offset
, requested_event_start_offset
);
2024 tokenlen
= requested_event_end_offset
- requested_event_start_offset
;
2025 msg
=tvb_format_text(tvb
,requested_event_start_offset
, tokenlen
);
2026 if(!strncmp("h245", msg
, 4)){
2027 dissect_megaco_h245(tvb
, pinfo
, megaco_requestedevent_tree
, requested_event_start_offset
, tokenlen
, msg
);
2029 proto_tree_add_text(megaco_requestedevent_tree
, tvb
, requested_event_start_offset
, tokenlen
,
2036 tvb_previous_offset
= tvb_current_offset
;
2037 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_RBRKT
,
2038 tvb_events_end_offset
, ',');
2040 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_events_end_offset
|| tvb_current_offset
< tvb_previous_offset
) {
2041 tvb_current_offset
= tvb_events_end_offset
;
2044 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2046 tvb_LBRKT
= tvb_previous_offset
;
2047 tvb_RBRKT
= tvb_previous_offset
;
2049 } while ( tvb_current_offset
< tvb_events_end_offset
);
2054 dissect_megaco_signaldescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2057 gint tokenlen
, pkg_tokenlen
, tvb_current_offset
, tvb_next_offset
, tvb_help_offset
;
2058 gint tvb_signals_end_offset
, tvb_signals_start_offset
, tvb_LBRKT
;
2059 /*proto_tree *megaco_signalsdescriptor_tree, *megaco_signalsdescriptor_ti;*/
2061 gint requested_signal_start_offset
, requested_signal_end_offset
;
2062 proto_tree
*megaco_requestedsignal_tree
, *megaco_requestedsignal_ti
;
2064 requested_signal_start_offset
= 0;
2065 requested_signal_end_offset
= 0;
2067 tvb_signals_end_offset
= tvb_RBRKT
;
2068 tvb_signals_start_offset
= tvb_previous_offset
;
2070 if(toupper(tvb_get_guint8(tvb
, tvb_previous_offset
+1))=='G')
2071 tokenlen
= 2; /* token is compact text (SG) */
2073 tokenlen
= 7; /* token must be verbose text (Signals) */
2075 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_previous_offset
+tokenlen
);
2077 if(tvb_get_guint8(tvb
, tvb_current_offset
)!='{') { /* {} has been omitted */
2079 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_signals_start_offset
, tokenlen
,
2080 "%s", "Empty Signal Descriptor");
2082 col_append_str(pinfo
->cinfo
, COL_INFO
, " (Signal:none)"); /* then say so */
2084 return; /* and return */
2087 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_signals_end_offset
, '{');
2088 tokenlen
= (tvb_LBRKT
+1) - tvb_signals_start_offset
;
2090 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_signals_start_offset
, tokenlen
,
2091 "%s", tvb_format_text(tvb
, tvb_signals_start_offset
, tokenlen
));
2094 megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_signal_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_ASCII|ENC_NA);
2095 megaco_signalsdescriptor_tree = proto_item_add_subtree(megaco_signalsdescriptor_ti, ett_megaco_signalsdescriptor);
2098 tvb_current_offset
= tvb_LBRKT
;
2099 tvb_next_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2100 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (Signal:%s)",tvb_format_text(tvb
, tvb_current_offset
,tokenlen
-tvb_current_offset
+tvb_previous_offset
));
2103 if ( tvb_current_offset
< tvb_signals_end_offset
&& tvb_current_offset
!= -1 && tvb_next_offset
!= tvb_signals_end_offset
){
2106 tvb_RBRKT
= tvb_next_offset
+1;
2107 tvb_LBRKT
= tvb_next_offset
+1;
2108 tvb_previous_offset
= tvb_next_offset
;
2113 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2114 tvb_signals_end_offset
, '}');
2115 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
,
2116 tvb_signals_end_offset
, '{');
2118 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,
2119 tvb_signals_end_offset
, ',');
2121 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_signals_end_offset
){
2122 tvb_current_offset
= tvb_signals_end_offset
;
2126 /* Descriptor includes no parameters */
2128 if ( tvb_LBRKT
> tvb_current_offset
|| tvb_LBRKT
== -1 ){
2130 tvb_RBRKT
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1)-1;
2133 /* Descriptor includes Parameters */
2135 if ( (tvb_current_offset
> tvb_LBRKT
&& tvb_LBRKT
!= -1)){
2137 while ( tvb_LBRKT
!= -1 && tvb_RBRKT
> tvb_LBRKT
){
2139 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
2140 tvb_signals_end_offset
, '{');
2141 if ( tvb_LBRKT
< tvb_RBRKT
&& tvb_LBRKT
!= -1)
2142 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2143 tvb_signals_end_offset
, '}');
2148 tvb_help_offset
= tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_signals_end_offset
, '{');
2150 /* if there are signalparameter */
2152 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
2154 requested_signal_start_offset
= tvb_help_offset
;
2155 requested_signal_end_offset
= tvb_RBRKT
;
2156 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_help_offset
-1);
2157 pkg_tokenlen
= tvb_help_offset
- tvb_previous_offset
;
2158 tokenlen
= tvb_LBRKT
+1 - tvb_previous_offset
;
2162 tokenlen
= pkg_tokenlen
= tvb_RBRKT
+1 - tvb_previous_offset
;
2165 megaco_requestedsignal_ti
= proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_previous_offset
, tokenlen
,
2166 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2167 megaco_requestedsignal_tree
= proto_item_add_subtree(megaco_requestedsignal_ti
, ett_megaco_requestedsignal
);
2169 proto_tree_add_item(megaco_requestedsignal_tree
,hf_megaco_pkgdname
,tvb
,tvb_previous_offset
,pkg_tokenlen
, ENC_ASCII
|ENC_NA
);
2171 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
2174 requested_signal_start_offset
= megaco_tvb_skip_wsp(tvb
, requested_signal_start_offset
+1);
2175 requested_signal_end_offset
= megaco_tvb_skip_wsp_return(tvb
, requested_signal_end_offset
-1);
2177 tokenlen
= requested_signal_end_offset
- requested_signal_start_offset
;
2179 msg
=tvb_format_text(tvb
,requested_signal_start_offset
, tokenlen
+1);
2180 if(!strncmp("h245", msg
, 4)){
2181 dissect_megaco_h245(tvb
, pinfo
, megaco_tree_command_line
, requested_signal_start_offset
, tokenlen
, msg
);
2183 proto_tree_add_text(megaco_tree_command_line
, tvb
, requested_signal_start_offset
, tokenlen
,
2186 /* Print the trailing '}' */
2187 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_RBRKT
, 1,
2188 "%s", tvb_format_text(tvb
, tvb_RBRKT
, 1));
2191 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_RBRKT
,
2192 tvb_signals_end_offset
, ',');
2194 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_signals_end_offset
|| tvb_current_offset
< tvb_previous_offset
){
2195 tvb_current_offset
= tvb_signals_end_offset
;
2198 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2200 tvb_LBRKT
= tvb_previous_offset
;
2201 tvb_RBRKT
= tvb_previous_offset
;
2202 /* Print the trailing '}' */
2203 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_signals_end_offset
, 1,
2204 "%s", tvb_format_text(tvb
, tvb_signals_end_offset
, 1));
2206 } while ( tvb_current_offset
< tvb_signals_end_offset
);
2209 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_signals_end_offset
, 1,
2210 "%s", tvb_format_text(tvb
, tvb_signals_end_offset
, 1));
2217 auditDescriptor = AuditToken LBRKT [ auditItem *(COMMA auditItem) ] RBRKT
2219 auditItem = ( MuxToken / ModemToken / MediaToken /
2220 SignalsToken / EventBufferToken /
2221 DigitMapToken / StatsToken / EventsToken /
2222 ObservedEventsToken / PackagesToken ) */
2224 dissect_megaco_auditdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree
, packet_info
*pinfo _U_
, gint tvb_stop
, gint tvb_offset
)
2226 gint tokenlen
, tvb_end
, tvb_next
, token_index
;
2227 proto_tree
*megaco_auditdescriptor_tree
, *megaco_auditdescriptor_ti
;
2229 tvb_next
= tvb_find_guint8(tvb
, tvb_offset
, tvb_stop
, '{'); /* find opening LBRKT - is this already checked by caller?*/
2230 if( tvb_next
== -1 ) /* complain and give up if not there */
2232 expert_add_info(pinfo
, megaco_tree
, &ei_megaco_audit_descriptor
);
2235 tokenlen
= (tvb_stop
+ 1) - tvb_offset
;
2237 megaco_auditdescriptor_ti
= proto_tree_add_none_format( megaco_tree
, hf_megaco_audit_descriptor
,
2238 tvb
, tvb_offset
, tokenlen
, "Audit descriptor" );
2240 megaco_auditdescriptor_tree
= proto_item_add_subtree( megaco_auditdescriptor_ti
, ett_megaco_auditdescriptor
);
2242 tokenlen
= tvb_next
+ 1 - tvb_offset
;
2244 proto_tree_add_text( megaco_auditdescriptor_tree
, tvb
, tvb_offset
, tokenlen
, "Audit token {" );
2246 tvb_offset
= tvb_next
;
2248 while( tvb_offset
< tvb_stop
)
2250 tvb_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1); /* find start of an auditItem */
2251 if( tvb_get_guint8(tvb
, tvb_offset
) != '}' ) /* got something */
2253 tvb_next
= tvb_find_guint8(tvb
, tvb_offset
, tvb_stop
, ','); /* end of an auditItem */
2254 if (tvb_next
== -1) tvb_next
= tvb_stop
; /* last item doesn't have a comma */
2255 tvb_end
= megaco_tvb_skip_wsp_return(tvb
, tvb_next
-1); /* trim any trailing whitespace */
2256 tokenlen
= tvb_end
- tvb_offset
; /* get length of token */
2258 token_index
= find_megaco_descriptors_names(tvb
, tvb_offset
, tokenlen
); /* lookup the token */
2259 if( token_index
== -1 ) token_index
= 0; /* if not found then 0 => Unknown */
2261 proto_tree_add_string(megaco_auditdescriptor_tree
, hf_megaco_audititem
, tvb
,
2262 tvb_offset
, tokenlen
, megaco_descriptors_names
[token_index
].name
); /* and display the long form */
2264 tvb_offset
= tvb_next
; /* advance pointer */
2267 proto_tree_add_text(megaco_auditdescriptor_tree
, tvb
, tvb_stop
, 1, "}"); /* End of auditDescriptor */
2271 * serviceChangeDescriptor = ServicesToken LBRKT serviceChangeParm
2272 * *(COMMA serviceChangeParm) RBRKT
2274 * ServicesToken = ("Services" / "SV")
2276 * serviceChangeParm = (serviceChangeMethod / serviceChangeReason /
2277 * serviceChangeDelay / serviceChangeAddress /
2278 * serviceChangeProfile / extension / TimeStamp /
2279 * serviceChangeMgcId / serviceChangeVersion )
2282 #define MEGACO_REASON_TOKEN 1
2283 #define MEGACO_DELAY_TOKEN 2
2284 #define MEGACO_SC_ADDR_TOKEN 3
2285 #define MEGACO_MGC_ID_TOKEN 4
2286 #define MEGACO_PROFILE_TOKEN 5
2287 #define MEGACO_VERSION_TOKEN 6
2288 #define MEGACO_METHOD_TOKEN 7
2290 static const megaco_tokens_t megaco_serviceChangeParm_names
[] = {
2291 { "Unknown-token", NULL
}, /* 0 Pad so that the real headers start at index 1 */
2293 { "Reason", "RE" }, /* 1 ReasonToken*/
2294 { "Delay", "DL" }, /* 2 DelayToken */
2295 { "ServiceChangeAddress", "AD" }, /* 3 ServiceChangeAddressToken */
2296 { "MgcIdToTry", "MG" }, /* 4 MgcIdToken */
2297 { "Profile", "PF" }, /* 5 ProfileToken */
2298 { "Version", "V" }, /* 6 VersionToken */
2299 { "Method", "MT" }, /* 7 MethodToken */
2302 /* Returns index of megaco_tokens_t */
2303 static gint
find_megaco_megaco_serviceChangeParm_names(tvbuff_t
*tvb
, int offset
, guint header_len
)
2307 for (i
= 1; i
< array_length(megaco_serviceChangeParm_names
); i
++) {
2308 if (header_len
== strlen(megaco_serviceChangeParm_names
[i
].name
) &&
2309 tvb_strncaseeql(tvb
, offset
, megaco_serviceChangeParm_names
[i
].name
, header_len
) == 0)
2311 if (megaco_serviceChangeParm_names
[i
].compact_name
!= NULL
&&
2312 header_len
== strlen(megaco_serviceChangeParm_names
[i
].compact_name
) &&
2313 tvb_strncaseeql(tvb
, offset
, megaco_serviceChangeParm_names
[i
].compact_name
, header_len
) == 0)
2320 * ServiceChangeReasons References
2321 * -------------------- ----------
2323 static const value_string MEGACO_ServiceChangeReasons_vals
[] = {
2324 {900, "Service Restored"},
2327 {903, "MGC Directed Change"},
2328 {904, "Termination malfunctioning"},
2329 {905, "Termination taken out of service"},
2330 {906, "Loss of lower layer connectivity (e.g. downstream sync)"},
2331 {907, "Transmission Failure"},
2332 {908, "MG Impending Failure"},
2333 {909, "MGC Impending Failure"},
2334 {910, "Media Capability Failure"},
2335 {911, "Modem Capability Failure"},
2336 {912, "Mux Capability Failure"},
2337 {913, "Signal Capability Failure"},
2338 {914, "Event Capability Failure"},
2339 {915, "State Loss"},
2340 {916, "Packages Change"},
2341 {917, "Capabilities Change"},
2342 {918, "Cancel Graceful"},
2343 {919, "Warm Failover"},
2344 {920, "Cold Failover"},
2349 dissect_megaco_servicechangedescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2352 gint tokenlen
, tvb_LBRKT
, tvb_offset
;
2354 gint tvb_current_offset
;
2355 gboolean more_params
= TRUE
;
2358 guint8 ServiceChangeReason_str
[4];
2360 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '{');
2362 if (tvb_LBRKT == -1)
2365 tokenlen
= (tvb_LBRKT
+ 1) - tvb_previous_offset
;
2366 proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tokenlen
,
2367 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2370 /* Start dissecting serviceChangeParm */
2371 tvb_previous_offset
= tvb_LBRKT
+ 1;
2372 while (more_params
){
2373 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_previous_offset
);
2374 /* Find token length */
2375 for (tvb_offset
=tvb_previous_offset
; tvb_offset
< tvb_RBRKT
; tvb_offset
++){
2376 if (!isalpha(tvb_get_guint8(tvb
, tvb_offset
))){
2380 tokenlen
= tvb_offset
- tvb_previous_offset
;
2381 token_index
= find_megaco_megaco_serviceChangeParm_names(tvb
, tvb_previous_offset
, tokenlen
);
2383 tvb_offset
= tvb_find_guint8(tvb
, tvb_offset
, tvb_RBRKT
, ',');
2384 if ((tvb_offset
== -1)||(tvb_offset
>=tvb_RBRKT
)){
2385 more_params
= FALSE
;
2386 tvb_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_RBRKT
-1);
2388 tokenlen
= tvb_offset
- tvb_previous_offset
;
2389 if (more_params
== TRUE
)
2392 switch(token_index
){
2393 case MEGACO_REASON_TOKEN
:
2394 /* ReasonToken EQUAL VALUE
2395 * VALUE = quotedString / 1*(SafeChar)
2397 item
= proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tokenlen
,
2398 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2400 /* As the reason code ( if a digit ) can be in quoted string or 'just' digit
2401 * look for a nine and hope for the best.
2403 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '9');
2404 if ( tvb_current_offset
== -1)
2407 tvb_get_nstringz0(tvb
,tvb_current_offset
,4,ServiceChangeReason_str
);
2408 reason
= atoi(ServiceChangeReason_str
);
2410 proto_item_append_text(item
,"[ %s ]", val_to_str(reason
, MEGACO_ServiceChangeReasons_vals
,"Unknown (%u)"));
2412 case MEGACO_DELAY_TOKEN
:
2413 case MEGACO_SC_ADDR_TOKEN
:
2414 case MEGACO_MGC_ID_TOKEN
:
2415 case MEGACO_PROFILE_TOKEN
:
2416 case MEGACO_VERSION_TOKEN
:
2417 case MEGACO_METHOD_TOKEN
:
2418 /* No special dissection: fall trough */
2421 * extension = extensionParameter parmValue
2422 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2424 proto_tree_add_text(megaco_tree
, tvb
, tvb_previous_offset
, tokenlen
,
2425 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2429 tvb_previous_offset
= tvb_offset
+1;
2433 /* extension = extensionParameter parmValue
2434 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2438 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2439 proto_tree_add_string(megaco_tree_command_line, hf_megaco_servicechange_descriptor, tvb,
2440 tvb_previous_offset, tokenlen,
2441 tvb_format_text(tvb, tvb_previous_offset,
2444 proto_tree_add_text(megaco_tree
, tvb
, tvb_RBRKT
, 1,"%s", tvb_format_text(tvb
, tvb_RBRKT
, 1));
2448 dissect_megaco_digitmapdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2453 tokenlen
= tvb_RBRKT
- tvb_previous_offset
;
2454 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_digitmap_descriptor
, tvb
,
2455 tvb_previous_offset
, tokenlen
,
2456 tvb_format_text(tvb
, tvb_previous_offset
,
2461 dissect_megaco_statisticsdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2466 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
2467 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_statistics_descriptor
, tvb
,
2468 tvb_previous_offset
, tokenlen
,
2469 tvb_format_text(tvb
, tvb_previous_offset
,
2474 dissect_megaco_observedeventsdescriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2477 gint tokenlen
, pkg_tokenlen
, tvb_current_offset
, tvb_next_offset
, tvb_help_offset
;
2478 gint tvb_observedevents_end_offset
, tvb_LBRKT
;
2479 proto_tree
*megaco_observedeventsdescriptor_tree
, *megaco_observedeventsdescriptor_ti
;
2481 gint requested_event_start_offset
, requested_event_end_offset
, param_start_offset
, param_end_offset
;
2482 proto_tree
*megaco_observedevent_tree
, *megaco_observedevent_ti
;
2484 requested_event_start_offset
= 0;
2485 requested_event_end_offset
= 0;
2488 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '{');
2489 tvb_next_offset
= tvb_LBRKT
;
2490 tokenlen
= (tvb_next_offset
+1) - tvb_previous_offset
;
2493 megaco_observedeventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_observedevents_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_ASCII|ENC_NA);
2494 megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor);
2497 megaco_observedeventsdescriptor_ti
= proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_previous_offset
, tokenlen
,
2498 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2499 megaco_observedeventsdescriptor_tree
= proto_item_add_subtree(megaco_observedeventsdescriptor_ti
, ett_megaco_observedeventsdescriptor
);
2501 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '=');
2502 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '{');
2504 if ( tvb_current_offset
< tvb_RBRKT
&& tvb_current_offset
!= -1 ){
2506 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2507 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_next_offset
-1);
2509 tokenlen
= tvb_help_offset
- tvb_current_offset
;
2511 proto_tree_add_string(megaco_observedeventsdescriptor_tree
, hf_megaco_requestid
, tvb
,
2512 tvb_current_offset
, tokenlen
,
2513 tvb_format_text(tvb
, tvb_current_offset
,
2516 tvb_observedevents_end_offset
= tvb_RBRKT
;
2518 tvb_RBRKT
= tvb_next_offset
+1;
2519 tvb_LBRKT
= tvb_next_offset
+1;
2520 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_next_offset
+1);
2525 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2526 tvb_observedevents_end_offset
, '}');
2527 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
,
2528 tvb_observedevents_end_offset
, '{');
2530 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,
2531 tvb_observedevents_end_offset
, ',');
2533 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_observedevents_end_offset
){
2534 tvb_current_offset
= tvb_observedevents_end_offset
;
2538 /* Descriptor includes no parameters */
2540 if ( tvb_LBRKT
> tvb_current_offset
|| tvb_LBRKT
== -1 ){
2542 tvb_RBRKT
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1)-1;
2545 /* Descriptor includes Parameters */
2547 if ( (tvb_current_offset
> tvb_LBRKT
&& tvb_LBRKT
!= -1)){
2549 while ( tvb_LBRKT
!= -1 && tvb_RBRKT
> tvb_LBRKT
){
2551 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
2552 tvb_observedevents_end_offset
, '{');
2553 if ( tvb_LBRKT
< tvb_RBRKT
&& tvb_LBRKT
!= -1){
2554 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2555 tvb_observedevents_end_offset
, '}');
2561 tvb_LBRKT
= tvb_help_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_observedevents_end_offset
, '{');
2563 /* if there are eventparameter */
2565 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
2567 requested_event_start_offset
= tvb_help_offset
;
2568 requested_event_end_offset
= tvb_RBRKT
;
2569 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_help_offset
-1);
2570 pkg_tokenlen
= tvb_help_offset
- tvb_previous_offset
;
2571 tokenlen
= tvb_LBRKT
+1 - tvb_previous_offset
;
2575 tokenlen
= pkg_tokenlen
= tvb_RBRKT
+1 - tvb_previous_offset
;
2578 megaco_observedevent_ti
= proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_previous_offset
, tokenlen
,
2579 "%s", tvb_format_text(tvb
, tvb_previous_offset
, tokenlen
));
2581 megaco_observedevent_tree
= proto_item_add_subtree(megaco_observedevent_ti
, ett_megaco_observedevent
);
2583 proto_tree_add_item(megaco_observedevent_tree
,hf_megaco_pkgdname
,tvb
,tvb_previous_offset
,pkg_tokenlen
, ENC_ASCII
|ENC_NA
);
2585 if ( tvb_help_offset
< tvb_RBRKT
&& tvb_help_offset
!= -1 ){
2587 requested_event_start_offset
= megaco_tvb_skip_wsp(tvb
, requested_event_start_offset
+1)-1;
2588 requested_event_end_offset
= megaco_tvb_skip_wsp_return(tvb
, requested_event_end_offset
-1);
2590 tvb_help_offset
= requested_event_start_offset
;
2595 param_start_offset
= megaco_tvb_skip_wsp(tvb
, tvb_help_offset
+1);
2597 tvb_help_offset
= tvb_find_guint8(tvb
, tvb_help_offset
+1,requested_event_end_offset
, ',');
2599 if ( tvb_help_offset
> requested_event_end_offset
|| tvb_help_offset
== -1){
2600 tvb_help_offset
= requested_event_end_offset
;
2603 param_end_offset
= megaco_tvb_skip_wsp(tvb
, tvb_help_offset
-1);
2605 tokenlen
= param_end_offset
- param_start_offset
+1;
2606 msg
=tvb_format_text(tvb
,param_start_offset
, tokenlen
);
2607 if(!strncmp("h245", msg
, 4)){
2608 dissect_megaco_h245(tvb
, pinfo
, megaco_tree_command_line
, param_start_offset
, tokenlen
, msg
);
2610 proto_tree_add_text(megaco_tree_command_line
, tvb
, param_start_offset
, tokenlen
,
2615 } while ( tvb_help_offset
< requested_event_end_offset
);
2618 tvb_previous_offset
= tvb_current_offset
;
2619 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_RBRKT
,
2620 tvb_observedevents_end_offset
, ',');
2622 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_observedevents_end_offset
){
2623 tvb_current_offset
= tvb_observedevents_end_offset
;
2625 if (tvb_current_offset
< tvb_previous_offset
) {
2626 expert_add_info_format(pinfo
, megaco_observedevent_ti
, &ei_megaco_parse_error
, "Parse error: Invalid offset");
2630 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2632 tvb_LBRKT
= tvb_previous_offset
;
2633 tvb_RBRKT
= tvb_previous_offset
;
2634 /* Print the trailing '}' */
2635 proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_observedevents_end_offset
, 1,
2636 "%s", tvb_format_text(tvb
, tvb_observedevents_end_offset
, 1));
2638 } while ( tvb_current_offset
< tvb_observedevents_end_offset
);
2642 dissect_megaco_topologydescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2647 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
2648 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_topology_descriptor
, tvb
,
2649 tvb_previous_offset
, tokenlen
,
2650 tvb_format_text_wsp(tvb
, tvb_previous_offset
,
2655 dissect_megaco_Packagesdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2658 gint tokenlen
, tvb_current_offset
, tvb_next_offset
, tvb_help_offset
;
2659 gint tvb_packages_end_offset
, tvb_LBRKT
;
2660 proto_tree
*megaco_packagesdescriptor_tree
, *megaco_packagesdescriptor_ti
;
2662 tokenlen
= (tvb_RBRKT
+1) - tvb_previous_offset
;
2664 megaco_packagesdescriptor_ti
= proto_tree_add_item(megaco_tree_command_line
,hf_megaco_packages_descriptor
,tvb
,tvb_previous_offset
,tokenlen
, ENC_ASCII
|ENC_NA
);
2665 megaco_packagesdescriptor_tree
= proto_item_add_subtree(megaco_packagesdescriptor_ti
, ett_megaco_packagesdescriptor
);
2669 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '=');
2670 tvb_next_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '{');
2672 if ( tvb_current_offset
< tvb_RBRKT
&& tvb_current_offset
!= -1 ){
2674 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2675 tvb_help_offset
= megaco_tvb_skip_wsp_return(tvb
, tvb_next_offset
-1);
2677 tokenlen
= tvb_help_offset
- tvb_current_offset
;
2679 proto_tree_add_string(megaco_packagesdescriptor_tree
, hf_megaco_requestid
, tvb
,
2680 tvb_current_offset
, tokenlen
,
2681 tvb_format_text(tvb
, tvb_current_offset
,
2684 tvb_packages_end_offset
= tvb_RBRKT
;
2686 tvb_RBRKT
= tvb_next_offset
+1;
2687 tvb_LBRKT
= tvb_next_offset
+1;
2688 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_next_offset
+1);
2693 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2694 tvb_packages_end_offset
, '}');
2695 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
,
2696 tvb_packages_end_offset
, '{');
2698 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
,
2699 tvb_packages_end_offset
, ',');
2701 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_packages_end_offset
){
2702 tvb_current_offset
= tvb_packages_end_offset
;
2706 /* Descriptor includes no parameters */
2708 if ( tvb_LBRKT
> tvb_current_offset
|| tvb_LBRKT
== -1 ){
2710 tvb_RBRKT
= megaco_tvb_skip_wsp_return(tvb
, tvb_current_offset
-1)-1;
2713 /* Descriptor includes Parameters */
2715 if ( (tvb_current_offset
> tvb_LBRKT
&& tvb_LBRKT
!= -1)){
2717 while ( tvb_LBRKT
!= -1 && tvb_RBRKT
> tvb_LBRKT
){
2719 tvb_LBRKT
= tvb_find_guint8(tvb
, tvb_LBRKT
+1,
2720 tvb_packages_end_offset
, '{');
2721 if ( tvb_LBRKT
< tvb_RBRKT
&& tvb_LBRKT
!= -1)
2722 tvb_RBRKT
= tvb_find_guint8(tvb
, tvb_RBRKT
+1,
2723 tvb_packages_end_offset
, '}');
2728 tokenlen
= tvb_RBRKT
+1 - tvb_previous_offset
;
2730 proto_tree_add_text(megaco_packagesdescriptor_tree
, tvb
, tvb_previous_offset
, tokenlen
,
2731 "%s", tvb_format_text(tvb
,tvb_previous_offset
,
2735 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_RBRKT
,
2736 tvb_packages_end_offset
, ',');
2738 if (tvb_current_offset
== -1 || tvb_current_offset
> tvb_packages_end_offset
){
2739 tvb_current_offset
= tvb_packages_end_offset
;
2742 tvb_previous_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2744 tvb_LBRKT
= tvb_previous_offset
;
2745 tvb_RBRKT
= tvb_previous_offset
;
2747 } while ( tvb_current_offset
< tvb_packages_end_offset
);
2751 /* The list of error code values is fetched from http://www.iana.org/assignments/megaco-h248 */
2754 static const value_string MEGACO_error_code_vals
[] = {
2756 {400, "Syntax error in message"},
2757 {401, "Protocol Error"},
2758 {402, "Unauthorized"},
2759 {403, "Syntax error in transaction request"},
2760 {406, "Version Not Supported"},
2761 {410, "Incorrect identifier"},
2762 {411, "The transaction refers to an unknown ContextId"},
2763 {412, "No ContextIDs available"},
2764 {421, "Unknown action or illegal combination of actions"},
2765 {422, "Syntax Error in Action"},
2766 {430, "Unknown TerminationID"},
2767 {431, "No TerminationID matched a wildcard"},
2768 {432, "Out of TerminationIDs or No TerminationID available"},
2769 {433, "TerminationID is already in a Context"},
2770 {434, "Max number of Terminations in a Context exceeded"},
2771 {435, "Termination ID is not in specified Context"},
2772 {440, "Unsupported or unknown Package"},
2773 {441, "Missing Remote or Local Descriptor"},
2774 {442, "Syntax Error in Command"},
2775 {443, "Unsupported or Unknown Command"},
2776 {444, "Unsupported or Unknown Descriptor"},
2777 {445, "Unsupported or Unknown Property"},
2778 {446, "Unsupported or Unknown Parameter"},
2779 {447, "Descriptor not legal in this command"},
2780 {448, "Descriptor appears twice in a command"},
2781 {450, "No such property in this package"},
2782 {451, "No such event in this package"},
2783 {452, "No such signal in this package"},
2784 {453, "No such statistic in this package"},
2785 {454, "No such parameter value in this package"},
2786 {455, "Property illegal in this Descriptor"},
2787 {456, "Property appears twice in this Descriptor"},
2788 {457, "Missing parameter in signal or event"},
2789 {458, "Unexpected Event/Request ID"},
2790 {459, "Unsupported or Unknown Profile"},
2791 {471, "Implied Add for Multiplex failure"},
2793 {500, "Internal software Failure in MG"},
2794 {501, "Not Implemented"},
2795 {502, "Not ready."},
2796 {503, "Service Unavailable"},
2797 {504, "Command Received from unauthorized entity"},
2798 {505, "Transaction Request Received before a Service Change Reply has been received"},
2799 {506, "Number of Transaction Pendings Exceeded"},
2800 {510, "Insufficient resources"},
2801 {512, "Media Gateway unequipped to detect requested Event"},
2802 {513, "Media Gateway unequipped to generate requested Signals"},
2803 {514, "Media Gateway cannot send the specified announcement"},
2804 {515, "Unsupported Media Type"},
2805 {517, "Unsupported or invalid mode"},
2806 {518, "Event buffer full"},
2807 {519, "Out of space to store digit map"},
2808 {520, "Digit Map undefined in the MG"},
2809 {521, "Termination is ServiceChanging"},
2810 {526, "Insufficient bandwidth"},
2811 {529, "Internal hardware failure in MG"},
2812 {530, "Temporary Network failure"},
2813 {531, "Permanent Network failure"},
2814 {532, "Audited Property, Statistic, Event or Signal does not exist"},
2815 {533, "Response exceeds maximum transport PDU size"},
2816 {534, "Illegal write or read only property"},
2817 {540, "Unexpected initial hook state"},
2818 {581, "Does Not Exist"},
2820 {600, "Illegal syntax within an announcement specification"},
2821 {601, "Variable type not supported"},
2822 {602, "Variable value out of range"},
2823 {603, "Category not supported"},
2824 {604, "Selector type not supported"},
2825 {605, "Selector value not supported"},
2826 {606, "Unknown segment ID"},
2827 {607, "Mismatch between play specification and provisioned data"},
2828 {608, "Provisioning error"},
2829 {609, "Invalid offset"},
2830 {610, "No free segment IDs"},
2831 {611, "Temporary segment not found"},
2832 {612, "Segment in use"},
2833 {613, "ISP port limit overrun"},
2834 {614, "No modems available"},
2835 {615, "Calling number unacceptable"},
2836 {616, "Called number unacceptable"},
2843 dissect_megaco_errordescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_tree_command_line
, gint tvb_RBRKT
, gint tvb_previous_offset
)
2849 gint tvb_current_offset
;
2851 proto_item
* hidden_item
;
2853 tvb_current_offset
= tvb_find_guint8(tvb
, tvb_previous_offset
, tvb_RBRKT
, '=');
2854 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_current_offset
+1);
2855 tvb_get_nstringz0(tvb
,tvb_current_offset
,4,error
);
2856 error_code
= atoi(error
);
2857 hidden_item
= proto_tree_add_string(megaco_tree_command_line
, hf_megaco_error_descriptor
, tvb
,
2858 tvb_current_offset
, 3,
2859 tvb_format_text(tvb
, tvb_current_offset
,
2861 PROTO_ITEM_SET_HIDDEN(hidden_item
);
2863 tokenlen
= (tvb_RBRKT
) - tvb_previous_offset
+1;
2866 proto_tree_add_string(megaco_tree_command_line
, hf_megaco_error_descriptor
, tvb
,
2867 tvb_previous_offset
, tokenlen
,
2868 tvb_format_text(tvb
, tvb_previous_offset
,
2871 item
= proto_tree_add_text(megaco_tree_command_line
, tvb
, tvb_current_offset
, 3,
2873 val_to_str(error_code
, MEGACO_error_code_vals
,
2876 PROTO_ITEM_SET_GENERATED(item
);
2880 dissect_megaco_TerminationStatedescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_mediadescriptor_tree
, gint tvb_next_offset
, gint tvb_current_offset
)
2886 proto_tree
*megaco_TerminationState_tree
, *megaco_TerminationState_ti
;
2888 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_next_offset
, '=');
2890 tokenlen
= tvb_next_offset
- tvb_current_offset
;
2892 megaco_TerminationState_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_TerminationState_descriptor,tvb,tvb_current_offset,tokenlen, ENC_ASCII|ENC_NA);
2893 megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState);
2895 megaco_TerminationState_ti
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_current_offset
, tokenlen
,
2896 "%s", tvb_format_text(tvb
, tvb_current_offset
, tokenlen
));
2897 megaco_TerminationState_tree
= proto_item_add_subtree(megaco_TerminationState_ti
, ett_megaco_TerminationState
);
2899 while ( tvb_offset
< tvb_next_offset
&& tvb_offset
!= -1 ){
2901 tempchar
= tvb_get_guint8(tvb
, tvb_current_offset
);
2902 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
2903 if ( (tempchar
>= 'a')&& (tempchar
<= 'z'))
2904 tempchar
= tempchar
- 0x20;
2906 switch ( tempchar
){
2909 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_offset
, ',');
2910 if ( tvb_offset
== -1 || tvb_offset
> tvb_next_offset
){
2911 tvb_offset
= tvb_next_offset
;
2914 tokenlen
= tvb_offset
- tvb_current_offset
;
2916 proto_tree_add_string(megaco_TerminationState_tree
, hf_megaco_Service_State
, tvb
,
2917 tvb_current_offset
, tokenlen
,
2918 tvb_format_text(tvb
, tvb_current_offset
,
2925 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_offset
, ',');
2926 if ( tvb_offset
== -1 || tvb_offset
> tvb_next_offset
){
2927 tvb_offset
= tvb_next_offset
;
2930 tokenlen
= tvb_offset
- tvb_current_offset
;
2932 proto_tree_add_string(megaco_TerminationState_tree
, hf_megaco_Event_Buffer_Control
, tvb
,
2933 tvb_current_offset
, tokenlen
,
2934 tvb_format_text(tvb
, tvb_current_offset
,
2940 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_offset
, ',');
2941 if ( tvb_offset
== -1 || tvb_offset
> tvb_next_offset
){
2942 tvb_offset
= tvb_next_offset
;
2945 tokenlen
= tvb_offset
- tvb_current_offset
;
2947 proto_tree_add_string(megaco_TerminationState_tree
, hf_megaco_Event_Buffer_Control
, tvb
,
2948 tvb_current_offset
, tokenlen
,
2949 tvb_format_text(tvb
, tvb_current_offset
,
2955 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_offset
, ',');
2956 if ( tvb_offset
== -1 || tvb_offset
> tvb_next_offset
){
2957 tvb_offset
= tvb_next_offset
;
2960 tokenlen
= tvb_offset
- tvb_current_offset
;
2962 proto_tree_add_text(megaco_TerminationState_tree
, tvb
, tvb_current_offset
, tokenlen
,
2963 "%s", tvb_format_text(tvb
,tvb_current_offset
,tokenlen
));
2968 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
2969 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_next_offset
, '=');
2972 proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_next_offset
, 1,
2973 "%s", tvb_format_text(tvb
, tvb_next_offset
, 1));
2978 dissect_megaco_Localdescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_mediadescriptor_tree
,packet_info
*pinfo
, gint tvb_next_offset
, gint tvb_current_offset
)
2983 proto_tree
*megaco_localdescriptor_tree
, *megaco_localdescriptor_ti
;
2985 tokenlen
= tvb_next_offset
- tvb_current_offset
;
2989 megaco_localdescriptor_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_Local_descriptor,tvb,tvb_current_offset,tokenlen, ENC_ASCII|ENC_NA);
2991 megaco_localdescriptor_ti
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_current_offset
, tokenlen
,
2992 "%s", tvb_format_text(tvb
, tvb_current_offset
, tokenlen
));
2993 megaco_localdescriptor_tree
= proto_item_add_subtree(megaco_localdescriptor_ti
, ett_megaco_Localdescriptor
);
2995 tokenlen
= tvb_next_offset
- tvb_current_offset
;
2996 if ( tokenlen
> 3 ){
2997 next_tvb
= tvb_new_subset(tvb
, tvb_current_offset
, tokenlen
, tokenlen
);
2998 call_dissector(sdp_handle
, next_tvb
, pinfo
, megaco_localdescriptor_tree
);
3003 * localControlDescriptor = LocalControlToken LBRKT localParm
3004 * *(COMMA localParm) RBRKT
3005 * ; at-most-once per item
3006 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3009 #define MEGACO_MODETOKEN 1
3010 #define MEGACO_RESERVEDVALUETOKEN 2
3011 #define MEGACO_RESERVEDGROUPTOKEN 3
3012 #define MEGACO_H324_H223CAPR 4
3013 #define MEGACO_H324_MUXTBL_IN 5
3014 #define MEGACO_H324_MUXTBL_OUT 6
3015 #define MEGACO_DS_DSCP 7
3016 #define MEGACO_GM_SAF 8
3017 #define MEGACO_GM_SAM 9
3018 #define MEGACO_GM_SPF 10
3019 #define MEGACO_GM_SPR 11
3020 #define MEGACO_GM_ESAS 12
3021 #define MEGACO_GM_LSA 13
3022 #define MEGACO_GM_ESPS 14
3023 #define MEGACO_GM_LSP 15
3024 #define MEGACO_GM_RSB 16
3026 static const megaco_tokens_t megaco_localParam_names
[] = {
3027 { "Unknown-token", NULL
}, /* 0 Pad so that the real headers start at index 1 */
3029 { "Mode", "MO" }, /* 1 */
3030 { "ReservedValue", "RV" }, /* 2 */
3031 { "ReservedGroup", "RG" }, /* 3 */
3032 /* propertyParm = pkgdName parmValue
3033 * Add more package names as needed.
3035 { "h324/h223capr", NULL
}, /* 4 */
3036 { "h324/muxtbl_in", NULL
}, /* 5 */
3037 { "h324/muxtbl_out", NULL
}, /* 6 */
3038 { "ds/dscp", NULL
}, /* 7 */
3039 { "gm/saf", NULL
}, /* 8 */
3040 { "gm/sam", NULL
}, /* 9 */
3041 { "gm/spf", NULL
}, /* 10 */
3042 { "gm/spr", NULL
}, /* 11 */
3043 { "gm/esas", NULL
}, /* 12 */
3044 { "gm/lsa", NULL
}, /* 13 */
3045 { "gm/esps", NULL
}, /* 14 */
3046 { "gm/lsp", NULL
}, /* 15 */
3047 { "gm/rsb", NULL
}, /* 16 */
3050 /* Returns index of megaco_tokens_t */
3051 static gint
find_megaco_localParam_names(tvbuff_t
*tvb
, int offset
, guint header_len
)
3055 for (i
= 1; i
< array_length(megaco_localParam_names
); i
++) {
3056 if (header_len
== strlen(megaco_localParam_names
[i
].name
) &&
3057 tvb_strncaseeql(tvb
, offset
, megaco_localParam_names
[i
].name
, header_len
) == 0)
3059 if (megaco_localParam_names
[i
].compact_name
!= NULL
&&
3060 header_len
== strlen(megaco_localParam_names
[i
].compact_name
) &&
3061 tvb_strncaseeql(tvb
, offset
, megaco_localParam_names
[i
].compact_name
, header_len
) == 0)
3069 dissect_megaco_LocalControldescriptor(tvbuff_t
*tvb
, proto_tree
*megaco_mediadescriptor_tree
, packet_info
*pinfo
, gint tvb_next_offset
, gint tvb_current_offset
)
3072 guint token_name_len
;
3073 gint tvb_offset
,tvb_help_offset
;
3074 gint token_index
= 0;
3079 /*proto_tree *megaco_LocalControl_tree, *megaco_LocalControl_ti; */
3084 tokenlen = tvb_next_offset - tvb_current_offset;
3086 megaco_LocalControl_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_LocalControl_descriptor,tvb,tvb_current_offset,tokenlen, ENC_ASCII|ENC_NA);
3087 megaco_LocalControl_tree = proto_item_add_subtree(megaco_LocalControl_ti, ett_megaco_LocalControldescriptor);
3089 while ( tvb_offset
< tvb_next_offset
&& tvb_offset
!= -1 ){
3091 tvb_help_offset
= tvb_current_offset
;
3094 * Find local parameter name
3095 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3096 * pkgdName = (PackageName SLASH ItemID) ;specific item
3097 * / (PackageName SLASH "*") ;all events in package
3098 * / ("*" SLASH "*") ; all events supported by the MG
3100 /* Find token length */
3101 for (tvb_offset
=tvb_current_offset
; tvb_offset
< tvb_next_offset
; tvb_offset
++){
3103 octet
= tvb_get_guint8(tvb
, tvb_offset
);
3104 if (!isalnum(octet
)){
3105 if ((octet
!='/')&&(octet
!='_')){
3110 token_name_len
= tvb_offset
- tvb_current_offset
;
3112 proto_tree_add_text(megaco_LocalControl_tree, tvb, tvb_current_offset, token_name_len,
3113 "%s", tvb_format_text(tvb,tvb_current_offset,token_name_len));
3116 token_index
= find_megaco_localParam_names(tvb
, tvb_current_offset
, token_name_len
);
3117 /* Find start of parameter value */
3118 tvb_offset
= tvb_find_guint8(tvb
, tvb_offset
, tvb_next_offset
, '=');
3119 if (tvb_offset
== -1)
3120 THROW(ReportedBoundsError
);
3121 /* Start search after '=' in case there is no SP*/
3123 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
);
3125 /* find if there are more parameters or not */
3126 tvb_offset
= tvb_find_guint8(tvb
, tvb_current_offset
, tvb_offset
, ',');
3127 if ( tvb_offset
< 0 || tvb_offset
> tvb_next_offset
){
3128 tvb_offset
= tvb_next_offset
;
3131 tokenlen
= megaco_tvb_skip_wsp_return(tvb
,tvb_offset
-1) - tvb_current_offset
;
3133 proto_tree_add_text(megaco_LocalControl_tree, tvb, tvb_current_offset, tokenlen,
3134 "%s", tvb_format_text(tvb,tvb_current_offset,tokenlen));
3137 switch ( token_index
){
3139 case MEGACO_MODETOKEN
: /* Mode */
3140 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_mode
, tvb
,
3141 tvb_current_offset
, tokenlen
,
3142 tvb_format_text(tvb
, tvb_current_offset
,
3144 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (Mode:%s)",tvb_format_text(tvb
, tvb_current_offset
,tokenlen
));
3145 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3148 case MEGACO_RESERVEDVALUETOKEN
: /* ReservedValue */
3149 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_reserve_value
, tvb
,
3150 tvb_current_offset
, tokenlen
,
3151 tvb_format_text(tvb
, tvb_current_offset
,
3154 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3156 case MEGACO_RESERVEDGROUPTOKEN
: /* ReservedGroup */
3157 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_reserve_group
, tvb
,
3158 tvb_current_offset
, tokenlen
,
3159 tvb_format_text(tvb
, tvb_current_offset
,
3161 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3164 case MEGACO_H324_H223CAPR
: /* h324/h223capr */
3165 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_h324_h223capr
, tvb
,
3166 tvb_current_offset
, tokenlen
,
3167 tvb_format_text(tvb
, tvb_current_offset
,
3170 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3171 tokenlen
= tvb_offset
- tvb_help_offset
;
3172 msg
=tvb_format_text(tvb
,tvb_help_offset
, tokenlen
);
3173 dissect_megaco_h324_h223caprn(tvb
, pinfo
, megaco_mediadescriptor_tree
, tvb_help_offset
, tokenlen
, msg
);
3177 case MEGACO_H324_MUXTBL_IN
: /* h324/muxtbl_in */
3179 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_h324_muxtbl_in
, tvb
,
3180 tvb_current_offset
, tokenlen
,
3181 tvb_format_text(tvb
, tvb_current_offset
,
3184 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3186 tokenlen
= tvb_offset
- tvb_help_offset
;
3187 msg
=tvb_format_text(tvb
,tvb_help_offset
, tokenlen
);
3188 /* Call the existing routine with tree = NULL to avoid an entry to the tree */
3189 dissect_megaco_h245(tvb
, pinfo
, NULL
, tvb_help_offset
, tokenlen
, msg
);
3193 case MEGACO_H324_MUXTBL_OUT
:
3195 proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_h324_muxtbl_out
, tvb
,
3196 tvb_current_offset
, tokenlen
,
3197 tvb_format_text(tvb
, tvb_current_offset
,
3200 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3202 tokenlen
= tvb_offset
- tvb_help_offset
;
3203 msg
=tvb_format_text(tvb
,tvb_help_offset
, tokenlen
);
3204 /* Call the existing routine with tree = NULL to avoid an entry to the tree */
3205 dissect_megaco_h245(tvb
, pinfo
, NULL
, tvb_help_offset
, tokenlen
, msg
);
3209 case MEGACO_DS_DSCP
:
3210 item
= proto_tree_add_string(megaco_mediadescriptor_tree
, hf_megaco_ds_dscp
, tvb
,
3211 tvb_current_offset
, tokenlen
,
3212 tvb_format_text(tvb
, tvb_current_offset
,
3215 tvb_get_nstringz0(tvb
,tvb_current_offset
,3,code_str
);
3216 proto_item_append_text(item
,"[ %s ]",
3217 val_to_str_ext((guint32
)strtoul(code_str
,NULL
,16), &dscp_vals_ext
,"Unknown (%u)"));
3219 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3223 tokenlen
= tvb_offset
- tvb_help_offset
;
3224 item
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3225 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3227 proto_item_append_text(item
," [Remote Source Address Filtering]");
3228 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3231 tokenlen
= tvb_offset
- tvb_help_offset
;
3232 item
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3233 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3235 proto_item_append_text(item
," [Remote Source Address Mask]");
3236 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3239 tokenlen
= tvb_offset
- tvb_help_offset
;
3240 item
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3241 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3243 proto_item_append_text(item
," [Remote Source Port Filtering]");
3244 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3247 tokenlen
= tvb_offset
- tvb_help_offset
;
3248 item
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3249 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3251 proto_item_append_text(item
," [Remote Source Port Range]");
3252 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3254 case MEGACO_GM_ESAS
:
3255 tokenlen
= tvb_offset
- tvb_help_offset
;
3256 item
= proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3257 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3259 proto_item_append_text(item
," [Explicit Source Address Setting]");
3260 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3263 tokenlen
= tvb_offset
- tvb_help_offset
;
3264 proto_tree_add_text(megaco_mediadescriptor_tree
, tvb
, tvb_help_offset
, tokenlen
,
3265 "%s", tvb_format_text(tvb
,tvb_help_offset
,
3267 tvb_current_offset
= megaco_tvb_skip_wsp(tvb
, tvb_offset
+1);
3273 /* Copied from MGCP dissector, prints whole message in raw text */
3275 static void tvb_raw_text_add(tvbuff_t
*tvb
, proto_tree
*tree
){
3277 gint tvb_linebegin
,tvb_lineend
,tvb_len
,linelen
;
3280 tvb_len
= tvb_length(tvb
);
3282 proto_tree_add_text(tree
, tvb
, 0, -1,"-------------- (RAW text output) ---------------");
3285 linelen
= tvb_find_line_end(tvb
,tvb_linebegin
,-1,&tvb_lineend
,FALSE
);
3286 proto_tree_add_text(tree
, tvb
, tvb_linebegin
, linelen
,
3287 "%s", tvb_format_text_wsp(tvb
,tvb_linebegin
,
3289 tvb_linebegin
= tvb_lineend
;
3290 } while ( tvb_lineend
< tvb_len
);
3294 * megaco_tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3295 * character following offset or offset + maxlength -1 whichever
3299 * tvb - The tvbuff in which we are skipping whitespaces, tab and end_of_line characters.
3300 * offset - The offset in tvb from which we begin trying to skip whitespace.
3302 * Returns: The position in tvb of the first non-whitespace
3304 static gint
megaco_tvb_skip_wsp(tvbuff_t
* tvb
, gint offset
){
3305 gint counter
= offset
;
3308 tvb_len
= tvb_length(tvb
);
3311 for(counter
= offset
; counter
< end
&&
3312 ((tempchar
= tvb_get_guint8(tvb
,counter
)) == ' ' ||
3313 tempchar
== '\t' || tempchar
== '\n' || tempchar
== '\r'); counter
++);
3317 static gint
megaco_tvb_skip_wsp_return(tvbuff_t
* tvb
, gint offset
){
3318 gint counter
= offset
;
3323 for(counter
= offset
; counter
> end
&&
3324 ((tempchar
= tvb_get_guint8(tvb
,counter
)) == ' ' ||
3325 tempchar
== '\t' || tempchar
== '\n' || tempchar
== '\r'); counter
--);
3330 static gint
megaco_tvb_find_token(tvbuff_t
* tvb
, gint offset
, gint maxlength
){
3336 pos
= tvb_pbrk_guint8(tvb
, pos
+ 1, maxlength
, "{}", &needle
);
3349 } while (counter
>0);
3354 pos
= megaco_tvb_skip_wsp(tvb
,pos
+1);
3359 void proto_reg_handoff_megaco(void);
3362 proto_register_megaco(void)
3364 static hf_register_info hf
[] = {
3365 { &hf_megaco_audititem
,
3366 { "Audit Item", "megaco.audititem", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3367 "Identity of item to be audited", HFILL
}},
3368 { &hf_megaco_audit_descriptor
,
3369 { "Audit Descriptor", "megaco.audit", FT_NONE
, BASE_NONE
, NULL
, 0x0,
3370 "Audit Descriptor of the megaco Command", HFILL
}},
3372 { &hf_megaco_command_line
,
3373 { "Command line", "megaco.command_line", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3374 "Commands of this message", HFILL
}},
3376 { &hf_megaco_command
,
3377 { "Command", "megaco.command", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3378 "Command of this message", HFILL
}},
3379 { &hf_megaco_Context
,
3380 { "Context", "megaco.context", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3381 "Context ID of this message", HFILL
}},
3382 { &hf_megaco_digitmap_descriptor
,
3383 { "DigitMap Descriptor", "megaco.digitmap", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3384 "DigitMap Descriptor of the megaco Command", HFILL
}},
3385 { &hf_megaco_error_descriptor
,
3386 { "ERROR Descriptor", "megaco.error", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3387 "Error Descriptor of the megaco Command", HFILL
}},
3388 { &hf_megaco_error_Frame
,
3389 { "ERROR frame", "megaco.error_frame", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3390 "Syntax error", HFILL
}},
3391 { &hf_megaco_Event_Buffer_Control
,
3392 { "Event Buffer Control", "megaco.eventbuffercontrol", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3393 "Event Buffer Control in Termination State Descriptor", HFILL
}},
3395 { &hf_megaco_events_descriptor
,
3396 { "Events Descriptor", "megaco.events", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3397 "Events Descriptor of the megaco Command", HFILL
}},
3400 { &hf_megaco_Local_descriptor
,
3401 { "Local Descriptor", "megaco.localdescriptor", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3402 "Local Descriptor in Media Descriptor", HFILL
}},
3405 { &hf_megaco_LocalControl_descriptor
,
3406 { "Local Control Descriptor", "megaco.localcontroldescriptor", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3407 "Local Control Descriptor in Media Descriptor", HFILL
}},
3410 { &hf_megaco_media_descriptor
,
3411 { "Media Descriptor", "megaco.media", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3412 "Media Descriptor of the megaco Command", HFILL
}},
3414 { &hf_megaco_modem_descriptor
,
3415 { "Modem Descriptor", "megaco.modem", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3416 "Modem Descriptor of the megaco Command", HFILL
}},
3418 { "Mode", "megaco.mode", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3419 "Mode sendonly/receiveonly/inactive/loopback", HFILL
}},
3420 { &hf_megaco_multiplex_descriptor
,
3421 { "Multiplex Descriptor", "megaco.multiplex", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3422 "Multiplex Descriptor of the megaco Command", HFILL
}},
3424 { &hf_megaco_observedevents_descriptor
,
3425 { "Observed Events Descriptor", "megaco.observedevents", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3426 "Observed Events Descriptor of the megaco Command", HFILL
}},
3428 { &hf_megaco_packages_descriptor
,
3429 { "Packages Descriptor", "megaco.packagesdescriptor", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3431 { &hf_megaco_pkgdname
,
3432 { "pkgdName", "megaco.pkgdname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3433 "PackageName SLASH ItemID", HFILL
}},
3435 { &hf_megaco_Remote_descriptor
,
3436 { "Remote Descriptor", "megaco.remotedescriptor", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3437 "Remote Descriptor in Media Descriptor", HFILL
}},
3439 { &hf_megaco_reserve_group
,
3440 { "Reserve Group", "megaco.reservegroup", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3441 "Reserve Group on or off", HFILL
}},
3442 { &hf_megaco_h324_muxtbl_in
,
3443 { "h324/muxtbl_in", "megaco.h324_muxtbl_in", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3445 { &hf_megaco_h324_muxtbl_out
,
3446 { "h324/muxtbl_out", "megaco.h324_muxtbl_out", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3448 { &hf_megaco_ds_dscp
,
3449 { "ds/dscp", "megaco.ds_dscp", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3450 "ds/dscp Differentiated Services Code Point", HFILL
}},
3451 { &hf_megaco_h324_h223capr
,
3452 { "h324/h223capr", "megaco.h324_h223capr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3454 { &hf_megaco_reserve_value
,
3455 { "Reserve Value", "megaco.reservevalue", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3456 "Reserve Value on or off", HFILL
}},
3457 { &hf_megaco_requestid
,
3458 { "RequestID", "megaco.requestid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3459 "RequestID in Events or Observedevents Descriptor", HFILL
}},
3461 { &hf_megaco_servicechange_descriptor
,
3462 { "Service Change Descriptor", "megaco.servicechange", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3463 "Service Change Descriptor of the megaco Command", HFILL
}},
3465 { &hf_megaco_Service_State
,
3466 { "Service State", "megaco.servicestates", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3467 "Service States in Termination State Descriptor", HFILL
}},
3469 { &hf_megaco_signal_descriptor
,
3470 { "Signal Descriptor", "megaco.signal", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3471 "Signal Descriptor of the megaco Command", HFILL
}},
3473 { &hf_megaco_statistics_descriptor
,
3474 { "Statistics Descriptor", "megaco.statistics", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3475 "Statistics Descriptor of the megaco Command", HFILL
}},
3476 { &hf_megaco_streamid
,
3477 { "StreamID", "megaco.streamid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3478 "StreamID in the Media Descriptor", HFILL
}},
3479 { &hf_megaco_termid
,
3480 { "Termination ID", "megaco.termid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3481 "Termination ID of this Command", HFILL
}},
3483 { &hf_megaco_TerminationState_descriptor
,
3484 { "Termination State Descriptor", "megaco.terminationstate", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3485 "Termination State Descriptor in Media Descriptor", HFILL
}},
3487 { &hf_megaco_topology_descriptor
,
3488 { "Topology Descriptor", "megaco.topology", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3489 "Topology Descriptor of the megaco Command", HFILL
}},
3490 { &hf_megaco_transaction
,
3491 { "Transaction", "megaco.transaction", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3492 "Message Originator", HFILL
}},
3493 { &hf_megaco_transid
,
3494 { "Transaction ID", "megaco.transid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3495 "Transaction ID of this message", HFILL
}},
3497 { "MediagatewayID", "megaco.mId", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3498 "Mediagateway ID", HFILL
}},
3499 { &hf_megaco_version
,
3500 { "Version", "megaco.version", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3504 { "h245", "megaco.h245", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3505 "Embedded H.245 message", HFILL
}},
3507 { &hf_megaco_h223Capability
,
3508 { "h223Capability", "megaco.h245.h223Capability", FT_NONE
, BASE_NONE
, NULL
, 0,
3509 "megaco.h245.H223Capability", HFILL
}},
3511 GCP_HF_ARR_ELEMS("megaco",megaco_ctx_ids
),
3513 /* Add more fields here */
3515 static gint
*ett
[] = {
3517 &ett_megaco_message
,
3518 &ett_megaco_message_body
,
3519 &ett_megaco_context
,
3520 &ett_megaco_command_line
,
3521 &ett_megaco_descriptors
,
3522 &ett_megaco_mediadescriptor
,
3523 &ett_megaco_TerminationState
,
3524 &ett_megaco_Remotedescriptor
,
3525 &ett_megaco_Localdescriptor
,
3526 &ett_megaco_LocalControldescriptor
,
3527 &ett_megaco_auditdescriptor
,
3528 &ett_megaco_eventsdescriptor
,
3529 &ett_megaco_observedeventsdescriptor
,
3530 &ett_megaco_observedevent
,
3531 &ett_megaco_packagesdescriptor
,
3532 &ett_megaco_requestedevent
,
3533 &ett_megaco_signalsdescriptor
,
3534 &ett_megaco_requestedsignal
,
3536 GCP_ETT_ARR_ELEMS(megaco_ctx_ids
),
3539 static ei_register_info ei
[] = {
3540 { &ei_megaco_errored_command
, { "megaco.errored_command", PI_RESPONSE_CODE
, PI_WARN
, "Errored Command", EXPFILL
}},
3541 { &ei_megaco_parse_error
, { "megaco.parse_error", PI_MALFORMED
, PI_ERROR
, "Parse error", EXPFILL
}},
3542 { &ei_megaco_error_descriptor_transaction_list
, { "megaco.error_descriptor_transaction_list.invalid", PI_MALFORMED
, PI_ERROR
, "Sorry, can't understand errorDescriptor / transactionList", EXPFILL
}},
3543 { &ei_megaco_audit_descriptor
, { "megaco.audit.malformed", PI_MALFORMED
, PI_ERROR
, "Badly constructed audit descriptor (no { )", EXPFILL
}},
3546 module_t
*megaco_module
;
3547 expert_module_t
* expert_megaco
;
3549 proto_megaco
= proto_register_protocol("MEGACO",
3550 "MEGACO", "megaco");
3552 register_dissector("megaco", dissect_megaco_text
, proto_megaco
);
3554 proto_register_field_array(proto_megaco
, hf
, array_length(hf
));
3555 proto_register_subtree_array(ett
, array_length(ett
));
3556 expert_megaco
= expert_register_protocol(proto_megaco
);
3557 expert_register_field_array(expert_megaco
, ei
, array_length(ei
));
3559 /* Register our configuration options, particularly our ports */
3561 megaco_module
= prefs_register_protocol(proto_megaco
, proto_reg_handoff_megaco
);
3563 prefs_register_uint_preference(megaco_module
, "sctp.txt_port",
3564 "MEGACO Text SCTP Port",
3565 "Set the SCTP port for MEGACO text messages",
3566 10, &global_megaco_txt_sctp_port
);
3568 prefs_register_uint_preference(megaco_module
, "tcp.txt_port",
3569 "MEGACO Text TCP Port",
3570 "Set the TCP port for MEGACO text messages",
3571 10, &global_megaco_txt_tcp_port
);
3573 prefs_register_uint_preference(megaco_module
, "udp.txt_port",
3574 "MEGACO Text UDP Port",
3575 "Set the UDP port for MEGACO text messages",
3576 10, &global_megaco_txt_udp_port
);
3579 prefs_register_uint_preference(megaco_module
, "sctp.bin_port",
3580 "MEGACO Binary SCTP Port",
3581 "Set the SCTP port for MEGACO binary messages",
3582 10, &global_megaco_bin_sctp_port
);
3584 prefs_register_uint_preference(megaco_module
, "tcp.bin_port",
3585 "MEGACO Binary TCP Port",
3586 "Set the TCP port for MEGACO binary messages",
3587 10, &global_megaco_bin_tcp_port
);
3589 prefs_register_uint_preference(megaco_module
, "udp.bin_port",
3590 "MEGACO Binary UDP Port",
3591 "Set the UDP port for MEGACO binary messages",
3592 10, &global_megaco_bin_udp_port
);
3595 prefs_register_bool_preference(megaco_module
, "display_raw_text",
3596 "Display raw text for MEGACO message",
3597 "Specifies that the raw text of the "
3598 "MEGACO message should be displayed "
3599 "instead of (or in addition to) the "
3601 &global_megaco_raw_text
);
3603 prefs_register_bool_preference(megaco_module
, "display_dissect_tree",
3604 "Display tree dissection for MEGACO message",
3605 "Specifies that the dissection tree of the "
3606 "MEGACO message should be displayed "
3607 "instead of (or in addition to) the "
3609 &global_megaco_dissect_tree
);
3610 prefs_register_bool_preference(megaco_module
, "ctx_info",
3612 "Maintain relationships between transactions and contexts "
3613 "and display an extra tree showing context data",
3614 &keep_persistent_data
);
3616 megaco_tap
= register_tap("megaco");
3620 /* Register all the bits needed with the filtering engine */
3621 /* The registration hand-off routine */
3623 proto_reg_handoff_megaco(void)
3625 static gboolean megaco_prefs_initialized
= FALSE
;
3626 static dissector_handle_t megaco_text_tcp_handle
;
3628 * Variables to allow for proper deletion of dissector registration when
3629 * the user changes port from the gui.
3631 static guint txt_sctp_port
;
3632 static guint txt_tcp_port
;
3633 static guint txt_udp_port
;
3635 static guint bin_sctp_port
;
3636 static guint bin_tcp_port
;
3637 static guint bin_udp_port
;
3640 if (!megaco_prefs_initialized
) {
3641 sdp_handle
= find_dissector("sdp");
3642 h245_handle
= find_dissector("h245dg");
3643 h248_handle
= find_dissector("h248");
3644 h248_otp_handle
= find_dissector("h248_otp");
3645 data_handle
= find_dissector("data");
3647 megaco_text_handle
= find_dissector("megaco");
3648 megaco_text_tcp_handle
= create_dissector_handle(dissect_megaco_text_tcp
, proto_megaco
);
3650 dissector_add_uint("sctp.ppi", H248_PAYLOAD_PROTOCOL_ID
, megaco_text_handle
);
3652 megaco_prefs_initialized
= TRUE
;
3654 dissector_delete_uint("sctp.port", txt_sctp_port
, megaco_text_handle
);
3655 dissector_delete_uint("tcp.port", txt_tcp_port
, megaco_text_tcp_handle
);
3656 dissector_delete_uint("udp.port", txt_udp_port
, megaco_text_handle
);
3659 /* Set our port number for future use */
3661 txt_sctp_port
= global_megaco_txt_sctp_port
;
3662 txt_tcp_port
= global_megaco_txt_tcp_port
;
3663 txt_udp_port
= global_megaco_txt_udp_port
;
3665 dissector_add_uint("sctp.port", global_megaco_txt_sctp_port
, megaco_text_handle
);
3666 dissector_add_uint("tcp.port", global_megaco_txt_tcp_port
, megaco_text_tcp_handle
);
3667 dissector_add_uint("udp.port", global_megaco_txt_udp_port
, megaco_text_handle
);