### Bug Summary

File: | builds/wireshark/wireshark/epan/dissectors/packet-megaco.c
Warning: | line 2768, column 5 Value stored to 'tvb_LBRKT_found' is never read

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
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/2026-01-31-100341-3623-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-megaco.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

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