wireshark/epan/dissectors/packet-actrace.c

816 lines
26 KiB
C
Raw Normal View History

/* 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 "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);
/* 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;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
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(wmem_packet_scope(), "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(wmem_packet_scope(), "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(wmem_packet_scope(), "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(wmem_packet_scope(), "MF: %u", par1);
} else if (par0 == SEND_TYPE_ADDRESS ) {
frame_label = wmem_strdup(wmem_packet_scope(), "MF: DNIS digit");
} else if (par0 == SEND_TYPE_ANI ) {
frame_label = wmem_strdup(wmem_packet_scope(), "MF: ANI digit");
} else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
frame_label = wmem_strdup(wmem_packet_scope(), "MF: src_category");
} else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
frame_label = wmem_strdup(wmem_packet_scope(), "MF: trf_capability");
} else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
frame_label = wmem_strdup(wmem_packet_scope(), "MF: inter_exch_sw");
}
} else if (function == SEND_CAS) {
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"));
} else if (function == SEND_DEST_NUM) {
if (par0 == SEND_TYPE_ADDRESS ) {
frame_label = wmem_strdup(wmem_packet_scope(), "DTMF/MF: sending DNIS");
} else if (par0 == SEND_TYPE_ANI ) {
frame_label = wmem_strdup(wmem_packet_scope(), "DTMF/MF: sending ANI");
}
}
}
if (frame_label != NULL) {
/* Initialise packet info for passing to tap */
actrace_pi = wmem_new(wmem_packet_scope(), 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;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
struct isdn_phdr isdn;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
offset += 4;
value = tvb_get_ntohl(tvb, offset+4);
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
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);
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
offset += 4;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
offset += 32;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
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(wmem_packet_scope(), 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);
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
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_tap = register_tap("actrace");
}
/* The registration hand-off routine */
void proto_reg_handoff_actrace(void)
{
dissector_handle_t actrace_handle;
ISDN, LAPD: clean up the way they connect to other dissectors. Have the ISDN dissector take the ISDN pseudo-header through its data argument, rather than assuming it's in pinfo->pseudo_header, so it can be used if the link-layer type of the capture isn't ISDN. Have it add the direction to its protocol tree, so it's there for all ISDN packets. Have more versions of the LAPD dissector: one where the ISDN direction information is available through an ISDN pseudo-header passed as its data argument; one for use when the link-layer type *is* LAPD, where the ISDN direction information may be available through the direction part of the packet flags. Pass more flags to the routine that does LAPD dissection to indicate the direction (user->network or network->user) and whether the user or network side is on another machine; set those appropriately in the dissector routines that call it. To set those flags: in the routine that handles WTAP_ENCAP_LAPD, check the direction flags in pinfo->rec->rec_header.packet_header.pack_flags; in the routine that handles WTAP_ENCAP_LINUX_LAPD, check the SLL header; in the routine that's called from the ISDN dissector and other dissectors that can supply an ISDN pseudo-header, check the struct isdn_phdr passed to it via the data argument; for the routine that's to be called from L2TP pseudowire type and SCTP dissector tables, pass nothing, as there's currently no direction indication supplied - if that information is available from the encapsulating protocol in some fashion, we should make changes to supply that information. Have the AudioCodes Trunk trace protocol dissector call the LAPD-with-pseudoheader dissector, handing it an ISDN pseudo-header with a direction indication from the direction field (and a channel of 0 to indicate the D channel). Have the Ascend text dump reader in libwiretap use WTAP_ENCAP_ASCEND for all packets, even Ethernet and ISDN packets, and have the Ascend text dump dissector handle that, calling the "no FCS" version of the Ethernet dissector and calling the LAPD-with-pseudoheader dissector with a pseudo-header filled in with the direction (and a channel of 0). Have the Catapult DCT 2000 text dump dissector call the LAPD-with-pseudoheader dissector with the pseudo-header supplied by libwireshark. Have the V5 envelope function frame get its ISDN pseudo-header from its data argument, and call the LAPD-with-pseudoheader dissector with that pseudo-header. Have the ISDN dissector treat its data argument as pointing to the ISDN pseudo-header, rather than assuming it's the one in pinfo->pseudo_header->isdn - the latter is the one supplied by libwiretap, but there's no guarantee that an ISDN pseudo-header was supplied by libwiretap, as the lowest-level protocol layer might not have been ISDN. Change-Id: I9f702b879bbc3fb42bcb43c28f797bfc327562c6 Reviewed-on: https://code.wireshark.org/review/37953 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
2020-07-25 09:20:10 +00:00
/* Get a handle for the LAPD-with-pseudoheader dissector. */
lapd_phdr_handle = find_dissector_add_dependency("lapd-phdr", proto_actrace);
actrace_handle = create_dissector_handle(dissect_actrace, 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:
*/