summaryrefslogtreecommitdiff
path: root/epan/dissectors/asn1/rrc
diff options
context:
space:
mode:
authorsswsdev <sswsdev@gmail.com>2017-04-14 13:41:37 +0300
committerPascal Quantin <pascal.quantin@gmail.com>2017-04-20 20:19:46 +0000
commit2e6cb9dbab154531b306e472642ff6033f0e341c (patch)
tree9c78185dc665b9682d1c97895008f1ee60d13d9e /epan/dissectors/asn1/rrc
parent09e787a8fb4a1a04366e57c059c4997abcd9183e (diff)
downloadwireshark-2e6cb9dbab154531b306e472642ff6033f0e341c.tar.gz
UMTS Iub: Added U-RNTI resolving logic for UEs on DCH
The goal is to figure out the U-RNTI for UEs in DCH to preserve a single continous RLC session when the UE moves to FACH (Since the UE ID in FACH is derived from the identity found in the MAC layer, which is sometimes the U-RNTI) UMTS RRC dissector now defines a single 'umts rrc private data' structure as the way to access the actx->private_data field Change-Id: Id0ffcbcdf0a8babe533915855909e250852e46cf Reviewed-on: https://code.wireshark.org/review/21087 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'epan/dissectors/asn1/rrc')
-rw-r--r--epan/dissectors/asn1/rrc/packet-rrc-template.c123
-rw-r--r--epan/dissectors/asn1/rrc/packet-rrc-template.h1
-rw-r--r--epan/dissectors/asn1/rrc/rrc.cnf182
3 files changed, 228 insertions, 78 deletions
diff --git a/epan/dissectors/asn1/rrc/packet-rrc-template.c b/epan/dissectors/asn1/rrc/packet-rrc-template.c
index 57b88e799a..13e78a0e03 100644
--- a/epan/dissectors/asn1/rrc/packet-rrc-template.c
+++ b/epan/dissectors/asn1/rrc/packet-rrc-template.c
@@ -60,8 +60,107 @@ extern int proto_fp; /*Handler to FP*/
GTree * hsdsch_muxed_flows = NULL;
GTree * rrc_ciph_inf = NULL;
+GTree * rrc_scrambling_code_urnti = NULL;
static int msg_type _U_;
+/*****************************************************************************/
+/* Packet private data */
+/* For this dissector, all access to actx->private_data should be made */
+/* through this API, which ensures that they will not overwrite each other!! */
+/*****************************************************************************/
+
+enum nas_sys_info_gsm_map {
+ RRC_NAS_SYS_UNKNOWN,
+ RRC_NAS_SYS_INFO_CS,
+ RRC_NAS_SYS_INFO_PS,
+ RRC_NAS_SYS_INFO_CN_COMMON
+};
+
+typedef struct umts_rrc_private_data_t
+{
+ guint32 s_rnc_id; /* The S-RNC ID part of a U-RNTI */
+ guint32 s_rnti; /* The S-RNTI part of a U-RNTI */
+ guint32 new_u_rnti;
+ guint32 scrambling_code;
+ enum nas_sys_info_gsm_map cn_domain;
+} umts_rrc_private_data_t;
+
+
+/* Helper function to get or create a struct that will be actx->private_data */
+static umts_rrc_private_data_t* umts_rrc_get_private_data(asn1_ctx_t *actx)
+{
+ if (actx->private_data != NULL) {
+ return (umts_rrc_private_data_t*)actx->private_data;
+ }
+ else {
+ umts_rrc_private_data_t* new_struct = wmem_new0(wmem_packet_scope(), umts_rrc_private_data_t);
+ actx->private_data = new_struct;
+ return new_struct;
+ }
+}
+
+static guint32 private_data_get_s_rnc_id(asn1_ctx_t *actx)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->s_rnc_id;
+}
+
+static void private_data_set_s_rnc_id(asn1_ctx_t *actx, guint32 s_rnc_id)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->s_rnc_id = s_rnc_id;
+}
+
+static guint32 private_data_get_s_rnti(asn1_ctx_t *actx)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->s_rnti;
+}
+
+static void private_data_set_s_rnti(asn1_ctx_t *actx, guint32 s_rnti)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->s_rnti = s_rnti;
+}
+
+static guint32 private_data_get_new_u_rnti(asn1_ctx_t *actx)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->new_u_rnti;
+}
+
+static void private_data_set_new_u_rnti(asn1_ctx_t *actx, guint32 new_u_rnti)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->new_u_rnti = new_u_rnti;
+}
+
+static guint32 private_data_get_scrambling_code(asn1_ctx_t *actx)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->scrambling_code;
+}
+
+static void private_data_set_scrambling_code(asn1_ctx_t *actx, guint32 scrambling_code)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->scrambling_code = scrambling_code;
+}
+
+static enum nas_sys_info_gsm_map private_data_get_cn_domain(asn1_ctx_t *actx)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->cn_domain;
+}
+
+static void private_data_set_cn_domain(asn1_ctx_t *actx, enum nas_sys_info_gsm_map cn_domain)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->cn_domain = cn_domain;
+}
+
+/*****************************************************************************/
+
static dissector_handle_t gsm_a_dtap_handle;
static dissector_handle_t rrc_ue_radio_access_cap_info_handle=NULL;
static dissector_handle_t rrc_pcch_handle=NULL;
@@ -74,12 +173,6 @@ static dissector_handle_t lte_rrc_ue_eutra_cap_handle=NULL;
static dissector_handle_t lte_rrc_dl_dcch_handle=NULL;
static dissector_handle_t gsm_rlcmac_dl_handle=NULL;
-enum nas_sys_info_gsm_map {
- RRC_NAS_SYS_INFO_CS,
- RRC_NAS_SYS_INFO_PS,
- RRC_NAS_SYS_INFO_CN_COMMON
-};
-
/* Forward declarations */
void proto_register_rrc(void);
void proto_reg_handoff_rrc(void);
@@ -143,15 +236,13 @@ static const true_false_string rrc_eutra_feat_group_ind_4_val = {
"UTRA CELL_FACH absolute priority cell reselection for all layers - Not supported"
};
static const value_string rrc_ims_info_atgw_trans_det_cont_type[] = {
- {0, "ATGW-IPv4-address-and-port"},
- {1, "ATGW-IPv6-address-and-port"},
- {2, "ATGW-not-available"},
- {0, NULL}
+ {0, "ATGW-IPv4-address-and-port"},
+ {1, "ATGW-IPv6-address-and-port"},
+ {2, "ATGW-not-available"},
+ {0, NULL}
};
static int flowd,type;
-static int cipher_start_val[2] _U_;
-
/*Stores how many channels we have detected for a HS-DSCH MAC-flow*/
#define RRC_MAX_NUM_HSDHSCH_MACDFLOW 8
static guint8 num_chans_per_flow[RRC_MAX_NUM_HSDHSCH_MACDFLOW];
@@ -256,11 +347,16 @@ rrc_init(void) {
rrc_free_key,
rrc_free_value);
- /*Initialize structure for muxed flow indication*/
rrc_ciph_inf = g_tree_new_full(rrc_key_cmp,
NULL, /* data pointer, optional */
NULL,
rrc_free_value);
+
+ /*Initialize Scrambling code to U-RNTI dictionary*/
+ rrc_scrambling_code_urnti = g_tree_new_full(rrc_key_cmp,
+ NULL,
+ NULL,
+ NULL);
}
static void
@@ -268,6 +364,7 @@ rrc_cleanup(void) {
/*Cleanup*/
g_tree_destroy(hsdsch_muxed_flows);
g_tree_destroy(rrc_ciph_inf);
+ g_tree_destroy(rrc_scrambling_code_urnti);
}
/*--- proto_register_rrc -------------------------------------------*/
diff --git a/epan/dissectors/asn1/rrc/packet-rrc-template.h b/epan/dissectors/asn1/rrc/packet-rrc-template.h
index 6ae2b0661d..437e835859 100644
--- a/epan/dissectors/asn1/rrc/packet-rrc-template.h
+++ b/epan/dissectors/asn1/rrc/packet-rrc-template.h
@@ -60,5 +60,6 @@ typedef struct rrc_ciph_info_
extern GTree * hsdsch_muxed_flows;
extern GTree * rrc_ciph_inf;
+extern GTree * rrc_scrambling_code_urnti;
#endif /* PACKET_RRC_H */
diff --git a/epan/dissectors/asn1/rrc/rrc.cnf b/epan/dissectors/asn1/rrc/rrc.cnf
index f85c7a69cf..796a63b4be 100644
--- a/epan/dissectors/asn1/rrc/rrc.cnf
+++ b/epan/dissectors/asn1/rrc/rrc.cnf
@@ -393,8 +393,18 @@ HandoverFromUTRANCommand-GSM-r6-IEs/gsm-message/single-GSM-Message single-GSM-Me
%(DEFAULT_BODY)s
#.FN_BODY RRCConnectionSetup
+ guint32 scrambling_code, new_u_rnti;
col_append_str(actx->pinfo->cinfo, COL_INFO, "RRCConnectionSetup");
%(DEFAULT_BODY)s
+ /* Mapping the U-RNTI assigned to the user to its Uplink Scrambling Code*/
+ scrambling_code = private_data_get_scrambling_code(actx);
+ new_u_rnti = private_data_get_new_u_rnti(actx);
+ if (new_u_rnti != 0 && scrambling_code != 0 && !actx->pinfo->fd->flags.visited) {
+ /* Check if a U-RNTI is already mapped to this scrambling code */
+ if ((guint32 *)g_tree_lookup(rrc_scrambling_code_urnti, GUINT_TO_POINTER(scrambling_code)) == NULL) {
+ g_tree_insert(rrc_scrambling_code_urnti, GUINT_TO_POINTER(scrambling_code), GUINT_TO_POINTER(new_u_rnti));
+ }
+ }
#.FN_BODY RRCConnectionSetupComplete
col_append_str(actx->pinfo->cinfo, COL_INFO, "RRCConnectionSetupComplete");
@@ -694,59 +704,101 @@ HNBName TYPE=FT_STRING DISPLAY=STR_UNICODE
%(DEFAULT_BODY)s
actx->created_item = proto_tree_add_item(tree, hf_index, hnbname_tvb, 0, -1, ENC_UTF_8|ENC_NA);
-#.FN_BODY CN-DomainIdentity VAL_PTR = &nas_sys_info_gsm_map
- guint32 nas_sys_info_gsm_map;
+#.FN_BODY CN-DomainIdentity VAL_PTR = &nas_sys_info
+ guint32 nas_sys_info;
%(DEFAULT_BODY)s
- col_append_fstr(actx->pinfo->cinfo, COL_INFO, "(%%s)", val_to_str_const(nas_sys_info_gsm_map,rrc_CN_DomainIdentity_vals,"Unknown"));
- actx->private_data = GUINT_TO_POINTER(nas_sys_info_gsm_map+1);
+ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "(%%s)", val_to_str_const(nas_sys_info,rrc_CN_DomainIdentity_vals,"Unknown"));
+ nas_sys_info++; /* CS = 0, PS = 1 but the enum defines 0 as Unknown and CS = 1, PS = 2 */
+ private_data_set_cn_domain(actx, (enum nas_sys_info_gsm_map) nas_sys_info);
#.FN_BODY CN-InformationInfo/cn-CommonGSM-MAP-NAS-SysInfo
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_CN_COMMON+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_CN_COMMON);
%(DEFAULT_BODY)s
#.FN_BODY CN-InformationInfo-r6/cn-CommonGSM-MAP-NAS-SysInfo
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_CN_COMMON+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_CN_COMMON);
%(DEFAULT_BODY)s
#.FN_BODY CN-InformationInfoFull/cn-CommonGSM-MAP-NAS-SysInfo
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_CN_COMMON+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_CN_COMMON);
%(DEFAULT_BODY)s
#.FN_BODY SysInfoType1/cn-CommonGSM-MAP-NAS-SysInfo
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_CN_COMMON+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_CN_COMMON);
%(DEFAULT_BODY)s
#.FN_BODY NAS-SystemInformationGSM-MAP VAL_PTR = &nas_sys_info_gsm_map_tvb
tvbuff_t *nas_sys_info_gsm_map_tvb = NULL;
guint32 length;
+ enum nas_sys_info_gsm_map cn_domain;
proto_tree *subtree;
%(DEFAULT_BODY)s
length = tvb_reported_length(nas_sys_info_gsm_map_tvb);
if (length) {
- if (actx->private_data) {
- switch (GPOINTER_TO_UINT(actx->private_data)-1) {
- case RRC_NAS_SYS_INFO_CN_COMMON:
- subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
- ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "CN Common GSM-MAP NAS system information");
- de_cn_common_gsm_map_nas_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
- break;
- case RRC_NAS_SYS_INFO_CS:
- subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
- ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "CS domain specific system information");
- de_cs_domain_spec_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
- break;
- case RRC_NAS_SYS_INFO_PS:
- subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
- ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "PS domain specific system information");
- de_ps_domain_spec_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
- break;
- default:
- break;
- }
- actx->private_data = NULL;
+ cn_domain = private_data_get_cn_domain(actx);
+ switch (cn_domain) {
+ case RRC_NAS_SYS_INFO_CN_COMMON:
+ subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
+ ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "CN Common GSM-MAP NAS system information");
+ de_cn_common_gsm_map_nas_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
+ break;
+ case RRC_NAS_SYS_INFO_CS:
+ subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
+ ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "CS domain specific system information");
+ de_cs_domain_spec_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
+ break;
+ case RRC_NAS_SYS_INFO_PS:
+ subtree = proto_tree_add_subtree(tree, nas_sys_info_gsm_map_tvb, 0, length,
+ ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo, NULL, "PS domain specific system information");
+ de_ps_domain_spec_sys_info(nas_sys_info_gsm_map_tvb, subtree, actx->pinfo, 0, length, NULL, 0);
+ break;
+ default:
+ break;
}
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_UNKNOWN);
+ }
+
+#.FN_BODY SRNC-Identity VAL_PTR = &s_rnc_id_tvb
+ tvbuff_t * s_rnc_id_tvb = NULL;
+%(DEFAULT_BODY)s
+ if (s_rnc_id_tvb) {
+ private_data_set_s_rnc_id(actx, tvb_get_ntohs(s_rnc_id_tvb, 0) >> 4);
+ }
+
+#.FN_BODY S-RNTI VAL_PTR = &s_rnti_tvb
+ tvbuff_t * s_rnti_tvb = NULL;
+%(DEFAULT_BODY)s
+ if (s_rnti_tvb) {
+ private_data_set_s_rnti(actx, tvb_get_ntoh24(s_rnti_tvb, 0) >> 4);
+ }
+
+#.FN_BODY U-RNTI
+ private_data_set_s_rnc_id(actx, 0);
+ private_data_set_s_rnti(actx, 0);
+ guint32 s_rnc_id;
+ guint32 s_rnti;
+ guint32 u_rnti_value;
+%(DEFAULT_BODY)s
+ gboolean is_new_urnti = hf_index != hf_rrc_u_RNTI; /* hf_rrc_u_RNTI is for current U-RNTI, any other hf is for new U-RNTI */
+ s_rnc_id = private_data_get_s_rnc_id(actx);
+ s_rnti = private_data_get_s_rnti(actx);
+ if(s_rnc_id != 0 && s_rnti != 0) {
+ u_rnti_value = (s_rnc_id << 20) | s_rnti;
+ /* We are looking for new allocated U-RNTIs, not previously used ones */
+ if (is_new_urnti) {
+ private_data_set_new_u_rnti(actx, u_rnti_value);
+ }
+ /* Adding U-RNTI value to it's tree item */
+ proto_item_append_text(actx->created_item,": %%08x", u_rnti_value);
}
+ private_data_set_s_rnc_id(actx, 0);
+ private_data_set_s_rnti(actx, 0);
+
+#.FN_BODY UL-ScramblingCode VAL_PTR = &scrambling_code
+guint32 scrambling_code;
+%(DEFAULT_BODY)s
+private_data_set_scrambling_code(actx,scrambling_code);
#.FN_BODY CellIdentity VAL_PTR = &cell_id_tvb
tvbuff_t * cell_id_tvb = NULL;
@@ -855,6 +907,7 @@ HNBName TYPE=FT_STRING DISPLAY=STR_UNICODE
rrc_ciphering_info * c_inf;
int i;
guint32 * start;
+ enum nas_sys_info_gsm_map cn_domain;
%(DEFAULT_BODY)s
@@ -866,45 +919,44 @@ HNBName TYPE=FT_STRING DISPLAY=STR_UNICODE
return offset;
}
/*Retrieve the start value for the two ciphering domains*/
- if (actx->private_data) {
- switch(GPOINTER_TO_UINT(actx->private_data)-1){
- case RRC_NAS_SYS_INFO_CS:
- /*
- g_warning("Not implemented");
- */
- break;
- case RRC_NAS_SYS_INFO_PS:
+ cn_domain = private_data_get_cn_domain(actx);
+ switch(cn_domain){
+ case RRC_NAS_SYS_INFO_CS:
+ /*
+ g_warning("Not implemented");
+ */
+ break;
+ case RRC_NAS_SYS_INFO_PS:
+
+ /*Find the entry for the communication context (taken from FP)*/
+ if( (c_inf =(rrc_ciphering_info *)g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id))) == NULL ){
+ c_inf = g_new0(rrc_ciphering_info,1);
- /*Find the entry for the communication context (taken from FP)*/
- if( (c_inf =(rrc_ciphering_info *)g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id))) == NULL ){
- c_inf = g_new0(rrc_ciphering_info,1);
-
- /*Initiate tree with START_PS values.*/
- if(!c_inf->start_ps)
- c_inf->start_ps = g_tree_new_full(rrc_key_cmp,
- NULL,rrc_free_key,rrc_free_value);
-
- /*Clear and initialize seq_no matrix*/
- for(i = 0; i< 31; i++){
- c_inf->seq_no[i][0] = -1;
- c_inf->seq_no[i][1] = -1;
- }
- g_tree_insert(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id), c_inf);
+ /*Initiate tree with START_PS values.*/
+ if(!c_inf->start_ps)
+ c_inf->start_ps = g_tree_new_full(rrc_key_cmp,
+ NULL,rrc_free_key,rrc_free_value);
+
+ /*Clear and initialize seq_no matrix*/
+ for(i = 0; i< 31; i++){
+ c_inf->seq_no[i][0] = -1;
+ c_inf->seq_no[i][1] = -1;
}
+ g_tree_insert(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id), c_inf);
+ }
- /*Retrieve and store the value*/
- start = g_new(guint32,1);
- *start = tvb_get_bits32(start_val,0,20,ENC_BIG_ENDIAN);
- if(c_inf && c_inf->start_ps)
- /*Insert the value based on current frame num since this might vary over time*/
- g_tree_insert(c_inf->start_ps, GUINT_TO_POINTER(actx->pinfo->num), start);
+ /*Retrieve and store the value*/
+ start = g_new(guint32,1);
+ *start = tvb_get_bits32(start_val,0,20,ENC_BIG_ENDIAN);
+ if(c_inf && c_inf->start_ps)
+ /*Insert the value based on current frame num since this might vary over time*/
+ g_tree_insert(c_inf->start_ps, GUINT_TO_POINTER(actx->pinfo->num), start);
- break;
- default:
- break;
- }
- actx->private_data = NULL;
+ break;
+ default:
+ break;
}
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_UNKNOWN);
#.FN_BODY RB-ActivationTimeInfo
fp_info *fpinf;
@@ -948,11 +1000,11 @@ HNBName TYPE=FT_STRING DISPLAY=STR_UNICODE
%(DEFAULT_BODY)s
#.FN_BODY UE-SecurityInformation
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_CS+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_CS);
%(DEFAULT_BODY)s
#.FN_BODY UE-SecurityInformation2
- actx->private_data = GUINT_TO_POINTER(RRC_NAS_SYS_INFO_PS+1);
+ private_data_set_cn_domain(actx, RRC_NAS_SYS_INFO_PS);
%(DEFAULT_BODY)s
#.FN_BODY ReleaseCause VAL_PTR=&value