aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-m3ua.c88
-rw-r--r--epan/dissectors/packet-mtp3.c3
-rw-r--r--epan/dissectors/packet-mtp3.h1
3 files changed, 83 insertions, 9 deletions
diff --git a/epan/dissectors/packet-m3ua.c b/epan/dissectors/packet-m3ua.c
index 943f096462..c444bd4a38 100644
--- a/epan/dissectors/packet-m3ua.c
+++ b/epan/dissectors/packet-m3ua.c
@@ -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
diff --git a/epan/dissectors/packet-mtp3.c b/epan/dissectors/packet-mtp3.c
index c902f2a649..bcfe0e7d27 100644
--- a/epan/dissectors/packet-mtp3.c
+++ b/epan/dissectors/packet-mtp3.c
@@ -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);
}
diff --git a/epan/dissectors/packet-mtp3.h b/epan/dissectors/packet-mtp3.h
index b9b09d9eda..33b2c8c1bd 100644
--- a/epan/dissectors/packet-mtp3.h
+++ b/epan/dissectors/packet-mtp3.h
@@ -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;