Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-actrace.c
blob49180df41ba21cbb3b5f1de4ead535dddeb2a4b1
1 /* packet-actrace.c
2 * Routines for AudioCodes Trunk traces packet disassembly
4 * Copyright (c) 2005 by Alejandro Vaquero <alejandro.vaquero@verso.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1999 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/tap.h>
18 #include <wiretap/wtap.h>
19 #include "packet-actrace.h"
21 #define UDP_PORT_ACTRACE 2428 /* Not IANA registered */
23 #define NOT_ACTRACE 0
24 #define ACTRACE_CAS 1
25 #define ACTRACE_ISDN 2
28 /* Forward declarations */
29 void proto_register_actrace(void);
30 void proto_reg_handoff_actrace(void);
32 static dissector_handle_t actrace_handle;
34 /* Define the actrace proto */
35 static int proto_actrace;
37 /* Define many headers for actrace */
38 /* ISDN headers */
39 static int hf_actrace_isdn_direction;
40 static int hf_actrace_isdn_trunk;
41 static int hf_actrace_isdn_length;
44 /* CAS headers */
45 static int hf_actrace_cas_time;
46 static int hf_actrace_cas_source;
47 static int hf_actrace_cas_current_state;
48 static int hf_actrace_cas_event;
49 static int hf_actrace_cas_next_state;
50 static int hf_actrace_cas_function;
51 static int hf_actrace_cas_par0;
52 static int hf_actrace_cas_par1;
53 static int hf_actrace_cas_par2;
54 static int hf_actrace_cas_trunk;
55 static int hf_actrace_cas_bchannel;
56 static int hf_actrace_cas_connection_id;
60 static dissector_handle_t lapd_phdr_handle;
62 #define ACTRACE_CAS_SOURCE_DSP 0
63 #define ACTRACE_CAS_SOURCE_USER 1
64 #define ACTRACE_CAS_SOURCE_TABLE 2
66 static const value_string actrace_cas_source_vals[] = {
67 {ACTRACE_CAS_SOURCE_DSP, "DSP"},
68 {ACTRACE_CAS_SOURCE_USER, "User"},
69 {ACTRACE_CAS_SOURCE_TABLE, "Table"},
70 {0, NULL }
73 static const value_string actrace_cas_source_vals_short[] = {
74 {ACTRACE_CAS_SOURCE_DSP, "D"},
75 {ACTRACE_CAS_SOURCE_USER, "U"},
76 {ACTRACE_CAS_SOURCE_TABLE, "T"},
77 {0, NULL }
80 #define ACTRACE_CAS_EV_11 17
81 #define ACTRACE_CAS_EV_10 18
82 #define ACTRACE_CAS_EV_01 19
83 #define ACTRACE_CAS_EV_00 20
85 #define ACTRACE_CAS_EV_DTMF 302
86 #define ACTRACE_CAS_EV_FIRST_DIGIT 63
88 static const value_string actrace_cas_event_ab_vals[] = {
89 {ACTRACE_CAS_EV_11, "11"},
90 {ACTRACE_CAS_EV_10, "10"},
91 {ACTRACE_CAS_EV_01, "01"},
92 {ACTRACE_CAS_EV_00, "00"},
93 {0, NULL}
96 static const value_string actrace_cas_mf_vals[] = {
97 {32, "1"},
98 {33, "2"},
99 {34, "3"},
100 {35, "4"},
101 {36, "5"},
102 {37, "6"},
103 {38, "7"},
104 {39, "8"},
105 {40, "9"},
106 {41, "0"},
107 {42, "A"},
108 {43, "B"},
109 {44, "C"},
110 {45, "*"},
111 {46, "#"},
112 {0, NULL}
114 static value_string_ext actrace_cas_mf_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_mf_vals);
116 static const value_string actrace_cas_event_vals[] = {
117 { 0, "FUNCTION0"},
118 { 1, "FUNCTION1"},
119 { 2, "FUNCTION2"},
120 { 3, "FUNCTION3"},
121 { 4, "EV_PLACE_CALL"},
122 { 5, "EV_TIMER_EXPIRED1"},
123 { 6, "EV_TIMER_EXPIRED2"},
124 { 7, "EV_TIMER_EXPIRED3"},
125 { 8, "EV_TIMER_EXPIRED4"},
126 { 9, "EV_TIMER_EXPIRED5"},
127 { 10, "EV_TIMER_EXPIRED6"},
128 { 11, "EV_TIMER_EXPIRED7"},
129 { 12, "EV_TIMER_EXPIRED8"},
130 { 13, "EV_ANSWER"},
131 { 14, "EV_DIAL_TONE_DETECTED"},
132 { 15, "EV_DIAL_ENDED"},
133 { 16, "EV_DISCONNECT"},
134 { ACTRACE_CAS_EV_11, "EV_CAS_1_1"},
135 { ACTRACE_CAS_EV_10, "EV_CAS_1_0"},
136 { ACTRACE_CAS_EV_01, "EV_CAS_0_1"},
137 { ACTRACE_CAS_EV_00, "EV_CAS_0_0"},
138 { 21, "EV_RB_TONE_STARTED"},
139 { 22, "EV_RB_TONE_STOPPED"},
140 { 23, "EV_BUSY_TONE"},
141 { 24, "EV_FAST_BUSY_TONE"},
142 { 25, "EV_HELLO_DETECTED"},
143 { 26, "EV_DIAL_TONE_STOPPED"},
144 { 27, "EV_DISCONNECT_INCOMING"},
145 { 28, "EV_RELEASE_CALL"},
146 { 29, "EV_DIALED_NUM_DETECTED"},
147 { 30, "EV_COUNTER1_EXPIRED"},
148 { 31, "EV_COUNTER2_EXPIRED"},
149 { 32, "EV_MFRn_1"},
150 { 33, "EV_MFRn_2"},
151 { 34, "EV_MFRn_3"},
152 { 35, "EV_MFRn_4"},
153 { 36, "EV_MFRn_5"},
154 { 37, "EV_MFRn_6"},
155 { 38, "EV_MFRn_7"},
156 { 39, "EV_MFRn_8"},
157 { 40, "EV_MFRn_9"},
158 { 41, "EV_MFRn_10"},
159 { 42, "EV_MFRn_11"},
160 { 43, "EV_MFRn_12"},
161 { 44, "EV_MFRn_13"},
162 { 45, "EV_MFRn_14"},
163 { 46, "EV_MFRn_15"},
164 { 47, "EV_MFRn_1_STOPPED"},
165 { 48, "EV_MFRn_2_STOPPED"},
166 { 49, "EV_MFRn_3_STOPPED"},
167 { 50, "EV_MFRn_4_STOPPED"},
168 { 51, "EV_MFRn_5_STOPPED"},
169 { 52, "EV_MFRn_6_STOPPED"},
170 { 53, "EV_MFRn_7_STOPPED"},
171 { 54, "EV_MFRn_8_STOPPED"},
172 { 55, "EV_MFRn_9_STOPPED"},
173 { 56, "EV_MFRn_10_STOPPED"},
174 { 57, "EV_MFRn_11_STOPPED"},
175 { 58, "EV_MFRn_12_STOPPED"},
176 { 59, "EV_MFRn_13_STOPPED"},
177 { 60, "EV_MFRn_14_STOPPED"},
178 { 61, "EV_MFRn_15_STOPPED"},
179 { 62, "EV_ANI_NUM_DETECTED"},
180 { ACTRACE_CAS_EV_FIRST_DIGIT, "EV_FIRST_DIGIT"},
181 { 64, "EV_END_OF_MF_DIGIT"},
182 { 65, "EV_ACCEPT"},
183 { 66, "EV_REJECT_BUSY"},
184 { 67, "EV_REJECT_CONGESTION"},
185 { 68, "EV_REJECT_UNALLOCATED"},
186 { 69, "EV_REJECT_RESERVE1"},
187 { 70, "EV_REJECT_RESERVE2"},
188 { 71, "EV_NO_ANI"},
189 { 100, "EV_INIT_CHANNEL"},
190 { 101, "EV_BUSY_TONE_STOPPED"},
191 { 102, "EV_FAST_BUSY_TONE_STOPPED"},
192 { 103, "EV_TO_USER"},
193 { 104, "SEND_FIRST_DIGIT"},
194 { 110, "EV_CLOSE_CHANNEL"},
195 { 111, "EV_OPEN_CHANNEL"},
196 { 112, "EV_FAIL_DIAL"},
197 { 113, "EV_FAIL_SEND_CAS"},
198 { 114, "EV_ALARM"},
199 { ACTRACE_CAS_EV_DTMF, "EV_DTMF"},
200 {1010, "EV_TIMER_EXPIRED10"},
201 {1020, "EV_DEBOUNCE_TIMER_EXPIRED"},
202 {1030, "EV_INTER_DIGIT_TIMER_EXPIRED"},
203 {0, NULL}
205 static value_string_ext actrace_cas_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_event_vals);
207 #define SEND_CAS 2
208 #define SEND_EVENT 3
209 #define CHANGE_COLLECT_TYPE 13
210 #define SEND_MF 8
211 #define SEND_DEST_NUM 4
213 static const value_string actrace_cas_function_vals[] = {
214 { 0, "NILL"},
215 { 1, "SET_TIMER"},
216 { SEND_CAS, "SEND_CAS"},
217 { SEND_EVENT, "SEND_EVENT"},
218 { SEND_DEST_NUM, "SEND_DEST_NUM"},
219 { 5, "DEL_TIMER"},
220 { 6, "START_COLLECT"},
221 { 7, "STOP_COLLECT"},
222 { SEND_MF, "SEND_MF"},
223 { 9, "STOP_DIAL_MF"},
224 {10, "SET_COUNTER"},
225 {11, "DEC_COUNTER"},
226 {12, "SEND_PROG_TON"},
227 {CHANGE_COLLECT_TYPE, "CHANGE_COLLECT_TYPE"},
228 {14, "GENERATE_CAS_EV"},
229 {0, NULL}
231 static value_string_ext actrace_cas_function_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_function_vals);
233 static const value_string actrace_cas_pstn_event_vals[] = {
234 { 64, "acEV_PSTN_INTERNAL_ERROR"},
235 { 65, "acEV_PSTN_CALL_CONNECTED"},
236 { 66, "acEV_PSTN_INCOMING_CALL_DETECTED"},
237 { 67, "acEV_PSTN_CALL_DISCONNECTED"},
238 { 68, "acEV_PSTN_CALL_RELEASED"},
239 { 69, "acEV_PSTN_REMOTE_ALERTING"},
240 { 70, "acEV_PSTN_STARTED"},
241 { 71, "acEV_PSTN_WARNING"},
242 { 72, "acEV_ISDN_PROGRESS_INDICATION"},
243 { 73, "acEV_PSTN_PROCEEDING_INDICATION"},
244 { 74, "acEV_PSTN_ALARM"},
245 { 75, "acEV_RESERVED"},
246 { 76, "acEV_PSTN_LINE_INFO"},
247 { 77, "acEV_PSTN_LOOP_CONFIRM"},
248 { 78, "acEV_PSTN_RESTART_CONFIRM"},
249 { 84, "acEV_ISDN_SETUP_ACK_IN"},
250 { 85, "acEV_PSTN_CALL_INFORMATION"},
251 {128, "acEV_CAS_SEIZURE_DETECTED"},
252 {129, "acEV_CAS_CHANNEL_BLOCKED"},
253 {130, "acEV_CAS_PROTOCOL_STARTED"},
254 {131, "acEV_PSTN_CALL_STATE_RESPONSE"},
255 {132, "acEV_CAS_SEIZURE_ACK"},
256 {0, NULL}
258 static value_string_ext actrace_cas_pstn_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_pstn_event_vals);
260 static const value_string actrace_cas_collect_type_vals[] = {
261 {0, "COLLECT_TYPE_ADDRESS"},
262 {1, "COLLECT_TYPE_ANI"},
263 {2, "COLLECT_TYPE_SOURCE_CATEGORY"},
264 {3, "COLLECT_TYPE_LINE_CATEGORY"},
265 {0, NULL}
268 #define SEND_TYPE_ADDRESS 1
269 #define SEND_TYPE_SPECIFIC 2
270 #define SEND_TYPE_INTER_EXCHANGE_SWITCH 3
271 #define SEND_TYPE_ANI 4
272 #define SEND_TYPE_SOURCE_CATEGORY 5
273 #define SEND_TYPE_TRANSFER_CAPABILITY 6
275 static const value_string actrace_cas_send_type_vals[] = {
276 {SEND_TYPE_ADDRESS, "ADDRESS"},
277 {SEND_TYPE_SPECIFIC, "SPECIFIC"},
278 {SEND_TYPE_INTER_EXCHANGE_SWITCH, "INTER_EXCHANGE_SWITCH"},
279 {SEND_TYPE_ANI, "ANI"},
280 {SEND_TYPE_SOURCE_CATEGORY, "SOURCE_CATEGORY"},
281 {SEND_TYPE_TRANSFER_CAPABILITY, "TRANSFER_CAPABILITY"},
282 {0, NULL}
285 static const value_string actrace_cas_cause_vals[] = {
286 { 1, "UNASSIGNED_NUMBER"},
287 { 2, "NO_ROUTE_TO_TRANSIT_NET"},
288 { 3, "NO_ROUTE_TO_DESTINATION"},
289 { 6, "CHANNEL_UNACCEPTABLE"},
290 { 7, "CALL_AWARDED_AND"},
291 { 8, "PREEMPTION"},
292 { 16, "NORMAL_CALL_CLEAR"},
293 { 17, "USER_BUSY"},
294 { 18, "NO_USER_RESPONDING"},
295 { 19, "NO_ANSWER_FROM_USER_ALERTED"},
296 { 20, "ACCEPT_DONE"},
297 { 21, "CALL_REJECTED"},
298 { 22, "NUMBER_CHANGED"},
299 { 26, "NON_SELECTED_USER_CLEARING"},
300 { 27, "DEST_OUT_OF_ORDER"},
301 { 28, "INVALID_NUMBER_FORMAT"},
302 { 29, "FACILITY_REJECT"},
303 { 30, "RESPONSE_TO_STATUS_ENQUIRY"},
304 { 31, "NORMAL_UNSPECIFIED"},
305 { 32, "CIRCUIT_CONGESTION"},
306 { 33, "USER_CONGESTION"},
307 { 34, "NO_CIRCUIT_AVAILABLE"},
308 { 38, "NETWORK_OUT_OF_ORDER"},
309 { 39, "PERM_FR_MODE_CONN_OUT_OF_S"},
310 { 40, "PERM_FR_MODE_CONN_OPERATIONAL"},
311 { 41, "NETWORK_TEMPORARY_FAILURE"},
312 { 42, "NETWORK_CONGESTION"},
313 { 43, "ACCESS_INFORMATION_DISCARDED"},
314 { 44, "REQUESTED_CIRCUIT_NOT_AVAILABLE"},
315 { 46, "PRECEDENCE_CALL_BLOCKED"},
316 { 47, "RESOURCE_UNAVAILABLE_UNSPECIFIED"},
317 { 49, "QUALITY_OF_SERVICE_UNAVAILABLE"},
318 { 50, "REQUESTED_FAC_NOT_SUBSCRIBED"},
319 { 53, "CUG_OUT_CALLS_BARRED"},
320 { 55, "CUG_INC_CALLS_BARRED"},
321 { 57, "BC_NOT_AUTHORIZED"},
322 { 58, "BC_NOT_PRESENTLY_AVAILABLE"},
323 { 62, "ACCES_INFO_SUBS_CLASS_INCONS"},
324 { 63, "SERVICE_NOT_AVAILABLE"},
325 { 65, "BC_NOT_IMPLEMENTED"},
326 { 66, "CHANNEL_TYPE_NOT_IMPLEMENTED"},
327 { 69, "REQUESTED_FAC_NOT_IMPLEMENTED"},
328 { 70, "ONLY_RESTRICTED_INFO_BEARER"},
329 { 79, "SERVICE_NOT_IMPLEMENTED_UNSPECIFIED"},
330 { 81, "INVALID_CALL_REF"},
331 { 82, "IDENTIFIED_CHANNEL_NOT_EXIST"},
332 { 83, "SUSPENDED_CALL_BUT_CALL_ID_NOT_EXIST"},
333 { 84, "CALL_ID_IN_USE"},
334 { 85, "NO_CALL_SUSPENDED"},
335 { 86, "CALL_HAVING_CALL_ID_CLEARED"},
336 { 87, "NOT_CUG_MEMBER"},
337 { 88, "INCOMPATIBLE_DESTINATION"},
338 { 90, "CUG_NON_EXISTENT"},
339 { 91, "INVALID_TRANSIT_NETWORK_SELECTION"},
340 { 95, "INVALID_MESSAGE_UNSPECIFIED"},
341 { 96, "MANDATORY_IE_MISSING"},
342 { 97, "MESSAGE_TYPE_NON_EXISTENT"},
343 { 98, "MESSAGE_STATE_INCONSISTENCY"},
344 { 99, "NON_EXISTENT_IE"},
345 {100, "INVALID_IE_CONTENT"},
346 {101, "MESSAGE_NOT_COMPATIBLE"},
347 {102, "RECOVERY_ON_TIMER_EXPIRY"},
348 {111, "PROTOCOL_ERROR_UNSPECIFIED"},
349 {127, "INTERWORKING_UNSPECIFIED"},
350 {128, "ACU_CAUSE_ACU_BAD_ADDRESS"},
351 {129, "ACU_CAUSE_ACU_BAD_SERVICE"},
352 {130, "ACU_CAUSE_ACU_COLLISION"},
353 {131, "ACU_CAUSE_ACU_FAC_REJECTED"},
354 {200, "C_ALREADY_BLOCKED"},
355 {201, "C_CHANNEL_BLOCKED"},
356 {202, "C_BLOCKING_DONE"},
357 {203, "C_ALREADY_UNBLOCKED"},
358 {204, "C_UNBLOCKING_DONE"},
359 {255, "ACU_NETWORK_CAUSE_NIL"},
360 {260, "CLRN_MFRn_A4"},
361 {261, "CLRN_MFRn_B1"},
362 {262, "CLRN_MFRn_B2"},
363 {263, "CLRN_MFRn_B3"},
364 {264, "CLRN_MFRn_B4"},
365 {265, "CLRN_MFRn_B5"},
366 {266, "CLRN_MFRn_B6"},
367 {267, "CLRN_MFRn_B7"},
368 {268, "CLRN_MFRn_B8"},
369 {269, "CLRN_MFRn_B9"},
370 {270, "CLRN_MFRn_B10"},
371 {271, "CLRN_MFRn_B11"},
372 {272, "CLRN_MFRn_B12"},
373 {273, "CLRN_MFRn_B13"},
374 {274, "CLRN_MFRn_B14"},
375 {275, "CLRN_MFRn_B15"},
376 {300, "ACURC_BUSY"},
377 {301, "ACURC_NOPROCEED"},
378 {302, "ACURC_NOANSWER"},
379 {303, "ACURC_NOAUTOANSWER"},
380 {304, "ACURC_CONGESTED"},
381 {305, "ACURC_INCOMING"},
382 {306, "ACURC_NOLINE"},
383 {307, "ACURC_ERRNUM"},
384 {308, "ACURC_INHNUM"},
385 {309, "ACURC_2MNUM"},
386 {310, "ACURC_HUNGUP"},
387 {311, "ACURC_NETWORK_ERROR"},
388 {312, "ACURC_TIMEOUT"},
389 {313, "ACURC_BAD_SERVICE"},
390 {314, "ACURC_INTERNAL"},
391 {315, "ACURC_OK"},
392 {316, "ACURC_BL_TIMEOUT"},
393 {317, "ACURC_IN_CALL"},
394 {318, "ACURC_CLEAR_RQ"},
395 {0, NULL}
397 static value_string_ext actrace_cas_cause_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_cause_vals);
399 /* ISDN */
400 #define PSTN_TO_BLADE 0x49446463
401 #define BLADE_TO_PSTN 0x49644443
403 static const value_string actrace_isdn_direction_vals[] = {
404 {PSTN_TO_BLADE, "Blade <-- PSTN"},
405 {BLADE_TO_PSTN, "Blade --> PSTN"},
406 {0, NULL}
410 * Define the tree for actrace
412 static int ett_actrace;
415 * Define the tap for actrace
417 static int actrace_tap;
418 static actrace_info_t *actrace_pi;
420 /* Some basic utility functions that are specific to this dissector */
421 static int is_actrace(tvbuff_t *tvb, int offset);
424 * The dissect functions
426 static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree);
427 static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
428 proto_tree *actrace_tree);
430 /************************************************************************
431 * dissect_actrace - The dissector for the AudioCodes Trace prtocol
432 ************************************************************************/
433 static int dissect_actrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
435 proto_tree *actrace_tree;
436 proto_item *ti;
437 int actrace_protocol;
439 /* Initialize variables */
440 actrace_tree = NULL;
443 * Check to see whether we're really dealing with AC trace by looking
444 * for a valid "source" and fixed len for CAS, and the direction for ISDN.
445 * This isn't infallible, but it's cheap and it's better than nothing.
447 actrace_protocol = is_actrace(tvb, 0);
448 if (actrace_protocol != NOT_ACTRACE)
451 * Set the columns now, so that they'll be set correctly if we throw
452 * an exception. We can set them later as well....
454 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_TRACE");
455 col_clear(pinfo->cinfo, COL_INFO);
457 if (tree)
459 /* Create our actrace subtree */
460 ti = proto_tree_add_item(tree,proto_actrace,tvb,0,-1, ENC_NA);
461 actrace_tree = proto_item_add_subtree(ti, ett_actrace);
464 switch (actrace_protocol)
466 case ACTRACE_CAS:
467 dissect_actrace_cas(tvb, pinfo, actrace_tree);
468 break;
469 case ACTRACE_ISDN:
470 dissect_actrace_isdn(tvb, pinfo, tree, actrace_tree);
471 break;
473 return tvb_captured_length(tvb);
476 return 0;
479 /* Dissect an individual actrace CAS message */
480 static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree)
482 /* Declare variables */
483 int32_t value, function, trunk, bchannel, source, event, curr_state, next_state;
484 int32_t par0, par1, par2;
485 const char *frame_label = NULL;
486 int direction = 0;
487 int offset = 0;
489 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS");
491 value = tvb_get_ntohl(tvb, offset);
492 proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value);
493 offset += 4;
495 source = tvb_get_ntohl(tvb, offset);
496 proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source);
497 offset += 4;
499 curr_state = tvb_get_ntohl(tvb, offset);
500 proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state);
501 offset += 4;
503 event = tvb_get_ntohl(tvb, offset);
504 proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event);
505 offset += 4;
507 next_state = tvb_get_ntohl(tvb, offset);
508 proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state);
509 offset += 4;
511 function = tvb_get_ntohl(tvb, offset);
512 proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function);
513 offset += 4;
515 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|",
516 val_to_str_const(source, actrace_cas_source_vals_short, "ukn"),
517 curr_state,
518 val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"),
519 next_state,
520 val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d"));
522 par0 = tvb_get_ntohl(tvb, offset);
523 switch (function)
525 case SEND_EVENT:
526 proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
527 par0, "%s", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "Unknown (%d)"));
528 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
529 val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d"));
530 break;
531 case CHANGE_COLLECT_TYPE:
532 proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
533 par0, "%s", val_to_str(par0, actrace_cas_collect_type_vals, "Unknown (%d)"));
534 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
535 val_to_str(par0, actrace_cas_collect_type_vals, "%d"));
536 break;
537 case SEND_MF:
538 case SEND_DEST_NUM:
539 proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
540 par0, "%s", val_to_str(par0, actrace_cas_send_type_vals, "Unknown (%d)"));
541 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
542 val_to_str(par0, actrace_cas_send_type_vals, "%d"));
543 break;
544 default:
545 proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0);
546 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0);
548 offset += 4;
550 par1 = tvb_get_ntohl(tvb, offset);
551 if (function == SEND_EVENT) {
552 proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4,
553 par1, "%s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)"));
554 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
555 val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d"));
556 } else {
557 proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1);
558 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1);
560 offset += 4;
562 par2 = tvb_get_ntohl(tvb, offset);
563 proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2);
564 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2);
565 offset += 4;
567 trunk = tvb_get_ntohl(tvb, offset);
568 proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk);
569 offset += 4;
571 bchannel = tvb_get_ntohl(tvb, offset);
572 proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel);
573 offset += 4;
575 col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel);
577 value = tvb_get_ntohl(tvb, offset);
578 proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value);
580 /* Add tap info for the Voip Graph */
581 if (source == ACTRACE_CAS_SOURCE_DSP) {
582 direction = 1;
583 if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) {
584 frame_label = wmem_strdup_printf(pinfo->pool, "AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") );
585 } else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */
586 frame_label = wmem_strdup_printf(pinfo->pool, "MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") );
587 } else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */
588 frame_label = wmem_strdup_printf(pinfo->pool, "DTMF: %u", par0 );
590 } else if (source == ACTRACE_CAS_SOURCE_TABLE) {
591 direction = 0;
592 if (function == SEND_MF) {
593 if (par0 == SEND_TYPE_SPECIFIC ) {
594 frame_label = wmem_strdup_printf(pinfo->pool, "MF: %u", par1);
595 } else if (par0 == SEND_TYPE_ADDRESS ) {
596 frame_label = wmem_strdup(pinfo->pool, "MF: DNIS digit");
597 } else if (par0 == SEND_TYPE_ANI ) {
598 frame_label = wmem_strdup(pinfo->pool, "MF: ANI digit");
599 } else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
600 frame_label = wmem_strdup(pinfo->pool, "MF: src_category");
601 } else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
602 frame_label = wmem_strdup(pinfo->pool, "MF: trf_capability");
603 } else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
604 frame_label = wmem_strdup(pinfo->pool, "MF: inter_exch_sw");
606 } else if (function == SEND_CAS) {
607 frame_label = wmem_strdup_printf(pinfo->pool, "AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR"));
608 } else if (function == SEND_DEST_NUM) {
609 if (par0 == SEND_TYPE_ADDRESS ) {
610 frame_label = wmem_strdup(pinfo->pool, "DTMF/MF: sending DNIS");
611 } else if (par0 == SEND_TYPE_ANI ) {
612 frame_label = wmem_strdup(pinfo->pool, "DTMF/MF: sending ANI");
617 if (frame_label != NULL) {
618 /* Initialise packet info for passing to tap */
619 actrace_pi = wmem_new(pinfo->pool, actrace_info_t);
621 actrace_pi->type = ACTRACE_CAS;
622 actrace_pi->direction = direction;
623 actrace_pi->trunk = trunk;
624 actrace_pi->cas_bchannel = bchannel;
625 actrace_pi->cas_frame_label = frame_label;
626 /* Report this packet to the tap */
627 tap_queue_packet(actrace_tap, pinfo, actrace_pi);
631 /* Dissect an individual actrace ISDN message */
632 static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
633 proto_tree *actrace_tree)
635 /* Declare variables */
636 int len;
637 int32_t value, trunk;
638 tvbuff_t *next_tvb;
639 int offset = 0;
640 struct isdn_phdr isdn;
642 offset += 4;
644 value = tvb_get_ntohl(tvb, offset+4);
645 proto_tree_add_int(actrace_tree, hf_actrace_isdn_direction, tvb, offset, 4, value);
646 offset += 4;
647 /* PSTN = Network */
648 isdn.uton = (value==BLADE_TO_PSTN);
649 isdn.channel = 0; /* D channel */
651 trunk = tvb_get_ntohs(tvb, offset);
652 proto_tree_add_int(actrace_tree, hf_actrace_isdn_trunk, tvb, offset, 2, trunk);
653 offset += 4;
655 offset += 32;
657 len = tvb_get_ntohs(tvb, offset);
658 proto_tree_add_int(actrace_tree, hf_actrace_isdn_length, tvb, offset, 2, len);
660 /* if it is a q931 packet (we don't want LAPD packets for Voip Graph) add tap info */
661 if (len > 4) {
662 /* Initialise packet info for passing to tap */
663 actrace_pi = wmem_new(pinfo->pool, actrace_info_t);
665 actrace_pi->type = ACTRACE_ISDN;
666 actrace_pi->direction = (value==PSTN_TO_BLADE?1:0);
667 actrace_pi->trunk = trunk;
669 /* Report this packet to the tap */
670 tap_queue_packet(actrace_tap, pinfo, actrace_pi);
673 /* Dissect lapd payload */
674 offset += 2 ;
675 next_tvb = tvb_new_subset_length(tvb, offset, len);
676 call_dissector_with_data(lapd_phdr_handle, next_tvb, pinfo, tree, &isdn);
678 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_ISDN");
679 col_prepend_fstr(pinfo->cinfo, COL_INFO, "Trunk:%d Blade %s PSTN "
680 , trunk, value==PSTN_TO_BLADE?"<--":"-->");
684 * is_actrace - A function for determining whether there is a
685 * AudioCodes packet at offset in tvb. The packet could be
686 * a CAS, ISDN or other Trunk protocol. Here we are only
687 * trying to decode CAS or ISDN protocols
689 * Parameter:
690 * tvb - The tvbuff in which we are looking for
691 * offset - The offset in tvb at which we are looking for
693 * Return: NOT_ACTRACE if there isn't an AudioCodes trace packet at offset
694 * in tvb, ACTRACE_CAS if there's a CAS packet there, ACTRACE_ISDN if
695 * there's an ISDN packet there.
697 static int is_actrace(tvbuff_t *tvb, int offset)
699 int tvb_len;
700 int32_t source, isdn_header;
702 tvb_len = tvb_reported_length(tvb);
704 /* is a CAS packet?
705 * the CAS messages are 48 byte fixed and the source should be 0,1 or 2 (DSP, User or Table)
707 source = tvb_get_ntohl(tvb, offset+4);
708 if ( (tvb_len == 48) && ((source > -1) && (source <3)) )
709 return ACTRACE_CAS;
710 /* is ISDN packet?
711 * the ISDN packets have 0x49446463 for packets from PSTN to the Blade and
712 * 0x49644443 for packets from the Blade to the PSTN at offset 4
714 isdn_header = tvb_get_ntohl(tvb, offset+4);
715 if ( (tvb_len >= 50) && ( (isdn_header == PSTN_TO_BLADE) || (isdn_header == BLADE_TO_PSTN)) )
716 return ACTRACE_ISDN;
717 return NOT_ACTRACE;
720 /* Register all the bits needed with the filtering engine */
721 void proto_register_actrace(void)
723 static hf_register_info hf[] =
725 /* CAS */
726 { &hf_actrace_cas_time,
727 { "Time", "actrace.cas.time", FT_INT32, BASE_DEC, NULL, 0x0,
728 "Capture Time", HFILL }},
729 { &hf_actrace_cas_source,
730 { "Source", "actrace.cas.source", FT_INT32, BASE_DEC, VALS(actrace_cas_source_vals), 0x0,
731 NULL, HFILL }},
732 { &hf_actrace_cas_current_state,
733 { "Current State", "actrace.cas.curr_state", FT_INT32, BASE_DEC, NULL, 0x0,
734 NULL, HFILL }},
735 { &hf_actrace_cas_event,
736 { "Event", "actrace.cas.event", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_event_vals_ext, 0x0,
737 "New Event", HFILL }},
738 { &hf_actrace_cas_next_state,
739 { "Next State", "actrace.cas.next_state", FT_INT32, BASE_DEC, NULL, 0x0,
740 NULL, HFILL }},
741 { &hf_actrace_cas_function,
742 { "Function", "actrace.cas.function", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_function_vals_ext, 0x0,
743 NULL, HFILL }},
744 { &hf_actrace_cas_par0,
745 { "Parameter 0", "actrace.cas.par0", FT_INT32, BASE_DEC, NULL, 0x0,
746 NULL, HFILL }},
747 { &hf_actrace_cas_par1,
748 { "Parameter 1", "actrace.cas.par1", FT_INT32, BASE_DEC, NULL, 0x0,
749 NULL, HFILL }},
750 { &hf_actrace_cas_par2,
751 { "Parameter 2", "actrace.cas.par2", FT_INT32, BASE_DEC, NULL, 0x0,
752 NULL, HFILL }},
753 { &hf_actrace_cas_trunk,
754 { "Trunk Number", "actrace.cas.trunk", FT_INT32, BASE_DEC, NULL, 0x0,
755 NULL, HFILL }},
756 { &hf_actrace_cas_bchannel,
757 { "BChannel", "actrace.cas.bchannel", FT_INT32, BASE_DEC, NULL, 0x0,
758 NULL, HFILL }},
759 { &hf_actrace_cas_connection_id,
760 { "Connection ID", "actrace.cas.conn_id", FT_INT32, BASE_DEC, NULL, 0x0,
761 NULL, HFILL }},
763 /* ISDN */
764 { &hf_actrace_isdn_trunk,
765 { "Trunk Number", "actrace.isdn.trunk", FT_INT16, BASE_DEC, NULL, 0x0,
766 NULL, HFILL }},
767 { &hf_actrace_isdn_direction,
768 { "Direction", "actrace.isdn.dir", FT_INT32, BASE_DEC, VALS(actrace_isdn_direction_vals), 0x0,
769 NULL, HFILL }},
770 { &hf_actrace_isdn_length,
771 { "Length", "actrace.isdn.length", FT_INT16, BASE_DEC, NULL, 0x0,
772 NULL, HFILL }},
775 static int *ett[] =
777 &ett_actrace,
780 module_t *actrace_module;
782 /* Register protocol */
783 proto_actrace = proto_register_protocol("AudioCodes Trunk Trace", "ACtrace", "actrace");
784 proto_register_field_array(proto_actrace, hf, array_length(hf));
785 proto_register_subtree_array(ett, array_length(ett));
787 /* Register our configuration options */
788 actrace_module = prefs_register_protocol(proto_actrace, NULL);
790 prefs_register_obsolete_preference(actrace_module, "display_dissect_tree");
792 actrace_handle = register_dissector("actrace", dissect_actrace, proto_actrace);
793 actrace_tap = register_tap("actrace");
796 /* The registration hand-off routine */
797 void proto_reg_handoff_actrace(void)
799 /* Get a handle for the LAPD-with-pseudoheader dissector. */
800 lapd_phdr_handle = find_dissector_add_dependency("lapd-phdr", proto_actrace);
802 dissector_add_uint_with_preference("udp.port", UDP_PORT_ACTRACE, actrace_handle);
806 * Editor modelines - https://www.wireshark.org/tools/modelines.html
808 * Local variables:
809 * c-basic-offset: 8
810 * tab-width: 8
811 * indent-tabs-mode: t
812 * End:
814 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
815 * :indentSize=8:tabSize=8:noTabs=false: