summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-actrace.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-actrace.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-actrace.c')
-rw-r--r--epan/dissectors/packet-actrace.c816
1 files changed, 816 insertions, 0 deletions
diff --git a/epan/dissectors/packet-actrace.c b/epan/dissectors/packet-actrace.c
new file mode 100644
index 00000000..83a597d3
--- /dev/null
+++ b/epan/dissectors/packet-actrace.c
@@ -0,0 +1,816 @@
+/* packet-actrace.c
+ * Routines for AudioCodes Trunk traces packet disassembly
+ *
+ * Copyright (c) 2005 by Alejandro Vaquero <alejandro.vaquero@verso.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/tap.h>
+#include <wiretap/wtap.h>
+#include "packet-actrace.h"
+
+#define UDP_PORT_ACTRACE 2428 /* Not IANA registered */
+
+#define NOT_ACTRACE 0
+#define ACTRACE_CAS 1
+#define ACTRACE_ISDN 2
+
+
+/* Forward declarations */
+void proto_register_actrace(void);
+void proto_reg_handoff_actrace(void);
+
+static dissector_handle_t actrace_handle;
+
+/* Define the actrace proto */
+static int proto_actrace = -1;
+
+/* Define many headers for actrace */
+/* ISDN headers */
+static int hf_actrace_isdn_direction = -1;
+static int hf_actrace_isdn_trunk = -1;
+static int hf_actrace_isdn_length = -1;
+
+
+/* CAS headers */
+static int hf_actrace_cas_time = -1;
+static int hf_actrace_cas_source = -1;
+static int hf_actrace_cas_current_state = -1;
+static int hf_actrace_cas_event = -1;
+static int hf_actrace_cas_next_state = -1;
+static int hf_actrace_cas_function = -1;
+static int hf_actrace_cas_par0 = -1;
+static int hf_actrace_cas_par1 = -1;
+static int hf_actrace_cas_par2 = -1;
+static int hf_actrace_cas_trunk = -1;
+static int hf_actrace_cas_bchannel = -1;
+static int hf_actrace_cas_connection_id = -1;
+
+
+
+static dissector_handle_t lapd_phdr_handle;
+
+#define ACTRACE_CAS_SOURCE_DSP 0
+#define ACTRACE_CAS_SOURCE_USER 1
+#define ACTRACE_CAS_SOURCE_TABLE 2
+
+static const value_string actrace_cas_source_vals[] = {
+ {ACTRACE_CAS_SOURCE_DSP, "DSP"},
+ {ACTRACE_CAS_SOURCE_USER, "User"},
+ {ACTRACE_CAS_SOURCE_TABLE, "Table"},
+ {0, NULL }
+};
+
+static const value_string actrace_cas_source_vals_short[] = {
+ {ACTRACE_CAS_SOURCE_DSP, "D"},
+ {ACTRACE_CAS_SOURCE_USER, "U"},
+ {ACTRACE_CAS_SOURCE_TABLE, "T"},
+ {0, NULL }
+};
+
+#define ACTRACE_CAS_EV_11 17
+#define ACTRACE_CAS_EV_10 18
+#define ACTRACE_CAS_EV_01 19
+#define ACTRACE_CAS_EV_00 20
+
+#define ACTRACE_CAS_EV_DTMF 302
+#define ACTRACE_CAS_EV_FIRST_DIGIT 63
+
+static const value_string actrace_cas_event_ab_vals[] = {
+ {ACTRACE_CAS_EV_11, "11"},
+ {ACTRACE_CAS_EV_10, "10"},
+ {ACTRACE_CAS_EV_01, "01"},
+ {ACTRACE_CAS_EV_00, "00"},
+ {0, NULL}
+};
+
+static const value_string actrace_cas_mf_vals[] = {
+ {32, "1"},
+ {33, "2"},
+ {34, "3"},
+ {35, "4"},
+ {36, "5"},
+ {37, "6"},
+ {38, "7"},
+ {39, "8"},
+ {40, "9"},
+ {41, "0"},
+ {42, "A"},
+ {43, "B"},
+ {44, "C"},
+ {45, "*"},
+ {46, "#"},
+ {0, NULL}
+};
+static value_string_ext actrace_cas_mf_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_mf_vals);
+
+static const value_string actrace_cas_event_vals[] = {
+ { 0, "FUNCTION0"},
+ { 1, "FUNCTION1"},
+ { 2, "FUNCTION2"},
+ { 3, "FUNCTION3"},
+ { 4, "EV_PLACE_CALL"},
+ { 5, "EV_TIMER_EXPIRED1"},
+ { 6, "EV_TIMER_EXPIRED2"},
+ { 7, "EV_TIMER_EXPIRED3"},
+ { 8, "EV_TIMER_EXPIRED4"},
+ { 9, "EV_TIMER_EXPIRED5"},
+ { 10, "EV_TIMER_EXPIRED6"},
+ { 11, "EV_TIMER_EXPIRED7"},
+ { 12, "EV_TIMER_EXPIRED8"},
+ { 13, "EV_ANSWER"},
+ { 14, "EV_DIAL_TONE_DETECTED"},
+ { 15, "EV_DIAL_ENDED"},
+ { 16, "EV_DISCONNECT"},
+ { ACTRACE_CAS_EV_11, "EV_CAS_1_1"},
+ { ACTRACE_CAS_EV_10, "EV_CAS_1_0"},
+ { ACTRACE_CAS_EV_01, "EV_CAS_0_1"},
+ { ACTRACE_CAS_EV_00, "EV_CAS_0_0"},
+ { 21, "EV_RB_TONE_STARTED"},
+ { 22, "EV_RB_TONE_STOPPED"},
+ { 23, "EV_BUSY_TONE"},
+ { 24, "EV_FAST_BUSY_TONE"},
+ { 25, "EV_HELLO_DETECTED"},
+ { 26, "EV_DIAL_TONE_STOPPED"},
+ { 27, "EV_DISCONNECT_INCOMING"},
+ { 28, "EV_RELEASE_CALL"},
+ { 29, "EV_DIALED_NUM_DETECTED"},
+ { 30, "EV_COUNTER1_EXPIRED"},
+ { 31, "EV_COUNTER2_EXPIRED"},
+ { 32, "EV_MFRn_1"},
+ { 33, "EV_MFRn_2"},
+ { 34, "EV_MFRn_3"},
+ { 35, "EV_MFRn_4"},
+ { 36, "EV_MFRn_5"},
+ { 37, "EV_MFRn_6"},
+ { 38, "EV_MFRn_7"},
+ { 39, "EV_MFRn_8"},
+ { 40, "EV_MFRn_9"},
+ { 41, "EV_MFRn_10"},
+ { 42, "EV_MFRn_11"},
+ { 43, "EV_MFRn_12"},
+ { 44, "EV_MFRn_13"},
+ { 45, "EV_MFRn_14"},
+ { 46, "EV_MFRn_15"},
+ { 47, "EV_MFRn_1_STOPPED"},
+ { 48, "EV_MFRn_2_STOPPED"},
+ { 49, "EV_MFRn_3_STOPPED"},
+ { 50, "EV_MFRn_4_STOPPED"},
+ { 51, "EV_MFRn_5_STOPPED"},
+ { 52, "EV_MFRn_6_STOPPED"},
+ { 53, "EV_MFRn_7_STOPPED"},
+ { 54, "EV_MFRn_8_STOPPED"},
+ { 55, "EV_MFRn_9_STOPPED"},
+ { 56, "EV_MFRn_10_STOPPED"},
+ { 57, "EV_MFRn_11_STOPPED"},
+ { 58, "EV_MFRn_12_STOPPED"},
+ { 59, "EV_MFRn_13_STOPPED"},
+ { 60, "EV_MFRn_14_STOPPED"},
+ { 61, "EV_MFRn_15_STOPPED"},
+ { 62, "EV_ANI_NUM_DETECTED"},
+ { ACTRACE_CAS_EV_FIRST_DIGIT, "EV_FIRST_DIGIT"},
+ { 64, "EV_END_OF_MF_DIGIT"},
+ { 65, "EV_ACCEPT"},
+ { 66, "EV_REJECT_BUSY"},
+ { 67, "EV_REJECT_CONGESTION"},
+ { 68, "EV_REJECT_UNALLOCATED"},
+ { 69, "EV_REJECT_RESERVE1"},
+ { 70, "EV_REJECT_RESERVE2"},
+ { 71, "EV_NO_ANI"},
+ { 100, "EV_INIT_CHANNEL"},
+ { 101, "EV_BUSY_TONE_STOPPED"},
+ { 102, "EV_FAST_BUSY_TONE_STOPPED"},
+ { 103, "EV_TO_USER"},
+ { 104, "SEND_FIRST_DIGIT"},
+ { 110, "EV_CLOSE_CHANNEL"},
+ { 111, "EV_OPEN_CHANNEL"},
+ { 112, "EV_FAIL_DIAL"},
+ { 113, "EV_FAIL_SEND_CAS"},
+ { 114, "EV_ALARM"},
+ { ACTRACE_CAS_EV_DTMF, "EV_DTMF"},
+ {1010, "EV_TIMER_EXPIRED10"},
+ {1020, "EV_DEBOUNCE_TIMER_EXPIRED"},
+ {1030, "EV_INTER_DIGIT_TIMER_EXPIRED"},
+ {0, NULL}
+};
+static value_string_ext actrace_cas_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_event_vals);
+
+#define SEND_CAS 2
+#define SEND_EVENT 3
+#define CHANGE_COLLECT_TYPE 13
+#define SEND_MF 8
+#define SEND_DEST_NUM 4
+
+static const value_string actrace_cas_function_vals[] = {
+ { 0, "NILL"},
+ { 1, "SET_TIMER"},
+ { SEND_CAS, "SEND_CAS"},
+ { SEND_EVENT, "SEND_EVENT"},
+ { SEND_DEST_NUM, "SEND_DEST_NUM"},
+ { 5, "DEL_TIMER"},
+ { 6, "START_COLLECT"},
+ { 7, "STOP_COLLECT"},
+ { SEND_MF, "SEND_MF"},
+ { 9, "STOP_DIAL_MF"},
+ {10, "SET_COUNTER"},
+ {11, "DEC_COUNTER"},
+ {12, "SEND_PROG_TON"},
+ {CHANGE_COLLECT_TYPE, "CHANGE_COLLECT_TYPE"},
+ {14, "GENERATE_CAS_EV"},
+ {0, NULL}
+};
+static value_string_ext actrace_cas_function_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_function_vals);
+
+static const value_string actrace_cas_pstn_event_vals[] = {
+ { 64, "acEV_PSTN_INTERNAL_ERROR"},
+ { 65, "acEV_PSTN_CALL_CONNECTED"},
+ { 66, "acEV_PSTN_INCOMING_CALL_DETECTED"},
+ { 67, "acEV_PSTN_CALL_DISCONNECTED"},
+ { 68, "acEV_PSTN_CALL_RELEASED"},
+ { 69, "acEV_PSTN_REMOTE_ALERTING"},
+ { 70, "acEV_PSTN_STARTED"},
+ { 71, "acEV_PSTN_WARNING"},
+ { 72, "acEV_ISDN_PROGRESS_INDICATION"},
+ { 73, "acEV_PSTN_PROCEEDING_INDICATION"},
+ { 74, "acEV_PSTN_ALARM"},
+ { 75, "acEV_RESERVED"},
+ { 76, "acEV_PSTN_LINE_INFO"},
+ { 77, "acEV_PSTN_LOOP_CONFIRM"},
+ { 78, "acEV_PSTN_RESTART_CONFIRM"},
+ { 84, "acEV_ISDN_SETUP_ACK_IN"},
+ { 85, "acEV_PSTN_CALL_INFORMATION"},
+ {128, "acEV_CAS_SEIZURE_DETECTED"},
+ {129, "acEV_CAS_CHANNEL_BLOCKED"},
+ {130, "acEV_CAS_PROTOCOL_STARTED"},
+ {131, "acEV_PSTN_CALL_STATE_RESPONSE"},
+ {132, "acEV_CAS_SEIZURE_ACK"},
+ {0, NULL}
+};
+static value_string_ext actrace_cas_pstn_event_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_pstn_event_vals);
+
+static const value_string actrace_cas_collect_type_vals[] = {
+ {0, "COLLECT_TYPE_ADDRESS"},
+ {1, "COLLECT_TYPE_ANI"},
+ {2, "COLLECT_TYPE_SOURCE_CATEGORY"},
+ {3, "COLLECT_TYPE_LINE_CATEGORY"},
+ {0, NULL}
+};
+
+#define SEND_TYPE_ADDRESS 1
+#define SEND_TYPE_SPECIFIC 2
+#define SEND_TYPE_INTER_EXCHANGE_SWITCH 3
+#define SEND_TYPE_ANI 4
+#define SEND_TYPE_SOURCE_CATEGORY 5
+#define SEND_TYPE_TRANSFER_CAPABILITY 6
+
+static const value_string actrace_cas_send_type_vals[] = {
+ {SEND_TYPE_ADDRESS, "ADDRESS"},
+ {SEND_TYPE_SPECIFIC, "SPECIFIC"},
+ {SEND_TYPE_INTER_EXCHANGE_SWITCH, "INTER_EXCHANGE_SWITCH"},
+ {SEND_TYPE_ANI, "ANI"},
+ {SEND_TYPE_SOURCE_CATEGORY, "SOURCE_CATEGORY"},
+ {SEND_TYPE_TRANSFER_CAPABILITY, "TRANSFER_CAPABILITY"},
+ {0, NULL}
+};
+
+static const value_string actrace_cas_cause_vals[] = {
+ { 1, "UNASSIGNED_NUMBER"},
+ { 2, "NO_ROUTE_TO_TRANSIT_NET"},
+ { 3, "NO_ROUTE_TO_DESTINATION"},
+ { 6, "CHANNEL_UNACCEPTABLE"},
+ { 7, "CALL_AWARDED_AND"},
+ { 8, "PREEMPTION"},
+ { 16, "NORMAL_CALL_CLEAR"},
+ { 17, "USER_BUSY"},
+ { 18, "NO_USER_RESPONDING"},
+ { 19, "NO_ANSWER_FROM_USER_ALERTED"},
+ { 20, "ACCEPT_DONE"},
+ { 21, "CALL_REJECTED"},
+ { 22, "NUMBER_CHANGED"},
+ { 26, "NON_SELECTED_USER_CLEARING"},
+ { 27, "DEST_OUT_OF_ORDER"},
+ { 28, "INVALID_NUMBER_FORMAT"},
+ { 29, "FACILITY_REJECT"},
+ { 30, "RESPONSE_TO_STATUS_ENQUIRY"},
+ { 31, "NORMAL_UNSPECIFIED"},
+ { 32, "CIRCUIT_CONGESTION"},
+ { 33, "USER_CONGESTION"},
+ { 34, "NO_CIRCUIT_AVAILABLE"},
+ { 38, "NETWORK_OUT_OF_ORDER"},
+ { 39, "PERM_FR_MODE_CONN_OUT_OF_S"},
+ { 40, "PERM_FR_MODE_CONN_OPERATIONAL"},
+ { 41, "NETWORK_TEMPORARY_FAILURE"},
+ { 42, "NETWORK_CONGESTION"},
+ { 43, "ACCESS_INFORMATION_DISCARDED"},
+ { 44, "REQUESTED_CIRCUIT_NOT_AVAILABLE"},
+ { 46, "PRECEDENCE_CALL_BLOCKED"},
+ { 47, "RESOURCE_UNAVAILABLE_UNSPECIFIED"},
+ { 49, "QUALITY_OF_SERVICE_UNAVAILABLE"},
+ { 50, "REQUESTED_FAC_NOT_SUBSCRIBED"},
+ { 53, "CUG_OUT_CALLS_BARRED"},
+ { 55, "CUG_INC_CALLS_BARRED"},
+ { 57, "BC_NOT_AUTHORIZED"},
+ { 58, "BC_NOT_PRESENTLY_AVAILABLE"},
+ { 62, "ACCES_INFO_SUBS_CLASS_INCONS"},
+ { 63, "SERVICE_NOT_AVAILABLE"},
+ { 65, "BC_NOT_IMPLEMENTED"},
+ { 66, "CHANNEL_TYPE_NOT_IMPLEMENTED"},
+ { 69, "REQUESTED_FAC_NOT_IMPLEMENTED"},
+ { 70, "ONLY_RESTRICTED_INFO_BEARER"},
+ { 79, "SERVICE_NOT_IMPLEMENTED_UNSPECIFIED"},
+ { 81, "INVALID_CALL_REF"},
+ { 82, "IDENTIFIED_CHANNEL_NOT_EXIST"},
+ { 83, "SUSPENDED_CALL_BUT_CALL_ID_NOT_EXIST"},
+ { 84, "CALL_ID_IN_USE"},
+ { 85, "NO_CALL_SUSPENDED"},
+ { 86, "CALL_HAVING_CALL_ID_CLEARED"},
+ { 87, "NOT_CUG_MEMBER"},
+ { 88, "INCOMPATIBLE_DESTINATION"},
+ { 90, "CUG_NON_EXISTENT"},
+ { 91, "INVALID_TRANSIT_NETWORK_SELECTION"},
+ { 95, "INVALID_MESSAGE_UNSPECIFIED"},
+ { 96, "MANDATORY_IE_MISSING"},
+ { 97, "MESSAGE_TYPE_NON_EXISTENT"},
+ { 98, "MESSAGE_STATE_INCONSISTENCY"},
+ { 99, "NON_EXISTENT_IE"},
+ {100, "INVALID_IE_CONTENT"},
+ {101, "MESSAGE_NOT_COMPATIBLE"},
+ {102, "RECOVERY_ON_TIMER_EXPIRY"},
+ {111, "PROTOCOL_ERROR_UNSPECIFIED"},
+ {127, "INTERWORKING_UNSPECIFIED"},
+ {128, "ACU_CAUSE_ACU_BAD_ADDRESS"},
+ {129, "ACU_CAUSE_ACU_BAD_SERVICE"},
+ {130, "ACU_CAUSE_ACU_COLLISION"},
+ {131, "ACU_CAUSE_ACU_FAC_REJECTED"},
+ {200, "C_ALREADY_BLOCKED"},
+ {201, "C_CHANNEL_BLOCKED"},
+ {202, "C_BLOCKING_DONE"},
+ {203, "C_ALREADY_UNBLOCKED"},
+ {204, "C_UNBLOCKING_DONE"},
+ {255, "ACU_NETWORK_CAUSE_NIL"},
+ {260, "CLRN_MFRn_A4"},
+ {261, "CLRN_MFRn_B1"},
+ {262, "CLRN_MFRn_B2"},
+ {263, "CLRN_MFRn_B3"},
+ {264, "CLRN_MFRn_B4"},
+ {265, "CLRN_MFRn_B5"},
+ {266, "CLRN_MFRn_B6"},
+ {267, "CLRN_MFRn_B7"},
+ {268, "CLRN_MFRn_B8"},
+ {269, "CLRN_MFRn_B9"},
+ {270, "CLRN_MFRn_B10"},
+ {271, "CLRN_MFRn_B11"},
+ {272, "CLRN_MFRn_B12"},
+ {273, "CLRN_MFRn_B13"},
+ {274, "CLRN_MFRn_B14"},
+ {275, "CLRN_MFRn_B15"},
+ {300, "ACURC_BUSY"},
+ {301, "ACURC_NOPROCEED"},
+ {302, "ACURC_NOANSWER"},
+ {303, "ACURC_NOAUTOANSWER"},
+ {304, "ACURC_CONGESTED"},
+ {305, "ACURC_INCOMING"},
+ {306, "ACURC_NOLINE"},
+ {307, "ACURC_ERRNUM"},
+ {308, "ACURC_INHNUM"},
+ {309, "ACURC_2MNUM"},
+ {310, "ACURC_HUNGUP"},
+ {311, "ACURC_NETWORK_ERROR"},
+ {312, "ACURC_TIMEOUT"},
+ {313, "ACURC_BAD_SERVICE"},
+ {314, "ACURC_INTERNAL"},
+ {315, "ACURC_OK"},
+ {316, "ACURC_BL_TIMEOUT"},
+ {317, "ACURC_IN_CALL"},
+ {318, "ACURC_CLEAR_RQ"},
+ {0, NULL}
+};
+static value_string_ext actrace_cas_cause_vals_ext = VALUE_STRING_EXT_INIT(actrace_cas_cause_vals);
+
+/* ISDN */
+#define PSTN_TO_BLADE 0x49446463
+#define BLADE_TO_PSTN 0x49644443
+
+static const value_string actrace_isdn_direction_vals[] = {
+ {PSTN_TO_BLADE, "Blade <-- PSTN"},
+ {BLADE_TO_PSTN, "Blade --> PSTN"},
+ {0, NULL}
+};
+
+/*
+ * Define the tree for actrace
+ */
+static int ett_actrace = -1;
+
+/*
+ * Define the tap for actrace
+ */
+static int actrace_tap = -1;
+static actrace_info_t *actrace_pi;
+
+/* Some basic utility functions that are specific to this dissector */
+static int is_actrace(tvbuff_t *tvb, gint offset);
+
+/*
+ * The dissect functions
+ */
+static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree);
+static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *actrace_tree);
+
+/************************************************************************
+ * dissect_actrace - The dissector for the AudioCodes Trace prtocol
+ ************************************************************************/
+static int dissect_actrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ proto_tree *actrace_tree;
+ proto_item *ti;
+ int actrace_protocol;
+
+ /* Initialize variables */
+ actrace_tree = NULL;
+
+ /*
+ * Check to see whether we're really dealing with AC trace by looking
+ * for a valid "source" and fixed len for CAS, and the direction for ISDN.
+ * This isn't infallible, but it's cheap and it's better than nothing.
+ */
+ actrace_protocol = is_actrace(tvb, 0);
+ if (actrace_protocol != NOT_ACTRACE)
+ {
+ /*
+ * Set the columns now, so that they'll be set correctly if we throw
+ * an exception. We can set them later as well....
+ */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_TRACE");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (tree)
+ {
+ /* Create our actrace subtree */
+ ti = proto_tree_add_item(tree,proto_actrace,tvb,0,-1, ENC_NA);
+ actrace_tree = proto_item_add_subtree(ti, ett_actrace);
+ }
+
+ switch (actrace_protocol)
+ {
+ case ACTRACE_CAS:
+ dissect_actrace_cas(tvb, pinfo, actrace_tree);
+ break;
+ case ACTRACE_ISDN:
+ dissect_actrace_isdn(tvb, pinfo, tree, actrace_tree);
+ break;
+ }
+ return tvb_captured_length(tvb);
+ }
+
+ return 0;
+}
+
+/* Dissect an individual actrace CAS message */
+static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree)
+{
+ /* Declare variables */
+ gint32 value, function, trunk, bchannel, source, event, curr_state, next_state;
+ gint32 par0, par1, par2;
+ const gchar *frame_label = NULL;
+ int direction = 0;
+ int offset = 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS");
+
+ value = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value);
+ offset += 4;
+
+ source = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source);
+ offset += 4;
+
+ curr_state = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state);
+ offset += 4;
+
+ event = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event);
+ offset += 4;
+
+ next_state = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state);
+ offset += 4;
+
+ function = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function);
+ offset += 4;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|",
+ val_to_str_const(source, actrace_cas_source_vals_short, "ukn"),
+ curr_state,
+ val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"),
+ next_state,
+ val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d"));
+
+ par0 = tvb_get_ntohl(tvb, offset);
+ switch (function)
+ {
+ case SEND_EVENT:
+ proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
+ par0, "%s", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "Unknown (%d)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
+ val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d"));
+ break;
+ case CHANGE_COLLECT_TYPE:
+ proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
+ par0, "%s", val_to_str(par0, actrace_cas_collect_type_vals, "Unknown (%d)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
+ val_to_str(par0, actrace_cas_collect_type_vals, "%d"));
+ break;
+ case SEND_MF:
+ case SEND_DEST_NUM:
+ proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4,
+ par0, "%s", val_to_str(par0, actrace_cas_send_type_vals, "Unknown (%d)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
+ val_to_str(par0, actrace_cas_send_type_vals, "%d"));
+ break;
+ default:
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0);
+ }
+ offset += 4;
+
+ par1 = tvb_get_ntohl(tvb, offset);
+ if (function == SEND_EVENT) {
+ proto_tree_add_int_format_value(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4,
+ par1, "%s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
+ val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d"));
+ } else {
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1);
+ }
+ offset += 4;
+
+ par2 = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2);
+ offset += 4;
+
+ trunk = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk);
+ offset += 4;
+
+ bchannel = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel);
+ offset += 4;
+
+ col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel);
+
+ value = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value);
+
+ /* Add tap info for the Voip Graph */
+ if (source == ACTRACE_CAS_SOURCE_DSP) {
+ direction = 1;
+ if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) {
+ frame_label = wmem_strdup_printf(pinfo->pool, "AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") );
+ } else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */
+ frame_label = wmem_strdup_printf(pinfo->pool, "MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") );
+ } else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */
+ frame_label = wmem_strdup_printf(pinfo->pool, "DTMF: %u", par0 );
+ }
+ } else if (source == ACTRACE_CAS_SOURCE_TABLE) {
+ direction = 0;
+ if (function == SEND_MF) {
+ if (par0 == SEND_TYPE_SPECIFIC ) {
+ frame_label = wmem_strdup_printf(pinfo->pool, "MF: %u", par1);
+ } else if (par0 == SEND_TYPE_ADDRESS ) {
+ frame_label = wmem_strdup(pinfo->pool, "MF: DNIS digit");
+ } else if (par0 == SEND_TYPE_ANI ) {
+ frame_label = wmem_strdup(pinfo->pool, "MF: ANI digit");
+ } else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
+ frame_label = wmem_strdup(pinfo->pool, "MF: src_category");
+ } else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
+ frame_label = wmem_strdup(pinfo->pool, "MF: trf_capability");
+ } else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
+ frame_label = wmem_strdup(pinfo->pool, "MF: inter_exch_sw");
+ }
+ } else if (function == SEND_CAS) {
+ frame_label = wmem_strdup_printf(pinfo->pool, "AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR"));
+ } else if (function == SEND_DEST_NUM) {
+ if (par0 == SEND_TYPE_ADDRESS ) {
+ frame_label = wmem_strdup(pinfo->pool, "DTMF/MF: sending DNIS");
+ } else if (par0 == SEND_TYPE_ANI ) {
+ frame_label = wmem_strdup(pinfo->pool, "DTMF/MF: sending ANI");
+ }
+ }
+ }
+
+ if (frame_label != NULL) {
+ /* Initialise packet info for passing to tap */
+ actrace_pi = wmem_new(pinfo->pool, actrace_info_t);
+
+ actrace_pi->type = ACTRACE_CAS;
+ actrace_pi->direction = direction;
+ actrace_pi->trunk = trunk;
+ actrace_pi->cas_bchannel = bchannel;
+ actrace_pi->cas_frame_label = frame_label;
+ /* Report this packet to the tap */
+ tap_queue_packet(actrace_tap, pinfo, actrace_pi);
+ }
+}
+
+/* Dissect an individual actrace ISDN message */
+static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *actrace_tree)
+{
+ /* Declare variables */
+ gint len;
+ gint32 value, trunk;
+ tvbuff_t *next_tvb;
+ int offset = 0;
+ struct isdn_phdr isdn;
+
+ offset += 4;
+
+ value = tvb_get_ntohl(tvb, offset+4);
+ proto_tree_add_int(actrace_tree, hf_actrace_isdn_direction, tvb, offset, 4, value);
+ offset += 4;
+ /* PSTN = Network */
+ isdn.uton = (value==BLADE_TO_PSTN);
+ isdn.channel = 0; /* D channel */
+
+ trunk = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_isdn_trunk, tvb, offset, 2, trunk);
+ offset += 4;
+
+ offset += 32;
+
+ len = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_int(actrace_tree, hf_actrace_isdn_length, tvb, offset, 2, len);
+
+ /* if it is a q931 packet (we don't want LAPD packets for Voip Graph) add tap info */
+ if (len > 4) {
+ /* Initialise packet info for passing to tap */
+ actrace_pi = wmem_new(pinfo->pool, actrace_info_t);
+
+ actrace_pi->type = ACTRACE_ISDN;
+ actrace_pi->direction = (value==PSTN_TO_BLADE?1:0);
+ actrace_pi->trunk = trunk;
+
+ /* Report this packet to the tap */
+ tap_queue_packet(actrace_tap, pinfo, actrace_pi);
+ }
+
+ /* Dissect lapd payload */
+ offset += 2 ;
+ next_tvb = tvb_new_subset_length(tvb, offset, len);
+ call_dissector_with_data(lapd_phdr_handle, next_tvb, pinfo, tree, &isdn);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_ISDN");
+ col_prepend_fstr(pinfo->cinfo, COL_INFO, "Trunk:%d Blade %s PSTN "
+ , trunk, value==PSTN_TO_BLADE?"<--":"-->");
+}
+
+/*
+ * is_actrace - A function for determining whether there is a
+ * AudioCodes packet at offset in tvb. The packet could be
+ * a CAS, ISDN or other Trunk protocol. Here we are only
+ * trying to decode CAS or ISDN protocols
+ *
+ * Parameter:
+ * tvb - The tvbuff in which we are looking for
+ * offset - The offset in tvb at which we are looking for
+ *
+ * Return: NOT_ACTRACE if there isn't an AudioCodes trace packet at offset
+ * in tvb, ACTRACE_CAS if there's a CAS packet there, ACTRACE_ISDN if
+ * there's an ISDN packet there.
+ */
+static int is_actrace(tvbuff_t *tvb, gint offset)
+{
+ gint tvb_len;
+ gint32 source, isdn_header;
+
+ tvb_len = tvb_reported_length(tvb);
+
+ /* is a CAS packet?
+ * the CAS messages are 48 byte fixed and the source should be 0,1 or 2 (DSP, User or Table)
+ */
+ source = tvb_get_ntohl(tvb, offset+4);
+ if ( (tvb_len == 48) && ((source > -1) && (source <3)) )
+ return ACTRACE_CAS;
+ /* is ISDN packet?
+ * the ISDN packets have 0x49446463 for packets from PSTN to the Blade and
+ * 0x49644443 for packets from the Blade to the PSTN at offset 4
+ */
+ isdn_header = tvb_get_ntohl(tvb, offset+4);
+ if ( (tvb_len >= 50) && ( (isdn_header == PSTN_TO_BLADE) || (isdn_header == BLADE_TO_PSTN)) )
+ return ACTRACE_ISDN;
+ return NOT_ACTRACE;
+}
+
+/* Register all the bits needed with the filtering engine */
+void proto_register_actrace(void)
+{
+ static hf_register_info hf[] =
+ {
+ /* CAS */
+ { &hf_actrace_cas_time,
+ { "Time", "actrace.cas.time", FT_INT32, BASE_DEC, NULL, 0x0,
+ "Capture Time", HFILL }},
+ { &hf_actrace_cas_source,
+ { "Source", "actrace.cas.source", FT_INT32, BASE_DEC, VALS(actrace_cas_source_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_current_state,
+ { "Current State", "actrace.cas.curr_state", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_event,
+ { "Event", "actrace.cas.event", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_event_vals_ext, 0x0,
+ "New Event", HFILL }},
+ { &hf_actrace_cas_next_state,
+ { "Next State", "actrace.cas.next_state", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_function,
+ { "Function", "actrace.cas.function", FT_INT32, BASE_DEC|BASE_EXT_STRING, &actrace_cas_function_vals_ext, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_par0,
+ { "Parameter 0", "actrace.cas.par0", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_par1,
+ { "Parameter 1", "actrace.cas.par1", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_par2,
+ { "Parameter 2", "actrace.cas.par2", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_trunk,
+ { "Trunk Number", "actrace.cas.trunk", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_bchannel,
+ { "BChannel", "actrace.cas.bchannel", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_cas_connection_id,
+ { "Connection ID", "actrace.cas.conn_id", FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ /* ISDN */
+ { &hf_actrace_isdn_trunk,
+ { "Trunk Number", "actrace.isdn.trunk", FT_INT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_isdn_direction,
+ { "Direction", "actrace.isdn.dir", FT_INT32, BASE_DEC, VALS(actrace_isdn_direction_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_actrace_isdn_length,
+ { "Length", "actrace.isdn.length", FT_INT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ };
+
+ static gint *ett[] =
+ {
+ &ett_actrace,
+ };
+
+ module_t *actrace_module;
+
+ /* Register protocol */
+ proto_actrace = proto_register_protocol("AudioCodes Trunk Trace", "ACtrace", "actrace");
+ proto_register_field_array(proto_actrace, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ /* Register our configuration options */
+ actrace_module = prefs_register_protocol(proto_actrace, NULL);
+
+ prefs_register_obsolete_preference(actrace_module, "display_dissect_tree");
+
+ actrace_handle = register_dissector("actrace", dissect_actrace, proto_actrace);
+ actrace_tap = register_tap("actrace");
+}
+
+/* The registration hand-off routine */
+void proto_reg_handoff_actrace(void)
+{
+ /* Get a handle for the LAPD-with-pseudoheader dissector. */
+ lapd_phdr_handle = find_dissector_add_dependency("lapd-phdr", proto_actrace);
+
+ dissector_add_uint_with_preference("udp.port", UDP_PORT_ACTRACE, actrace_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */