forked from osmocom/wireshark
Add heuristic MTP3 standard detection to M3UA (not for the draft M3UA versions).
The SCCP heuristics actually don't work all that well here but checking the PCs (in M3UA) seems to do a decent job at least of differentiating ANSI from ITU. svn path=/trunk/; revision=47407
This commit is contained in:
parent
5754564be8
commit
21b1b0c5da
|
@ -41,9 +41,13 @@
|
|||
#include <epan/sctpppids.h>
|
||||
#include <epan/emem.h>
|
||||
#include "packet-mtp3.h"
|
||||
#include "packet-sccp.h"
|
||||
#include "packet-frame.h"
|
||||
#include "packet-q708.h"
|
||||
#include <epan/tap.h>
|
||||
|
||||
static gint m3ua_pref_mtp3_standard;
|
||||
|
||||
#define SCTP_PORT_M3UA 2905
|
||||
#define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
|
||||
|
||||
|
@ -1109,24 +1113,92 @@ dissect_circuit_range_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_t
|
|||
#define DATA_SLS_OFFSET (DATA_MP_OFFSET + DATA_MP_LENGTH)
|
||||
#define DATA_ULP_OFFSET (DATA_SLS_OFFSET + DATA_SLS_LENGTH)
|
||||
|
||||
static guint
|
||||
m3ua_heur_mtp3_standard(tvbuff_t *tvb, packet_info *pinfo, guint32 opc, guint32 dpc, guint8 si)
|
||||
{
|
||||
switch (si) {
|
||||
case MTP_SI_SCCP:
|
||||
{
|
||||
if (opc < ITU_PC_MASK && dpc < ITU_PC_MASK &&
|
||||
looks_like_valid_sccp(PINFO_FD_NUM(pinfo), tvb, ITU_STANDARD)) {
|
||||
|
||||
return ITU_STANDARD;
|
||||
}
|
||||
/* Network 0 is reserved in ANSI */
|
||||
/* Could also check that cluster!=0 for small networks (networks 1-5) */
|
||||
if ((opc & ANSI_NETWORK_MASK) > 0 && (dpc & ANSI_NETWORK_MASK) > 0 &&
|
||||
looks_like_valid_sccp(PINFO_FD_NUM(pinfo), tvb, ANSI_STANDARD)) {
|
||||
|
||||
return ANSI_STANDARD;
|
||||
}
|
||||
if (looks_like_valid_sccp(PINFO_FD_NUM(pinfo), tvb, CHINESE_ITU_STANDARD)) {
|
||||
return CHINESE_ITU_STANDARD;
|
||||
}
|
||||
if (opc < JAPAN_PC_MASK && dpc < JAPAN_PC_MASK &&
|
||||
looks_like_valid_sccp(PINFO_FD_NUM(pinfo), tvb, JAPAN_STANDARD)) {
|
||||
|
||||
return JAPAN_STANDARD;
|
||||
}
|
||||
|
||||
return HEURISTIC_FAILED_STANDARD;
|
||||
|
||||
}
|
||||
default:
|
||||
return HEURISTIC_FAILED_STANDARD;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
m3ua_reset_mtp3_standard(void)
|
||||
{
|
||||
mtp3_standard = m3ua_pref_mtp3_standard;
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *parameter_tree, proto_item *parameter_item)
|
||||
{
|
||||
guint16 ulp_length;
|
||||
tvbuff_t *payload_tvb;
|
||||
proto_item *item;
|
||||
proto_item *item, *gen_item;
|
||||
mtp3_tap_rec_t* mtp3_tap = ep_alloc0(sizeof(mtp3_tap_rec_t));
|
||||
proto_tree *q708_tree;
|
||||
gint heuristic_standard;
|
||||
guint8 si;
|
||||
guint32 opc, dpc;
|
||||
|
||||
si = tvb_get_guint8(parameter_tvb, DATA_SI_OFFSET);
|
||||
ulp_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH - DATA_HDR_LENGTH;
|
||||
payload_tvb = tvb_new_subset(parameter_tvb, DATA_ULP_OFFSET, ulp_length, ulp_length);
|
||||
dpc = tvb_get_ntohl(parameter_tvb, DATA_DPC_OFFSET);
|
||||
opc = tvb_get_ntohl(parameter_tvb, DATA_OPC_OFFSET);
|
||||
|
||||
m3ua_pref_mtp3_standard = mtp3_standard;
|
||||
|
||||
if (mtp3_heuristic_standard) {
|
||||
heuristic_standard = m3ua_heur_mtp3_standard(payload_tvb, pinfo, opc, dpc, si);
|
||||
if (heuristic_standard == HEURISTIC_FAILED_STANDARD) {
|
||||
gen_item = proto_tree_add_text(tree, parameter_tvb, 0, 0, "Could not determine Heuristic using %s", val_to_str_const(mtp3_standard, mtp3_standard_vals, "unknown"));
|
||||
} else {
|
||||
gen_item = proto_tree_add_text(tree, parameter_tvb, 0, 0, "%s", val_to_str_const(heuristic_standard, mtp3_standard_vals, "unknown"));
|
||||
|
||||
mtp3_standard = heuristic_standard;
|
||||
|
||||
/* Register a frame-end routine to ensure mtp3_standard is set
|
||||
* back even if an exception is thrown.
|
||||
*/
|
||||
register_frame_end_routine(pinfo, m3ua_reset_mtp3_standard);
|
||||
}
|
||||
PROTO_ITEM_SET_GENERATED(gen_item);
|
||||
}
|
||||
|
||||
mtp3_tap->addr_dpc.type = mtp3_standard;
|
||||
mtp3_tap->addr_dpc.pc = tvb_get_ntohl(parameter_tvb,DATA_DPC_OFFSET);
|
||||
mtp3_tap->addr_dpc.pc = dpc;
|
||||
mtp3_tap->addr_dpc.ni = tvb_get_guint8(parameter_tvb, DATA_NI_OFFSET);
|
||||
SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) &mtp3_tap->addr_dpc);
|
||||
|
||||
|
||||
mtp3_tap->addr_opc.type = mtp3_standard;
|
||||
mtp3_tap->addr_opc.pc = tvb_get_ntohl(parameter_tvb,DATA_OPC_OFFSET);
|
||||
mtp3_tap->addr_opc.pc = opc;
|
||||
mtp3_tap->addr_opc.ni = tvb_get_guint8(parameter_tvb, DATA_NI_OFFSET);
|
||||
SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) &mtp3_tap->addr_opc);
|
||||
|
||||
|
@ -1140,19 +1212,19 @@ dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, pro
|
|||
if (parameter_tree) {
|
||||
item = proto_tree_add_item(parameter_tree, hf_protocol_data_opc, parameter_tvb, DATA_OPC_OFFSET, DATA_OPC_LENGTH, ENC_BIG_ENDIAN);
|
||||
if (mtp3_pc_structured())
|
||||
proto_item_append_text(item, " (%s)", mtp3_pc_to_str(tvb_get_ntohl(parameter_tvb, DATA_OPC_OFFSET)));
|
||||
proto_item_append_text(item, " (%s)", mtp3_pc_to_str(opc));
|
||||
if(mtp3_tap->addr_opc.ni == MTP3_NI_INT0) {
|
||||
q708_tree = proto_item_add_subtree(item,ett_q708_opc);
|
||||
/* Q.708 (1984-10) Numbering of International Signalling Point Codes */
|
||||
analyze_q708_ispc(parameter_tvb, q708_tree, DATA_OPC_OFFSET, DATA_OPC_LENGTH, mtp3_tap->addr_opc.pc);
|
||||
analyze_q708_ispc(parameter_tvb, q708_tree, DATA_OPC_OFFSET, DATA_OPC_LENGTH, opc);
|
||||
}
|
||||
|
||||
item = proto_tree_add_item(parameter_tree, hf_protocol_data_dpc, parameter_tvb, DATA_DPC_OFFSET, DATA_DPC_LENGTH, ENC_BIG_ENDIAN);
|
||||
if (mtp3_pc_structured())
|
||||
proto_item_append_text(item, " (%s)", mtp3_pc_to_str(tvb_get_ntohl(parameter_tvb, DATA_DPC_OFFSET)));
|
||||
proto_item_append_text(item, " (%s)", mtp3_pc_to_str(dpc));
|
||||
if(mtp3_tap->addr_dpc.ni == MTP3_NI_INT0) {
|
||||
q708_tree = proto_item_add_subtree(item,ett_q708_dpc);
|
||||
analyze_q708_ispc(parameter_tvb, q708_tree, DATA_DPC_OFFSET, DATA_DPC_LENGTH, mtp3_tap->addr_dpc.pc);
|
||||
analyze_q708_ispc(parameter_tvb, q708_tree, DATA_DPC_OFFSET, DATA_DPC_LENGTH, dpc);
|
||||
}
|
||||
|
||||
proto_tree_add_item(parameter_tree, hf_protocol_data_si, parameter_tvb, DATA_SI_OFFSET, DATA_SI_LENGTH, ENC_BIG_ENDIAN);
|
||||
|
@ -1185,6 +1257,8 @@ dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, pro
|
|||
payload_tvb = tvb_new_subset(parameter_tvb, DATA_ULP_OFFSET, ulp_length, ulp_length);
|
||||
if (!dissector_try_uint(si_dissector_table, tvb_get_guint8(parameter_tvb, DATA_SI_OFFSET), payload_tvb, pinfo, tree))
|
||||
call_dissector(data_handle, payload_tvb, pinfo, tree);
|
||||
|
||||
mtp3_standard = m3ua_pref_mtp3_standard;
|
||||
}
|
||||
|
||||
#define CORR_ID_OFFSET PARAMETER_VALUE_OFFSET
|
||||
|
|
|
@ -651,7 +651,6 @@ dissect_mtp3_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
call_dissector(data_handle, payload_tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
#define HEURISTIC_FAILED_STANDARD 0xffff
|
||||
static guint
|
||||
heur_mtp3_standard(tvbuff_t *tvb, packet_info *pinfo, guint8 si)
|
||||
{
|
||||
|
@ -721,7 +720,7 @@ dissect_mtp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
mtp3_standard = heuristic_standard;
|
||||
|
||||
/* Register a frame-end routine to ensure mtp3_standard is set
|
||||
* back, even if an exception is thrown.
|
||||
* back even if an exception is thrown.
|
||||
*/
|
||||
register_frame_end_routine(pinfo, reset_mtp3_standard);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ typedef enum {
|
|||
CHINESE_ITU_STANDARD = 3,
|
||||
JAPAN_STANDARD = 4
|
||||
} Standard_Type;
|
||||
#define HEURISTIC_FAILED_STANDARD 0xffff
|
||||
|
||||
extern gint mtp3_standard;
|
||||
extern gboolean mtp3_heuristic_standard;
|
||||
|
|
Loading…
Reference in New Issue