aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2007-04-03 19:08:00 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2007-04-03 19:08:00 +0000
commit9709011a9b553b9c3a9db0931366b6216b7ba4c6 (patch)
tree1ede0f1dc1100843504dacfa6fdfdf154ef95549 /epan/dissectors
parent8177d0f4a9242b0dd1b6c6a3aca63c819d1bda4c (diff)
Implement a proposal from Elefterios Gabriel for SCCP:
Add a table of DPCs and SSNs that allow to override the protocol that would be choosen so that the same SSN can use two different protocols in two different DPCs. I did not believe it someone could have done it, then I saw the captures... svn path=/trunk/; revision=21321
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-bssap.c2
-rw-r--r--epan/dissectors/packet-camel.c4
-rw-r--r--epan/dissectors/packet-camel.h2
-rw-r--r--epan/dissectors/packet-gsm_map.c8
-rw-r--r--epan/dissectors/packet-gsm_map.h2
-rw-r--r--epan/dissectors/packet-sccp.c233
-rw-r--r--epan/dissectors/packet-tcap.c39
-rw-r--r--epan/dissectors/packet-tcap.h5
8 files changed, 256 insertions, 39 deletions
diff --git a/epan/dissectors/packet-bssap.c b/epan/dissectors/packet-bssap.c
index ab39c59898..52c05b90f3 100644
--- a/epan/dissectors/packet-bssap.c
+++ b/epan/dissectors/packet-bssap.c
@@ -2491,6 +2491,8 @@ proto_register_bssap(void)
proto_bssap = proto_register_protocol("BSSAP/BSAP", "BSSAP", "bssap");
/*proto_bssap_plus = proto_register_protocol("BSSAP2", "BSSAP2", "bssap2");*/
+ register_dissector("bssap", dissect_bssap, proto_bssap);
+
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_bssap, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
diff --git a/epan/dissectors/packet-camel.c b/epan/dissectors/packet-camel.c
index d89c1fba83..4aba308a2c 100644
--- a/epan/dissectors/packet-camel.c
+++ b/epan/dissectors/packet-camel.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-camel.c */
+/* .\packet-camel.c */
/* ../../tools/asn2wrs.py -b -e -p camel -c camel.cnf -s packet-camel-template camel.asn */
/* Input file: packet-camel-template.c */
@@ -10599,6 +10599,8 @@ void proto_register_camel(void) {
/* Register protocol */
proto_camel = proto_register_protocol(PNAME, PSNAME, PFNAME);
+ register_dissector("camel", dissect_camel, proto_camel);
+
proto_register_field_array(proto_camel, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
diff --git a/epan/dissectors/packet-camel.h b/epan/dissectors/packet-camel.h
index 2b424bcbe3..ff3465d429 100644
--- a/epan/dissectors/packet-camel.h
+++ b/epan/dissectors/packet-camel.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-camel.h */
+/* .\packet-camel.h */
/* ../../tools/asn2wrs.py -b -e -p camel -c camel.cnf -s packet-camel-template camel.asn */
/* Input file: packet-camel-template.h */
diff --git a/epan/dissectors/packet-gsm_map.c b/epan/dissectors/packet-gsm_map.c
index b48085e93f..d423612e0c 100644
--- a/epan/dissectors/packet-gsm_map.c
+++ b/epan/dissectors/packet-gsm_map.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-gsm_map.c */
+/* .\packet-gsm_map.c */
/* ../../tools/asn2wrs.py -b -e -p gsm_map -c gsmmap.cnf -s packet-gsm_map-template GSMMAP.asn */
/* Input file: packet-gsm_map-template.c */
@@ -16619,7 +16619,7 @@ static guint8 gsmmap_pdu_type = 0;
static guint8 gsm_map_pdu_size = 0;
static int
-dissect_gsm_map_GSMMAPPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo , proto_tree *tree, int hf_index) {
+dissect_gsm_map_GSMMAPPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo , proto_tree *tree, int hf_index _U_) {
char *version_ptr;
struct tcap_private_t * p_private_tcap;
@@ -21548,7 +21548,9 @@ void proto_register_gsm_map(void) {
/* Register protocol */
proto_gsm_map = proto_register_protocol(PNAME, PSNAME, PFNAME);
-/*XXX register_dissector("gsm_map", dissect_gsm_map, proto_gsm_map);*/
+
+ register_dissector("gsm_map", dissect_gsm_map, proto_gsm_map);
+
/* Register fields and subtrees */
proto_register_field_array(proto_gsm_map, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
diff --git a/epan/dissectors/packet-gsm_map.h b/epan/dissectors/packet-gsm_map.h
index b30f287af4..6f493f30c6 100644
--- a/epan/dissectors/packet-gsm_map.h
+++ b/epan/dissectors/packet-gsm_map.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-gsm_map.h */
+/* .\packet-gsm_map.h */
/* ../../tools/asn2wrs.py -b -e -p gsm_map -c gsmmap.cnf -s packet-gsm_map-template GSMMAP.asn */
/* Input file: packet-gsm_map-template.h */
diff --git a/epan/dissectors/packet-sccp.c b/epan/dissectors/packet-sccp.c
index 67665d8116..3737fdf2e4 100644
--- a/epan/dissectors/packet-sccp.c
+++ b/epan/dissectors/packet-sccp.c
@@ -53,6 +53,7 @@
#include "packet-tcap.h"
#include "packet-sccp.h"
#include "tap.h"
+#include <epan/uat.h>
static Standard_Type decode_mtp3_standard;
#define SCCP_SI 3
@@ -62,6 +63,7 @@ static Standard_Type decode_mtp3_standard;
#define POINTER_LENGTH 1
#define POINTER_LENGTH_LONG 2
+
/* Same as below but with names typed out */
static const value_string sccp_message_type_values[] = {
{ SCCP_MSG_TYPE_CR, "Connection Request" },
@@ -699,6 +701,44 @@ static GHashTable *sccp_xudt_msg_fragment_table = NULL;
static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
+#define SCCP_USER_DATA 0
+#define SCCP_USER_TCAP 1
+#define SCCP_USER_RANAP 2
+#define SCCP_USER_BSSAP 3
+#define SCCP_USER_GSMMAP 4
+#define SCCP_USER_CAMEL 5
+#define SCCP_USER_INAP 6
+
+typedef struct _sccp_user_t {
+ guint ni;
+ range_t* called_pc;
+ range_t* called_ssn;
+ guint user;
+ gboolean uses_tcap;
+ dissector_handle_t* handlep;
+} sccp_user_t;
+
+static sccp_user_t* sccp_users;
+static guint num_sccp_users;
+
+static dissector_handle_t data_handle;
+static dissector_handle_t tcap_handle;
+static dissector_handle_t ranap_handle;
+static dissector_handle_t bssap_handle;
+static dissector_handle_t gsmmap_handle;
+static dissector_handle_t camel_handle;
+static dissector_handle_t inap_handle;
+
+static value_string sccp_users_vals[] = {
+ { SCCP_USER_DATA, "Data"},
+ { SCCP_USER_TCAP, "TCAP"},
+ { SCCP_USER_RANAP, "RANAP"},
+ { SCCP_USER_BSSAP, "BSSAP"},
+ { SCCP_USER_GSMMAP, "GSM MAP"},
+ { SCCP_USER_CAMEL, "CAMEL"},
+ { SCCP_USER_INAP, "INAP"},
+ { 0, NULL }
+};
/*
* Here are the global variables associated with
@@ -719,7 +759,6 @@ static guint8 message_type = 0;
static guint dlr = 0;
static guint slr = 0;
-static dissector_handle_t data_handle;
static dissector_table_t sccp_ssn_dissector_table;
static emem_tree_t* assocs = NULL;
@@ -778,12 +817,15 @@ sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_
emem_tree_key_t bw_key[] = {
{1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
};
-
+
if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! pinfo->fd->flags.visited ) {
assoc = new_assoc(opck,dpck);
se_tree_insert32_array(assocs,bw_key,assoc);
assoc->has_bw_key = TRUE;
}
+
+ pinfo->p2p_dir = P2P_DIR_SENT;
+
break;
}
case SCCP_MSG_TYPE_CC:
@@ -794,7 +836,7 @@ sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_
emem_tree_key_t bw_key[] = {
{1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
};
-
+
if ( ( assoc = se_tree_lookup32_array(assocs,bw_key) ) ) {
goto got_assoc;
}
@@ -803,9 +845,12 @@ sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_
goto got_assoc;
}
- assoc = new_assoc(opck,dpck);
+ assoc = new_assoc(dpck,opck);
got_assoc:
+
+ pinfo->p2p_dir = P2P_DIR_RECV;
+
if ( ! pinfo->fd->flags.visited && ! assoc->has_bw_key ) {
se_tree_insert32_array(assocs,bw_key,assoc);
assoc->has_bw_key = TRUE;
@@ -823,9 +868,17 @@ sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_
emem_tree_key_t key[] = {
{1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
};
-
+
assoc = se_tree_lookup32_array(assocs,key);
-
+
+ if (assoc) {
+ if (assoc->calling_dpc == dpck) {
+ pinfo->p2p_dir = P2P_DIR_RECV;
+ } else {
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ }
+ }
+
break;
}
}
@@ -1446,40 +1499,74 @@ dissect_sccp_refusal_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length,
col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
}
+
/* This function is used for both data and long data (ITU only) parameters */
static void
dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 ssn = INVALID_SSN;
guint8 other_ssn = INVALID_SSN;
-
+ const mtp3_addr_pc_t* dpc;
+ const mtp3_addr_pc_t* opc;
+
if (trace_sccp && assoc && assoc != &no_assoc) {
pinfo->sccp_info = assoc->curr_msg;
} else {
pinfo->sccp_info = NULL;
}
- if ( assoc ) {
- other_ssn = INVALID_SSN;
-
- switch (pinfo->p2p_dir) {
- case P2P_DIR_SENT:
- ssn = assoc->calling_ssn;
- break;
- case P2P_DIR_RECV:
- ssn = assoc->called_ssn;
- break;
- default:
- ssn = assoc->called_ssn;
- other_ssn = assoc->calling_ssn;
- break;
+ switch (pinfo->p2p_dir) {
+ case P2P_DIR_SENT:
+ ssn = assoc->calling_ssn;
+ dpc = (mtp3_addr_pc_t*)pinfo->dst.data;
+ opc = (mtp3_addr_pc_t*)pinfo->src.data;
+ break;
+ case P2P_DIR_RECV:
+ ssn = assoc->called_ssn;
+ dpc = (mtp3_addr_pc_t*)pinfo->src.data;
+ opc = (mtp3_addr_pc_t*)pinfo->dst.data;
+ break;
+ default:
+ ssn = assoc->called_ssn;
+ other_ssn = assoc->calling_ssn;
+ dpc = (mtp3_addr_pc_t*)pinfo->dst.data;
+ opc = (mtp3_addr_pc_t*)pinfo->src.data;
+ break;
+ }
+
+
+ if (num_sccp_users && pinfo->src.type == AT_SS7PC) {
+ guint i;
+ dissector_handle_t handle = NULL;
+ gboolean uses_tcap = FALSE;
+
+ for (i=0; i < num_sccp_users; i++) {
+ sccp_user_t* u = &(sccp_users[i]);
+
+ if (dpc->ni != u->ni) continue;
+
+ if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) {
+ handle = *(u->handlep);
+ uses_tcap = u->uses_tcap;
+ break;
+ } else if (value_is_in_range(u->called_ssn, other_ssn) && value_is_in_range(u->called_pc, opc->pc) ) {
+ handle = *(u->handlep);
+ uses_tcap = u->uses_tcap;
+ break;
}
+ }
- } else {
- ssn = assoc->called_ssn;
- other_ssn = assoc->calling_ssn;
- }
+ if (handle) {
+ if (uses_tcap) {
+ call_tcap_dissector(handle, tvb, pinfo, tree);
+ } else {
+ call_dissector(handle, tvb, pinfo, tree);
+ }
+ return;
+ }
+ }
+
if (ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) {
return;
}
@@ -2502,6 +2589,68 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
+/*** SccpUsers Table **/
+
+static struct _sccp_ul {
+ guint id;
+ gboolean uses_tcap;
+ dissector_handle_t* handlep;
+ } user_list[] = {
+ {SCCP_USER_DATA,FALSE,&data_handle},
+ {SCCP_USER_TCAP,FALSE,&tcap_handle},
+ {SCCP_USER_RANAP,FALSE,&ranap_handle},
+ {SCCP_USER_BSSAP,FALSE,&bssap_handle},
+ {SCCP_USER_GSMMAP,TRUE,&gsmmap_handle},
+ {SCCP_USER_CAMEL,TRUE,&camel_handle},
+ {SCCP_USER_INAP,TRUE,&inap_handle},
+ {0,FALSE,NULL}
+};
+
+static void sccp_users_update_cb(void* r, char** err _U_) {
+ sccp_user_t* u = r;
+ struct _sccp_ul* c;
+
+ for (c=user_list; c->handlep; c++) {
+ if (c->id == u->user) {
+ u->uses_tcap = c->uses_tcap;
+ u->handlep = c->handlep;
+ return;
+ }
+ }
+
+ u->uses_tcap = FALSE;
+ u->handlep = &data_handle;
+}
+
+static void* sccp_users_copy_cb(void* n, const void* o, unsigned siz) {
+ const sccp_user_t* u = o;
+ sccp_user_t* un = n;
+
+ un->ni = u->ni;
+ un->user = u->user;
+ un->uses_tcap = u->uses_tcap;
+ un->handlep = u->handlep;
+ if (u->called_pc) un->called_pc = range_copy(u->called_pc);
+ if (u->called_ssn) un->called_ssn= range_copy(u->called_ssn);
+
+ return n;
+}
+
+static void sccp_users_free_cb(void*r) {
+ sccp_user_t* u = r;
+ if (u->called_pc) g_free(u->called_pc);
+ if (u->called_ssn) g_free(u->called_ssn);
+}
+
+
+UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
+UAT_RANGE_CB_DEF(sccp_users,called_pc,sccp_user_t)
+UAT_RANGE_CB_DEF(sccp_users,called_ssn,sccp_user_t)
+UAT_VS_DEF(sccp_users, user, sccp_user_t, SCCP_USER_DATA, "Data")
+
+/** End SccpUsersTable **/
+
+
static void init_sccp(void) {
next_assoc_id = 1;
fragment_table_init (&sccp_xudt_msg_fragment_table);
@@ -2908,7 +3057,29 @@ proto_register_sccp(void)
&ett_sccp_assoc
};
- /* Register the protocol name and description */
+
+ static uat_field_t users_flds[] = {
+ UAT_FLD_DEC(sccp_users,ni,"Network Indicator"),
+ UAT_FLD_RANGE(sccp_users,called_pc,65535,"DPCs for which this protocol is to be used"),
+ UAT_FLD_RANGE(sccp_users,called_ssn,65535,"Called SSNs for which this protocol is to be used"),
+ UAT_FLD_VS(sccp_users,user,sccp_users_vals,"The User Protocol"),
+ UAT_END_FIELDS
+ };
+
+
+ uat_t* users_uat = uat_new("SCCP Users Table",
+ sizeof(sccp_user_t),
+ "sccp_users",
+ (void**) &sccp_users,
+ &num_sccp_users,
+ UAT_CAT_PORTS,
+ "ChSccpUsers",
+ sccp_users_copy_cb,
+ sccp_users_update_cb,
+ sccp_users_free_cb,
+ users_flds );
+
+ /* Register the protocol name and description */
proto_sccp = proto_register_protocol("Signalling Connection Control Part",
"SCCP", "sccp");
@@ -2918,6 +3089,7 @@ proto_register_sccp(void)
proto_register_field_array(proto_sccp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+
sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
register_heur_dissector_list("sccp", &heur_subdissector_list);
@@ -2950,6 +3122,9 @@ proto_register_sccp(void)
&show_key_params);
+ prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
+ "A table that enumerates user protocols to be used against specific PCs and SSNs",
+ users_uat);
register_init_routine(&init_sccp);
@@ -2970,5 +3145,11 @@ proto_reg_handoff_sccp(void)
dissector_add_string("tali.opcode", "sccp", sccp_handle);
data_handle = find_dissector("data");
+ tcap_handle = find_dissector("tcap");
+ ranap_handle = find_dissector("ranap");
+ bssap_handle = find_dissector("bssap");
+ gsmmap_handle = find_dissector("gsm_map");
+ camel_handle = find_dissector("camel");
+ inap_handle = find_dissector("inap");
}
diff --git a/epan/dissectors/packet-tcap.c b/epan/dissectors/packet-tcap.c
index d7ebc824be..3d1227fa64 100644
--- a/epan/dissectors/packet-tcap.c
+++ b/epan/dissectors/packet-tcap.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-tcap.c */
+/* .\packet-tcap.c */
/* ../../tools/asn2wrs.py -b -e -p tcap -c tcap.cnf -s packet-tcap-template tcap.asn */
/* Input file: packet-tcap-template.c */
@@ -206,6 +206,8 @@ gint ett_tcap_stat = -1;
static struct tcapsrt_info_t * gp_tcapsrt_info;
static gboolean tcap_subdissector_used=FALSE;
+static dissector_handle_t requested_subdissector_handle = NULL;
+
static struct tcaphash_context_t * gp_tcap_context=NULL;
@@ -263,7 +265,7 @@ static gint ett_tcap_OperationCode = -1;
static gint ett_tcap_ErrorCode = -1;
/*--- End of included file: packet-tcap-ett.c ---*/
-#line 76 "packet-tcap-template.c"
+#line 78 "packet-tcap-template.c"
#define MAX_SSN 254
static range_t *global_ssn_range;
@@ -2322,7 +2324,7 @@ dissect_tcap_ERROR(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
/*--- End of included file: packet-tcap-fn.c ---*/
-#line 141 "packet-tcap-template.c"
+#line 143 "packet-tcap-template.c"
@@ -2971,7 +2973,7 @@ proto_register_tcap(void)
"", HFILL }},
/*--- End of included file: packet-tcap-hfarr.c ---*/
-#line 297 "packet-tcap-template.c"
+#line 299 "packet-tcap-template.c"
};
/* Setup protocol subtree array */
@@ -3036,7 +3038,7 @@ proto_register_tcap(void)
&ett_tcap_ErrorCode,
/*--- End of included file: packet-tcap-ettarr.c ---*/
-#line 307 "packet-tcap-template.c"
+#line 309 "packet-tcap-template.c"
};
/*static enum_val_t tcap_options[] = {
@@ -3301,7 +3303,13 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
subdissector_handle=p_tcap_context->subdissector_handle;
is_subdissector=TRUE;
}
-
+
+ /* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
+ if (!is_subdissector && requested_subdissector_handle) {
+ is_subdissector = TRUE;
+ subdissector_handle = requested_subdissector_handle;
+ }
+
if (!is_subdissector) {
/*
* If we do not currently know the subdissector, we have to find it
@@ -3340,6 +3348,7 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
} else {
/* We have it already */
}
+
/* Call the sub dissector if present, and not already called */
if (is_subdissector)
call_dissector(subdissector_handle, next_tvb, pinfo, tcap_top_tree);
@@ -3380,3 +3389,21 @@ dissect_tcap_TheExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb, int off
return offset;
}
+
+
+void call_tcap_dissector(dissector_handle_t handle, tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
+
+ requested_subdissector_handle = handle;
+
+ TRY {
+ dissect_tcap(tvb, pinfo, tree);
+ } CATCH_ALL {
+ requested_subdissector_handle = NULL;
+ RETHROW;
+ } ENDTRY;
+
+ requested_subdissector_handle = NULL;
+
+}
+
+
diff --git a/epan/dissectors/packet-tcap.h b/epan/dissectors/packet-tcap.h
index e96d482a19..d15cd47b39 100644
--- a/epan/dissectors/packet-tcap.h
+++ b/epan/dissectors/packet-tcap.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* ./packet-tcap.h */
+/* .\packet-tcap.h */
/* ../../tools/asn2wrs.py -b -e -p tcap -c tcap.cnf -s packet-tcap-template tcap.asn */
/* Input file: packet-tcap-template.h */
@@ -49,6 +49,7 @@
#define ANSI_TC_INVOKE_N 0xed
#define ANSI_TC_RRN 0xee
+
#define TCAP_SEQ_TAG 0x30
#define TCAP_SET_TAG 0x31
@@ -84,4 +85,6 @@ extern void add_itu_tcap_subdissector(guint32 ssn, dissector_handle_t dissector)
extern void delete_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
extern void delete_itu_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
+extern void call_tcap_dissector(dissector_handle_t, tvbuff_t*, packet_info*, proto_tree*);
+
#endif /* PACKET_tcap_H */