diff options
author | sswsdev <sswsdev@gmail.com> | 2017-04-14 13:41:37 +0300 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2017-04-20 20:19:46 +0000 |
commit | 2e6cb9dbab154531b306e472642ff6033f0e341c (patch) | |
tree | 9c78185dc665b9682d1c97895008f1ee60d13d9e /epan/dissectors/asn1/rrc | |
parent | 09e787a8fb4a1a04366e57c059c4997abcd9183e (diff) |
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.c | 123 | ||||
-rw-r--r-- | epan/dissectors/asn1/rrc/packet-rrc-template.h | 1 | ||||
-rw-r--r-- | epan/dissectors/asn1/rrc/rrc.cnf | 182 |
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 |