diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2007-04-03 19:08:00 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2007-04-03 19:08:00 +0000 |
commit | 9709011a9b553b9c3a9db0931366b6216b7ba4c6 (patch) | |
tree | 1ede0f1dc1100843504dacfa6fdfdf154ef95549 /epan/dissectors | |
parent | 8177d0f4a9242b0dd1b6c6a3aca63c819d1bda4c (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.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-camel.c | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-camel.h | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.h | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-sccp.c | 233 | ||||
-rw-r--r-- | epan/dissectors/packet-tcap.c | 39 | ||||
-rw-r--r-- | epan/dissectors/packet-tcap.h | 5 |
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 */ |