Bug Summary

File:epan/dissectors/packet-megaco.c
Warning:line 3581, column 9
Value stored to 'tvb_LBRKT' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-megaco.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-12-23-100342-3583-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-megaco.c
1/* packet-megaco.c
2 * Routines for megaco packet disassembly
3 * RFC 3015
4 *
5 * Christian Falckenberg, 2002/10/17
6 * Copyright (c) 2002 by Christian Falckenberg
7 * <christian.falckenberg@nortelnetworks.com>
8 *
9 * Christoph Wiest, 2003/06/28
10 * Modified 2003 by Christoph Wiest
11 * <ch.wiest@tesionmail.de>
12 * Modified 2004 by Anders Broman
13 * <anders.broman@ericsson.com>
14 * To handle TPKT headers if over TCP
15 * Modified 2005 by Karl Knoebl
16 * <karl.knoebl@siemens.com>
17 * provide info to COL_INFO and some "prettification"
18 *
19 * Copyright (c) 2006 Anders Broman <anders.broman@ericsson.com>
20 *
21 * Wireshark - Network traffic analyzer
22 * By Gerald Combs <gerald@wireshark.org>
23 * Copyright 1999 Gerald Combs
24 *
25 * SPDX-License-Identifier: GPL-2.0-or-later
26 */
27
28
29#include "config.h"
30
31#include <stdlib.h>
32
33#include <epan/packet.h>
34#include <epan/tap.h>
35#include <epan/rtd_table.h>
36#include <epan/prefs.h>
37#include <epan/prefs-int.h>
38#include <epan/exported_pdu.h>
39#include <epan/asn1.h>
40#include <epan/charsets.h>
41#include <epan/unit_strings.h>
42
43#include <wsutil/array.h>
44#include <wsutil/strtoi.h>
45#include "packet-ber.h"
46#include "packet-tpkt.h"
47#include "packet-h245.h"
48#include "packet-h248.h"
49#include "packet-ip.h"
50#include "packet-media-type.h"
51#include "packet-sdp.h"
52#include "packet-sctp.h"
53
54void proto_register_megaco(void);
55void proto_reg_handoff_megaco(void);
56
57#define PORT_MEGACO_TXT2944 2944
58#define PORT_MEGACO_BIN2945 2945
59
60static pref_t *sip_hide_generated_call_ids;
61
62
63/* Define the megaco proto */
64static int proto_megaco;
65
66/* Define headers for megaco */
67static int hf_megaco_start;
68static int hf_megaco_version;
69static int hf_megaco_transaction;
70static int hf_megaco_transid;
71static int hf_megaco_Context;
72static int hf_megaco_Context_generated;
73/* static int hf_megaco_command_line; */
74static int hf_megaco_command;
75static int hf_megaco_command_optional;
76static int hf_megaco_wildcard_response;
77static int hf_megaco_termid;
78
79
80
81/* Define headers in subtree for megaco */
82static int hf_megaco_modem_descriptor;
83static int hf_megaco_multiplex_descriptor;
84static int hf_megaco_media_descriptor;
85static int hf_megaco_Local_descriptor;
86static int hf_megaco_events_descriptor;
87static int hf_megaco_signal_descriptor;
88static int hf_megaco_audit_descriptor;
89/* static int hf_megaco_servicechange_descriptor; */
90static int hf_megaco_digitmap_descriptor;
91static int hf_megaco_statistics_descriptor;
92static int hf_megaco_observedevents_descriptor;
93static int hf_megaco_topology_descriptor;
94static int hf_megaco_error_descriptor;
95static int hf_megaco_error_code;
96static int hf_megaco_error_string;
97static int hf_megaco_TerminationState_descriptor;
98static int hf_megaco_Remote_descriptor;
99static int hf_megaco_LocalControl_descriptor;
100static int hf_megaco_packages_descriptor;
101static int hf_megaco_Service_State;
102static int hf_megaco_Event_Buffer_Control;
103static int hf_megaco_mode;
104static int hf_megaco_reserve_group;
105static int hf_megaco_h324_muxtbl_in;
106static int hf_megaco_h324_muxtbl_out;
107static int hf_megaco_ds_dscp;
108static int hf_megaco_gm_saf;
109static int hf_megaco_gm_sam;
110static int hf_megaco_gm_spf;
111static int hf_megaco_gm_spr;
112static int hf_megaco_gm_esas;
113static int hf_megaco_tman_pol;
114static int hf_megaco_gm_rsb;
115static int hf_megaco_tman_sdr;
116static int hf_megaco_tman_mbs;
117static int hf_megaco_tman_pdr;
118static int hf_megaco_tman_dvt;
119static int hf_megaco_ipdc_realm;
120static int hf_megaco_h324_h223capr;
121static int hf_megaco_reserve_value;
122static int hf_megaco_streamid;
123static int hf_megaco_requestid;
124static int hf_megaco_pkgdname;
125static int hf_megaco_mId;
126static int hf_megaco_h245;
127static int hf_megaco_h223Capability;
128static int hf_megaco_audititem;
129static int hf_megaco_priority;
130
131/* Define the trees for megaco */
132static int ett_megaco;
133static int ett_megaco_message;
134static int ett_megaco_message_body;
135static int ett_megaco_context;
136static int ett_megaco_command_line;
137static int ett_megaco_mediadescriptor;
138static int ett_megaco_descriptors;
139static int ett_megaco_raw_text;
140static int ett_megaco_error_descriptor;
141static int ett_megaco_TerminationState;
142static int ett_megaco_Localdescriptor;
143static int ett_megaco_Remotedescriptor;
144static int ett_megaco_LocalControldescriptor;
145static int ett_megaco_auditdescriptor;
146static int ett_megaco_eventsdescriptor;
147static int ett_megaco_statisticsdescriptor;
148static int ett_megaco_observedeventsdescriptor;
149static int ett_megaco_observedevent;
150static int ett_megaco_packagesdescriptor;
151static int ett_megaco_requestedevent;
152static int ett_megaco_signalsdescriptor;
153static int ett_megaco_requestedsignal;
154static int ett_megaco_h245;
155
156static gcp_hf_ett_t megaco_ctx_ids;
157
158static expert_field ei_megaco_errored_command;
159static expert_field ei_megaco_no_command;
160static expert_field ei_megaco_no_descriptor;
161static expert_field ei_megaco_error_descriptor_transaction_list;
162static expert_field ei_megaco_parse_error;
163static expert_field ei_megaco_audit_descriptor;
164static expert_field ei_megaco_signal_descriptor;
165static expert_field ei_megaco_reason_invalid;
166static expert_field ei_megaco_error_code_invalid;
167static expert_field ei_megaco_invalid_sdr;
168
169static dissector_handle_t megaco_text_handle;
170
171static int megaco_tap;
172static int exported_pdu_tap = -1;
173
174
175/* patterns used for tvb_ws_mempbrk_pattern_uint8 */
176static ws_mempbrk_pattern pbrk_whitespace;
177static ws_mempbrk_pattern pbrk_braces;
178
179/* Used when command type is needed to differentiate parsing, extend as needed */
180typedef enum
181{
182 MEGACO_CMD_NOT_SET = 0,
183 MEGACO_CMD_PRIORITY,
184} megaco_commands_enum_t;
185
186/*
187* Here are the global variables associated with
188* the various user definable characteristics of the dissection
189*
190* H.248/MEGACO has two kinds of message formats: text and binary (ASN.1).
191* The binary message format is dissected in packet-h248.c
192*
193* global_megaco_raw_text determines whether we are going to display
194* the raw text of the megaco message, much like the HTTP dissector does.
195*
196* global_megaco_dissect_tree determines whether we are going to display
197* a detailed tree that expresses a somewhat more semantically meaningful
198* decode.
199*/
200static bool_Bool global_megaco_raw_text = true1;
201static bool_Bool global_megaco_dissect_tree = true1;
202
203static const value_string megaco_context_vals[] = {
204 { CHOOSE_CONTEXT0xFFFFFFFE, "Choose one" },
205 { ALL_CONTEXTS0xFFFFFFFF, "All" },
206 { NULL_CONTEXT0, "NULL" },
207
208 { 0, NULL((void*)0) }
209};
210
211/* Some basic utility functions that are specific to this dissector */
212static int megaco_tvb_skip_wsp(tvbuff_t *tvb, int offset);
213static int megaco_tvb_skip_wsp_return(tvbuff_t *tvb, int offset);
214
215#define NUM_TIMESTATS12 12
216
217static const value_string megaco_message_type[] = {
218 { 0, "ADD "},
219 { 1, "MOVE"},
220 { 2, "MDFY"},
221 { 3, "SUBT"},
222 { 4, "AUCP"},
223 { 5, "AUVL"},
224 { 6, "NTFY"},
225 { 7, "SVCC"},
226 { 8, "TOPO"},
227 { 9, "NONE"},
228 { 10, "ALL "},
229 { 0, NULL((void*)0)}
230};
231
232#define GCP_CMD_REPLY_CASEcase GCP_CMD_ADD_REPLY: case GCP_CMD_MOVE_REPLY: case GCP_CMD_MOD_REPLY
: case GCP_CMD_SUB_REPLY: case GCP_CMD_AUDITCAP_REPLY: case GCP_CMD_AUDITVAL_REPLY
: case GCP_CMD_NOTIFY_REPLY: case GCP_CMD_SVCCHG_REPLY: case GCP_CMD_TOPOLOGY_REPLY
: case GCP_CMD_REPLY:
\
233 case GCP_CMD_ADD_REPLY: \
234 case GCP_CMD_MOVE_REPLY: \
235 case GCP_CMD_MOD_REPLY: \
236 case GCP_CMD_SUB_REPLY: \
237 case GCP_CMD_AUDITCAP_REPLY: \
238 case GCP_CMD_AUDITVAL_REPLY: \
239 case GCP_CMD_NOTIFY_REPLY: \
240 case GCP_CMD_SVCCHG_REPLY: \
241 case GCP_CMD_TOPOLOGY_REPLY: \
242 case GCP_CMD_REPLY:
243
244#define GCP_CMD_REQ_CASEcase GCP_CMD_ADD_REQ: case GCP_CMD_MOVE_REQ: case GCP_CMD_MOD_REQ
: case GCP_CMD_SUB_REQ: case GCP_CMD_AUDITCAP_REQ: case GCP_CMD_AUDITVAL_REQ
: case GCP_CMD_NOTIFY_REQ: case GCP_CMD_SVCCHG_REQ: case GCP_CMD_TOPOLOGY_REQ
: case GCP_CMD_CTX_ATTR_AUDIT_REQ: case GCP_CMD_OTHER_REQ:
\
245 case GCP_CMD_ADD_REQ: \
246 case GCP_CMD_MOVE_REQ: \
247 case GCP_CMD_MOD_REQ: \
248 case GCP_CMD_SUB_REQ: \
249 case GCP_CMD_AUDITCAP_REQ: \
250 case GCP_CMD_AUDITVAL_REQ: \
251 case GCP_CMD_NOTIFY_REQ: \
252 case GCP_CMD_SVCCHG_REQ: \
253 case GCP_CMD_TOPOLOGY_REQ: \
254 case GCP_CMD_CTX_ATTR_AUDIT_REQ: \
255 case GCP_CMD_OTHER_REQ:
256
257static bool_Bool
258megacostat_is_duplicate_reply(const gcp_cmd_t* cmd)
259{
260 switch (cmd->type) {
261
262 GCP_CMD_REPLY_CASEcase GCP_CMD_ADD_REPLY: case GCP_CMD_MOVE_REPLY: case GCP_CMD_MOD_REPLY
: case GCP_CMD_SUB_REPLY: case GCP_CMD_AUDITCAP_REPLY: case GCP_CMD_AUDITVAL_REPLY
: case GCP_CMD_NOTIFY_REPLY: case GCP_CMD_SVCCHG_REPLY: case GCP_CMD_TOPOLOGY_REPLY
: case GCP_CMD_REPLY:
263 {
264 gcp_cmd_msg_t *cmd_msg;
265 /* cycle through commands to find same command in the transaction */
266 for (cmd_msg = cmd->trx->cmds;
267 (cmd_msg != NULL((void*)0)) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
268 cmd_msg = cmd_msg->next) {
269 if (cmd_msg->cmd->type == cmd->type)
270 return true1;
271 }
272
273 return false0;
274 }
275 break;
276 default:
277 return false0;
278 break;
279 }
280}
281
282static bool_Bool
283megacostat_had_request(const gcp_cmd_t* cmd)
284{
285 switch (cmd->type) {
286
287 GCP_CMD_REPLY_CASEcase GCP_CMD_ADD_REPLY: case GCP_CMD_MOVE_REPLY: case GCP_CMD_MOD_REPLY
: case GCP_CMD_SUB_REPLY: case GCP_CMD_AUDITCAP_REPLY: case GCP_CMD_AUDITVAL_REPLY
: case GCP_CMD_NOTIFY_REPLY: case GCP_CMD_SVCCHG_REPLY: case GCP_CMD_TOPOLOGY_REPLY
: case GCP_CMD_REPLY:
288 {
289 gcp_cmd_msg_t *cmd_msg;
290 /* cycle through commands to find a request in the transaction */
291 for (cmd_msg = cmd->trx->cmds;
292 (cmd_msg != NULL((void*)0)) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
293 cmd_msg = cmd_msg->next) {
294
295 switch (cmd_msg->cmd->type) {
296
297 GCP_CMD_REQ_CASEcase GCP_CMD_ADD_REQ: case GCP_CMD_MOVE_REQ: case GCP_CMD_MOD_REQ
: case GCP_CMD_SUB_REQ: case GCP_CMD_AUDITCAP_REQ: case GCP_CMD_AUDITVAL_REQ
: case GCP_CMD_NOTIFY_REQ: case GCP_CMD_SVCCHG_REQ: case GCP_CMD_TOPOLOGY_REQ
: case GCP_CMD_CTX_ATTR_AUDIT_REQ: case GCP_CMD_OTHER_REQ:
298 return true1;
299 break;
300 default:
301 return false0;
302 break;
303 }
304 }
305
306 return false0;
307 }
308 break;
309 default:
310 return false0;
311 break;
312 }
313}
314
315static void
316megacostat_filtercheck(const char *opt_arg _U___attribute__((unused)), const char **filter _U___attribute__((unused)), char** err)
317{
318 pref_t *megaco_ctx_track, *h248_ctx_track;
319
320 megaco_ctx_track = prefs_find_preference(prefs_find_module("megaco"), "ctx_info");
321 h248_ctx_track = prefs_find_preference(prefs_find_module("h248"), "ctx_info");
322
323 if (!megaco_ctx_track || !h248_ctx_track) {
324 /* No such preferences */
325 return;
326 }
327
328 if (!prefs_get_bool_value(megaco_ctx_track, pref_current) || !prefs_get_bool_value(h248_ctx_track, pref_current)) {
329 *err = ws_strdup_printf("Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n"wmem_strdup_printf(((void*)0), "Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n"
"has to be set to true to enable measurement of service response times.\n"
)
330 "has to be set to true to enable measurement of service response times.\n")wmem_strdup_printf(((void*)0), "Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n"
"has to be set to true to enable measurement of service response times.\n"
)
;
331 }
332}
333
334static tap_packet_status
335megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U___attribute__((unused)), const void *pmi, tap_flags_t flags _U___attribute__((unused)))
336{
337 rtd_data_t* rtd_data = (rtd_data_t*)pms;
338 rtd_stat_table* ms = &rtd_data->stat_table;
339 const gcp_cmd_t *mi=(const gcp_cmd_t*)pmi;
340 nstime_t delta;
341 tap_packet_status ret = TAP_PACKET_DONT_REDRAW;
342
343 switch (mi->type) {
344
345 GCP_CMD_REQ_CASEcase GCP_CMD_ADD_REQ: case GCP_CMD_MOVE_REQ: case GCP_CMD_MOD_REQ
: case GCP_CMD_SUB_REQ: case GCP_CMD_AUDITCAP_REQ: case GCP_CMD_AUDITVAL_REQ
: case GCP_CMD_NOTIFY_REQ: case GCP_CMD_SVCCHG_REQ: case GCP_CMD_TOPOLOGY_REQ
: case GCP_CMD_CTX_ATTR_AUDIT_REQ: case GCP_CMD_OTHER_REQ:
346 if(!mi->trx->initial) {
347 /* Track Context is probably disabled, we cannot
348 * measure service response time */
349 return TAP_PACKET_DONT_REDRAW;
350 }
351
352 else if(mi->trx->initial->framenum != mi->msg->framenum){
353 /* Duplicate is ignored */
354 ms->time_stats[0].req_dup_num++;
355 }
356 else {
357 ms->time_stats[0].open_req_num++;
358 }
359 break;
360
361 GCP_CMD_REPLY_CASEcase GCP_CMD_ADD_REPLY: case GCP_CMD_MOVE_REPLY: case GCP_CMD_MOD_REPLY
: case GCP_CMD_SUB_REPLY: case GCP_CMD_AUDITCAP_REPLY: case GCP_CMD_AUDITVAL_REPLY
: case GCP_CMD_NOTIFY_REPLY: case GCP_CMD_SVCCHG_REPLY: case GCP_CMD_TOPOLOGY_REPLY
: case GCP_CMD_REPLY:
362 if(megacostat_is_duplicate_reply(mi)){
363 /* Duplicate is ignored */
364 ms->time_stats[0].rsp_dup_num++;
365 }
366 else if (!megacostat_had_request(mi)) {
367 /* no request was seen */
368 ms->time_stats[0].disc_rsp_num++;
369 }
370 else {
371 ms->time_stats[0].open_req_num--;
372 /* calculate time delta between request and response */
373 nstime_delta(&delta, &pinfo->abs_ts, &mi->trx->initial->frametime);
374
375 switch(mi->type) {
376
377 case GCP_CMD_ADD_REPLY:
378 time_stat_update(&(ms->time_stats[0].rtd[0]),&delta, pinfo);
379 break;
380 case GCP_CMD_MOVE_REPLY:
381 time_stat_update(&(ms->time_stats[0].rtd[1]),&delta, pinfo);
382 break;
383 case GCP_CMD_MOD_REPLY:
384 time_stat_update(&(ms->time_stats[0].rtd[2]),&delta, pinfo);
385 break;
386 case GCP_CMD_SUB_REPLY:
387 time_stat_update(&(ms->time_stats[0].rtd[3]),&delta, pinfo);
388 break;
389 case GCP_CMD_AUDITCAP_REPLY:
390 time_stat_update(&(ms->time_stats[0].rtd[4]),&delta, pinfo);
391 break;
392 case GCP_CMD_AUDITVAL_REPLY:
393 time_stat_update(&(ms->time_stats[0].rtd[5]),&delta, pinfo);
394 break;
395 case GCP_CMD_NOTIFY_REPLY:
396 time_stat_update(&(ms->time_stats[0].rtd[6]),&delta, pinfo);
397 break;
398 case GCP_CMD_SVCCHG_REPLY:
399 time_stat_update(&(ms->time_stats[0].rtd[7]),&delta, pinfo);
400 break;
401 case GCP_CMD_TOPOLOGY_REPLY:
402 time_stat_update(&(ms->time_stats[0].rtd[8]),&delta, pinfo);
403 break;
404 case GCP_CMD_REPLY:
405 time_stat_update(&(ms->time_stats[0].rtd[9]),&delta, pinfo);
406 break;
407 default:
408 time_stat_update(&(ms->time_stats[0].rtd[11]),&delta, pinfo);
409 }
410
411 time_stat_update(&(ms->time_stats[0].rtd[10]),&delta, pinfo);
412 ret = TAP_PACKET_REDRAW;
413 }
414 break;
415
416 default:
417 break;
418 }
419
420 return ret;
421}
422
423/* Call the export PDU tap with relevant data */
424static void
425export_megaco_pdu(packet_info *pinfo, tvbuff_t *tvb)
426{
427 exp_pdu_data_t *exp_pdu_data = export_pdu_create_common_tags(pinfo, "megaco", EXP_PDU_TAG_DISSECTOR_NAME12);
428
429 exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
430 exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
431 exp_pdu_data->pdu_tvb = tvb;
432
433 tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
434
435}
436
437/*
438* The various functions that either dissect some
439* subpart of MEGACO. These aren't really proto dissectors but they
440* are written in the same style.
441*
442*/
443static void
444dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, proto_tree *top_tree, uint32_t context);
445static void
446dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int tvb_RBRKT, int tvb_previous_offset);
447static void
448dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *tree, int tvb_RBRKT, int tvb_previous_offset);
449static void
450dissect_megaco_errordescriptor(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int tvb_RBRKT, int tvb_previous_offset);
451static void
452dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset);
453static void
454dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int tvb_next_offset, int tvb_current_offset);
455static void
456dissect_megaco_LocalRemotedescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int tvb_next_offset, int tvb_current_offset, uint32_t context, bool_Bool is_local);
457static void
458dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int tvb_next_offset, int tvb_current_offset, proto_tree *top_tree);
459static void
460dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int tvb_next_offset, int tvb_current_offset);
461static void
462tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
463static int
464dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
465static int
466megaco_tvb_find_token(tvbuff_t *tvb, int offset, int maxlength);
467static dissector_handle_t data_handle;
468static dissector_handle_t sdp_handle;
469static dissector_handle_t h245_handle;
470static dissector_handle_t h248_handle;
471static dissector_handle_t h248_otp_handle;
472
473static bool_Bool keep_persistent_data;
474
475/*
476 * dissect_megaco_text over TCP, there will be a TPKT header there
477 *
478 */
479static int dissect_megaco_text_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
480{
481 int lv_tpkt_len;
482
483 /* This code is copied from the Q.931 dissector, some parts skipped.
484 * Check whether this looks like a TPKT-encapsulated
485 * MEGACO packet.
486 *
487 * The minimum length of a MEGACO message is 6?:
488 * Re-assembly ?
489 */
490 lv_tpkt_len = is_tpkt(tvb, 6);
491 if (lv_tpkt_len == -1) {
492 /*
493 * It's not a TPKT packet;
494 * Is in MEGACO ?
495 */
496 dissect_megaco_text(tvb, pinfo, tree, data);
497 }
498 dissect_tpkt_encap(tvb, pinfo, tree, true1,
499 megaco_text_handle);
500
501 return tvb_captured_length(tvb);
502}
503
504#define ERRORTOKEN1 1
505#define TRANSTOKEN2 2
506#define REPLYTOKEN3 3
507#define PENDINGTOKEN4 4
508#define RESPONSEACKTOKEN5 5
509
510typedef struct {
511 const char *name;
512 const char *compact_name;
513} megaco_tokens_t;
514
515static const megaco_tokens_t megaco_messageBody_names[] = {
516 { "Unknown-token", NULL((void*)0) }, /* 0 Pad so that the real headers start at index 1 */
517 { "Error", "ER" }, /* 1 */
518 { "Transaction", "T" }, /* 2 */
519 { "Reply", "P" }, /* 3 */
520 { "Pending", "PN" }, /* 4 */
521 { "TransactionResponseAck", "K" }, /* 5 */
522};
523
524/* Returns index of megaco_tokens_t */
525static int find_megaco_messageBody_names(tvbuff_t *tvb, int offset, unsigned header_len)
526{
527 unsigned i;
528
529 for (i = 1; i < array_length(megaco_messageBody_names)(sizeof (megaco_messageBody_names) / sizeof (megaco_messageBody_names
)[0])
; i++) {
530 if (header_len == strlen(megaco_messageBody_names[i].name) &&
531 tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].name, header_len) == 0)
532 return i;
533 if (megaco_messageBody_names[i].compact_name != NULL((void*)0) &&
534 header_len == strlen(megaco_messageBody_names[i].compact_name) &&
535 tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].compact_name, header_len) == 0)
536 return i;
537 }
538
539 return -1;
540}
541
542static proto_item *
543megaco_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
544 int start, int length, const char *value)
545{
546 proto_item *pi;
547
548 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
549 if (!global_megaco_dissect_tree) {
550 proto_item_set_hidden(pi);
551 }
552
553 return pi;
554}
555
556static proto_item *
557my_proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
558 int start, int length, uint32_t value)
559{
560 proto_item *pi;
561
562 pi = proto_tree_add_uint(tree, hfindex, tvb, start, 1, value);
563 /* String length may be longer than FT_UINT will allow */
564 proto_item_set_len(pi, length);
565
566 if (!global_megaco_dissect_tree) {
567 proto_item_set_hidden(pi);
568 }
569
570 return pi;
571}
572
573/*
574 * dissect_megaco_text - The dissector for the MEGACO Protocol, using
575 * text encoding.
576 */
577static int
578dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
579{
580 int tvb_len, len;
581 int tvb_offset,tvb_current_offset,tvb_previous_offset,tvb_next_offset,tokenlen;
582 int context_offset, context_length, save_offset, save_length;
583 int tvb_command_start_offset, tvb_command_end_offset;
584 int tvb_transaction_end_offset;
585 proto_tree *megaco_tree, *message_body_tree, *megaco_tree_command_line;
586 proto_item *ti, *sub_ti;
587
588 uint8_t word[15];
589 uint8_t TermID[30];
590 uint8_t tempchar;
591 int tvb_RBRKT, tvb_LBRKT, RBRKT_counter, LBRKT_counter;
592 unsigned token_index=0;
593 uint32_t dword;
594 unsigned char needle;
595
596 gcp_msg_t *msg = NULL((void*)0);
597 gcp_trx_t *trx = NULL((void*)0);
598 gcp_ctx_t *ctx = NULL((void*)0);
599 gcp_cmd_t *cmd = NULL((void*)0);
600 gcp_term_t *term = NULL((void*)0);
601 gcp_trx_type_t trx_type = GCP_TRX_NONE;
602 uint32_t trx_id = 0, pending_id;
603 uint32_t ctx_id = 0;
604 gcp_cmd_type_t cmd_type = GCP_CMD_NONE;
605 gcp_wildcard_t wild_term = GCP_WILDCARD_NONE;
606 bool_Bool short_form;
607
608 megaco_commands_enum_t megaco_command = MEGACO_CMD_NOT_SET;
609 /* Initialize variables */
610 tvb_len = tvb_reported_length(tvb);
611 megaco_tree = NULL((void*)0);
612 ti = NULL((void*)0);
613 tvb_offset = 0;
614 RBRKT_counter = 0;
615 LBRKT_counter = 0;
616
617 /* Check if H.248 in otp(Erlang) internal format
618 * XXX Needs improvement?
619 * Ref:
620 * http://www.erlang.org/doc/apps/megaco/part_frame.html
621 * 4.1 Internal form of messages
622 * 4.2 The different encodings
623 */
624 dword = tvb_get_ntoh24(tvb,0);
625 if ((dword == 0x836803)&&(h248_otp_handle)){
626 call_dissector(h248_otp_handle, tvb, pinfo, tree);
627 return tvb_captured_length(tvb);
628 }
629
630 msg = gcp_msg(pinfo, tvb_raw_offset(tvb), keep_persistent_data);
631
632 /*
633 * Check to see whether we're really dealing with MEGACO by looking
634 * for the "MEGACO" string or a "!".This needs to be improved when supporting
635 * binary encodings. Bugfix add skipping of leading spaces.
636 */
637 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
638
639 if(!tvb_get_raw_bytes_as_stringz(tvb,tvb_offset,sizeof(word),word)) return tvb_captured_length(tvb);
640
641 /* Quick fix for MEGACO packet with Authentication Header,
642 * marked as "AU" or "Authentication".
643 */
644 if ((tvb_strncaseeql(tvb, tvb_offset, "Authentication", 14) == 0) ||
645 (tvb_strncaseeql(tvb, tvb_offset, "AU", 2) == 0)) {
646 int counter;
647 uint8_t next;
648
649 /* move offset to end of auth header (EOL or WSP) */
650 for ( counter = tvb_offset; counter < tvb_len; counter++ ) {
651 needle = tvb_get_uint8(tvb, counter);
652 if (needle == ' ' || needle == '\r' || needle == '\n') {
653 next = tvb_get_uint8(tvb, counter+1);
654 if (next == ' ' || next == '\r' || next == '\n') {
655 continue;
656 }
657 tvb_offset = counter + 1;
658 break;
659 }
660 }
661 }
662
663 short_form = (tvb_get_uint8(tvb, tvb_offset ) == '!');
664
665 if (tvb_strncaseeql(tvb, tvb_offset, "MEGACO", 6) != 0 && !short_form){
666 int8_t ber_class;
667 bool_Bool pc;
668 int32_t tag;
669 dissector_handle_t handle = data_handle;
670
671 get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
672
673 if (ber_class == BER_CLASS_UNI0 && pc && tag == BER_UNI_TAG_SEQUENCE16 ) {
674 handle = h248_handle;
675 }
676
677 call_dissector(handle,tvb,pinfo,tree);
678 return tvb_captured_length(tvb);
679 }
680
681
682 /* Display MEGACO in protocol column */
683 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MEGACO");
684
685 /* Report this packet to the tap */
686 if (!pinfo->flags.in_error_pkt) {
687 if (have_tap_listener(exported_pdu_tap)) {
688 export_megaco_pdu(pinfo, tvb);
689 }
690 }
691
692 /* Build the info tree if we've been given a root */
693 /* Create megaco subtree */
694 ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, ENC_NA0x00000000);
695 megaco_tree = proto_item_add_subtree(ti, ett_megaco);
696
697 /* Format of 'message' is = MegacopToken SLASH Version SEP mId SEP messageBody */
698 /* MegacopToken = "MEGACO" or "!" */
699 /* According to H248.1-200205 Annex B Text encoding ( protocol version 2 ) */
700
701 /* Find version */
702 tvb_previous_offset = tvb_find_uint8(tvb, 0,
703 tvb_len, '/');
704 if (tvb_previous_offset == -1) {
705 expert_add_info_format(pinfo, ti, &ei_megaco_parse_error,
706 "Sorry, no \"/\" in the MEGACO header, I can't parse this packet");
707 return tvb_captured_length(tvb);
708 }
709
710 megaco_tree_add_string(megaco_tree, hf_megaco_start, tvb, 0, tvb_previous_offset+1,
711 (char*)tvb_get_string_enc(pinfo->pool, tvb, 0, tvb_previous_offset, ENC_UTF_80x00000002|ENC_NA0x00000000));
712
713 /* skip / */
714 tvb_previous_offset++;
715
716 /* assume at least one digit in version */
717 tvb_current_offset = tvb_previous_offset + 1;
718
719 if (g_ascii_isdigit(tvb_get_uint8(tvb, tvb_current_offset))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_current_offset
))] & G_ASCII_DIGIT) != 0)
) {
720 /* 2-digit version */
721 tvb_current_offset++;
722 }
723
724 megaco_tree_add_string(megaco_tree, hf_megaco_version, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset,
725 (char*)tvb_get_string_enc(pinfo->pool, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, ENC_UTF_80x00000002|ENC_NA0x00000000));
726
727 tvb_previous_offset = tvb_current_offset;
728 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
729
730 if (tvb_previous_offset == tvb_current_offset) {
731 expert_add_info_format(pinfo, ti, &ei_megaco_parse_error,
732 "[ Parse error: missing SEP in MEGACO header ]");
733 return tvb_current_offset;
734 }
735
736 tvb_previous_offset = tvb_current_offset;
737
738 /* mId should follow here,
739 * mId = (( domainAddress / domainName ) [":" portNumber]) / mtpAddress / deviceName
740 * domainAddress = "[" (IPv4address / IPv6address) "]"
741 * domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /".") ">"
742 * mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT
743 * MTPToken = ("MTP")
744 * deviceName = pathNAME
745 * pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )["@" pathDomainName ]
746 */
747
748 tvb_current_offset = tvb_ws_mempbrk_pattern_uint8(tvb, tvb_current_offset, -1, &pbrk_whitespace, &needle);
749 if (tvb_current_offset == -1) {
750 expert_add_info_format(pinfo, ti, &ei_megaco_parse_error,
751 "[ Parse error: no body in MEGACO message (missing SEP after mId) ]");
752 return tvb_captured_length(tvb);
753 }
754
755 tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset);
756
757 /* At this point we should point to the "\n" ending the mId element
758 * or to the next character after white space SEP
759 */
760 megaco_tree_add_string(megaco_tree, hf_megaco_mId, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset,
761 (char*)tvb_get_string_enc(pinfo->pool, tvb, tvb_previous_offset, tvb_current_offset - tvb_previous_offset, ENC_UTF_80x00000002|ENC_NA0x00000000));
762
763 col_clear(pinfo->cinfo, COL_INFO);
764 do{
765 tvb_previous_offset = tvb_next_offset;
766
767/* Next part is
768 * : messageBody = ( errorDescriptor / transactionList )
769 * errorDescriptor = ErrorToken EQUAL ErrorCode LBRKT [quotedString] RBRKT
770 * ErrorToken = ("Error" / "ER")
771 *
772 * transactionList = 1*( transactionRequest / transactionReply /
773 * transactionPending / transactionResponseAck )
774 *
775 * transactionResponseAck = ResponseAckToken LBRKT
776 * transactionAck*(COMMA transactionAck) RBRKT
777 * ResponseAckToken = ("TransactionResponseAck"/ "K")
778 *
779 * transactionPending = PendingToken EQUAL TransactionID LBRKT RBRKT
780 * PendingToken = ("Pending" / "PN")
781 *
782 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
783 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
784 * ReplyToken = ("Reply" / "P")
785 *
786 * transactionRequest = TransToken EQUAL TransactionID LBRKT
787 * actionRequest *(COMMA actionRequest) RBRKT
788 * TransToken = ("Transaction" / "T")
789 */
790
791 /* Find token length */
792 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_len-1; tvb_offset++){
793 if (!g_ascii_isalpha(tvb_get_uint8(tvb, tvb_offset ))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_offset ))] &
G_ASCII_ALPHA) != 0)
){
794 break;
795 }
796 }
797 tokenlen = tvb_offset - tvb_previous_offset;
798 token_index = find_megaco_messageBody_names(tvb, tvb_previous_offset, tokenlen);
799 /* Debug code
800 ws_warning("token_index %u",token_index);
801 */
802
803 tvb_LBRKT = tvb_find_uint8(tvb, tvb_offset, tvb_len, '{');
804 tvb_current_offset = tvb_LBRKT;
805 tvb_transaction_end_offset = megaco_tvb_find_token(tvb, tvb_LBRKT - 1, tvb_len);
806
807 switch ( token_index ){
808 /* errorDescriptor */
809 case ERRORTOKEN1:
810 col_set_str(pinfo->cinfo, COL_INFO, "Error ");
811
812 tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_len); /*tvb_find_uint8(tvb, tvb_offset+1, tvb_len, '}');*/
813
814 ti = proto_tree_add_format_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset);
815 message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
816
817 if (tree) {
818 megaco_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
819 tvb_previous_offset, tokenlen,
820 "Error" );
821
822 tvb_command_start_offset = tvb_previous_offset;
823 dissect_megaco_errordescriptor(tvb, pinfo, megaco_tree, tvb_len-1, tvb_command_start_offset);
824 }
825 return tvb_captured_length(tvb);
826 /* transactionResponseAck
827 * transactionResponseAck = ResponseAckToken LBRKT transactionAck
828 * *(COMMA transactionAck) RBRKT
829 * transactionAck = transactionID / (transactionID "-" transactionID)
830 */
831 case RESPONSEACKTOKEN5:
832 tvb_LBRKT = tvb_find_uint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
833 tvb_offset = tvb_LBRKT;
834 save_offset = tvb_previous_offset;
835 save_length = tvb_current_offset-tvb_previous_offset;
836
837 megaco_tree_add_string(megaco_tree, hf_megaco_transaction, tvb,
838 save_offset, save_length, "TransactionResponseAck" );
839
840 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
841 tvb_current_offset = tvb_find_uint8(tvb, tvb_offset+1, tvb_len, '}');
842 /*tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_transaction_end_offset);*/
843 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset)-1; /* cut last RBRKT */
844 len = tvb_current_offset - tvb_previous_offset;
845
846 pending_id = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb,tvb_previous_offset,len),NULL((void*)0),10);
847 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d TransactionResponseAck", pending_id);
848
849 my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, pending_id);
850
851 if(global_megaco_raw_text){
852 tvb_raw_text_add(tvb, megaco_tree);
853 }
854 return tvb_captured_length(tvb);
855 /* Pe and PN is transactionPending, P+"any char" is transactionReply */
856 case PENDINGTOKEN4:
857
858 tvb_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1;
859 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
860 tvb_LBRKT = tvb_find_uint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
861 tvb_current_offset = tvb_LBRKT;
862 save_offset = tvb_previous_offset;
863 save_length = tvb_current_offset-tvb_previous_offset;
864
865 megaco_tree_add_string(megaco_tree, hf_megaco_transaction, tvb,
866 save_offset, save_length, "Reply" );
867
868 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
869 len = tvb_current_offset - tvb_offset;
870
871 pending_id = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb,tvb_offset,len),NULL((void*)0),10);
872 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d Pending", pending_id);
873
874 my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, pending_id);
875 return tvb_captured_length(tvb);
876
877 /* transactionReply */
878 case REPLYTOKEN3:
879 trx_type = GCP_TRX_REPLY;
880 tvb_LBRKT = tvb_find_uint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
881 save_offset = tvb_previous_offset;
882 save_length = tvb_LBRKT-tvb_previous_offset;
883
884 megaco_tree_add_string(megaco_tree, hf_megaco_transaction, tvb,
885 save_offset, save_length, "Reply" );
886
887 tvb_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1;
888 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
889 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1);
890 len = tvb_current_offset - tvb_offset;
891
892 trx_id = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb,tvb_offset,len),NULL((void*)0),10);
893 col_add_fstr(pinfo->cinfo, COL_INFO, "%d Reply ", trx_id);
894
895 my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, trx_id);
896
897 /* Find if we have a errorDescriptor or actionReplyList */
898 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
899 tempchar = tvb_get_uint8(tvb,tvb_offset);
900 if ((tempchar == 'E')||(tempchar == 'e')){
901 dissect_megaco_errordescriptor(tvb, pinfo, megaco_tree, tvb_transaction_end_offset-1, tvb_offset);
902 return tvb_captured_length(tvb);
903 }
904 /* Offset should be at first printable char after { */
905 tvb_previous_offset = tvb_offset;
906 break;
907 case TRANSTOKEN2:
908 /* TransactionRequest */
909 trx_type = GCP_TRX_REQUEST;
910 save_offset = tvb_previous_offset;
911 save_length = tvb_current_offset-tvb_previous_offset;
912 megaco_tree_add_string(megaco_tree, hf_megaco_transaction, tvb,
913 save_offset, save_length, "Request" );
914
915 tvb_offset = tvb_find_uint8(tvb, tvb_offset, tvb_transaction_end_offset, '=')+1;
916 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
917 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
918 len = tvb_current_offset - tvb_offset;
919
920 trx_id = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb,tvb_offset,len),NULL((void*)0),10);
921 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%d Request", trx_id);
922
923 my_proto_tree_add_uint(megaco_tree, hf_megaco_transid, tvb, save_offset, save_length, trx_id);
924 /* Offset should be at first printable char after { */
925 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
926
927 break;
928 default :
929 proto_tree_add_expert_format(tree, pinfo, &ei_megaco_error_descriptor_transaction_list, tvb, 0, -1,
930 "Sorry, can't understand errorDescriptor / transactionList = %s, can't parse it pos %u",
931 tvb_format_text(pinfo->pool, tvb,tvb_previous_offset,2),tvb_previous_offset);
932 return tvb_captured_length(tvb);
933 } /* end switch */
934/* Only these remains now
935 * transactionReply = ReplyToken EQUAL TransactionID LBRKT
936 * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
937 * ReplyToken = ("Reply" / "P")
938 *
939 * errorDescriptor = ErrorToken EQUAL ErrorCode
940 * LBRKT [quotedString] RBRKT
941 *
942 * transactionRequest = TransToken EQUAL TransactionID LBRKT
943 * actionRequest *(COMMA actionRequest) RBRKT
944 * TransToken = ("Transaction" / "T")
945 */
946
947 trx = gcp_trx(msg , trx_id , trx_type, pinfo, keep_persistent_data);
948
949 /* Find Context */
950nextcontext:
951
952
953
954
955 tvb_next_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '{');
956 context_offset = tvb_previous_offset;
957 context_length = tvb_next_offset-tvb_previous_offset+1;
958
959 tvb_previous_offset = tvb_find_uint8(tvb, tvb_current_offset, tvb_transaction_end_offset, '=')+1;
960 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
961
962 if (tvb_current_offset >= tvb_next_offset) {
963 proto_tree_add_expert_format(megaco_tree, pinfo, &ei_megaco_parse_error,
964 tvb, context_offset, context_length, "Parse error: Invalid offset");
965 return tvb_captured_length(tvb);
966 }
967 tvb_current_offset = tvb_next_offset;
968
969
970 tokenlen = tvb_current_offset - tvb_previous_offset;
971 tempchar = tvb_get_uint8(tvb, tvb_previous_offset );
972
973 if (tvb_get_uint8(tvb, tvb_current_offset-1 ) == ' '){
974 tokenlen--;
975 }
976
977 switch ( tempchar ){
978 case '$':
979 ctx_id = CHOOSE_CONTEXT0xFFFFFFFE;
980 break;
981 case '*':
982 ctx_id = ALL_CONTEXTS0xFFFFFFFF;
983 break;
984 case '-':
985 ctx_id = NULL_CONTEXT0;
986 break;
987 default:
988 ctx_id = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb, tvb_previous_offset, tokenlen),NULL((void*)0),10);
989 }
990
991 my_proto_tree_add_uint(megaco_tree, hf_megaco_Context, tvb, context_offset, context_length, ctx_id);
992 sub_ti = my_proto_tree_add_uint(megaco_tree, hf_megaco_Context_generated, tvb, context_offset, context_length, ctx_id);
993 proto_item_set_generated(sub_ti);
994 col_append_fstr(pinfo->cinfo, COL_INFO, " |=%s", val_to_str(pinfo->pool, ctx_id, megaco_context_vals, "%d"));
995
996 ctx = gcp_ctx(msg,trx,ctx_id,pinfo,keep_persistent_data);
997
998 /* Find Commands */
999
1000 /* If Transaction is Request, Reply or Pending */
1001 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
1002 tvb_command_end_offset = tvb_command_start_offset;
1003
1004 tvb_LBRKT = tvb_command_start_offset;
1005 tvb_RBRKT = tvb_command_start_offset;
1006
1007 /* The following loop find the individual contexts, commands and call the for every Descriptor a subroutine */
1008
1009 do {
1010 tvb_command_end_offset = tvb_find_uint8(tvb, tvb_command_end_offset +1,
1011 tvb_transaction_end_offset, ',');
1012
1013 if ( tvb_command_end_offset == -1 || tvb_command_end_offset > tvb_transaction_end_offset){
1014 tvb_command_end_offset = tvb_transaction_end_offset ;
1015
1016 }
1017
1018 /* checking how many left brackets are before the next comma */
1019
1020 while ( tvb_find_uint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') != -1
1021 && (tvb_find_uint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') < tvb_command_end_offset)){
1022
1023 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1,
1024 tvb_transaction_end_offset, '{');
1025
1026 LBRKT_counter++;
1027 }
1028
1029 /* checking how many right brackets are before the next comma */
1030
1031 while ( (tvb_find_uint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') != -1 )
1032 && (tvb_find_uint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') <= tvb_command_end_offset)
1033 && LBRKT_counter != 0){
1034
1035 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
1036 tvb_transaction_end_offset, '}');
1037 RBRKT_counter++;
1038
1039
1040 }
1041
1042 /* If equal or more right brackets before the comma, one command is complete */
1043
1044 if ( LBRKT_counter <= RBRKT_counter ){
1045
1046 tvb_current_offset = tvb_find_uint8(tvb, tvb_command_start_offset,
1047 tvb_transaction_end_offset, '{');
1048
1049
1050 /* includes no descriptors */
1051
1052 if ( LBRKT_counter == 0 ){
1053
1054 tvb_current_offset = tvb_command_end_offset;
1055
1056 /* the last command in a context */
1057
1058 if ( tvb_find_uint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') < tvb_current_offset
1059 && tvb_find_uint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') != -1){
1060
1061 tvb_previous_offset = tvb_find_uint8(tvb, tvb_command_start_offset,
1062 tvb_transaction_end_offset, '}');
1063
1064 len = tvb_previous_offset - tvb_command_start_offset;
1065
1066 tvb_previous_offset = megaco_tvb_skip_wsp_return(tvb, tvb_previous_offset -1);
1067
1068 tokenlen = tvb_previous_offset - tvb_command_start_offset;
1069
1070 }
1071
1072 /* not the last command in a context*/
1073
1074 else{
1075 len = tvb_current_offset - tvb_command_start_offset;
1076 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
1077
1078 tokenlen = tvb_current_offset - tvb_command_start_offset;
1079 }
1080 }
1081
1082 /* command includes descriptors */
1083
1084 else{
1085 len = tvb_current_offset - tvb_command_start_offset;
1086 tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
1087
1088 tokenlen = tvb_current_offset - tvb_command_start_offset;
1089 }
1090
1091 /* if a next context is specified */
1092
1093 if ( tvb_get_uint8(tvb, tvb_command_start_offset ) == 'C'){
1094 tvb_current_offset = tvb_command_start_offset;
1095 tvb_previous_offset = tvb_command_start_offset;
1096 LBRKT_counter = 0;
1097 RBRKT_counter = 0;
1098 goto nextcontext;
1099 }
1100
1101 megaco_tree_command_line = proto_tree_add_subtree(megaco_tree, tvb, tvb_command_start_offset, len+1, ett_megaco_command_line, &sub_ti, "Command: ");
1102 megaco_command = MEGACO_CMD_NOT_SET;
1103 /* creation of the megaco_tree_command_line additionally Command and Transaction ID will be printed in this line */
1104 /* Changed to use the lines above. this code is saved if there is complaints
1105 sub_ti = proto_tree_add_item(megaco_tree,hf_megaco_command_line,tvb,tvb_command_start_offset,tokenlen, ENC_UTF_8);
1106 megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
1107 */
1108 if (!global_megaco_dissect_tree) {
1109 proto_item_set_hidden(sub_ti);
1110 }
1111
1112 tvb_next_offset = tvb_command_start_offset + tokenlen;
1113
1114 /* Try to dissect Topology Descriptor before the command */
1115 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset);
1116 if ( (tempchar >= 'a')&& (tempchar <= 'z')){
1117 tempchar = tempchar - 0x20;
1118 }
1119 if ( tempchar == 'T') {
1120 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1121
1122 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1123 tempchar = tempchar - 0x20;
1124
1125 if ( tempchar == 'P' || tempchar == 'O'){
1126 int tvb_topology_end_offset = tvb_find_uint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}');
1127 if ( tvb_topology_end_offset == -1 ){
1128 expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Missing \"}\"");
1129 return tvb_captured_length(tvb);
1130 }
1131
1132 tvb_command_start_offset = tvb_find_uint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');
1133 if ( tvb_command_start_offset == -1 ){
1134 expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Missing \"{\"");
1135 return tvb_captured_length(tvb);
1136 }
1137 dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_topology_end_offset-1, tvb_command_start_offset+1);
1138
1139 /* Command after Topology Descriptor */
1140 tvb_command_start_offset = tvb_find_uint8(tvb, tvb_topology_end_offset + 1,
1141 tvb_transaction_end_offset, ',');
1142
1143 if ( tvb_command_start_offset == -1 ){
1144 /* No Command present after Topology Descriptor */
1145 break;
1146
1147 } else {
1148 /* Try to find the first char of the command */
1149 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_start_offset + 1);
1150 RBRKT_counter = 0;
1151 LBRKT_counter = 0;
1152 tvb_LBRKT = tvb_command_start_offset;
1153 tvb_RBRKT = tvb_command_start_offset;
1154 /*tvb_next_offset = tvb_find_uint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');*/
1155 continue;
1156 }
1157
1158 }
1159 }
1160
1161 /* Additional value */
1162 if ( tvb_get_uint8(tvb, tvb_command_start_offset ) == 'O'){
1163
1164 proto_tree_add_item(megaco_tree_command_line, hf_megaco_command_optional, tvb, tvb_command_start_offset, 2, ENC_NA0x00000000);
1165 tvb_command_start_offset = tvb_command_start_offset+2;
1166
1167 }
1168
1169 /* Additional value */
1170 if ( tvb_get_uint8(tvb, tvb_command_start_offset ) == 'W'){
1171
1172 proto_tree_add_item(megaco_tree_command_line, hf_megaco_wildcard_response, tvb, tvb_command_start_offset, 2, ENC_NA0x00000000 );
1173 tvb_command_start_offset = tvb_command_start_offset+2;
1174 }
1175
1176 tvb_offset = tvb_find_uint8(tvb, tvb_command_start_offset,
1177 tvb_transaction_end_offset, '=');
1178 if (tvb_offset == -1 ) {
1179 proto_tree_add_expert_format(megaco_tree, pinfo, &ei_megaco_parse_error, tvb, tvb_command_start_offset, len+1, "Parse error: Missing \"=\"");
1180 return tvb_captured_length(tvb);
1181 }
1182 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_offset -1);
1183 tokenlen = tvb_offset - tvb_command_start_offset;
1184
1185 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset);
1186 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1187 tempchar = tempchar - 0x20;
1188
1189 if ( tempchar != 'E' ){
1190 /* Short form used */
1191 if (short_form){
1192
1193 switch ( tempchar ){
1194
1195 case 'A':
1196
1197 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1198 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1199 tempchar = tempchar - 0x20;
1200
1201 switch ( tempchar ){
1202
1203 case 'V':
1204 switch(trx_type) {
1205 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
1206 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; break;
1207 default: cmd_type = GCP_CMD_NONE; break;
1208 }
1209
1210 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1211 tvb_command_start_offset, tokenlen, "AuditValue");
1212 col_append_str(pinfo->cinfo, COL_INFO, " AuditValue");
1213 proto_item_append_text(sub_ti, "AuditValue");
1214 break;
1215
1216 case 'C':
1217 switch(trx_type) {
1218 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
1219 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break;
1220 default: cmd_type = GCP_CMD_NONE; break;
1221 }
1222 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1223 tvb_command_start_offset, tokenlen, "AuditCapability");
1224 col_append_str(pinfo->cinfo, COL_INFO, " AuditCapability");
1225 proto_item_append_text(sub_ti, "AuditCapability");
1226 break;
1227
1228 default:
1229 switch(trx_type) {
1230 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
1231 case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_REPLY; break;
1232 default: cmd_type = GCP_CMD_NONE; break;
1233 }
1234
1235 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1236 tvb_command_start_offset, tokenlen, "Add");
1237 col_append_str(pinfo->cinfo, COL_INFO, " Add");
1238 proto_item_append_text(sub_ti, "Add");
1239 break;
1240 }
1241 break;
1242
1243 case 'I':
1244 /* "IEPS" */
1245 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1246 if(tempchar == 'E'){
1247 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1248 tvb_command_start_offset, tokenlen, "IEPSCall");
1249 col_append_str(pinfo->cinfo, COL_INFO, " IEPSCall");
1250 proto_item_append_text(sub_ti, "IEPSCall");
1251 }
1252 cmd_type = GCP_CMD_NONE;
1253 break;
1254 case 'N':
1255 switch(trx_type) {
1256 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
1257 case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_REPLY; break;
1258 default: cmd_type = GCP_CMD_NONE; break;
1259 }
1260
1261 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1262 tvb_command_start_offset, tokenlen, "Notify");
1263 col_append_str(pinfo->cinfo, COL_INFO, " Notify");
1264 proto_item_append_text(sub_ti, "Notify");
1265 break;
1266
1267 case 'M':
1268
1269 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1270 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1271 tempchar = tempchar - 0x20;
1272
1273 switch ( tempchar ){
1274 case 'F':
1275 switch(trx_type) {
1276 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
1277 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_REPLY; break;
1278 default: cmd_type = GCP_CMD_NONE; break;
1279 }
1280
1281 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1282 tvb_command_start_offset, tokenlen, "Modify");
1283 col_append_str(pinfo->cinfo, COL_INFO, " Modify");
1284 proto_item_append_text(sub_ti, "Modify");
1285 break;
1286
1287 case 'V':
1288 switch(trx_type) {
1289 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
1290 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break;
1291 default: cmd_type = GCP_CMD_NONE; break;
1292 }
1293 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1294 tvb_command_start_offset, tokenlen, "Move");
1295 col_append_str(pinfo->cinfo, COL_INFO, " Move");
1296 proto_item_append_text(sub_ti, "Move");
1297 break;
1298 }
1299 break;
1300
1301 case 'P':
1302 cmd_type = GCP_CMD_NONE;
1303 /*
1304 PackagesToken = ("Packages" / "PG")
1305 PendingToken = ("Pending" / "PN")
1306 PriorityToken = ("Priority" / "PR")
1307 ProfileToken = ("Profile" / "PF")
1308 */
1309 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1310 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1311 tempchar = tempchar - 0x20;
1312
1313 switch ( tempchar ){
1314 case 'G':
1315 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1316 tvb_command_start_offset, tokenlen, "Packages");
1317 col_append_str(pinfo->cinfo, COL_INFO, " Packages");
1318 proto_item_append_text(sub_ti, "Packages");
1319 break;
1320 case 'N':
1321 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1322 tvb_command_start_offset, tokenlen, "Pending");
1323 col_append_str(pinfo->cinfo, COL_INFO, " Pending");
1324 proto_item_append_text(sub_ti, "Pending");
1325 break;
1326 case 'R':
1327 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1328 tvb_command_start_offset, tokenlen, "Priority");
1329 col_append_str(pinfo->cinfo, COL_INFO, " Priority");
1330 proto_item_append_text(sub_ti, "Priority");
1331 megaco_command = MEGACO_CMD_PRIORITY;
1332 break;
1333 case 'F':
1334 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1335 tvb_command_start_offset, tokenlen, "Profile");
1336 col_append_str(pinfo->cinfo, COL_INFO, " Profile");
1337 proto_item_append_text(sub_ti, "Profile");
1338 break;
1339 }
1340 break;
1341
1342 case 'S':
1343 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset+1);
1344 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1345 tempchar = tempchar - 0x20;
1346
1347 switch ( tempchar ){
1348
1349 case 'C':
1350 switch(trx_type) {
1351 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
1352 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break;
1353 default: cmd_type = GCP_CMD_NONE; break;
1354 }
1355 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1356 tvb_command_start_offset, tokenlen, "ServiceChange");
1357 col_append_str(pinfo->cinfo, COL_INFO, " ServiceChange");
1358 proto_item_append_text(sub_ti, "ServiceChange");
1359 break;
1360
1361 default:
1362 switch(trx_type) {
1363 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
1364 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
1365 default: cmd_type = GCP_CMD_NONE; break;
1366 }
1367 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1368 tvb_command_start_offset, tokenlen, "Subtract");
1369 col_append_str(pinfo->cinfo, COL_INFO, " Subtract");
1370 proto_item_append_text(sub_ti, "Subtract");
1371 break;
1372 }
1373 break;
1374
1375 default:
1376 proto_item_append_text(sub_ti, "<None> 0x%02x", tempchar);
1377 expert_add_info(pinfo, sub_ti, &ei_megaco_no_command);
1378 return tvb_captured_length(tvb);
1379 }
1380 }
1381 else{
1382 char* command = tvb_format_text(pinfo->pool, tvb, tvb_command_start_offset, tokenlen);
1383
1384 if ( g_str_equal(command,"Subtract")(strcmp ((const char *) (command), (const char *) ("Subtract"
)) == 0)
) {
1385 switch(trx_type) {
1386 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
1387 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
1388 default: cmd_type = GCP_CMD_NONE; break;
1389 }
1390 } else if ( g_str_equal(command,"AuditValue")(strcmp ((const char *) (command), (const char *) ("AuditValue"
)) == 0)
) {
1391 switch(trx_type) {
1392 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
1393 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; break;
1394 default: cmd_type = GCP_CMD_NONE; break;
1395 }
1396 } else if ( g_str_equal(command,"AuditCapability")(strcmp ((const char *) (command), (const char *) ("AuditCapability"
)) == 0)
) {
1397 switch(trx_type) {
1398 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
1399 case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break;
1400 default: cmd_type = GCP_CMD_NONE; break;
1401 }
1402 } else if ( g_str_equal(command,"Add")(strcmp ((const char *) (command), (const char *) ("Add")) ==
0)
) {
1403 switch(trx_type) {
1404 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
1405 case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_REPLY; break;
1406 default: cmd_type = GCP_CMD_NONE; break;
1407 }
1408 } else if ( g_str_equal(command,"Notify")(strcmp ((const char *) (command), (const char *) ("Notify"))
== 0)
) {
1409 switch(trx_type) {
1410 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
1411 case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_REPLY; break;
1412 default: cmd_type = GCP_CMD_NONE; break;
1413 }
1414 } else if ( g_str_equal(command,"Modify")(strcmp ((const char *) (command), (const char *) ("Modify"))
== 0)
) {
1415 switch(trx_type) {
1416 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
1417 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_REPLY; break;
1418 default: cmd_type = GCP_CMD_NONE; break;
1419 }
1420 } else if ( g_str_equal(command,"Move")(strcmp ((const char *) (command), (const char *) ("Move")) ==
0)
) {
1421 switch(trx_type) {
1422 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
1423 case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break;
1424 default: cmd_type = GCP_CMD_NONE; break;
1425 }
1426 } else if ( g_str_equal(command,"ServiceChange")(strcmp ((const char *) (command), (const char *) ("ServiceChange"
)) == 0)
) {
1427 switch(trx_type) {
1428 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
1429 case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break;
1430 default: cmd_type = GCP_CMD_NONE; break;
1431 }
1432 } else {
1433 switch(trx_type) {
1434 case GCP_TRX_REQUEST: cmd_type = GCP_CMD_OTHER_REQ; break;
1435 case GCP_TRX_REPLY: cmd_type = GCP_CMD_REPLY; break;
1436 default: cmd_type = GCP_CMD_NONE; break;
1437 }
1438 }
1439
1440
1441 proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
1442 tvb_command_start_offset, tokenlen, command);
1443 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command);
1444 proto_item_append_text(sub_ti, " %s", command);
1445 }
1446
1447 if (cmd_type == GCP_CMD_NONE && trx_type == GCP_TRX_REPLY) {
1448 cmd_type = GCP_CMD_REPLY;
1449 }
1450
1451 if (cmd_type != GCP_CMD_NONE) {
1452 cmd = gcp_cmd(msg, trx, ctx, cmd_type, tvb_command_start_offset, pinfo, keep_persistent_data);
1453 tap_queue_packet(megaco_tap, pinfo, cmd);
1454 }
1455
1456 tvb_offset = tvb_find_uint8(tvb, tvb_command_start_offset,
1457 tvb_transaction_end_offset, '=');
1458 if (tvb_offset == -1 ) {
1459 expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Missing \"=\"");
1460 return tvb_captured_length(tvb);
1461 }
1462 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
1463 tokenlen = tvb_next_offset - tvb_offset;
1464 if (tokenlen+1 <= 0) {
1465 expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Invalid token length (%d)", tokenlen+1);
1466 return tvb_captured_length(tvb);
1467 }
1468
1469 tempchar = tvb_get_uint8(tvb, tvb_offset);
1470 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
1471 tempchar = tempchar - 0x20;
1472
1473 term = wmem_new0(pinfo->pool, gcp_term_t)((gcp_term_t*)wmem_alloc0((pinfo->pool), sizeof(gcp_term_t
)))
;
1474 wild_term = GCP_WILDCARD_NONE;
1475 term->type = GCP_TERM_TYPE_UNKNOWN0;
1476 int bytelen;
1477
1478 switch ( tempchar ){
1479
1480 case 'E':
1481 if ((tokenlen+1 > (int) sizeof(TermID))) {
1482 expert_add_info_format(pinfo, sub_ti, &ei_megaco_parse_error, "Parse error: Invalid TermID length (%d)", tokenlen+1);
1483 return tvb_captured_length(tvb);
1484 }
1485 bytelen = tvb_get_raw_bytes_as_stringz(tvb,tvb_offset,tokenlen+1,TermID);
1486 TermID[0] = 'e';
1487
1488 term->buffer = get_utf_8_string(pinfo->pool, TermID, bytelen);
1489 term->len = (int)strlen((char*)term->buffer);
1490 term->str = (const char *)term->buffer;
1491
1492 gcp_cmd_add_term(msg, trx, cmd, term, wild_term, pinfo, keep_persistent_data);
1493
1494 /*** TERM ***/
1495 proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1496 tvb_offset, tokenlen, term->str);
1497 break;
1498
1499 case '*':
1500 wild_term = GCP_WILDCARD_ALL;
1501 term->len = 1;
1502 term->buffer = (const uint8_t*)(term->str = "*");
1503
1504 gcp_cmd_add_term(msg, trx, cmd, term, wild_term, pinfo, keep_persistent_data);
1505
1506 proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1507 tvb_offset, tokenlen,
1508 "WildCard all");
1509 col_append_str(pinfo->cinfo, COL_INFO, "=*");
1510 break;
1511
1512 case '$':
1513 wild_term = GCP_WILDCARD_CHOOSE;
1514
1515 term->len = 1;
1516 term->buffer = (const uint8_t*)(term->str = "$");
1517
1518 gcp_cmd_add_term(msg, trx, cmd, term, wild_term, pinfo, keep_persistent_data);
1519
1520 proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1521 tvb_offset, tokenlen,
1522 "WildCard any");
1523 col_append_str(pinfo->cinfo, COL_INFO, "=$");
1524 break;
1525 case 'O':
1526 break;
1527
1528 default:
1529 /*** TERM ***/
1530 switch (megaco_command) {
1531 case MEGACO_CMD_PRIORITY:
1532 proto_tree_add_string(megaco_tree_command_line, hf_megaco_priority, tvb,
1533 tvb_offset, tokenlen,
1534 tvb_format_text(pinfo->pool, tvb, tvb_offset,
1535 tokenlen));
1536 break;
1537 default:
1538 proto_tree_add_string(megaco_tree_command_line, hf_megaco_termid, tvb,
1539 tvb_offset, tokenlen,
1540 tvb_format_text(pinfo->pool, tvb, tvb_offset,
1541 tokenlen));
1542
1543 term->len = tokenlen;
1544 term->buffer = (const uint8_t*)(term->str = tvb_format_text(pinfo->pool, tvb, tvb_offset, tokenlen));
1545
1546 gcp_cmd_add_term(msg, trx, cmd, term, wild_term, pinfo, keep_persistent_data);
1547 break;
1548 }
1549
1550 col_append_fstr(pinfo->cinfo, COL_INFO, "=%s",tvb_format_text(pinfo->pool, tvb, tvb_offset,tokenlen));
1551 break;
1552 }
1553
1554 }
1555 /* Dissect the Descriptors */
1556
1557
1558 if ( LBRKT_counter != 0 && tvb_current_offset != tvb_command_end_offset){
1559
1560 int tvb_descriptors_start_offset, tvb_descriptors_end_offset;
1561 tvb_descriptors_start_offset = tvb_find_uint8(tvb, tvb_command_start_offset,
1562 tvb_transaction_end_offset, '{');
1563
1564 tvb_descriptors_end_offset = tvb_descriptors_start_offset;
1565 if ( tvb_descriptors_end_offset > tvb_transaction_end_offset )
1566 tvb_descriptors_end_offset = tvb_transaction_end_offset;
1567
1568 while ( LBRKT_counter > 0 ){
1569
1570 tvb_descriptors_end_offset = tvb_find_uint8(tvb, tvb_descriptors_end_offset+1,
1571 tvb_transaction_end_offset, '}');
1572
1573 LBRKT_counter--;
1574
1575 }
1576
1577 tempchar = tvb_get_uint8(tvb, tvb_command_start_offset);
1578
1579 if ( tempchar == 'E'|| tempchar == 'e'){
1580 /* errorDescriptor */
1581 tvb_descriptors_start_offset = tvb_command_start_offset - 1;
1582 }
1583 dissect_megaco_descriptors(tvb_new_subset_length(tvb, tvb_descriptors_start_offset, tvb_descriptors_end_offset - tvb_descriptors_start_offset + 1), megaco_tree_command_line, pinfo, tree, ctx_id);
1584 }
1585 RBRKT_counter = 0;
1586 LBRKT_counter = 0;
1587 tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_end_offset +1);
1588 tvb_LBRKT = tvb_command_start_offset;
1589 tvb_RBRKT = tvb_command_start_offset;
1590
1591 }
1592
1593 } while ( tvb_command_end_offset < tvb_transaction_end_offset );
1594
1595 if (keep_persistent_data) {
1596 gcp_msg_to_str(msg,pinfo->pool,keep_persistent_data);
1597 gcp_analyze_msg(megaco_tree, pinfo, tvb, msg, &megaco_ctx_ids, &ei_megaco_errored_command);
1598 }
1599
1600 tvb_next_offset = tvb_transaction_end_offset;
1601 }
1602 while( tvb_transaction_end_offset > 0 && tvb_transaction_end_offset < tvb_len - 2);
1603
1604 if(global_megaco_raw_text){
1605 tvb_raw_text_add(tvb, megaco_tree);
1606 }
1607
1608 return tvb_captured_length(tvb);
1609}
1610
1611#define MEGACO_MODEM_TOKEN1 1
1612#define MEGACO_MUX_TOKEN2 2
1613#define MEGACO_MEDIA_TOKEN3 3
1614#define MEGACO_SIGNALS_TOKEN4 4
1615#define MEGACO_SERVICES_TOKEN5 5
1616#define MEGACO_STATS_TOKEN6 6
1617#define MEGACO_ERROR_TOKEN7 7
1618#define MEGACO_EVENTS_TOKEN8 8
1619#define MEGACO_AUDIT_TOKEN9 9
1620#define MEGACO_DIGITMAP_TOKEN10 10
1621#define MEGACO_OE_TOKEN11 11
1622#define MEGACO_TOPOLOGY_TOKEN12 12
1623#define MEGACO_PACKAGES_TOKEN13 13
1624
1625static const megaco_tokens_t megaco_descriptors_names[] = {
1626 { "Unknown-token", NULL((void*)0) }, /* 0 Pad so that the real headers start at index 1 */
1627 { "Modem", "MD" }, /* 1 */
1628 { "Mux", "MX" }, /* 2 */
1629 { "Media", "M" }, /* 3 */
1630 { "Signals", "SG" }, /* 4 */
1631 { "Services", "SV" }, /* 5 */
1632 { "Statistics", "SA" }, /* 6 */
1633 { "Error", "ER" }, /* 7 */
1634 { "Events", "E" }, /* 8 */
1635 { "Audit", "AT" }, /* 9 */
1636 { "DigitMap", "DM" }, /* 10 */
1637 { "ObservedEvents", "OE" }, /* 11 */
1638 { "Topology", "TP" }, /* 12 */
1639 { "Packages", "PG" }, /* 13 */
1640};
1641
1642/* Returns index of megaco_tokens_t */
1643/* note - also called by dissect_megaco_auditdescriptor */
1644static int find_megaco_descriptors_names(tvbuff_t *tvb, int offset, unsigned header_len)
1645{
1646 unsigned i;
1647
1648 for (i = 1; i < array_length(megaco_descriptors_names)(sizeof (megaco_descriptors_names) / sizeof (megaco_descriptors_names
)[0])
; i++) {
1649 if (header_len == strlen(megaco_descriptors_names[i].name) &&
1650 tvb_strncaseeql(tvb, offset, megaco_descriptors_names[i].name, header_len) == 0)
1651 return i;
1652 if (megaco_descriptors_names[i].compact_name != NULL((void*)0) &&
1653 header_len == strlen(megaco_descriptors_names[i].compact_name) &&
1654 tvb_strncaseeql(tvb, offset, megaco_descriptors_names[i].compact_name, header_len) == 0)
1655 return i;
1656 }
1657 return -1;
1658}
1659
1660static void
1661dissect_megaco_modemdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
1662{
1663
1664 int tokenlen;
1665
1666 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1667 proto_tree_add_string(megaco_tree_command_line, hf_megaco_modem_descriptor, tvb,
1668 tvb_previous_offset, tokenlen,
1669 tvb_format_text(pinfo->pool, tvb, tvb_previous_offset,
1670 tokenlen));
1671
1672}
1673static void
1674dissect_megaco_multiplexdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
1675{
1676
1677 int tokenlen;
1678
1679 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
1680 proto_tree_add_string(megaco_tree_command_line, hf_megaco_multiplex_descriptor, tvb,
1681 tvb_previous_offset, tokenlen,
1682 tvb_format_text(pinfo->pool, tvb, tvb_previous_offset,
1683 tokenlen));
1684
1685}
1686
1687/* mediaDescriptor = MediaToken LBRKT mediaParm *(COMMA mediaParm) RBRKT
1688 * MediaToken = ("Media" / "M")
1689 *
1690 * mediaParm = (streamParm / streamDescriptor /terminationStateDescriptor)
1691 *
1692 * ; at-most one terminationStateDescriptor
1693 * ; and either streamParm(s) or streamDescriptor(s) but not both
1694 * streamParm = ( localDescriptor / remoteDescriptor /localControlDescriptor )
1695 * localDescriptor = LocalToken LBRKT octetString RBRKT
1696 * LocalToken = ("Local" / "L")
1697 * octetString = *(nonEscapeChar)
1698 * nonEscapeChar = ( "\}" / %x01-7C / %x7E-FF )
1699 * remoteDescriptor = RemoteToken LBRKT octetString RBRKT
1700 * RemoteToken = ("Remote" / "R")
1701 * localControlDescriptor = LocalControlToken LBRKT localParm*(COMMA localParm) RBRKT
1702 * LocalControlToken = ("LocalControl" / "O")
1703 * localParm = ( streamMode / propertyParm / reservedValueMode
1704 * streamDescriptor = StreamToken EQUAL StreamID LBRKT streamParm*(COMMA streamParm) RBRKT
1705 * StreamToken = ("Stream" / "ST")
1706 * terminationStateDescriptor = TerminationStateToken LBRKTterminationStateParm
1707 * *( COMMA terminationStateParm ) RBRKT
1708 * TerminationStateToken = ("TerminationState" / "TS")
1709 * terminationStateParm =(propertyParm / serviceStates / eventBufferControl )
1710 */
1711
1712#define MEGACO_LOCAL_TOKEN1 1
1713#define MEGACO_REMOTE_TOKEN2 2
1714#define MEGACO_LOCAL_CONTROL_TOKEN3 3
1715#define MEGACO_STREAM_TOKEN4 4
1716#define MEGACO_TERMINATION_STATE_DESC5 5
1717// MEGACO_STATS_TOKEN is already defined as 6 above
1718
1719static const megaco_tokens_t megaco_mediaParm_names[] = {
1720 { "Unknown-token", NULL((void*)0) }, /* 0 Pad so that the real headers start at index 1 */
1721 { "Local", "L" }, /* 1 */
1722 { "Remote", "R" }, /* 2 */
1723 { "LocalControl", "O" }, /* 3 */
1724 { "Stream", "ST" }, /* 4 */
1725 { "TerminationState", "TS" }, /* 5 */
1726 { "Statistics", "SA" }, /* 6 */
1727};
1728
1729/* Returns index of megaco_tokens_t */
1730static int find_megaco_mediaParm_names(tvbuff_t *tvb, int offset, unsigned header_len)
1731{
1732 unsigned i;
1733
1734 for (i = 1; i < array_length(megaco_mediaParm_names)(sizeof (megaco_mediaParm_names) / sizeof (megaco_mediaParm_names
)[0])
; i++) {
1735 if (header_len == strlen(megaco_mediaParm_names[i].name) &&
1736 tvb_strncaseeql(tvb, offset, megaco_mediaParm_names[i].name, header_len) == 0)
1737 return i;
1738 if (megaco_mediaParm_names[i].compact_name != NULL((void*)0) &&
1739 header_len == strlen(megaco_mediaParm_names[i].compact_name) &&
1740 tvb_strncaseeql(tvb, offset, megaco_mediaParm_names[i].compact_name, header_len) == 0)
1741 return i;
1742 }
1743
1744 return -1;
1745}
1746
1747static void
1748dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line,packet_info *pinfo, int tvb_last_RBRKT,
1749 int tvb_previous_offset, int start_offset, proto_tree *top_tree, uint32_t context)
1750{
1751
1752 int tokenlen, tvb_LBRKT, tvb_RBRKT;
1753 int tvb_next_offset, tvb_current_offset, tvb_offset, equal_offset, save_offset;
1754 int mediaParm;
1755 unsigned streamId;
1756
1757 proto_tree *megaco_mediadescriptor_tree;
1758 proto_item *megaco_mediadescriptor_ti, *ti;
1759
1760 megaco_mediadescriptor_ti = proto_tree_add_item(megaco_tree_command_line, hf_megaco_media_descriptor, tvb, start_offset, 1, ENC_NA0x00000000);
1761 megaco_mediadescriptor_tree = proto_item_add_subtree(megaco_mediadescriptor_ti, ett_megaco_mediadescriptor);
1762
1763 while ( tvb_previous_offset < tvb_last_RBRKT){
1764 /* Start of token */
1765 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
1766
1767 /* Find token length */
1768 for (tvb_next_offset=tvb_current_offset; tvb_next_offset < tvb_last_RBRKT; tvb_next_offset++){
1769 if (!g_ascii_isalpha(tvb_get_uint8(tvb, tvb_next_offset ))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_next_offset )
)] & G_ASCII_ALPHA) != 0)
){
1770 break;
1771 }
1772 }
1773 tokenlen = tvb_next_offset - tvb_current_offset;
1774
1775 mediaParm = find_megaco_mediaParm_names(tvb, tvb_current_offset, tokenlen);
1776
1777 tvb_LBRKT = tvb_find_uint8(tvb, tvb_next_offset , tvb_last_RBRKT, '{');
1778 if (tvb_LBRKT == -1) {
1779 // Not found, use the end offset.
1780 tvb_LBRKT = tvb_last_RBRKT;
1781 }
1782 tvb_RBRKT = tvb_find_uint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, '}');
1783 if (tvb_RBRKT == -1) {
1784 // Not found, use the end offset.
1785 tvb_RBRKT = tvb_last_RBRKT;
1786 }
1787
1788 switch ( mediaParm ){
1789 case MEGACO_LOCAL_TOKEN1:
1790 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1791 dissect_megaco_LocalRemotedescriptor(tvb, megaco_mediadescriptor_tree, pinfo,
1792 tvb_RBRKT, tvb_current_offset, context, true1);
1793 tvb_current_offset = tvb_RBRKT;
1794 break;
1795 case MEGACO_REMOTE_TOKEN2:
1796 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1797 dissect_megaco_LocalRemotedescriptor(tvb, megaco_mediadescriptor_tree, pinfo,
1798 tvb_RBRKT, tvb_current_offset, context, false0);
1799 tvb_current_offset = tvb_RBRKT;
1800 break;
1801 case MEGACO_LOCAL_CONTROL_TOKEN3:
1802 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1803 dissect_megaco_LocalControldescriptor(tvb, megaco_mediadescriptor_tree, pinfo,
1804 tvb_RBRKT, tvb_current_offset, top_tree);
1805 tvb_current_offset = tvb_RBRKT;
1806 break;
1807 case MEGACO_STREAM_TOKEN4:
1808 save_offset = tvb_current_offset;
1809 equal_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_last_RBRKT, '=');
1810 tvb_current_offset = megaco_tvb_skip_wsp(tvb, equal_offset+1);
1811 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1);
1812 tokenlen = tvb_offset - tvb_current_offset;
1813
1814 streamId = (unsigned)strtoul(tvb_format_text(pinfo->pool, tvb, tvb_current_offset,tokenlen),NULL((void*)0),10);
1815 ti = proto_tree_add_uint(megaco_mediadescriptor_tree, hf_megaco_streamid, tvb,
1816 save_offset, 1, streamId);
1817 proto_item_set_len(ti, tvb_offset-save_offset);
1818 tvb_previous_offset = tvb_LBRKT+1;
1819 continue;
1820 case MEGACO_TERMINATION_STATE_DESC5:
1821 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1822 dissect_megaco_TerminationStatedescriptor(tvb, pinfo, megaco_mediadescriptor_tree,
1823 tvb_RBRKT, tvb_current_offset);
1824 tvb_current_offset = tvb_RBRKT;
1825 break;
1826 case MEGACO_STATS_TOKEN6:
1827 // dissect_megaco_statisticsdescriptor wants the previous
1828 // offset, don't skip forward.
1829 //tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
1830 dissect_megaco_statisticsdescriptor(tvb, megaco_mediadescriptor_tree,
1831 tvb_RBRKT, tvb_current_offset);
1832 tvb_current_offset = tvb_RBRKT;
1833 break;
1834 default:
1835 break;
1836 };
1837 /* more parameters ? */
1838 tvb_next_offset = tvb_find_uint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, ',');
1839 if (tvb_next_offset > tvb_last_RBRKT) tvb_next_offset = tvb_last_RBRKT;
1840 if ( tvb_next_offset != -1 ){
1841 /* (raw formatting removed)
1842 tokenlen = tvb_next_offset - tvb_RBRKT+1;
1843 proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_RBRKT, tokenlen); */
1844 tvb_previous_offset = tvb_next_offset+1;
1845 } else{
1846 /* Add the trailing '}' (raw formatting removed) */
1847 /* proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_RBRKT, 1); */
1848 tvb_previous_offset = tvb_last_RBRKT;
1849 }
1850
1851 } /* End while */
1852
1853 proto_item_set_end(megaco_mediadescriptor_ti, tvb, tvb_previous_offset);
1854}
1855
1856static void
1857dissect_megaco_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, int offset, int len, proto_tree *top_tree)
1858{
1859 /*proto_item *item;*/
1860 /*proto_tree *tree;*/
1861 char *msg = tvb_format_text(pinfo->pool, tvb, offset, len);
1862
1863 /*item= */proto_tree_add_item(megaco_tree, hf_megaco_h245, tvb, offset, len, ENC_NA0x00000000);
1864 /*tree = proto_item_add_subtree(item, ett_megaco_h245); */
1865
1866 /* arbitrary maximum length */
1867 if(len<20480){
1868 int i;
1869 tvbuff_t *h245_tvb;
1870 uint8_t *buf = (uint8_t *)wmem_alloc(pinfo->pool, 10240);
1871
1872 /* first, skip to where the encoded pdu starts, this is
1873 the first hex digit after the '=' char.
1874 */
1875 while(1){
1876 if((*msg==0)||(*msg=='\n')){
1877 return;
1878 }
1879 if(*msg=='='){
1880 msg++;
1881 break;
1882 }
1883 msg++;
1884 }
1885 while(1){
1886 if((*msg==0)||(*msg=='\n')){
1887 return;
1888 }
1889 if( ((*msg>='0')&&(*msg<='9'))
1890 || ((*msg>='a')&&(*msg<='f'))
1891 || ((*msg>='A')&&(*msg<='F'))){
1892 break;
1893 }
1894 msg++;
1895 }
1896 i=0;
1897 while( ((*msg>='0')&&(*msg<='9'))
1898 ||((*msg>='a')&&(*msg<='f'))
1899 ||((*msg>='A')&&(*msg<='F')) ){
1900 int val;
1901 if((*msg>='0')&&(*msg<='9')){
1902 val=(*msg)-'0';
1903 } else if((*msg>='a')&&(*msg<='f')){
1904 val=(*msg)-'a'+10;
1905 } else if((*msg>='A')&&(*msg<='F')){
1906 val=(*msg)-'A'+10;
1907 } else {
1908 return;
1909 }
1910 val<<=4;
1911 msg++;
1912 if((*msg>='0')&&(*msg<='9')){
1913 val|=(*msg)-'0';
1914 } else if((*msg>='a')&&(*msg<='f')){
1915 val|=(*msg)-'a'+10;
1916 } else if((*msg>='A')&&(*msg<='F')){
1917 val|=(*msg)-'A'+10;
1918 } else {
1919 return;
1920 }
1921 msg++;
1922
1923 buf[i]=(uint8_t)val;
1924 i++;
1925 }
1926 if(i==0){
1927 return;
1928 }
1929 h245_tvb = tvb_new_child_real_data(tvb, buf,i,i);
1930 add_new_data_source(pinfo, h245_tvb, "H.245 over MEGACO");
1931 /* should go through a handle, however, the two h245 entry
1932 points are different, one is over tpkt and the other is raw
1933 */
1934 call_dissector(h245_handle, h245_tvb, pinfo, top_tree);
1935/* dissect_h245_MultimediaSystemControlMessage(h245_tvb, pinfo, tree);*/
1936 }
1937}
1938
1939static void
1940dissect_megaco_h324_h223caprn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree, int offset _U___attribute__((unused)), int len, char *msg)
1941{
1942 asn1_ctx_t actx;
1943
1944 /* arbitrary maximum length */
1945 if(len<20480){
1946 int i;
1947 tvbuff_t *h245_tvb;
1948 uint8_t *buf = (uint8_t *)wmem_alloc(pinfo->pool, 10240);
1949
1950 /* first, skip to where the encoded pdu starts, this is
1951 the first hex digit after the '=' char.
1952 */
1953 while(1){
1954 if((*msg==0)||(*msg=='\n')){
1955 return;
1956 }
1957 if(*msg=='='){
1958 msg++;
1959 break;
1960 }
1961 msg++;
1962 }
1963 while(1){
1964 if((*msg==0)||(*msg=='\n')){
1965 return;
1966 }
1967 if( ((*msg>='0')&&(*msg<='9'))
1968 || ((*msg>='a')&&(*msg<='f'))
1969 || ((*msg>='A')&&(*msg<='F'))){
1970 break;
1971 }
1972 msg++;
1973 }
1974 i=0;
1975 while( ((*msg>='0')&&(*msg<='9'))
1976 ||((*msg>='a')&&(*msg<='f'))
1977 ||((*msg>='A')&&(*msg<='F')) ){
1978 int val;
1979 if((*msg>='0')&&(*msg<='9')){
1980 val=(*msg)-'0';
1981 } else if((*msg>='a')&&(*msg<='f')){
1982 val=(*msg)-'a'+10;
1983 } else if((*msg>='A')&&(*msg<='F')){
1984 val=(*msg)-'A'+10;
1985 } else {
1986 return;
1987 }
1988 val<<=4;
1989 msg++;
1990 if((*msg>='0')&&(*msg<='9')){
1991 val|=(*msg)-'0';
1992 } else if((*msg>='a')&&(*msg<='f')){
1993 val|=(*msg)-'a'+10;
1994 } else if((*msg>='A')&&(*msg<='F')){
1995 val|=(*msg)-'A'+10;
1996 } else {
1997 return;
1998 }
1999 msg++;
2000
2001 buf[i]=(uint8_t)val;
2002 i++;
2003 }
2004 if(i==0){
2005 return;
2006 }
2007 h245_tvb = tvb_new_child_real_data(tvb, buf,i,i);
2008 add_new_data_source(pinfo, h245_tvb, "H.245 over MEGACO");
2009 /* should go through a handle, however, the two h245 entry
2010 points are different, one is over tpkt and the other is raw
2011 */
2012 asn1_ctx_init(&actx, ASN1_ENC_PER, true1, pinfo);
2013 dissect_h245_H223Capability(h245_tvb, 0, &actx, megaco_tree, hf_megaco_h223Capability);
2014 }
2015}
2016
2017static void
2018dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset, proto_tree *top_tree)
2019{
2020
2021 int tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2022 int tvb_events_end_offset, tvb_LBRKT;
2023 proto_tree *megaco_eventsdescriptor_tree, *megaco_requestedevent_tree;
2024 proto_item *megaco_eventsdescriptor_ti, *megaco_requestedevent_ti, *ti;
2025
2026 int requested_event_start_offset = 0,
2027 requested_event_end_offset = 0;
2028
2029 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2030
2031 megaco_eventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_events_descriptor,tvb,tvb_previous_offset, tokenlen, ENC_NA0x00000000);
2032 megaco_eventsdescriptor_tree = proto_item_add_subtree(megaco_eventsdescriptor_ti, ett_megaco_eventsdescriptor);
2033
2034 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
2035 tvb_next_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2036
2037 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
2038
2039 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2040 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
2041
2042 tokenlen = tvb_help_offset - tvb_current_offset;
2043
2044 ti = proto_tree_add_uint(megaco_eventsdescriptor_tree, hf_megaco_requestid, tvb,
2045 tvb_current_offset, 1,
2046 (uint32_t) strtoul(tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen), NULL((void*)0), 10));
2047 proto_item_set_len(ti, tokenlen);
2048
2049 tvb_events_end_offset = tvb_RBRKT;
2050
2051 tvb_RBRKT = tvb_next_offset+1;
2052 tvb_LBRKT = tvb_next_offset+1;
2053 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
2054
2055
2056 do {
2057
2058 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2059 tvb_events_end_offset, '}');
2060 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT,
2061 tvb_events_end_offset, '{');
2062
2063 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset,
2064 tvb_events_end_offset, ',');
2065
2066 if (tvb_current_offset == -1 || tvb_current_offset > tvb_events_end_offset){
2067 tvb_current_offset = tvb_events_end_offset;
2068 }
2069
2070
2071 /* Descriptor includes no parameters */
2072
2073 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2074
2075 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2076 }
2077
2078 /* Descriptor includes Parameters */
2079
2080 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2081
2082 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2083
2084 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1,
2085 tvb_events_end_offset, '{');
2086 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
2087 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2088 tvb_events_end_offset, '}');
2089 }
2090
2091 }
2092
2093 tvb_help_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_events_end_offset, '{');
2094
2095 /* if there are eventparameter */
2096
2097 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2098
2099 requested_event_start_offset = tvb_help_offset;
2100 requested_event_end_offset = tvb_RBRKT;
2101 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2102 tokenlen = tvb_help_offset - tvb_previous_offset;
2103 }
2104 /* no parameters */
2105 else {
2106 tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2107 }
2108
2109 megaco_requestedevent_ti = proto_tree_add_item(megaco_eventsdescriptor_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,tokenlen, ENC_UTF_80x00000002);
2110 megaco_requestedevent_tree = proto_item_add_subtree(megaco_requestedevent_ti, ett_megaco_requestedevent);
2111
2112 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2113
2114 requested_event_start_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1);
2115 requested_event_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_event_end_offset-1);
2116
2117 if (!tvb_strncaseeql(tvb, requested_event_start_offset, "dm", 2)) {
2118 dissect_megaco_digitmapdescriptor(tvb, pinfo, megaco_requestedevent_tree, requested_event_end_offset, requested_event_start_offset);
2119 }
2120 else{
2121 tokenlen = requested_event_end_offset - requested_event_start_offset;
2122 if(!tvb_strneql(tvb, requested_event_start_offset, "h245", 4)){
2123 dissect_megaco_h245(tvb, pinfo, megaco_requestedevent_tree, requested_event_start_offset, tokenlen, top_tree);
2124 } else {
2125 proto_tree_add_format_text(megaco_requestedevent_tree, tvb, requested_event_start_offset, tokenlen);
2126 }
2127 }
2128
2129 }
2130
2131 tvb_previous_offset = tvb_current_offset;
2132 tvb_current_offset = tvb_find_uint8(tvb, tvb_RBRKT,
2133 tvb_events_end_offset, ',');
2134
2135 if (tvb_current_offset == -1 || tvb_current_offset > tvb_events_end_offset || tvb_current_offset < tvb_previous_offset ) {
2136 tvb_current_offset = tvb_events_end_offset;
2137 }
2138
2139 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2140
2141 tvb_LBRKT = tvb_previous_offset;
2142 tvb_RBRKT = tvb_previous_offset;
2143
2144 } while ( tvb_current_offset < tvb_events_end_offset );
2145 }
2146}
2147
2148static void
2149dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset, proto_tree *top_tree)
2150{
2151
2152 int tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2153 int tvb_signals_end_offset, tvb_signals_start_offset, tvb_LBRKT;
2154 proto_tree *megaco_signalsdescriptor_tree, *megaco_requestedsignal_tree;
2155 proto_item *megaco_signalsdescriptor_ti, *megaco_requestedsignal_ti;
2156
2157 int requested_signal_start_offset = 0,
2158 requested_signal_end_offset = 0;
2159
2160 tvb_signals_end_offset = tvb_RBRKT;
2161 tvb_signals_start_offset = tvb_previous_offset;
2162
2163 if(g_ascii_toupper(tvb_get_uint8(tvb, tvb_previous_offset+1))=='G')
2164 tokenlen = 2; /* token is compact text (SG) */
2165 else
2166 tokenlen = 7; /* token must be verbose text (Signals) */
2167
2168 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset+tokenlen);
2169
2170 if(tvb_get_uint8(tvb, tvb_current_offset)!='{') { /* {} has been omitted */
2171
2172 megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line, hf_megaco_signal_descriptor, tvb, tvb_signals_start_offset, tokenlen, ENC_NA0x00000000);
2173 expert_add_info(pinfo, megaco_signalsdescriptor_ti, &ei_megaco_signal_descriptor);
2174
2175 col_append_str(pinfo->cinfo, COL_INFO, " (Signal:none)"); /* then say so */
2176
2177 return; /* and return */
2178 }
2179
2180 tvb_LBRKT = tvb_find_uint8(tvb, tvb_previous_offset, tvb_signals_end_offset, '{');
2181 if (tvb_LBRKT == -1) {
2182 // This should not happen, because we should at least find the '{' found
2183 // above at tvb_current_offset. DISSECTOR_ASSERT?
2184 return;
2185 }
2186 tokenlen = (tvb_LBRKT+1) - tvb_signals_start_offset;
2187
2188 megaco_signalsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_signal_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA0x00000000);
2189 megaco_signalsdescriptor_tree = proto_item_add_subtree(megaco_signalsdescriptor_ti, ett_megaco_signalsdescriptor);
2190
2191 tvb_current_offset = tvb_LBRKT;
2192 tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2193 col_append_fstr(pinfo->cinfo, COL_INFO, " (Signal:%s)",tvb_format_text(pinfo->pool, tvb, tvb_current_offset,tokenlen-tvb_current_offset+tvb_previous_offset));
2194
2195
2196 if ( tvb_current_offset < tvb_signals_end_offset && tvb_current_offset != -1 && tvb_next_offset != tvb_signals_end_offset){
2197
2198
2199 tvb_RBRKT = tvb_next_offset+1;
2200 tvb_LBRKT = tvb_next_offset+1;
2201 tvb_previous_offset = tvb_next_offset;
2202
2203
2204 do {
2205
2206 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2207 tvb_signals_end_offset, '}');
2208 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT,
2209 tvb_signals_end_offset, '{');
2210
2211 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset,
2212 tvb_signals_end_offset, ',');
2213
2214 if (tvb_current_offset == -1 || tvb_current_offset > tvb_signals_end_offset){
2215 tvb_current_offset = tvb_signals_end_offset;
2216 }
2217
2218
2219 /* Descriptor includes no parameters */
2220
2221 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2222
2223 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2224 }
2225
2226 /* Descriptor includes Parameters */
2227
2228 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2229
2230 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2231
2232 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1,
2233 tvb_signals_end_offset, '{');
2234 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
2235 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2236 tvb_signals_end_offset, '}');
2237 }
2238
2239 }
2240
2241 tvb_help_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_signals_end_offset, '{');
2242
2243 /* if there are signalparameter */
2244
2245 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2246
2247 requested_signal_start_offset = tvb_help_offset;
2248 requested_signal_end_offset = tvb_RBRKT;
2249 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2250 pkg_tokenlen = tvb_help_offset - tvb_previous_offset;
2251 }
2252 /* no parameters */
2253 else {
2254 pkg_tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2255 }
2256
2257 megaco_requestedsignal_ti = proto_tree_add_item(megaco_signalsdescriptor_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, ENC_UTF_80x00000002);
2258 megaco_requestedsignal_tree = proto_item_add_subtree(megaco_requestedsignal_ti, ett_megaco_requestedsignal);
2259
2260 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2261 requested_signal_start_offset = megaco_tvb_skip_wsp(tvb, requested_signal_start_offset +1);
2262 requested_signal_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_signal_end_offset-1);
2263
2264 tokenlen = requested_signal_end_offset - requested_signal_start_offset;
2265
2266 if(!tvb_strneql(tvb, requested_signal_start_offset, "h245", 4)){
2267 dissect_megaco_h245(tvb, pinfo, megaco_requestedsignal_tree, requested_signal_start_offset, tokenlen, top_tree);
2268 } else {
2269 proto_tree_add_format_text( megaco_requestedsignal_tree, tvb, requested_signal_start_offset, tokenlen);
2270 }
2271 /* Print the trailing '}' (raw formatting removed) */
2272 /* proto_tree_add_format_text( megaco_requestedsignal_tree, tvb, tvb_RBRKT, 1); */
2273 }
2274
2275 tvb_current_offset = tvb_find_uint8(tvb, tvb_RBRKT,
2276 tvb_signals_end_offset, ',');
2277
2278 if (tvb_current_offset == -1 || tvb_current_offset > tvb_signals_end_offset || tvb_current_offset < tvb_previous_offset){
2279 tvb_current_offset = tvb_signals_end_offset;
2280 }
2281
2282 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2283
2284 tvb_LBRKT = tvb_previous_offset;
2285 tvb_RBRKT = tvb_previous_offset;
2286 /* Print the trailing '}' (raw formatting removed) */
2287 /* proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); */
2288
2289 } while ( tvb_current_offset < tvb_signals_end_offset );
2290 }else{
2291 /* signals{} (raw formatting removed)
2292 proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_signals_end_offset, 1); */
2293 }
2294
2295
2296}
2297
2298/*
2299 auditDescriptor = AuditToken LBRKT [ auditItem *(COMMA auditItem) ] RBRKT
2300
2301 V1:
2302 auditItem = ( MuxToken / ModemToken / MediaToken /
2303 SignalsToken / EventBufferToken /
2304 DigitMapToken / StatsToken / EventsToken /
2305 ObservedEventsToken / PackagesToken )
2306
2307 V3:
2308 auditItem = ( auditReturnItem / SignalsToken / EventBufferToken /
2309 EventsToken / indAudterminationAudit )
2310
2311 auditReturnItem = ( MuxToken / ModemToken / MediaToken / DigitMapToken /
2312 StatsToken / ObservedEventsToken / PackagesToken )
2313
2314 indAudauditReturnParameter
2315 = ( indAudmediaDescriptor / indAudeventsDescriptor /
2316 indAudsignalsDescriptor / indAuddigitMapDescriptor /
2317 indAudeventBufferDescriptor /
2318 indAudstatisticsDescriptor / indAudpackagesDescriptor )
2319 */
2320static void
2321dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree, packet_info *pinfo _U___attribute__((unused)), int tvb_stop, int tvb_offset, proto_tree *top_tree, uint32_t context)
2322{
2323 int tokenlen, tvb_end, tvb_next, tvb_LBRKT, tvb_token_end, token_index;
2324 proto_tree *megaco_auditdescriptor_tree, *megaco_auditdescriptor_ti;
2325 bool_Bool descriptor;
2326
2327 tvb_next = tvb_find_uint8(tvb, tvb_offset, tvb_stop, '{'); /* find opening LBRKT - is this already checked by caller?*/
2328 if( tvb_next == -1 ) /* complain and give up if not there */
2329 {
2330 expert_add_info(pinfo, megaco_tree, &ei_megaco_audit_descriptor);
2331 return;
2332 }
2333 tokenlen = (tvb_stop + 1) - tvb_offset;
2334
2335 megaco_auditdescriptor_ti = proto_tree_add_item( megaco_tree, hf_megaco_audit_descriptor, tvb, tvb_offset, tokenlen, ENC_NA0x00000000);
2336 megaco_auditdescriptor_tree = proto_item_add_subtree( megaco_auditdescriptor_ti, ett_megaco_auditdescriptor );
2337
2338 tvb_offset = tvb_next;
2339
2340 while( tvb_offset < tvb_stop )
2341 {
2342 tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1); /* find start of an auditItem */
2343 if( tvb_get_uint8(tvb, tvb_offset) != '}' ) /* got something */
2344 {
2345 tvb_next = tvb_find_uint8(tvb, tvb_offset, tvb_stop, ','); /* end of an auditItem */
2346 if (tvb_next == -1) /* last item doesn't have a comma */
2347 tvb_next = tvb_stop;
2348
2349 tvb_LBRKT = tvb_find_uint8(tvb, tvb_offset, tvb_stop, '{');
2350
2351 tvb_end = megaco_tvb_skip_wsp_return(tvb, tvb_next-1); /* trim any trailing whitespace */
2352
2353 if ( tvb_LBRKT > tvb_next || tvb_LBRKT == -1 ){
2354 /* auditItem has no parameters (i.e., is a Token) */
2355 descriptor = false0;
2356 tvb_token_end = tvb_end;
2357 } else {
2358 /* auditItem includes Parameters (i.e., is a Descriptor) */
2359 descriptor = true1;
2360 for (tvb_token_end=tvb_offset; tvb_token_end < tvb_end ; tvb_token_end++){
2361 if (!g_ascii_isalpha(tvb_get_uint8(tvb, tvb_token_end ))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_token_end ))
] & G_ASCII_ALPHA) != 0)
){
2362 break;
2363 }
2364 }
2365 }
2366
2367 tokenlen = tvb_token_end - tvb_offset; /* get length of token */
2368
2369 token_index = find_megaco_descriptors_names(tvb, tvb_offset, tokenlen); /* lookup the token */
2370 if( token_index == -1 ) /* if not found then 0 => Unknown */
2371 token_index = 0;
2372
2373 if (descriptor) {
2374
2375 switch ( token_index ){
2376 case MEGACO_MEDIA_TOKEN3:
2377 {
2378 int temp_offset = tvb_find_uint8(tvb, tvb_offset, tvb_stop, '{');
2379 int save_offset = tvb_offset;
2380
2381 tvb_offset = megaco_tvb_skip_wsp(tvb, temp_offset +1);
2382 dissect_megaco_mediadescriptor(tvb, megaco_auditdescriptor_tree, pinfo, tvb_end, tvb_offset, save_offset, top_tree, context);
2383 break;
2384 }
2385 case MEGACO_SIGNALS_TOKEN4:
2386 dissect_megaco_signaldescriptor(tvb, pinfo, megaco_auditdescriptor_tree, tvb_end, tvb_offset, top_tree);
2387 break;
2388 case MEGACO_STATS_TOKEN6:
2389 dissect_megaco_statisticsdescriptor(tvb, megaco_auditdescriptor_tree, tvb_end, tvb_offset);
2390 break;
2391 case MEGACO_EVENTS_TOKEN8:
2392 dissect_megaco_eventsdescriptor(tvb, pinfo, megaco_auditdescriptor_tree, tvb_end, tvb_offset, top_tree);
2393 break;
2394 case MEGACO_DIGITMAP_TOKEN10:
2395 dissect_megaco_digitmapdescriptor(tvb, pinfo, megaco_auditdescriptor_tree, tvb_end, tvb_offset);
2396 break;
2397 case MEGACO_PACKAGES_TOKEN13:
2398 dissect_megaco_Packagesdescriptor(tvb, pinfo, megaco_auditdescriptor_tree, tvb_end, tvb_offset);
2399 break;
2400 default:
2401 tokenlen = tvb_end - tvb_offset;
2402 proto_tree_add_string(megaco_auditdescriptor_tree, hf_megaco_audititem, tvb,
2403 tvb_offset, tokenlen, megaco_descriptors_names[token_index].name); /* and display the long form */
2404 break;
2405 }
2406 } else {
2407 proto_tree_add_string(megaco_auditdescriptor_tree, hf_megaco_audititem, tvb,
2408 tvb_offset, tokenlen, megaco_descriptors_names[token_index].name); /* and display the long form */
2409 }
2410
2411 tvb_offset = tvb_next; /* advance pointer */
2412 }
2413 }
2414}
2415
2416/*
2417 * serviceChangeDescriptor = ServicesToken LBRKT serviceChangeParm
2418 * *(COMMA serviceChangeParm) RBRKT
2419 *
2420 * ServicesToken = ("Services" / "SV")
2421 *
2422 * serviceChangeParm = (serviceChangeMethod / serviceChangeReason /
2423 * serviceChangeDelay / serviceChangeAddress /
2424 * serviceChangeProfile / extension / TimeStamp /
2425 * serviceChangeMgcId / serviceChangeVersion )
2426 *
2427 */
2428#define MEGACO_REASON_TOKEN1 1
2429#define MEGACO_DELAY_TOKEN2 2
2430#define MEGACO_SC_ADDR_TOKEN3 3
2431#define MEGACO_MGC_ID_TOKEN4 4
2432#define MEGACO_PROFILE_TOKEN5 5
2433#define MEGACO_VERSION_TOKEN6 6
2434#define MEGACO_METHOD_TOKEN7 7
2435
2436static const megaco_tokens_t megaco_serviceChangeParm_names[] = {
2437 { "Unknown-token", NULL((void*)0) }, /* 0 Pad so that the real headers start at index 1 */
2438 /* streamMode */
2439 { "Reason", "RE" }, /* 1 ReasonToken*/
2440 { "Delay", "DL" }, /* 2 DelayToken */
2441 { "ServiceChangeAddress", "AD" }, /* 3 ServiceChangeAddressToken */
2442 { "MgcIdToTry", "MG" }, /* 4 MgcIdToken */
2443 { "Profile", "PF" }, /* 5 ProfileToken */
2444 { "Version", "V" }, /* 6 VersionToken */
2445 { "Method", "MT" }, /* 7 MethodToken */
2446};
2447
2448/* Returns index of megaco_tokens_t */
2449static int find_megaco_megaco_serviceChangeParm_names(tvbuff_t *tvb, int offset, unsigned header_len)
2450{
2451 unsigned i;
2452
2453 for (i = 1; i < array_length(megaco_serviceChangeParm_names)(sizeof (megaco_serviceChangeParm_names) / sizeof (megaco_serviceChangeParm_names
)[0])
; i++) {
2454 if (header_len == strlen(megaco_serviceChangeParm_names[i].name) &&
2455 tvb_strncaseeql(tvb, offset, megaco_serviceChangeParm_names[i].name, header_len) == 0)
2456 return i;
2457 if (megaco_serviceChangeParm_names[i].compact_name != NULL((void*)0) &&
2458 header_len == strlen(megaco_serviceChangeParm_names[i].compact_name) &&
2459 tvb_strncaseeql(tvb, offset, megaco_serviceChangeParm_names[i].compact_name, header_len) == 0)
2460 return i;
2461 }
2462
2463 return -1;
2464}
2465/*
2466 * ServiceChangeReasons References
2467 * -------------------- ----------
2468 */
2469static const value_string MEGACO_ServiceChangeReasons_vals[] = {
2470 {900, "Service Restored"},
2471 {901, "Cold Boot"},
2472 {902, "Warm Boot"},
2473 {903, "MGC Directed Change"},
2474 {904, "Termination malfunctioning"},
2475 {905, "Termination taken out of service"},
2476 {906, "Loss of lower layer connectivity (e.g. downstream sync)"},
2477 {907, "Transmission Failure"},
2478 {908, "MG Impending Failure"},
2479 {909, "MGC Impending Failure"},
2480 {910, "Media Capability Failure"},
2481 {911, "Modem Capability Failure"},
2482 {912, "Mux Capability Failure"},
2483 {913, "Signal Capability Failure"},
2484 {914, "Event Capability Failure"},
2485 {915, "State Loss"},
2486 {916, "Packages Change"},
2487 {917, "Capabilities Change"},
2488 {918, "Cancel Graceful"},
2489 {919, "Warm Failover"},
2490 {920, "Cold Failover"},
2491 { 0, NULL((void*)0) }
2492};
2493
2494static void
2495dissect_megaco_servicechangedescriptor(tvbuff_t *tvb, packet_info* pinfo, proto_tree *megaco_tree, int tvb_RBRKT,
2496 int tvb_previous_offset)
2497{
2498
2499 int tokenlen, tvb_LBRKT, tvb_offset;
2500 int token_index;
2501 int tvb_current_offset;
2502 bool_Bool more_params = true1;
2503 proto_item* item;
2504 int reason;
2505 bool_Bool reason_valid;
2506 uint8_t ServiceChangeReason_str[4];
2507
2508 tvb_LBRKT = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2509 /*
2510 if (tvb_LBRKT == -1)
2511 return;
2512 */
2513 tokenlen = (tvb_LBRKT + 1) - tvb_previous_offset;
2514 proto_tree_add_format_text(megaco_tree, tvb, tvb_previous_offset, tokenlen);
2515
2516 /* Start dissecting serviceChangeParm */
2517 tvb_previous_offset = tvb_LBRKT + 1;
2518 while (more_params){
2519 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
2520 /* Find token length */
2521 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_RBRKT; tvb_offset++){
2522 if (!g_ascii_isalpha(tvb_get_uint8(tvb, tvb_offset ))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_offset ))] &
G_ASCII_ALPHA) != 0)
){
2523 break;
2524 }
2525 }
2526 tokenlen = tvb_offset - tvb_previous_offset;
2527 token_index = find_megaco_megaco_serviceChangeParm_names(tvb, tvb_previous_offset, tokenlen);
2528
2529 tvb_offset = tvb_find_uint8(tvb, tvb_offset, tvb_RBRKT, ',');
2530 if ((tvb_offset == -1)||(tvb_offset >=tvb_RBRKT)){
2531 more_params = false0;
2532 tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_RBRKT-1);
2533 }
2534 tokenlen = tvb_offset - tvb_previous_offset;
2535 if (more_params == true1 )
2536 /* Include ',' */
2537 tokenlen++;
2538 switch(token_index){
2539 case MEGACO_REASON_TOKEN1:
2540 /* ReasonToken EQUAL VALUE
2541 * VALUE = quotedString / 1*(SafeChar)
2542 */
2543 item = proto_tree_add_format_text(megaco_tree, tvb, tvb_previous_offset, tokenlen);
2544
2545 /* As the reason code ( if a digit ) can be in quoted string or 'just' digit
2546 * look for a nine and hope for the best.
2547 */
2548 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '9');
2549 if ( tvb_current_offset == -1)
2550 break;
2551
2552 tvb_get_raw_bytes_as_stringz(tvb,tvb_current_offset,4,ServiceChangeReason_str);
2553 reason_valid = ws_strtoi32((char*)ServiceChangeReason_str, NULL((void*)0), &reason);
2554 proto_item_append_text(item,"[ %s ]", val_to_str(pinfo->pool, reason, MEGACO_ServiceChangeReasons_vals,"Unknown (%u)"));
2555 if (!reason_valid)
2556 expert_add_info(pinfo, item, &ei_megaco_reason_invalid);
2557 break;
2558 case MEGACO_DELAY_TOKEN2:
2559 case MEGACO_SC_ADDR_TOKEN3:
2560 case MEGACO_MGC_ID_TOKEN4:
2561 case MEGACO_PROFILE_TOKEN5:
2562 case MEGACO_VERSION_TOKEN6:
2563 case MEGACO_METHOD_TOKEN7:
2564 /* No special dissection: fall through */
2565 default:
2566 /* Unknown or:
2567 * extension = extensionParameter parmValue
2568 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2569 */
2570 proto_tree_add_format_text(megaco_tree, tvb, tvb_previous_offset, tokenlen);
2571 break;
2572 }
2573
2574 tvb_previous_offset = tvb_offset +1;
2575
2576 }/*End while */
2577
2578 /* extension = extensionParameter parmValue
2579 * extensionParameter = "X" ("-" / "+") 1*6(ALPHA / DIGIT)
2580 */
2581
2582 /*
2583 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2584 proto_tree_add_string(megaco_tree_command_line, hf_megaco_servicechange_descriptor, tvb,
2585 tvb_previous_offset, tokenlen,
2586 tvb_format_text(pinfo->pool, tvb, tvb_previous_offset,
2587 tokenlen));
2588 */
2589 proto_tree_add_format_text(megaco_tree, tvb, tvb_RBRKT, 1);
2590
2591}
2592static void
2593dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
2594{
2595
2596 int tokenlen;
2597
2598 tokenlen = tvb_RBRKT - tvb_previous_offset;
2599 proto_tree_add_string(megaco_tree_command_line, hf_megaco_digitmap_descriptor, tvb,
2600 tvb_previous_offset, tokenlen,
2601 tvb_format_text(pinfo->pool, tvb, tvb_previous_offset,
2602 tokenlen));
2603
2604}
2605static void
2606dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
2607{
2608 int tokenlen;
2609 proto_tree *megaco_statisticsdescriptor_tree;
2610 proto_item *megaco_statisticsdescriptor_ti;
2611 int tvb_help_offset, param_start_offset, param_end_offset = 0;
2612
2613 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2614
2615 megaco_statisticsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_statistics_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA0x00000000);
2616 megaco_statisticsdescriptor_tree = proto_item_add_subtree(megaco_statisticsdescriptor_ti, ett_megaco_statisticsdescriptor);
2617
2618 tvb_help_offset = tvb_find_uint8(tvb, tvb_previous_offset+1, tvb_RBRKT, '{');
2619 do {
2620 param_start_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset+1);
2621
2622 tvb_help_offset = tvb_find_uint8(tvb, tvb_help_offset+1, tvb_RBRKT, ',');
2623
2624 if ( tvb_help_offset > tvb_RBRKT || tvb_help_offset == -1){
2625 tvb_help_offset = tvb_RBRKT;
2626 param_end_offset = megaco_tvb_skip_wsp_return(tvb, tvb_RBRKT-1);
2627 tokenlen = param_end_offset - param_start_offset;
2628 } else {
2629 param_end_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset-1);
2630 tokenlen = param_end_offset - param_start_offset+1;
2631 }
2632
2633 proto_tree_add_format_text(megaco_statisticsdescriptor_tree, tvb,param_start_offset, tokenlen);
2634
2635 } while ( tvb_help_offset < tvb_RBRKT );
2636}
2637
2638static void
2639dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset, proto_tree *top_tree)
2640{
2641
2642 int tokenlen, pkg_tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2643 int tvb_observedevents_end_offset, tvb_LBRKT;
2644 proto_tree *megaco_observedeventsdescriptor_tree, *megaco_observedevent_tree;
2645 proto_item *megaco_observedeventsdescriptor_ti, *megaco_observedevent_ti, *ti;
2646
2647 int requested_event_start_offset, requested_event_end_offset, param_start_offset, param_end_offset;
2648
2649 requested_event_start_offset = 0;
2650 requested_event_end_offset = 0;
2651
2652 tvb_LBRKT = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2653 tvb_next_offset = tvb_LBRKT;
2654 tokenlen = (tvb_next_offset+1) - tvb_previous_offset;
2655
2656 megaco_observedeventsdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_observedevents_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_NA0x00000000);
2657 megaco_observedeventsdescriptor_tree = proto_item_add_subtree(megaco_observedeventsdescriptor_ti, ett_megaco_observedeventsdescriptor);
2658
2659 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
2660 tvb_next_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2661
2662 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
2663
2664 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2665 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
2666
2667 tokenlen = tvb_help_offset - tvb_current_offset;
2668
2669 ti = proto_tree_add_uint(megaco_observedeventsdescriptor_tree, hf_megaco_requestid, tvb,
2670 tvb_current_offset, 1,
2671 (uint32_t) strtoul(tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen), NULL((void*)0), 10));
2672 proto_item_set_len(ti, tokenlen);
2673
2674 tvb_observedevents_end_offset = tvb_RBRKT;
2675
2676 tvb_RBRKT = tvb_next_offset+1;
2677 tvb_LBRKT = tvb_next_offset+1;
2678 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
2679
2680
2681 do {
2682
2683 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2684 tvb_observedevents_end_offset, '}');
2685 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT,
2686 tvb_observedevents_end_offset, '{');
2687
2688 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset,
2689 tvb_observedevents_end_offset, ',');
2690
2691 if (tvb_current_offset == -1 || tvb_current_offset > tvb_observedevents_end_offset){
2692 tvb_current_offset = tvb_observedevents_end_offset;
2693 }
2694
2695
2696 /* Descriptor includes no parameters */
2697
2698 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2699
2700 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2701 }
2702
2703 /* Descriptor includes Parameters */
2704
2705 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2706
2707 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2708
2709 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1,
2710 tvb_observedevents_end_offset, '{');
2711 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1){
2712 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2713 tvb_observedevents_end_offset, '}');
2714 }
2715 }
2716
2717 }
2718
2719 tvb_LBRKT = tvb_help_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_observedevents_end_offset, '{');
2720
2721 /* if there are eventparameter */
2722
2723 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2724
2725 requested_event_start_offset = tvb_help_offset;
2726 requested_event_end_offset = tvb_RBRKT;
2727 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_help_offset-1);
2728 pkg_tokenlen = tvb_help_offset - tvb_previous_offset;
2729 tokenlen = tvb_LBRKT+1 - tvb_previous_offset;
2730 }
2731 /* no parameters */
2732 else {
2733 tokenlen = pkg_tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2734 }
2735
2736 megaco_observedevent_ti = proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_previous_offset, tokenlen);
2737
2738 megaco_observedevent_tree = proto_item_add_subtree(megaco_observedevent_ti, ett_megaco_observedevent);
2739
2740 proto_tree_add_item(megaco_observedevent_tree,hf_megaco_pkgdname,tvb,tvb_previous_offset,pkg_tokenlen, ENC_UTF_80x00000002);
2741
2742 if ( tvb_help_offset < tvb_RBRKT && tvb_help_offset != -1 ){
2743
2744 requested_event_start_offset = megaco_tvb_skip_wsp(tvb, requested_event_start_offset +1)-1;
2745 requested_event_end_offset = megaco_tvb_skip_wsp_return(tvb, requested_event_end_offset-1);
2746
2747 tvb_help_offset = requested_event_start_offset;
2748
2749 do {
2750 param_start_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset+1);
2751
2752 tvb_help_offset = tvb_find_uint8(tvb, tvb_help_offset+1,requested_event_end_offset, ',');
2753
2754 if ( tvb_help_offset > requested_event_end_offset || tvb_help_offset == -1){
2755 tvb_help_offset = requested_event_end_offset;
2756 }
2757
2758 param_end_offset = megaco_tvb_skip_wsp(tvb, tvb_help_offset-1);
2759
2760 tokenlen = param_end_offset - param_start_offset+1;
2761 if(!tvb_strneql(tvb, param_start_offset, "h245", 4)){
2762 dissect_megaco_h245(tvb, pinfo, megaco_tree_command_line, param_start_offset, tokenlen, top_tree);
2763 } else {
2764 proto_tree_add_format_text(megaco_tree_command_line, tvb, param_start_offset, tokenlen);
2765 }
2766
2767
2768 } while ( tvb_help_offset < requested_event_end_offset );
2769 }
2770
2771 tvb_previous_offset = tvb_current_offset;
2772 tvb_current_offset = tvb_find_uint8(tvb, tvb_RBRKT,
2773 tvb_observedevents_end_offset, ',');
2774
2775 if (tvb_current_offset == -1 || tvb_current_offset > tvb_observedevents_end_offset ){
2776 tvb_current_offset = tvb_observedevents_end_offset;
2777 }
2778 if (tvb_current_offset < tvb_previous_offset) {
2779 expert_add_info_format(pinfo, megaco_observedevent_ti, &ei_megaco_parse_error, "Parse error: Invalid offset");
2780 return;
2781 }
2782
2783 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2784
2785 tvb_LBRKT = tvb_previous_offset;
2786 tvb_RBRKT = tvb_previous_offset;
2787 /* Print the trailing '}' (raw formatting removed) */
2788 /* proto_tree_add_format_text(megaco_tree_command_line, tvb, tvb_observedevents_end_offset, 1); */
2789
2790 } while ( tvb_current_offset < tvb_observedevents_end_offset );
2791 }
2792}
2793static void
2794dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
2795{
2796
2797 int tokenlen;
2798
2799 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2800 proto_tree_add_item(megaco_tree_command_line, hf_megaco_topology_descriptor, tvb,
2801 tvb_previous_offset, tokenlen, ENC_ASCII0x00000000);
2802
2803}
2804static void
2805dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_tree_command_line, int tvb_RBRKT, int tvb_previous_offset)
2806{
2807
2808 int tokenlen, tvb_current_offset, tvb_next_offset, tvb_help_offset;
2809 int tvb_packages_end_offset, tvb_LBRKT;
2810 proto_tree *megaco_packagesdescriptor_tree;
2811 proto_item *megaco_packagesdescriptor_ti, *ti;
2812
2813 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
2814
2815 megaco_packagesdescriptor_ti = proto_tree_add_item(megaco_tree_command_line,hf_megaco_packages_descriptor,tvb,tvb_previous_offset,tokenlen, ENC_UTF_80x00000002);
2816 megaco_packagesdescriptor_tree = proto_item_add_subtree(megaco_packagesdescriptor_ti, ett_megaco_packagesdescriptor);
2817
2818 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '=');
2819 tvb_next_offset = tvb_find_uint8(tvb, tvb_previous_offset, tvb_RBRKT, '{');
2820
2821 if ( tvb_current_offset < tvb_RBRKT && tvb_current_offset != -1 ){
2822
2823 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
2824 tvb_help_offset = megaco_tvb_skip_wsp_return(tvb, tvb_next_offset-1);
2825
2826 tokenlen = tvb_help_offset - tvb_current_offset;
2827
2828 ti = proto_tree_add_uint(megaco_packagesdescriptor_tree, hf_megaco_requestid, tvb,
2829 tvb_current_offset, 1,
2830 (uint32_t) strtoul(tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen), NULL((void*)0), 10));
2831 proto_item_set_len(ti, tokenlen);
2832
2833 tvb_packages_end_offset = tvb_RBRKT;
2834
2835 tvb_RBRKT = tvb_next_offset+1;
2836 tvb_LBRKT = tvb_next_offset+1;
2837 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_next_offset+1);
2838
2839
2840 do {
2841
2842 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2843 tvb_packages_end_offset, '}');
2844 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT,
2845 tvb_packages_end_offset, '{');
2846
2847 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset,
2848 tvb_packages_end_offset, ',');
2849
2850 if (tvb_current_offset == -1 || tvb_current_offset > tvb_packages_end_offset){
2851 tvb_current_offset = tvb_packages_end_offset;
2852 }
2853
2854
2855 /* Descriptor includes no parameters */
2856
2857 if ( tvb_LBRKT > tvb_current_offset || tvb_LBRKT == -1 ){
2858
2859 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
2860 }
2861
2862 /* Descriptor includes Parameters */
2863
2864 if ( (tvb_current_offset > tvb_LBRKT && tvb_LBRKT != -1)){
2865
2866 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
2867
2868 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1,
2869 tvb_packages_end_offset, '{');
2870 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
2871 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1,
2872 tvb_packages_end_offset, '}');
2873 }
2874
2875 }
2876
2877 tokenlen = tvb_RBRKT+1 - tvb_previous_offset;
2878
2879 proto_tree_add_format_text(megaco_packagesdescriptor_tree, tvb, tvb_previous_offset, tokenlen);
2880
2881 tvb_current_offset = tvb_find_uint8(tvb, tvb_RBRKT,
2882 tvb_packages_end_offset, ',');
2883
2884 if (tvb_current_offset == -1 || tvb_current_offset > tvb_packages_end_offset ){
2885 tvb_current_offset = tvb_packages_end_offset;
2886 }
2887
2888 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
2889
2890 tvb_LBRKT = tvb_previous_offset;
2891 tvb_RBRKT = tvb_previous_offset;
2892
2893 } while ( tvb_current_offset < tvb_packages_end_offset );
2894 }
2895
2896}
2897/* The list of error code values is fetched from http://www.iana.org/assignments/megaco-h248 */
2898/* 2003-08-28 */
2899
2900static const value_string MEGACO_error_code_vals[] = {
2901
2902 {400, "Syntax error in message"},
2903 {401, "Protocol Error"},
2904 {402, "Unauthorized"},
2905 {403, "Syntax error in transaction request"},
2906 {406, "Version Not Supported"},
2907 {410, "Incorrect identifier"},
2908 {411, "The transaction refers to an unknown ContextId"},
2909 {412, "No ContextIDs available"},
2910 {421, "Unknown action or illegal combination of actions"},
2911 {422, "Syntax Error in Action"},
2912 {430, "Unknown TerminationID"},
2913 {431, "No TerminationID matched a wildcard"},
2914 {432, "Out of TerminationIDs or No TerminationID available"},
2915 {433, "TerminationID is already in a Context"},
2916 {434, "Max number of Terminations in a Context exceeded"},
2917 {435, "Termination ID is not in specified Context"},
2918 {440, "Unsupported or unknown Package"},
2919 {441, "Missing Remote or Local Descriptor"},
2920 {442, "Syntax Error in Command"},
2921 {443, "Unsupported or Unknown Command"},
2922 {444, "Unsupported or Unknown Descriptor"},
2923 {445, "Unsupported or Unknown Property"},
2924 {446, "Unsupported or Unknown Parameter"},
2925 {447, "Descriptor not legal in this command"},
2926 {448, "Descriptor appears twice in a command"},
2927 {450, "No such property in this package"},
2928 {451, "No such event in this package"},
2929 {452, "No such signal in this package"},
2930 {453, "No such statistic in this package"},
2931 {454, "No such parameter value in this package"},
2932 {455, "Property illegal in this Descriptor"},
2933 {456, "Property appears twice in this Descriptor"},
2934 {457, "Missing parameter in signal or event"},
2935 {458, "Unexpected Event/Request ID"},
2936 {459, "Unsupported or Unknown Profile"},
2937 {471, "Implied Add for Multiplex failure"},
2938
2939 {500, "Internal software Failure in MG"},
2940 {501, "Not Implemented"},
2941 {502, "Not ready."},
2942 {503, "Service Unavailable"},
2943 {504, "Command Received from unauthorized entity"},
2944 {505, "Transaction Request Received before a Service Change Reply has been received"},
2945 {506, "Number of Transaction Pendings Exceeded"},
2946 {510, "Insufficient resources"},
2947 {512, "Media Gateway unequipped to detect requested Event"},
2948 {513, "Media Gateway unequipped to generate requested Signals"},
2949 {514, "Media Gateway cannot send the specified announcement"},
2950 {515, "Unsupported Media Type"},
2951 {517, "Unsupported or invalid mode"},
2952 {518, "Event buffer full"},
2953 {519, "Out of space to store digit map"},
2954 {520, "Digit Map undefined in the MG"},
2955 {521, "Termination is ServiceChanging"},
2956 {526, "Insufficient bandwidth"},
2957 {529, "Internal hardware failure in MG"},
2958 {530, "Temporary Network failure"},
2959 {531, "Permanent Network failure"},
2960 {532, "Audited Property, Statistic, Event or Signal does not exist"},
2961 {533, "Response exceeds maximum transport PDU size"},
2962 {534, "Illegal write or read only property"},
2963 {540, "Unexpected initial hook state"},
2964 {581, "Does Not Exist"},
2965
2966 {600, "Illegal syntax within an announcement specification"},
2967 {601, "Variable type not supported"},
2968 {602, "Variable value out of range"},
2969 {603, "Category not supported"},
2970 {604, "Selector type not supported"},
2971 {605, "Selector value not supported"},
2972 {606, "Unknown segment ID"},
2973 {607, "Mismatch between play specification and provisioned data"},
2974 {608, "Provisioning error"},
2975 {609, "Invalid offset"},
2976 {610, "No free segment IDs"},
2977 {611, "Temporary segment not found"},
2978 {612, "Segment in use"},
2979 {613, "ISP port limit overrun"},
2980 {614, "No modems available"},
2981 {615, "Calling number unacceptable"},
2982 {616, "Called number unacceptable"},
2983 { 0, NULL((void*)0) }
2984};
2985
2986
2987
2988static void
2989dissect_megaco_errordescriptor(tvbuff_t *tvb, packet_info* pinfo, proto_tree *megaco_tree_command_line,
2990 int tvb_RBRKT, int tvb_previous_offset)
2991{
2992
2993 int tokenlen;
2994 int error_code;
2995 uint8_t error[4];
2996 int tvb_current_offset;
2997 proto_item* item;
2998 proto_tree* error_tree;
2999 bool_Bool error_code_valid;
3000
3001 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset , tvb_RBRKT, '=');
3002 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
3003
3004 tokenlen = (tvb_RBRKT) - tvb_previous_offset+1;
3005
3006 item = proto_tree_add_item(megaco_tree_command_line, hf_megaco_error_descriptor, tvb,
3007 tvb_previous_offset, tokenlen, ENC_NA0x00000000);
3008 error_tree = proto_item_add_subtree(item, ett_megaco_error_descriptor);
3009
3010 /* Get the error code */
3011 tvb_get_raw_bytes_as_stringz(tvb,tvb_current_offset,4,error);
3012 error_code_valid = ws_strtoi32((char*)error, NULL((void*)0), &error_code);
3013 item = proto_tree_add_uint(error_tree, hf_megaco_error_code, tvb, tvb_current_offset, 3, error_code);
3014 if (!error_code_valid)
3015 expert_add_info(pinfo, item, &ei_megaco_error_code_invalid);
3016
3017 /* Get the error string (even though we have a value_string that should match) */
3018 tvb_previous_offset = tvb_find_uint8(tvb, tvb_current_offset, tvb_RBRKT, '\"');
3019 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset+1, tvb_RBRKT, '\"');
3020
3021 tokenlen = tvb_current_offset - tvb_previous_offset-1;
3022 proto_tree_add_item(error_tree, hf_megaco_error_string, tvb, tvb_previous_offset+1, tokenlen, ENC_UTF_80x00000002);
3023}
3024static void
3025dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *megaco_mediadescriptor_tree, int tvb_next_offset, int tvb_current_offset)
3026{
3027 int tokenlen;
3028 int tvb_offset;
3029 uint8_t tempchar;
3030
3031 proto_tree *megaco_TerminationState_tree, *megaco_TerminationState_ti;
3032
3033 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_next_offset, '=');
3034
3035 tokenlen = tvb_next_offset - tvb_current_offset;
3036 megaco_TerminationState_ti = proto_tree_add_item(megaco_mediadescriptor_tree,hf_megaco_TerminationState_descriptor,tvb,tvb_current_offset,tokenlen, ENC_NA0x00000000);
3037 megaco_TerminationState_tree = proto_item_add_subtree(megaco_TerminationState_ti, ett_megaco_TerminationState);
3038
3039 while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){
3040
3041 tempchar = tvb_get_uint8(tvb, tvb_current_offset);
3042 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3043 if ( (tempchar >= 'a')&& (tempchar <= 'z'))
3044 tempchar = tempchar - 0x20;
3045
3046 switch ( tempchar ){
3047
3048 case 'S':
3049 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_offset, ',');
3050 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3051 tvb_offset = tvb_next_offset;
3052 }
3053
3054 tokenlen = tvb_offset - tvb_current_offset;
3055
3056 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Service_State, tvb,
3057 tvb_current_offset, tokenlen,
3058 tvb_format_text(pinfo->pool, tvb, tvb_current_offset,
3059 tokenlen));
3060
3061 break;
3062
3063 case 'B':
3064
3065 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_offset, ',');
3066 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3067 tvb_offset = tvb_next_offset;
3068 }
3069
3070 tokenlen = tvb_offset - tvb_current_offset;
3071
3072 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Event_Buffer_Control, tvb,
3073 tvb_current_offset, tokenlen,
3074 tvb_format_text(pinfo->pool, tvb, tvb_current_offset,
3075 tokenlen));
3076
3077 break;
3078
3079 case 'E':
3080 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_offset, ',');
3081 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3082 tvb_offset = tvb_next_offset;
3083 }
3084
3085 tokenlen = tvb_offset - tvb_current_offset;
3086
3087 proto_tree_add_string(megaco_TerminationState_tree, hf_megaco_Event_Buffer_Control, tvb,
3088 tvb_current_offset, tokenlen,
3089 tvb_format_text(pinfo->pool, tvb, tvb_current_offset,
3090 tokenlen));
3091
3092 break;
3093
3094 default:
3095 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_offset, ',');
3096 if ( tvb_offset == -1 || tvb_offset > tvb_next_offset ){
3097 tvb_offset = tvb_next_offset;
3098 }
3099
3100 tokenlen = tvb_offset - tvb_current_offset;
3101
3102 proto_tree_add_format_text(megaco_TerminationState_tree, tvb, tvb_current_offset, tokenlen);
3103 break;
3104 }
3105
3106
3107 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3108 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_next_offset, '=');
3109
3110 }
3111 /* (raw formatting removed)
3112 proto_tree_add_format_text(megaco_mediadescriptor_tree, tvb, tvb_next_offset, 1); */
3113}
3114
3115static void
3116dissect_megaco_LocalRemotedescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, packet_info *pinfo,
3117 int tvb_next_offset, int tvb_current_offset, uint32_t context, bool_Bool is_local)
3118{
3119 int tokenlen;
3120 tvbuff_t *next_tvb;
3121 media_content_info_t content_info = { MEDIA_CONTAINER_SIP_DATA, NULL((void*)0), NULL((void*)0), NULL((void*)0) };
3122
3123 sdp_setup_info_t setup_info;
3124
3125 /* Only fill in the info when we have valid contex */
3126 if ((context != 0) && (context < 0xfffffffe)) {
3127 setup_info = (sdp_setup_info_t){
3128 .hf_id = hf_megaco_Context_generated,
3129 .hf_type = SDP_TRACE_ID_HF_TYPE_UINT32,
3130 .trace_id.num = context,
3131 };
3132 if (!sip_hide_generated_call_ids) {
3133 setup_info.add_hidden = false0;
3134 } else {
3135 setup_info.add_hidden = prefs_get_bool_value(sip_hide_generated_call_ids, pref_current);
3136 }
3137 content_info.data = &setup_info;
3138 }
3139
3140 proto_tree *megaco_localdescriptor_tree;
3141 proto_item *megaco_localdescriptor_item;
3142
3143 tokenlen = tvb_next_offset - tvb_current_offset;
3144
3145 if (is_local) {
3146 megaco_localdescriptor_item = proto_tree_add_item(megaco_mediadescriptor_tree, hf_megaco_Local_descriptor, tvb, tvb_current_offset, tokenlen, ENC_NA0x00000000);
3147 megaco_localdescriptor_tree = proto_item_add_subtree(megaco_localdescriptor_item, ett_megaco_Localdescriptor);
3148 } else {
3149 megaco_localdescriptor_item = proto_tree_add_item(megaco_mediadescriptor_tree, hf_megaco_Remote_descriptor, tvb, tvb_current_offset, tokenlen, ENC_NA0x00000000);
3150 megaco_localdescriptor_tree = proto_item_add_subtree(megaco_localdescriptor_item, ett_megaco_Remotedescriptor);
3151 }
3152
3153 if ( tokenlen > 3 ){
3154 next_tvb = tvb_new_subset_length(tvb, tvb_current_offset, tokenlen);
3155 call_dissector_with_data(sdp_handle, next_tvb, pinfo, megaco_localdescriptor_tree, &content_info);
3156 }
3157}
3158
3159/*
3160 * localControlDescriptor = LocalControlToken LBRKT localParm
3161 * *(COMMA localParm) RBRKT
3162 * ; at-most-once per item
3163 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3164 */
3165
3166#define MEGACO_MODETOKEN1 1
3167#define MEGACO_RESERVEDVALUETOKEN2 2
3168#define MEGACO_RESERVEDGROUPTOKEN3 3
3169#define MEGACO_H324_H223CAPR4 4
3170#define MEGACO_H324_MUXTBL_IN5 5
3171#define MEGACO_H324_MUXTBL_OUT6 6
3172#define MEGACO_DS_DSCP7 7
3173#define MEGACO_GM_SAF8 8
3174#define MEGACO_GM_SAM9 9
3175#define MEGACO_GM_SPF10 10
3176#define MEGACO_GM_SPR11 11
3177#define MEGACO_GM_ESAS12 12
3178#define MEGACO_GM_LSA13 13
3179#define MEGACO_GM_ESPS14 14
3180#define MEGACO_GM_LSP15 15
3181#define MEGACO_GM_RSB16 16
3182#define MEGACO_TMAN_POL17 17
3183#define MEGACO_TMAN_SDR18 18
3184#define MEGACO_TMAN_MBS19 19
3185#define MEGACO_TMAN_PDR20 20
3186#define MEGACO_TMAN_DVT21 21
3187#define MEGACO_IPDC_REALM22 22
3188
3189static const megaco_tokens_t megaco_localParam_names[] = {
3190 { "Unknown-token", NULL((void*)0) }, /* 0 Pad so that the real headers start at index 1 */
3191 /* streamMode */
3192 { "Mode", "MO" }, /* 1 */
3193 { "ReservedValue", "RV" }, /* 2 */
3194 { "ReservedGroup", "RG" }, /* 3 */
3195 /* propertyParm = pkgdName parmValue
3196 * Add more package names as needed.
3197 */
3198 { "h324/h223capr", NULL((void*)0) }, /* 4 */
3199 { "h324/muxtbl_in", NULL((void*)0) }, /* 5 */
3200 { "h324/muxtbl_out", NULL((void*)0) }, /* 6 */
3201 { "ds/dscp", NULL((void*)0) }, /* 7 */
3202 { "gm/saf", NULL((void*)0) }, /* 8 */
3203 { "gm/sam", NULL((void*)0) }, /* 9 */
3204 { "gm/spf", NULL((void*)0) }, /* 10 */
3205 { "gm/spr", NULL((void*)0) }, /* 11 */
3206 { "gm/esas", NULL((void*)0) }, /* 12 */
3207 { "gm/lsa", NULL((void*)0) }, /* 13 */
3208 { "gm/esps", NULL((void*)0) }, /* 14 */
3209 { "gm/lsp", NULL((void*)0) }, /* 15 */
3210 { "gm/rsb", NULL((void*)0) }, /* 16 */
3211 { "tman/pol", NULL((void*)0) }, /* 17 */
3212 { "tman/sdr", NULL((void*)0) }, /* 18 */
3213 { "tman/mbs", NULL((void*)0) }, /* 19 */
3214 { "tman/pdr", NULL((void*)0) }, /* 20 */
3215 { "tman/dvt", NULL((void*)0) }, /* 21 */
3216 { "ipdc/realm", NULL((void*)0) }, /* 22 */
3217};
3218
3219/* Returns index of megaco_tokens_t */
3220static int find_megaco_localParam_names(tvbuff_t *tvb, int offset, unsigned header_len)
3221{
3222 unsigned i;
3223
3224 for (i = 1; i < array_length(megaco_localParam_names)(sizeof (megaco_localParam_names) / sizeof (megaco_localParam_names
)[0])
; i++) {
3225 if (header_len == strlen(megaco_localParam_names[i].name) &&
3226 tvb_strncaseeql(tvb, offset, megaco_localParam_names[i].name, header_len) == 0)
3227 return i;
3228 if (megaco_localParam_names[i].compact_name != NULL((void*)0) &&
3229 header_len == strlen(megaco_localParam_names[i].compact_name) &&
3230 tvb_strncaseeql(tvb, offset, megaco_localParam_names[i].compact_name, header_len) == 0)
3231 return i;
3232 }
3233
3234 return -1;
3235}
3236
3237static void
3238dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *megaco_mediadescriptor_tree, packet_info *pinfo, int tvb_next_offset, int tvb_current_offset, proto_tree *top_tree)
3239{
3240 int tokenlen;
3241 unsigned token_name_len;
3242 int tvb_offset = 0,tvb_help_offset;
3243 int token_index = 0;
3244 char *msg;
3245 proto_item* item;
3246 uint8_t code_str[3];
3247
3248 proto_tree *megaco_LocalControl_tree;
3249 proto_item *megaco_LocalControl_item;
3250
3251 tokenlen = tvb_next_offset - tvb_current_offset;
3252
3253 megaco_LocalControl_item = proto_tree_add_item(megaco_mediadescriptor_tree, hf_megaco_LocalControl_descriptor, tvb, tvb_current_offset, tokenlen, ENC_NA0x00000000);
3254 megaco_LocalControl_tree = proto_item_add_subtree(megaco_LocalControl_item, ett_megaco_LocalControldescriptor);
3255
3256 while ( tvb_offset < tvb_next_offset && tvb_offset != -1 ){
3257
3258 tvb_help_offset = tvb_current_offset;
3259
3260 /*
3261 * Find local parameter name
3262 * localParm = ( streamMode / propertyParm / reservedValueMode / reservedGroupMode )
3263 * pkgdName = (PackageName SLASH ItemID) ;specific item
3264 * / (PackageName SLASH "*") ;all events in package
3265 * / ("*" SLASH "*") ; all events supported by the MG
3266 */
3267 /* Find token length */
3268 for (tvb_offset=tvb_current_offset; tvb_offset < tvb_next_offset; tvb_offset++){
3269 uint8_t octet;
3270 octet = tvb_get_uint8(tvb, tvb_offset);
3271 if (!g_ascii_isalnum(octet)((g_ascii_table[(guchar) (octet)] & G_ASCII_ALNUM) != 0)){
3272 if ((octet!='/')&&(octet!='_')){
3273 break;
3274 }
3275 }
3276 }
3277 token_name_len = tvb_offset - tvb_current_offset;
3278 /* Debug Code
3279 proto_tree_add_format_text(megaco_LocalControl_tree, tvb, tvb_current_offset, token_name_len);
3280 */
3281 token_index = find_megaco_localParam_names(tvb, tvb_current_offset, token_name_len);
3282 /* Find start of parameter value */
3283 tvb_offset = tvb_find_uint8(tvb, tvb_offset , tvb_next_offset, '=');
3284 if (tvb_offset == -1) {
3285 expert_add_info(pinfo, megaco_LocalControl_item, &ei_megaco_parse_error);
3286 return;
3287 }
3288 /* Start search after '=' in case there is no SP*/
3289 tvb_offset++;
3290 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
3291
3292 /* find if there are more parameters or not */
3293 tvb_offset = tvb_find_uint8(tvb, tvb_current_offset , tvb_offset, ',');
3294 if ( tvb_offset < 0 || tvb_offset > tvb_next_offset ){
3295 tvb_offset = tvb_next_offset;
3296 }
3297
3298 tokenlen = megaco_tvb_skip_wsp_return(tvb,tvb_offset-1) - tvb_current_offset;
3299 /* Debug Code
3300 proto_tree_add_format_text(megaco_LocalControl_tree, tvb, tvb_current_offset, tokenlen);
3301 */
3302 switch ( token_index ){
3303
3304 case MEGACO_MODETOKEN1: /* Mode */
3305 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_mode, tvb,
3306 tvb_help_offset, tvb_offset-tvb_help_offset,
3307 tvb_format_text(pinfo->pool, tvb, tvb_current_offset,
3308 tokenlen));
3309 col_append_fstr(pinfo->cinfo, COL_INFO, " (Mode:%s)",tvb_format_text(pinfo->pool, tvb, tvb_current_offset,tokenlen));
3310 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3311 break;
3312
3313 case MEGACO_RESERVEDVALUETOKEN2: /* ReservedValue */
3314 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_reserve_value, tvb,
3315 tvb_help_offset, tvb_offset-tvb_help_offset,
3316 tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3317
3318 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3319 break;
3320 case MEGACO_RESERVEDGROUPTOKEN3: /* ReservedGroup */
3321 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_reserve_group, tvb,
3322 tvb_help_offset, tvb_offset-tvb_help_offset,
3323 tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3324 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3325 break;
3326
3327 case MEGACO_H324_H223CAPR4: /* h324/h223capr */
3328 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_h223capr, tvb,
3329 tvb_help_offset, tvb_offset-tvb_help_offset,
3330 tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3331
3332 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3333 tokenlen = tvb_offset - tvb_help_offset;
3334 msg=tvb_format_text(pinfo->pool, tvb,tvb_help_offset, tokenlen);
3335 dissect_megaco_h324_h223caprn(tvb, pinfo, megaco_mediadescriptor_tree, tvb_help_offset, tokenlen, msg);
3336
3337 break;
3338
3339 case MEGACO_H324_MUXTBL_IN5: /* h324/muxtbl_in */
3340
3341 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_muxtbl_in, tvb,
3342 tvb_help_offset, tvb_offset-tvb_help_offset,
3343 tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3344
3345 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3346
3347 tokenlen = tvb_offset - tvb_help_offset;
3348 /* Call the existing routine with tree = NULL to avoid an entry to the tree */
3349 dissect_megaco_h245(tvb, pinfo, NULL((void*)0), tvb_help_offset, tokenlen, top_tree);
3350
3351 break;
3352
3353 case MEGACO_H324_MUXTBL_OUT6:
3354
3355 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_h324_muxtbl_out, tvb,
3356 tvb_current_offset, tokenlen,
3357 tvb_format_text(pinfo->pool, tvb, tvb_current_offset,
3358 tokenlen));
3359
3360 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3361
3362 tokenlen = tvb_offset - tvb_help_offset;
3363 /* Call the existing routine with tree = NULL to avoid an entry to the tree */
3364 dissect_megaco_h245(tvb, pinfo, NULL((void*)0), tvb_help_offset, tokenlen, top_tree);
3365
3366 break;
3367
3368 case MEGACO_DS_DSCP7:
3369 tvb_get_raw_bytes_as_stringz(tvb,tvb_current_offset,3,code_str);
3370 item = proto_tree_add_uint(megaco_LocalControl_tree, hf_megaco_ds_dscp, tvb,
3371 tvb_help_offset, 1, (uint32_t) strtoul((char*)code_str,NULL((void*)0),16));
3372 proto_item_set_len(item, tvb_offset-tvb_help_offset);
3373 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3374 break;
3375
3376 case MEGACO_GM_SAF8:
3377 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_saf, tvb,
3378 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3379 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3380 break;
3381 case MEGACO_GM_SAM9:
3382 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_sam, tvb,
3383 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3384 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3385 break;
3386 case MEGACO_GM_SPF10:
3387 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_spf, tvb,
3388 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3389 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3390 break;
3391 case MEGACO_GM_SPR11:
3392 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_spr, tvb,
3393 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3394 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3395 break;
3396 case MEGACO_GM_ESAS12:
3397 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_esas, tvb,
3398 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3399 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3400 break;
3401 case MEGACO_GM_RSB16:
3402 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_gm_rsb, tvb,
3403 tvb_help_offset, tvb_offset - tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3404 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset + 1);
3405 break;
3406 case MEGACO_TMAN_POL17:
3407 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_pol, tvb,
3408 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3409 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3410 break;
3411 case MEGACO_TMAN_SDR18:
3412 {
3413 int32_t sdr;
3414 bool_Bool sdr_valid;
3415 proto_item* pi;
3416
3417 sdr_valid = ws_strtoi32(tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen), NULL((void*)0), &sdr);
3418 pi =proto_tree_add_int(megaco_LocalControl_tree, hf_megaco_tman_sdr, tvb, tvb_help_offset,
3419 tvb_offset - tvb_help_offset, sdr);
3420 proto_item_append_text(pi, " [%i b/s]", sdr*8);
3421 if (!sdr_valid) {
3422 expert_add_info(pinfo, pi, &ei_megaco_invalid_sdr);
3423 }
3424 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset + 1);
3425 }
3426 break;
3427 case MEGACO_TMAN_MBS19:
3428 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_mbs, tvb,
3429 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3430 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3431 break;
3432 case MEGACO_TMAN_PDR20:
3433 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_pdr, tvb,
3434 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3435 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3436 break;
3437 case MEGACO_TMAN_DVT21:
3438 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_tman_dvt, tvb,
3439 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3440 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3441 break;
3442 case MEGACO_IPDC_REALM22:
3443 proto_tree_add_string(megaco_LocalControl_tree, hf_megaco_ipdc_realm, tvb,
3444 tvb_help_offset, tvb_offset-tvb_help_offset, tvb_format_text(pinfo->pool, tvb, tvb_current_offset, tokenlen));
3445 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3446 break;
3447
3448 default:
3449 tokenlen = tvb_offset - tvb_help_offset;
3450 proto_tree_add_format_text(megaco_LocalControl_tree, tvb, tvb_help_offset, tokenlen);
3451 tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_offset +1);
3452
3453 break;
3454 }
3455 }
3456}
3457
3458static void
3459dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *megaco_command_tree, packet_info *pinfo, proto_tree *top_tree, uint32_t context)
3460{
3461 int tvb_len, token_index, tvb_offset, temp_offset;
3462 int tvb_current_offset,tvb_previous_offset,save_offset,tokenlen;
3463 int tvb_RBRKT, tvb_LBRKT;
3464 proto_tree* descriptor_tree;
3465 proto_item* descriptor_item;
3466
3467 tvb_len = tvb_reported_length(tvb);
3468 int tvb_descriptors_end_offset = tvb_len - 1;
3469
3470 descriptor_tree = proto_tree_add_subtree(megaco_command_tree, tvb, 0, tvb_len,
3471 ett_megaco_descriptors, &descriptor_item, "Descriptors");
3472
3473 tvb_LBRKT = megaco_tvb_skip_wsp(tvb, 1);
3474
3475 tvb_previous_offset = tvb_LBRKT;
3476 tvb_RBRKT = 0;
3477
3478 do {
3479 /* Find the end of this descriptor / start of next. */
3480 tvb_current_offset = tvb_find_uint8(tvb, tvb_previous_offset,
3481 tvb_len, ',');
3482
3483 if (tvb_current_offset == -1) {
3484 tvb_current_offset = tvb_descriptors_end_offset;
3485 }
3486 if (tvb_current_offset <= tvb_previous_offset) {
3487 expert_add_info_format(pinfo, descriptor_item, &ei_megaco_parse_error, "Parse error: Invalid offset");
3488 return;
3489 }
3490
3491 /* Look for parameters in the next description */
3492 tvb_LBRKT = tvb_find_uint8(tvb, tvb_previous_offset,
3493 tvb_current_offset - tvb_previous_offset, '{');
3494 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1, tvb_len, '}');
3495 if (tvb_RBRKT == -1)
3496 tvb_RBRKT = tvb_descriptors_end_offset;
3497
3498 if (tvb_LBRKT == -1) {
3499 /* Descriptor includes no parameters */
3500 if (tvb_current_offset > tvb_RBRKT){
3501 tvb_current_offset = tvb_RBRKT;
3502 }
3503 tvb_RBRKT = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1)-1;
3504 } else {
3505 /* Descriptor includes Parameters */
3506 while ( tvb_LBRKT != -1 && tvb_RBRKT > tvb_LBRKT ){
3507
3508 tvb_LBRKT = tvb_find_uint8(tvb, tvb_LBRKT+1, tvb_len, '{');
3509 if ( tvb_LBRKT < tvb_RBRKT && tvb_LBRKT != -1)
3510 tvb_RBRKT = tvb_find_uint8(tvb, tvb_RBRKT+1, tvb_len, '}');
3511 }
3512 }
3513 if (tvb_RBRKT == -1)
3514 tvb_RBRKT = tvb_descriptors_end_offset;
3515
3516 /* Find token length */
3517 for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_descriptors_end_offset; tvb_offset++){
3518 if (!g_ascii_isalpha(tvb_get_uint8(tvb, tvb_offset ))((g_ascii_table[(guchar) (tvb_get_uint8(tvb, tvb_offset ))] &
G_ASCII_ALPHA) != 0)
){
3519 break;
3520 }
3521 }
3522 tokenlen = tvb_offset - tvb_previous_offset;
3523 token_index = find_megaco_descriptors_names(tvb, tvb_previous_offset, tokenlen);
3524 switch ( token_index ){
3525 case MEGACO_MODEM_TOKEN1:
3526 dissect_megaco_modemdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3527 break;
3528 case MEGACO_MUX_TOKEN2:
3529 dissect_megaco_multiplexdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3530 break;
3531 case MEGACO_MEDIA_TOKEN3:
3532 /*TODO: Move this to the top when all branches fixed !!!*/
3533 temp_offset = tvb_find_uint8(tvb, tvb_previous_offset,tvb_descriptors_end_offset, '{');
3534 save_offset = tvb_previous_offset;
3535
3536 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, temp_offset +1);
3537 dissect_megaco_mediadescriptor(tvb, descriptor_tree, pinfo, tvb_RBRKT, tvb_previous_offset, save_offset, top_tree, context);
3538 break;
3539 case MEGACO_SIGNALS_TOKEN4:
3540 dissect_megaco_signaldescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree);
3541 break;
3542 case MEGACO_SERVICES_TOKEN5:
3543 dissect_megaco_servicechangedescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3544 break;
3545 case MEGACO_STATS_TOKEN6:
3546 dissect_megaco_statisticsdescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3547 break;
3548 case MEGACO_ERROR_TOKEN7:
3549 dissect_megaco_errordescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3550 break;
3551 case MEGACO_EVENTS_TOKEN8:
3552 dissect_megaco_eventsdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree);
3553 break;
3554 case MEGACO_AUDIT_TOKEN9:
3555 dissect_megaco_auditdescriptor(tvb, descriptor_tree, pinfo, tvb_RBRKT, tvb_previous_offset, top_tree, context);
3556 break;
3557 case MEGACO_DIGITMAP_TOKEN10:
3558 dissect_megaco_digitmapdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3559 break;
3560 case MEGACO_OE_TOKEN11:
3561 /* ObservedEventsToken */
3562 dissect_megaco_observedeventsdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset, top_tree);
3563 break;
3564 case MEGACO_TOPOLOGY_TOKEN12:
3565 dissect_megaco_topologydescriptor(tvb, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3566 break;
3567 case MEGACO_PACKAGES_TOKEN13:
3568 dissect_megaco_Packagesdescriptor(tvb, pinfo, descriptor_tree, tvb_RBRKT, tvb_previous_offset);
3569 break;
3570 default:
3571 tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
3572 proto_tree_add_expert(descriptor_tree, pinfo, &ei_megaco_no_descriptor, tvb, tvb_previous_offset, tokenlen);
3573 break;
3574 }
3575
3576 tvb_current_offset = tvb_find_uint8(tvb, tvb_RBRKT, tvb_len, ',');
3577 if (tvb_current_offset == -1) {
3578 tvb_current_offset = tvb_descriptors_end_offset;
3579 }
3580 tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset+1);
3581 tvb_LBRKT = tvb_previous_offset;
Value stored to 'tvb_LBRKT' is never read
3582 tvb_RBRKT = tvb_previous_offset;
3583
3584 } while ( tvb_current_offset < tvb_descriptors_end_offset );
3585
3586}
3587
3588/* Copied from MGCP dissector, prints whole message in raw text */
3589
3590static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree){
3591
3592 int tvb_linebegin,tvb_lineend,linelen;
3593 proto_tree* text_tree;
3594
3595 tvb_linebegin = 0;
3596
3597 if (tree) {
3598 text_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_megaco_raw_text, NULL((void*)0), "-------------- (RAW text output) ---------------");
3599
3600 do {
3601 linelen = tvb_find_line_end(tvb,tvb_linebegin,-1,&tvb_lineend,false0);
3602 proto_tree_add_format_wsp_text(text_tree, tvb, tvb_linebegin, linelen);
3603 tvb_linebegin = tvb_lineend;
3604 } while (tvb_offset_exists(tvb, tvb_lineend) && linelen > 0);
3605 }
3606}
3607
3608/*
3609* megaco_tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3610* character following offset or offset + maxlength -1 whichever
3611* is smaller.
3612*
3613* Parameters:
3614* tvb - The tvbuff in which we are skipping whitespaces, tab and end_of_line characters.
3615* offset - The offset in tvb from which we begin trying to skip whitespace.
3616*
3617* Returns: The position in tvb of the first non-whitespace
3618*/
3619static int megaco_tvb_skip_wsp(tvbuff_t* tvb, int offset ){
3620 int counter = offset;
3621 int end = tvb_reported_length(tvb);
3622
3623 for(counter = offset; counter < end &&
3624 (g_ascii_isspace(tvb_get_uint8(tvb,counter))((g_ascii_table[(guchar) (tvb_get_uint8(tvb,counter))] & G_ASCII_SPACE
) != 0)
); counter++);
3625 return (counter);
3626}
3627
3628static int megaco_tvb_skip_wsp_return(tvbuff_t* tvb, int offset){
3629 int counter = offset;
3630 int end = 0;
3631
3632 for(counter = offset; counter > end &&
3633 (g_ascii_isspace(tvb_get_uint8(tvb,counter))((g_ascii_table[(guchar) (tvb_get_uint8(tvb,counter))] & G_ASCII_SPACE
) != 0)
); counter--);
3634 counter++;
3635 return (counter);
3636}
3637
3638static int megaco_tvb_find_token(tvbuff_t* tvb, int offset, int maxlength){
3639 int counter = 0;
3640 int pos = offset;
3641 unsigned char needle;
3642
3643 do {
3644 pos = tvb_ws_mempbrk_pattern_uint8(tvb, pos + 1, maxlength, &pbrk_braces, &needle);
3645 if(pos == -1)
3646 return -1;
3647 switch(needle){
3648 case '{':
3649 counter++;
3650 break;
3651 case '}':
3652 counter--;
3653 break;
3654 default:
3655 break;
3656 }
3657 } while (counter>0);
3658 if(counter<0)
3659 return -1;
3660 else
3661 {
3662 pos = megaco_tvb_skip_wsp(tvb,pos+1);
3663 return pos;
3664 }
3665}
3666
3667static void
3668megaco_fmt_content( char *result, uint32_t context )
3669{
3670 switch(context)
3671 {
3672 case CHOOSE_CONTEXT0xFFFFFFFE:
3673 case ALL_CONTEXTS0xFFFFFFFF:
3674 case NULL_CONTEXT0:
3675 (void) g_strlcpy(result, val_to_str_const(context, megaco_context_vals, "Unknown"), ITEM_LABEL_LENGTH240);
3676 break;
3677 default:
3678 snprintf( result, ITEM_LABEL_LENGTH240, "%d", context);
3679 }
3680}
3681
3682void
3683proto_register_megaco(void)
3684{
3685 static hf_register_info hf[] = {
3686 { &hf_megaco_audititem,
3687 { "Audit Item", "megaco.audititem", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3688 "Identity of item to be audited", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3689 { &hf_megaco_audit_descriptor,
3690 { "Audit Descriptor", "megaco.audit", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3691 "Audit Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3692#if 0
3693 { &hf_megaco_command_line,
3694 { "Command line", "megaco.command_line", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3695 "Commands of this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3696#endif
3697 { &hf_megaco_command,
3698 { "Command", "megaco.command", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3699 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3700 { &hf_megaco_command_optional,
3701 { "Optional Command", "megaco.command_optional", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3702 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3703 { &hf_megaco_wildcard_response,
3704 { "Wildcarded response to a command", "megaco.wildcard_response", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3705 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3706
3707 { &hf_megaco_Context,
3708 { "Context", "megaco.context", FT_UINT32, BASE_CUSTOM, CF_FUNC(megaco_fmt_content)((const void *) (size_t) (megaco_fmt_content)), 0x0,
3709 "Context ID of this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3710 { &hf_megaco_Context_generated,
3711 { "Generated Context", "megaco.context.generated", FT_UINT32, BASE_CUSTOM, CF_FUNC(megaco_fmt_content)((const void *) (size_t) (megaco_fmt_content)), 0x0,
3712 "Used to track Context ID across protocols", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3713 { &hf_megaco_digitmap_descriptor,
3714 { "DigitMap Descriptor", "megaco.digitmap", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3715 "DigitMap Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3716 { &hf_megaco_error_descriptor,
3717 { "ERROR Descriptor", "megaco.error", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3718 "Error Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3719 { &hf_megaco_error_code,
3720 { "ERROR Code", "megaco.error_code", FT_UINT32, BASE_DEC, VALS(MEGACO_error_code_vals)((0 ? (const struct _value_string*)0 : ((MEGACO_error_code_vals
))))
, 0x0,
3721 "Error Code of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3722 { &hf_megaco_error_string,
3723 { "ERROR String", "megaco.error_string", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3724 "Error String of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3725 { &hf_megaco_Event_Buffer_Control,
3726 { "Event Buffer Control", "megaco.eventbuffercontrol", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3727 "Event Buffer Control in Termination State Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3728 { &hf_megaco_events_descriptor,
3729 { "Events Descriptor", "megaco.events", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3730 "Events Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3731 { &hf_megaco_Local_descriptor,
3732 { "Local Descriptor", "megaco.localdescriptor", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3733 "Local Descriptor in Media Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3734 { &hf_megaco_LocalControl_descriptor,
3735 { "Local Control Descriptor", "megaco.localcontroldescriptor", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3736 "Local Control Descriptor in Media Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3737 { &hf_megaco_media_descriptor,
3738 { "Media Descriptor", "megaco.media", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3739 "Media Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3740 { &hf_megaco_modem_descriptor,
3741 { "Modem Descriptor", "megaco.modem", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3742 "Modem Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3743 { &hf_megaco_mode,
3744 { "Mode", "megaco.mode", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3745 "Mode sendonly/receiveonly/inactive/loopback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3746 { &hf_megaco_multiplex_descriptor,
3747 { "Multiplex Descriptor", "megaco.multiplex", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3748 "Multiplex Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3749 { &hf_megaco_observedevents_descriptor,
3750 { "Observed Events Descriptor", "megaco.observedevents", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3751 "Observed Events Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3752 { &hf_megaco_packages_descriptor,
3753 { "Packages Descriptor", "megaco.packagesdescriptor", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3754 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3755 { &hf_megaco_pkgdname,
3756 { "pkgdName", "megaco.pkgdname", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3757 "PackageName SLASH ItemID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3758 { &hf_megaco_Remote_descriptor,
3759 { "Remote Descriptor", "megaco.remotedescriptor", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3760 "Remote Descriptor in Media Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3761 { &hf_megaco_reserve_group,
3762 { "Reserve Group", "megaco.reservegroup", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3763 "Reserve Group on or off", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3764 { &hf_megaco_h324_muxtbl_in,
3765 { "h324/muxtbl_in", "megaco.h324_muxtbl_in", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3766 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3767 { &hf_megaco_h324_muxtbl_out,
3768 { "h324/muxtbl_out", "megaco.h324_muxtbl_out", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3769 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3770 { &hf_megaco_ds_dscp,
3771 { "Differentiated Services Code Point", "megaco.ds_dscp", FT_UINT32, BASE_HEX|BASE_EXT_STRING0x00000200, &dscp_vals_ext, 0x0,
3772 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3773 { &hf_megaco_gm_saf,
3774 { "Remote Source Address Filtering", "megaco.gm_saf", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3775 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3776 { &hf_megaco_gm_sam,
3777 { "Remote Source Address Mask", "megaco.gm_sam", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3778 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3779 { &hf_megaco_gm_spf,
3780 { "Remote Source Port Filtering", "megaco.gm_spf", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3781 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3782 { &hf_megaco_gm_spr,
3783 { "Remote Source Port Range", "megaco.gm_spr", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3784 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3785 { &hf_megaco_gm_esas,
3786 { "Explicit Source Address Setting", "megaco.gm_esas", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3787 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3788 { &hf_megaco_tman_pol,
3789 { "Policing", "megaco.tman_pol", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3791 { &hf_megaco_gm_rsb,
3792 { "RTCP Allocation Specific Behaviour", "megaco.gm_rsb", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3793 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3794 { &hf_megaco_tman_sdr,
3795 { "Sustainable Data Rate", "megaco.tman_sdr", FT_INT32, BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytespsecond)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytespsecond
))))
, 0x0,
3796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3797 { &hf_megaco_tman_mbs,
3798 { "Maximum Burst Rate", "megaco.tman_mbs", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3799 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3800 { &hf_megaco_tman_pdr,
3801 { "Peak Data Rate", "megaco.tman_pdr", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3803 { &hf_megaco_tman_dvt,
3804 { "Delay Variation Tolerance", "megaco.tman_dvt", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3805 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3806 { &hf_megaco_ipdc_realm,
3807 { "IP Realm Identifier", "megaco.ipdc_realm", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3808 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3809 { &hf_megaco_h324_h223capr,
3810 { "h324/h223capr", "megaco.h324_h223capr", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3811 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3812 { &hf_megaco_reserve_value,
3813 { "Reserve Value", "megaco.reservevalue", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3814 "Reserve Value on or off", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3815 { &hf_megaco_requestid,
3816 { "RequestID", "megaco.requestid", FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
3817 "RequestID in Events or Observedevents Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3818#if 0
3819 { &hf_megaco_servicechange_descriptor,
3820 { "Service Change Descriptor", "megaco.servicechange", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3821 "Service Change Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3822#endif
3823 { &hf_megaco_Service_State,
3824 { "Service State", "megaco.servicestates", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3825 "Service States in Termination State Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3826 { &hf_megaco_signal_descriptor,
3827 { "Signal Descriptor", "megaco.signal", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3828 "Signal Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3829 { &hf_megaco_statistics_descriptor,
3830 { "Statistics Descriptor", "megaco.statistics", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3831 "Statistics Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3832 { &hf_megaco_streamid,
3833 { "StreamID", "megaco.streamid", FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
3834 "StreamID in the Media Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3835 { &hf_megaco_termid,
3836 { "Termination ID", "megaco.termid", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3837 "Termination ID of this Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3838 { &hf_megaco_TerminationState_descriptor,
3839 { "Termination State Descriptor", "megaco.terminationstate", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3840 "Termination State Descriptor in Media Descriptor", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3841 { &hf_megaco_topology_descriptor,
3842 { "Topology Descriptor", "megaco.topology", FT_STRING, BASE_STR_WSP, NULL((void*)0), 0x0,
3843 "Topology Descriptor of the megaco Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3844 { &hf_megaco_transaction,
3845 { "Transaction", "megaco.transaction", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3846 "Message Originator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3847 { &hf_megaco_transid,
3848 { "Transaction ID", "megaco.transid", FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
3849 "Transaction ID of this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3850 { &hf_megaco_mId,
3851 { "MediagatewayID", "megaco.mId", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3852 "Mediagateway ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3853 { &hf_megaco_version,
3854 { "Version", "megaco.version", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3855 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3856 { &hf_megaco_start,
3857 { "Start token", "megaco.start_token", FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3858 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3859 { &hf_megaco_h245,
3860 { "h245", "megaco.h245", FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3861 "Embedded H.245 message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3862 { &hf_megaco_h223Capability,
3863 { "h223Capability", "megaco.h245.h223Capability", FT_NONE, BASE_NONE, NULL((void*)0), 0,
3864 "megaco.h245.H223Capability", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3865 { &hf_megaco_priority,
3866 { "Priority", "megaco.priority", FT_STRING, BASE_NONE, NULL((void*)0), 0,
3867 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3868
3869 GCP_HF_ARR_ELEMS("megaco",megaco_ctx_ids){ &(megaco_ctx_ids.hf.ctx), { "Context", "megaco" ".ctx",
FT_UINT32, BASE_HEX, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0) }}, { &(megaco_ctx_ids.hf.ctx_term), { "Termination"
, "megaco" ".ctx.term", FT_STRING, BASE_NONE, ((void*)0), 0, (
(void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}, { &
(megaco_ctx_ids.hf.ctx_term_type), { "Type", "megaco" ".ctx.term.type"
, FT_UINT32, BASE_HEX, ((0 ? (const struct _value_string*)0 :
((gcp_term_types)))), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0) }}, { &(megaco_ctx_ids.hf.ctx_term_bir),
{ "BIR", "megaco" ".ctx.term.bir", FT_STRING, BASE_NONE, ((void
*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
}, { &(megaco_ctx_ids.hf.ctx_term_nsap), { "NSAP", "megaco"
".ctx.term.nsap", FT_STRING, BASE_NONE, ((void*)0), 0, ((void
*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}, { &(megaco_ctx_ids
.hf.ctx_cmd), { "Command in Frame", "megaco" ".ctx.cmd", FT_FRAMENUM
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0) }}
,
3870
3871 /* Add more fields here */
3872 };
3873 static int *ett[] = {
3874 &ett_megaco,
3875 &ett_megaco_message,
3876 &ett_megaco_message_body,
3877 &ett_megaco_context,
3878 &ett_megaco_command_line,
3879 &ett_megaco_descriptors,
3880 &ett_megaco_raw_text,
3881 &ett_megaco_error_descriptor,
3882 &ett_megaco_mediadescriptor,
3883 &ett_megaco_TerminationState,
3884 &ett_megaco_Remotedescriptor,
3885 &ett_megaco_Localdescriptor,
3886 &ett_megaco_LocalControldescriptor,
3887 &ett_megaco_auditdescriptor,
3888 &ett_megaco_eventsdescriptor,
3889 &ett_megaco_statisticsdescriptor,
3890 &ett_megaco_observedeventsdescriptor,
3891 &ett_megaco_observedevent,
3892 &ett_megaco_packagesdescriptor,
3893 &ett_megaco_requestedevent,
3894 &ett_megaco_signalsdescriptor,
3895 &ett_megaco_requestedsignal,
3896 &ett_megaco_h245,
3897 GCP_ETT_ARR_ELEMS(megaco_ctx_ids)&(megaco_ctx_ids.ett.ctx),&(megaco_ctx_ids.ett.ctx_cmds
),&(megaco_ctx_ids.ett.ctx_terms),&(megaco_ctx_ids.ett
.ctx_term)
,
3898 };
3899
3900 static ei_register_info ei[] = {
3901 { &ei_megaco_errored_command, { "megaco.errored_command", PI_RESPONSE_CODE0x03000000, PI_WARN0x00600000, "Errored Command", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3902 { &ei_megaco_parse_error, { "megaco.parse_error", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Parse error", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3903 { &ei_megaco_error_descriptor_transaction_list, { "megaco.error_descriptor_transaction_list.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Sorry, can't understand errorDescriptor / transactionList", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3904 { &ei_megaco_audit_descriptor, { "megaco.audit.malformed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Badly constructed audit descriptor (no { )", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3905 { &ei_megaco_signal_descriptor, { "megaco.signal_descriptor.empty", PI_PROTOCOL0x09000000, PI_NOTE0x00400000, "Empty Signal Descriptor", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3906 { &ei_megaco_no_command, { "megaco.no_command", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "No Command detectable", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3907 { &ei_megaco_no_descriptor, { "megaco.no_descriptor", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "No Descriptor detectable", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3908 { &ei_megaco_reason_invalid, { "megaco.change_reason.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Invalid Service Change Reason", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
3909 { &ei_megaco_error_code_invalid,{ "megaco.error_code.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Invalid error code", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
} },
3910 { &ei_megaco_invalid_sdr, { "megaco.sdr.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Invalid Sustainable Data Rate", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}}
3911 };
3912
3913 module_t *megaco_module;
3914 expert_module_t* expert_megaco;
3915
3916 proto_megaco = proto_register_protocol("MEGACO", "MEGACO", "megaco");
3917
3918 megaco_text_handle = register_dissector("megaco", dissect_megaco_text, proto_megaco);
3919
3920 proto_register_field_array(proto_megaco, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
3921 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
3922 expert_megaco = expert_register_protocol(proto_megaco);
3923 expert_register_field_array(expert_megaco, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
3924
3925 /* Register our configuration options, particularly our ports */
3926
3927 megaco_module = prefs_register_protocol(proto_megaco, NULL((void*)0));
3928
3929 prefs_register_bool_preference(megaco_module, "display_raw_text",
3930 "Display raw text for MEGACO message",
3931 "Specifies that the raw text of the "
3932 "MEGACO message should be displayed "
3933 "instead of (or in addition to) the "
3934 "dissection tree",
3935 &global_megaco_raw_text);
3936
3937 prefs_register_bool_preference(megaco_module, "display_dissect_tree",
3938 "Display tree dissection for MEGACO message",
3939 "Specifies that the dissection tree of the "
3940 "MEGACO message should be displayed "
3941 "instead of (or in addition to) the "
3942 "raw text",
3943 &global_megaco_dissect_tree);
3944 prefs_register_bool_preference(megaco_module, "ctx_info",
3945 "Track Context",
3946 "Maintain relationships between transactions and contexts "
3947 "and display an extra tree showing context data",
3948 &keep_persistent_data);
3949
3950 megaco_tap = register_tap("megaco");
3951
3952 /* compile patterns */
3953 ws_mempbrk_compile(&pbrk_whitespace, " \t\r\n");
3954 ws_mempbrk_compile(&pbrk_braces, "{}");
3955
3956 register_rtd_table(proto_megaco, NULL((void*)0), 1, NUM_TIMESTATS12, megaco_message_type, megacostat_packet, megacostat_filtercheck);
3957}
3958
3959/* Register all the bits needed with the filtering engine */
3960/* The registration hand-off routine */
3961void
3962proto_reg_handoff_megaco(void)
3963{
3964 dissector_handle_t megaco_text_tcp_handle;
3965
3966 sdp_handle = find_dissector_add_dependency("sdp", proto_megaco);
3967 h245_handle = find_dissector_add_dependency("h245dg", proto_megaco);
3968 h248_handle = find_dissector_add_dependency("h248", proto_megaco);
3969 h248_otp_handle = find_dissector_add_dependency("h248_otp", proto_megaco);
3970 data_handle = find_dissector("data");
3971
3972 megaco_text_tcp_handle = create_dissector_handle(dissect_megaco_text_tcp, proto_megaco);
3973
3974 dissector_add_uint_with_preference("tcp.port", PORT_MEGACO_TXT2944, megaco_text_tcp_handle);
3975 dissector_add_uint_with_preference("udp.port", PORT_MEGACO_TXT2944, megaco_text_handle);
3976 dissector_add_uint_with_preference("sctp.port", PORT_MEGACO_TXT2944, megaco_text_handle);
3977 dissector_add_uint("sctp.ppi", H248_PAYLOAD_PROTOCOL_ID7, megaco_text_handle);
3978
3979 exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7"OSI layer 7");
3980
3981 sip_hide_generated_call_ids = prefs_find_preference(prefs_find_module("sip"), "hide_generated_call_id");
3982
3983}
3984
3985/*
3986 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3987 *
3988 * Local variables:
3989 * c-basic-offset: 4
3990 * tab-width: 8
3991 * indent-tabs-mode: nil
3992 * End:
3993 *
3994 * vi: set shiftwidth=4 tabstop=8 expandtab:
3995 * :indentSize=4:tabSize=8:noTabs=true:
3996 */