MSWSP: add ids for another unknown Property Set
[wireshark-wip.git] / epan / dissectors / packet-actrace.c
blobc3e68feb2479d4d246a0fe09f6314a99ffaef0ab
1 /* packet-actrace.c
2 * Routines for AudioCodes Trunk traces packet disassembly
4 * Copyright (c) 2005 by Alejandro Vaquero <alejandro.vaquero@verso.com>
6 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "config.h"
29 #include <epan/packet.h>
30 #include <epan/prefs.h>
31 #include <epan/tap.h>
32 #include "packet-actrace.h"
33 #include <epan/wmem/wmem.h>
35 #define UDP_PORT_ACTRACE 2428
36 #define NOT_ACTRACE 0
37 #define ACTRACE_CAS 1
38 #define ACTRACE_ISDN 2
41 /* Forward declarations */
42 void proto_register_actrace(void);
43 void proto_reg_handoff_actrace(void);
46 /* Define the actrace proto */
47 static int proto_actrace = -1;
49 /* Define many headers for actrace */
50 /* ISDN headers */
51 static int hf_actrace_isdn_direction = -1;
52 static int hf_actrace_isdn_trunk = -1;
53 static int hf_actrace_isdn_length = -1;
56 /* CAS headers */
57 static int hf_actrace_cas_time = -1;
58 static int hf_actrace_cas_source = -1;
59 static int hf_actrace_cas_current_state = -1;
60 static int hf_actrace_cas_event = -1;
61 static int hf_actrace_cas_next_state = -1;
62 static int hf_actrace_cas_function = -1;
63 static int hf_actrace_cas_par0 = -1;
64 static int hf_actrace_cas_par1 = -1;
65 static int hf_actrace_cas_par2 = -1;
66 static int hf_actrace_cas_trunk = -1;
67 static int hf_actrace_cas_bchannel = -1;
68 static int hf_actrace_cas_connection_id = -1;
72 static dissector_handle_t lapd_handle;
74 #define ACTRACE_CAS_SOURCE_DSP 0
75 #define ACTRACE_CAS_SOURCE_USER 1
76 #define ACTRACE_CAS_SOURCE_TABLE 2
78 static const value_string actrace_cas_source_vals[] = {
79 {ACTRACE_CAS_SOURCE_DSP, "DSP"},
80 {ACTRACE_CAS_SOURCE_USER, "User"},
81 {ACTRACE_CAS_SOURCE_TABLE, "Table"},
82 {0, NULL }
85 static const value_string actrace_cas_source_vals_short[] = {
86 {ACTRACE_CAS_SOURCE_DSP, "D"},
87 {ACTRACE_CAS_SOURCE_USER, "U"},
88 {ACTRACE_CAS_SOURCE_TABLE, "T"},
89 {0, NULL }
92 #define ACTRACE_CAS_EV_11 17
93 #define ACTRACE_CAS_EV_10 18
94 #define ACTRACE_CAS_EV_01 19
95 #define ACTRACE_CAS_EV_00 20
97 #define ACTRACE_CAS_EV_DTMF 302
98 #define ACTRACE_CAS_EV_FIRST_DIGIT 63
100 static const value_string actrace_cas_event_ab_vals[] = {
101 {ACTRACE_CAS_EV_11, "11"},
102 {ACTRACE_CAS_EV_10, "10"},
103 {ACTRACE_CAS_EV_01, "01"},
104 {ACTRACE_CAS_EV_00, "00"},
105 {0, NULL}
108 static const value_string actrace_cas_mf_vals[] = {
109 {32, "1"},
110 {33, "2"},
111 {34, "3"},
112 {35, "4"},
113 {36, "5"},
114 {37, "6"},
115 {38, "7"},
116 {39, "8"},
117 {40, "9"},
118 {41, "0"},
119 {42, "A"},
120 {43, "B"},
121 {44, "C"},
122 {45, "*"},
123 {46, "#"},
124 {0, NULL}
126 static value_string_ext actrace_cas_mf_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_mf_vals);
128 static const value_string actrace_cas_event_vals[] = {
129 {0, "FUNCTION0"},
130 {1, "FUNCTION1"},
131 {2, "FUNCTION2"},
132 {3, "FUNCTION3"},
133 {4, "EV_PLACE_CALL"},
134 {5, "EV_TIMER_EXPIRED1"},
135 {6, "EV_TIMER_EXPIRED2"},
136 {7, "EV_TIMER_EXPIRED3"},
137 {8, "EV_TIMER_EXPIRED4"},
138 {9, "EV_TIMER_EXPIRED5"},
139 {10, "EV_TIMER_EXPIRED6"},
140 {11, "EV_TIMER_EXPIRED7"},
141 {12, "EV_TIMER_EXPIRED8"},
142 {13, "EV_ANSWER"},
143 {14, "EV_DIAL_TONE_DETECTED"},
144 {15, "EV_DIAL_ENDED"},
145 {16, "EV_DISCONNECT"},
146 {ACTRACE_CAS_EV_11, "EV_CAS_1_1"},
147 {ACTRACE_CAS_EV_10, "EV_CAS_1_0"},
148 {ACTRACE_CAS_EV_01, "EV_CAS_0_1"},
149 {ACTRACE_CAS_EV_00, "EV_CAS_0_0"},
150 {21, "EV_RB_TONE_STARTED"},
151 {22, "EV_RB_TONE_STOPPED"},
152 {23, "EV_BUSY_TONE"},
153 {24, "EV_FAST_BUSY_TONE"},
154 {25, "EV_HELLO_DETECTED"},
155 {26, "EV_DIAL_TONE_STOPPED"},
156 {27, "EV_DISCONNECT_INCOMING"},
157 {28, "EV_RELEASE_CALL"},
158 {29, "EV_DIALED_NUM_DETECTED"},
159 {30, "EV_COUNTER1_EXPIRED"},
160 {31, "EV_COUNTER2_EXPIRED"},
161 {32, "EV_MFRn_1"},
162 {33, "EV_MFRn_2"},
163 {34, "EV_MFRn_3"},
164 {35, "EV_MFRn_4"},
165 {36, "EV_MFRn_5"},
166 {37, "EV_MFRn_6"},
167 {38, "EV_MFRn_7"},
168 {39, "EV_MFRn_8"},
169 {40, "EV_MFRn_9"},
170 {41, "EV_MFRn_10"},
171 {42, "EV_MFRn_11"},
172 {43, "EV_MFRn_12"},
173 {44, "EV_MFRn_13"},
174 {45, "EV_MFRn_14"},
175 {46, "EV_MFRn_15"},
176 {47, "EV_MFRn_1_STOPPED"},
177 {48, "EV_MFRn_2_STOPPED"},
178 {49, "EV_MFRn_3_STOPPED"},
179 {50, "EV_MFRn_4_STOPPED"},
180 {51, "EV_MFRn_5_STOPPED"},
181 {52, "EV_MFRn_6_STOPPED"},
182 {53, "EV_MFRn_7_STOPPED"},
183 {54, "EV_MFRn_8_STOPPED"},
184 {55, "EV_MFRn_9_STOPPED"},
185 {56, "EV_MFRn_10_STOPPED"},
186 {57, "EV_MFRn_11_STOPPED"},
187 {58, "EV_MFRn_12_STOPPED"},
188 {59, "EV_MFRn_13_STOPPED"},
189 {60, "EV_MFRn_14_STOPPED"},
190 {61, "EV_MFRn_15_STOPPED"},
191 {62, "EV_ANI_NUM_DETECTED"},
192 {ACTRACE_CAS_EV_FIRST_DIGIT, "EV_FIRST_DIGIT"},
193 {64, "EV_END_OF_MF_DIGIT"},
194 {65, "EV_ACCEPT"},
195 {66, "EV_REJECT_BUSY"},
196 {67, "EV_REJECT_CONGESTION"},
197 {68, "EV_REJECT_UNALLOCATED"},
198 {69, "EV_REJECT_RESERVE1"},
199 {70, "EV_REJECT_RESERVE2"},
200 {71, "EV_NO_ANI"},
201 {100, "EV_INIT_CHANNEL"},
202 {101, "EV_BUSY_TONE_STOPPED"},
203 {102, "EV_FAST_BUSY_TONE_STOPPED"},
204 {103, "EV_TO_USER"},
205 {104, "SEND_FIRST_DIGIT"},
206 {110, "EV_CLOSE_CHANNEL"},
207 {111, "EV_OPEN_CHANNEL"},
208 {112, "EV_FAIL_DIAL"},
209 {113, "EV_FAIL_SEND_CAS"},
210 {114, "EV_ALARM"},
211 {ACTRACE_CAS_EV_DTMF, "EV_DTMF"},
212 {1010, "EV_TIMER_EXPIRED10"},
213 {1020, "EV_DEBOUNCE_TIMER_EXPIRED"},
214 {1030, "EV_INTER_DIGIT_TIMER_EXPIRED"},
215 {0, NULL}
217 static value_string_ext actrace_cas_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_event_vals);
219 #define SEND_CAS 2
220 #define SEND_EVENT 3
221 #define CHANGE_COLLECT_TYPE 13
222 #define SEND_MF 8
223 #define SEND_DEST_NUM 4
225 static const value_string actrace_cas_function_vals[] = {
226 {0, "NILL"},
227 {1, "SET_TIMER"},
228 {SEND_CAS, "SEND_CAS"},
229 {SEND_EVENT, "SEND_EVENT"},
230 {SEND_DEST_NUM, "SEND_DEST_NUM"},
231 {5, "DEL_TIMER"},
232 {6, "START_COLLECT"},
233 {7, "STOP_COLLECT"},
234 {SEND_MF, "SEND_MF"},
235 {9, "STOP_DIAL_MF"},
236 {10, "SET_COUNTER"},
237 {11, "DEC_COUNTER"},
238 {12, "SEND_PROG_TON"},
239 {CHANGE_COLLECT_TYPE, "CHANGE_COLLECT_TYPE"},
240 {14, "GENERATE_CAS_EV"},
241 {0, NULL}
243 static value_string_ext actrace_cas_function_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_function_vals);
245 static const value_string actrace_cas_pstn_event_vals[] = {
246 {64, "acEV_PSTN_INTERNAL_ERROR"},
247 {65, "acEV_PSTN_CALL_CONNECTED"},
248 {66, "acEV_PSTN_INCOMING_CALL_DETECTED"},
249 {67, "acEV_PSTN_CALL_DISCONNECTED"},
250 {68, "acEV_PSTN_CALL_RELEASED"},
251 {69, "acEV_PSTN_REMOTE_ALERTING"},
252 {70, "acEV_PSTN_STARTED"},
253 {71, "acEV_PSTN_WARNING"},
254 {72, "acEV_ISDN_PROGRESS_INDICATION"},
255 {73, "acEV_PSTN_PROCEEDING_INDICATION"},
256 {74, "acEV_PSTN_ALARM"},
257 {75, "acEV_RESERVED"},
258 {76, "acEV_PSTN_LINE_INFO"},
259 {77, "acEV_PSTN_LOOP_CONFIRM"},
260 {78, "acEV_PSTN_RESTART_CONFIRM"},
261 {84, "acEV_ISDN_SETUP_ACK_IN"},
262 {85, "acEV_PSTN_CALL_INFORMATION"},
263 {128, "acEV_CAS_SEIZURE_DETECTED"},
264 {129, "acEV_CAS_CHANNEL_BLOCKED"},
265 {130, "acEV_CAS_PROTOCOL_STARTED"},
266 {131, "acEV_PSTN_CALL_STATE_RESPONSE"},
267 {132, "acEV_CAS_SEIZURE_ACK"},
268 {0, NULL}
270 static value_string_ext actrace_cas_pstn_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_pstn_event_vals);
272 static const value_string actrace_cas_collect_type_vals[] = {
273 {0, "COLLECT_TYPE_ADDRESS"},
274 {1, "COLLECT_TYPE_ANI"},
275 {2, "COLLECT_TYPE_SOURCE_CATEGORY"},
276 {3, "COLLECT_TYPE_LINE_CATEGORY"},
277 {0, NULL}
280 #define SEND_TYPE_ADDRESS 1
281 #define SEND_TYPE_SPECIFIC 2
282 #define SEND_TYPE_INTER_EXCHANGE_SWITCH 3
283 #define SEND_TYPE_ANI 4
284 #define SEND_TYPE_SOURCE_CATEGORY 5
285 #define SEND_TYPE_TRANSFER_CAPABILITY 6
287 static const value_string actrace_cas_send_type_vals[] = {
288 {SEND_TYPE_ADDRESS, "ADDRESS"},
289 {SEND_TYPE_SPECIFIC, "SPECIFIC"},
290 {SEND_TYPE_INTER_EXCHANGE_SWITCH, "INTER_EXCHANGE_SWITCH"},
291 {SEND_TYPE_ANI, "ANI"},
292 {SEND_TYPE_SOURCE_CATEGORY, "SOURCE_CATEGORY"},
293 {SEND_TYPE_TRANSFER_CAPABILITY, "TRANSFER_CAPABILITY"},
294 {0, NULL}
297 static const value_string actrace_cas_cause_vals[] = {
298 {1, "UNASSIGNED_NUMBER"},
299 {2, "NO_ROUTE_TO_TRANSIT_NET"},
300 {3, "NO_ROUTE_TO_DESTINATION"},
301 {6, "CHANNEL_UNACCEPTABLE"},
302 {7, "CALL_AWARDED_AND"},
303 {8, "PREEMPTION"},
304 {16, "NORMAL_CALL_CLEAR"},
305 {17, "USER_BUSY"},
306 {18, "NO_USER_RESPONDING"},
307 {19, "NO_ANSWER_FROM_USER_ALERTED"},
308 {20, "ACCEPT_DONE"},
309 {21, "CALL_REJECTED"},
310 {22, "NUMBER_CHANGED"},
311 {26, "NON_SELECTED_USER_CLEARING"},
312 {27, "DEST_OUT_OF_ORDER"},
313 {28, "INVALID_NUMBER_FORMAT"},
314 {29, "FACILITY_REJECT"},
315 {30, "RESPONSE_TO_STATUS_ENQUIRY"},
316 {31, "NORMAL_UNSPECIFIED"},
317 {32, "CIRCUIT_CONGESTION"},
318 {33, "USER_CONGESTION"},
319 {34, "NO_CIRCUIT_AVAILABLE"},
320 {38, "NETWORK_OUT_OF_ORDER"},
321 {39, "PERM_FR_MODE_CONN_OUT_OF_S"},
322 {40, "PERM_FR_MODE_CONN_OPERATIONAL"},
323 {41, "NETWORK_TEMPORARY_FAILURE"},
324 {42, "NETWORK_CONGESTION"},
325 {43, "ACCESS_INFORMATION_DISCARDED"},
326 {44, "REQUESTED_CIRCUIT_NOT_AVAILABLE"},
327 {46, "PRECEDENCE_CALL_BLOCKED"},
328 {47, "RESOURCE_UNAVAILABLE_UNSPECIFIED"},
329 {49, "QUALITY_OF_SERVICE_UNAVAILABLE"},
330 {50, "REQUESTED_FAC_NOT_SUBSCRIBED"},
331 {53, "CUG_OUT_CALLS_BARRED"},
332 {55, "CUG_INC_CALLS_BARRED"},
333 {57, "BC_NOT_AUTHORIZED"},
334 {58, "BC_NOT_PRESENTLY_AVAILABLE"},
335 {62, "ACCES_INFO_SUBS_CLASS_INCONS"},
336 {63, "SERVICE_NOT_AVAILABLE"},
337 {65, "BC_NOT_IMPLEMENTED"},
338 {66, "CHANNEL_TYPE_NOT_IMPLEMENTED"},
339 {69, "REQUESTED_FAC_NOT_IMPLEMENTED"},
340 {70, "ONLY_RESTRICTED_INFO_BEARER"},
341 {79, "SERVICE_NOT_IMPLEMENTED_UNSPECIFIED"},
342 {81, "INVALID_CALL_REF"},
343 {82, "IDENTIFIED_CHANNEL_NOT_EXIST"},
344 {83, "SUSPENDED_CALL_BUT_CALL_ID_NOT_EXIST"},
345 {84, "CALL_ID_IN_USE"},
346 {85, "NO_CALL_SUSPENDED"},
347 {86, "CALL_HAVING_CALL_ID_CLEARED"},
348 {87, "NOT_CUG_MEMBER"},
349 {88, "INCOMPATIBLE_DESTINATION"},
350 {90, "CUG_NON_EXISTENT"},
351 {91, "INVALID_TRANSIT_NETWORK_SELECTION"},
352 {95, "INVALID_MESSAGE_UNSPECIFIED"},
353 {96, "MANDATORY_IE_MISSING"},
354 {97, "MESSAGE_TYPE_NON_EXISTENT"},
355 {98, "MESSAGE_STATE_INCONSISTENCY"},
356 {99, "NON_EXISTENT_IE"},
357 {100, "INVALID_IE_CONTENT"},
358 {101, "MESSAGE_NOT_COMPATIBLE"},
359 {102, "RECOVERY_ON_TIMER_EXPIRY"},
360 {111, "PROTOCOL_ERROR_UNSPECIFIED"},
361 {127, "INTERWORKING_UNSPECIFIED"},
362 {128, "ACU_CAUSE_ACU_BAD_ADDRESS"},
363 {129, "ACU_CAUSE_ACU_BAD_SERVICE"},
364 {130, "ACU_CAUSE_ACU_COLLISION"},
365 {131, "ACU_CAUSE_ACU_FAC_REJECTED"},
366 {200, "C_ALREADY_BLOCKED"},
367 {201, "C_CHANNEL_BLOCKED"},
368 {202, "C_BLOCKING_DONE"},
369 {203, "C_ALREADY_UNBLOCKED"},
370 {204, "C_UNBLOCKING_DONE"},
371 {255, "ACU_NETWORK_CAUSE_NIL"},
372 {260, "CLRN_MFRn_A4"},
373 {261, "CLRN_MFRn_B1"},
374 {262, "CLRN_MFRn_B2"},
375 {263, "CLRN_MFRn_B3"},
376 {264, "CLRN_MFRn_B4"},
377 {265, "CLRN_MFRn_B5"},
378 {266, "CLRN_MFRn_B6"},
379 {267, "CLRN_MFRn_B7"},
380 {268, "CLRN_MFRn_B8"},
381 {269, "CLRN_MFRn_B9"},
382 {270, "CLRN_MFRn_B10"},
383 {271, "CLRN_MFRn_B11"},
384 {272, "CLRN_MFRn_B12"},
385 {273, "CLRN_MFRn_B13"},
386 {274, "CLRN_MFRn_B14"},
387 {275, "CLRN_MFRn_B15"},
388 {300, "ACURC_BUSY"},
389 {301, "ACURC_NOPROCEED"},
390 {302, "ACURC_NOANSWER"},
391 {303, "ACURC_NOAUTOANSWER"},
392 {304, "ACURC_CONGESTED"},
393 {305, "ACURC_INCOMING"},
394 {306, "ACURC_NOLINE"},
395 {307, "ACURC_ERRNUM"},
396 {308, "ACURC_INHNUM"},
397 {309, "ACURC_2MNUM"},
398 {310, "ACURC_HUNGUP"},
399 {311, "ACURC_NETWORK_ERROR"},
400 {312, "ACURC_TIMEOUT"},
401 {313, "ACURC_BAD_SERVICE"},
402 {314, "ACURC_INTERNAL"},
403 {315, "ACURC_OK"},
404 {316, "ACURC_BL_TIMEOUT"},
405 {317, "ACURC_IN_CALL"},
406 {318, "ACURC_CLEAR_RQ"},
407 {0, NULL}
409 static value_string_ext actrace_cas_cause_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_cause_vals);
411 /* ISDN */
412 #define PSTN_TO_BLADE 0x49446463
413 #define BLADE_TO_PSTN 0x49644443
415 static const value_string actrace_isdn_direction_vals[] = {
416 {PSTN_TO_BLADE, "Blade <-- PSTN"},
417 {BLADE_TO_PSTN, "Blade --> PSTN"},
418 {0, NULL}
422 * Define the tree for actrace
424 static int ett_actrace = -1;
427 * Define the tap for actrace
429 static int actrace_tap = -1;
430 static actrace_info_t *actrace_pi;
433 * Here are the global variables associated with
434 * the user definable characteristics of the dissection
436 static guint global_actrace_udp_port = UDP_PORT_ACTRACE;
438 /* Some basic utility functions that are specific to this dissector */
439 static int is_actrace(tvbuff_t *tvb, gint offset);
442 * The dissect functions
444 static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree);
445 static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
446 proto_tree *actrace_tree);
448 /************************************************************************
449 * dissect_actrace - The dissector for the AudioCodes Trace prtocol
450 ************************************************************************/
451 static int dissect_actrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
453 proto_tree *actrace_tree;
454 proto_item *ti;
455 int actrace_protocol;
457 /* Initialize variables */
458 actrace_tree = NULL;
461 * Check to see whether we're really dealing with AC trace by looking
462 * for a valid "source" and fixed len for CAS, and the direction for ISDN.
463 * This isn't infallible, but it's cheap and it's better than nothing.
465 actrace_protocol = is_actrace(tvb, 0);
466 if (actrace_protocol != NOT_ACTRACE)
469 * Set the columns now, so that they'll be set correctly if we throw
470 * an exception. We can set them later as well....
472 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_TRACE");
473 col_clear(pinfo->cinfo, COL_INFO);
475 if (tree)
477 /* Create our actrace subtree */
478 ti = proto_tree_add_item(tree,proto_actrace,tvb,0,-1, ENC_NA);
479 actrace_tree = proto_item_add_subtree(ti, ett_actrace);
482 switch (actrace_protocol)
484 case ACTRACE_CAS:
485 dissect_actrace_cas(tvb, pinfo, actrace_tree);
486 break;
487 case ACTRACE_ISDN:
488 dissect_actrace_isdn(tvb, pinfo, tree, actrace_tree);
489 break;
491 return tvb_length(tvb);
494 return 0;
497 /* Dissect an individual actrace CAS message */
498 static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree)
500 /* Declare variables */
501 gint32 value, function, trunk, bchannel, source, event, curr_state, next_state;
502 gint32 par0, par1, par2;
503 const gchar *frame_label = NULL;
504 int direction = 0;
505 int offset = 0;
507 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS");
509 value = tvb_get_ntohl(tvb, offset);
510 proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value);
511 offset += 4;
513 source = tvb_get_ntohl(tvb, offset);
514 proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source);
515 offset += 4;
517 curr_state = tvb_get_ntohl(tvb, offset);
518 proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state);
519 offset += 4;
521 event = tvb_get_ntohl(tvb, offset);
522 proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event);
523 offset += 4;
525 next_state = tvb_get_ntohl(tvb, offset);
526 proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state);
527 offset += 4;
529 function = tvb_get_ntohl(tvb, offset);
530 proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function);
531 offset += 4;
533 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|",
534 val_to_str_const(source, actrace_cas_source_vals_short, "ukn"),
535 curr_state,
536 val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"),
537 next_state,
538 val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d"));
540 par0 = tvb_get_ntohl(tvb, offset);
541 switch (function)
543 case SEND_EVENT:
544 proto_tree_add_text(actrace_tree, tvb, offset, 4,
545 "Parameter 0: %s", val_to_str_ext(par0,
546 &actrace_cas_pstn_event_vals_ext, "Unknown (%d)"));
547 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
548 val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d"));
549 break;
550 case CHANGE_COLLECT_TYPE:
551 proto_tree_add_text(actrace_tree, tvb, offset, 4,
552 "Parameter 0: %s", val_to_str(par0,
553 actrace_cas_collect_type_vals, "Unknown (%d)"));
554 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
555 val_to_str(par0, actrace_cas_collect_type_vals, "%d"));
556 break;
557 case SEND_MF:
558 case SEND_DEST_NUM:
559 proto_tree_add_text(actrace_tree, tvb, offset, 4,
560 "Parameter 0: %s", val_to_str(par0,
561 actrace_cas_send_type_vals, "Unknown (%d)"));
562 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
563 val_to_str(par0, actrace_cas_send_type_vals, "%d"));
564 break;
565 default:
566 proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0);
567 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0);
569 offset += 4;
571 par1 = tvb_get_ntohl(tvb, offset);
572 if (function == SEND_EVENT) {
573 proto_tree_add_text(actrace_tree, tvb, offset, 4,
574 "Parameter 1: %s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)"));
575 col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
576 val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d"));
577 } else {
578 proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1);
579 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1);
581 offset += 4;
583 par2 = tvb_get_ntohl(tvb, offset);
584 proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2);
585 col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2);
586 offset += 4;
588 trunk = tvb_get_ntohl(tvb, offset);
589 proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk);
590 offset += 4;
592 bchannel = tvb_get_ntohl(tvb, offset);
593 proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel);
594 offset += 4;
596 col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel);
598 value = tvb_get_ntohl(tvb, offset);
599 proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value);
601 /* Add tap info for the Voip Graph */
602 if (source == ACTRACE_CAS_SOURCE_DSP) {
603 direction = 1;
604 if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) {
605 frame_label = wmem_strdup_printf(wmem_packet_scope(), "AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") );
606 } else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */
607 frame_label = wmem_strdup_printf(wmem_packet_scope(), "MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") );
608 } else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */
609 frame_label = wmem_strdup_printf(wmem_packet_scope(), "DTMF: %u", par0 );
611 } else if (source == ACTRACE_CAS_SOURCE_TABLE) {
612 direction = 0;
613 if (function == SEND_MF) {
614 if (par0 == SEND_TYPE_SPECIFIC ) {
615 frame_label = wmem_strdup_printf(wmem_packet_scope(), "MF: %u", par1);
616 } else if (par0 == SEND_TYPE_ADDRESS ) {
617 frame_label = wmem_strdup(wmem_packet_scope(), "MF: DNIS digit");
618 } else if (par0 == SEND_TYPE_ANI ) {
619 frame_label = wmem_strdup(wmem_packet_scope(), "MF: ANI digit");
620 } else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
621 frame_label = wmem_strdup(wmem_packet_scope(), "MF: src_category");
622 } else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
623 frame_label = wmem_strdup(wmem_packet_scope(), "MF: trf_capability");
624 } else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
625 frame_label = wmem_strdup(wmem_packet_scope(), "MF: inter_exch_sw");
627 } else if (function == SEND_CAS) {
628 frame_label = wmem_strdup_printf(wmem_packet_scope(), "AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR"));
629 } else if (function == SEND_DEST_NUM) {
630 if (par0 == SEND_TYPE_ADDRESS ) {
631 frame_label = wmem_strdup(wmem_packet_scope(), "DTMF/MF: sending DNIS");
632 } else if (par0 == SEND_TYPE_ANI ) {
633 frame_label = wmem_strdup(wmem_packet_scope(), "DTMF/MF: sending ANI");
638 if (frame_label != NULL) {
639 /* Initialise packet info for passing to tap */
640 actrace_pi = wmem_new(wmem_packet_scope(), actrace_info_t);
642 actrace_pi->type = ACTRACE_CAS;
643 actrace_pi->direction = direction;
644 actrace_pi->trunk = trunk;
645 actrace_pi->cas_bchannel = bchannel;
646 actrace_pi->cas_frame_label = frame_label;
647 /* Report this packet to the tap */
648 tap_queue_packet(actrace_tap, pinfo, actrace_pi);
652 /* Dissect an individual actrace ISDN message */
653 static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
654 proto_tree *actrace_tree)
656 /* Declare variables */
657 gint len;
658 gint32 value, trunk;
659 tvbuff_t *next_tvb;
660 int offset = 0;
662 len = tvb_get_ntohs(tvb, 44);
664 value = tvb_get_ntohl(tvb, offset+4);
665 proto_tree_add_int(actrace_tree, hf_actrace_isdn_direction, tvb, offset+4, 4, value);
667 offset += 8;
668 trunk = tvb_get_ntohs(tvb, offset);
669 proto_tree_add_int(actrace_tree, hf_actrace_isdn_trunk, tvb, offset, 2, trunk);
671 offset = 44;
672 proto_tree_add_int(actrace_tree, hf_actrace_isdn_length, tvb, offset, 2, len);
675 /* if it is a q931 packet (we don't want LAPD packets for Voip Graph) add tap info */
676 if (len > 4) {
677 /* Initialise packet info for passing to tap */
678 actrace_pi = wmem_new(wmem_packet_scope(), actrace_info_t);
680 actrace_pi->type = ACTRACE_ISDN;
681 actrace_pi->direction = (value==PSTN_TO_BLADE?1:0);
682 actrace_pi->trunk = trunk;
684 /* Report this packet to the tap */
685 tap_queue_packet(actrace_tap, pinfo, actrace_pi);
688 /* Dissect lapd payload */
689 offset += 2 ;
690 next_tvb = tvb_new_subset(tvb, offset, len, len);
691 call_dissector(lapd_handle, next_tvb, pinfo, tree);
693 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_ISDN");
694 col_prepend_fstr(pinfo->cinfo, COL_INFO, "Trunk:%d Blade %s PSTN "
695 , trunk, value==PSTN_TO_BLADE?"<--":"-->");
699 * is_actrace - A function for determining whether there is a
700 * AudioCodes packet at offset in tvb. The packet could be
701 * a CAS, ISDN or other Trunk protocol. Here we are only
702 * trying to decode CAS or ISDN protocols
704 * Parameter:
705 * tvb - The tvbuff in which we are looking for
706 * offset - The offset in tvb at which we are looking for
708 * Return: NOT_ACTRACE if there isn't an AudioCodes trace packet at offset
709 * in tvb, ACTRACE_CAS if there's a CAS packet there, ACTRACE_ISDN if
710 * there's an ISDN packet there.
712 static int is_actrace(tvbuff_t *tvb, gint offset)
714 gint tvb_len;
715 gint32 source, isdn_header;
717 tvb_len = tvb_reported_length(tvb);
719 /* is a CAS packet?
720 * the CAS messages are 48 byte fixed and the source should be 0,1 or 2 (DSP, User or Table)
722 source = tvb_get_ntohl(tvb, offset+4);
723 if ( (tvb_len == 48) && ((source > -1) && (source <3)) )
724 return ACTRACE_CAS;
725 /* is ISDN packet?
726 * the ISDN packets have 0x49446463 for packets from PSTN to the Blade and
727 * 0x49644443 for packets from the Blade to the PSTN at offset 4
729 isdn_header = tvb_get_ntohl(tvb, offset+4);
730 if ( (tvb_len >= 50) && ( (isdn_header == PSTN_TO_BLADE) || (isdn_header == BLADE_TO_PSTN)) )
731 return ACTRACE_ISDN;
732 return NOT_ACTRACE;
735 /* Register all the bits needed with the filtering engine */
736 void proto_register_actrace(void)
738 static hf_register_info hf[] =
740 /* CAS */
741 { &hf_actrace_cas_time,
742 { "Time", "actrace.cas.time", FT_INT32, BASE_DEC, NULL, 0x0,
743 "Capture Time", HFILL }},
744 { &hf_actrace_cas_source,
745 { "Source", "actrace.cas.source", FT_INT32, BASE_DEC, VALS(actrace_cas_source_vals), 0x0,
746 NULL, HFILL }},
747 { &hf_actrace_cas_current_state,
748 { "Current State", "actrace.cas.curr_state", FT_INT32, BASE_DEC, NULL, 0x0,
749 NULL, HFILL }},
750 { &hf_actrace_cas_event,
751 { "Event", "actrace.cas.event", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_event_vals_ext, 0x0,
752 "New Event", HFILL }},
753 { &hf_actrace_cas_next_state,
754 { "Next State", "actrace.cas.next_state", FT_INT32, BASE_DEC, NULL, 0x0,
755 NULL, HFILL }},
756 { &hf_actrace_cas_function,
757 { "Function", "actrace.cas.function", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_function_vals_ext, 0x0,
758 NULL, HFILL }},
759 { &hf_actrace_cas_par0,
760 { "Parameter 0", "actrace.cas.par0", FT_INT32, BASE_DEC, NULL, 0x0,
761 NULL, HFILL }},
762 { &hf_actrace_cas_par1,
763 { "Parameter 1", "actrace.cas.par1", FT_INT32, BASE_DEC, NULL, 0x0,
764 NULL, HFILL }},
765 { &hf_actrace_cas_par2,
766 { "Parameter 2", "actrace.cas.par2", FT_INT32, BASE_DEC, NULL, 0x0,
767 NULL, HFILL }},
768 { &hf_actrace_cas_trunk,
769 { "Trunk Number", "actrace.cas.trunk", FT_INT32, BASE_DEC, NULL, 0x0,
770 NULL, HFILL }},
771 { &hf_actrace_cas_bchannel,
772 { "BChannel", "actrace.cas.bchannel", FT_INT32, BASE_DEC, NULL, 0x0,
773 NULL, HFILL }},
774 { &hf_actrace_cas_connection_id,
775 { "Connection ID", "actrace.cas.conn_id", FT_INT32, BASE_DEC, NULL, 0x0,
776 NULL, HFILL }},
778 /* ISDN */
779 { &hf_actrace_isdn_trunk,
780 { "Trunk Number", "actrace.isdn.trunk", FT_INT16, BASE_DEC, NULL, 0x0,
781 NULL, HFILL }},
782 { &hf_actrace_isdn_direction,
783 { "Direction", "actrace.isdn.dir", FT_INT32, BASE_DEC, VALS(actrace_isdn_direction_vals), 0x0,
784 NULL, HFILL }},
785 { &hf_actrace_isdn_length,
786 { "Length", "actrace.isdn.length", FT_INT16, BASE_DEC, NULL, 0x0,
787 NULL, HFILL }},
790 static gint *ett[] =
792 &ett_actrace,
795 module_t *actrace_module;
797 /* Register protocol */
798 proto_actrace = proto_register_protocol("AudioCodes Trunk Trace", "ACtrace", "actrace");
799 proto_register_field_array(proto_actrace, hf, array_length(hf));
800 proto_register_subtree_array(ett, array_length(ett));
802 /* Register our configuration options */
803 actrace_module = prefs_register_protocol(proto_actrace, proto_reg_handoff_actrace);
805 prefs_register_uint_preference(actrace_module, "udp_port",
806 "AudioCodes Trunk Trace UDP port",
807 "Set the UDP port for AudioCodes Trunk Traces."
808 "Use http://x.x.x.x/TrunkTraces to enable the traces in the Blade",
809 10, &global_actrace_udp_port);
811 prefs_register_obsolete_preference(actrace_module, "display_dissect_tree");
813 actrace_tap = register_tap("actrace");
816 /* The registration hand-off routine */
817 void proto_reg_handoff_actrace(void)
819 static gboolean actrace_prefs_initialized = FALSE;
820 static dissector_handle_t actrace_handle;
821 static guint actrace_udp_port;
823 if (!actrace_prefs_initialized)
825 actrace_handle = new_create_dissector_handle(dissect_actrace, proto_actrace);
826 /* Get a handle for the lapd dissector. */
827 lapd_handle = find_dissector("lapd");
828 actrace_prefs_initialized = TRUE;
830 else
832 dissector_delete_uint("udp.port", actrace_udp_port, actrace_handle);
835 /* Set our port number for future use */
836 actrace_udp_port = global_actrace_udp_port;
838 dissector_add_uint("udp.port", global_actrace_udp_port, actrace_handle);