aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/asn1
diff options
context:
space:
mode:
authorDarien Spencer <cusneud@mail.com>2017-08-19 17:33:14 +0300
committerPascal Quantin <pascal.quantin@gmail.com>2017-09-13 19:24:20 +0000
commitbdf10a239fcf873e1fff955f0fb6d8fd41aefcf3 (patch)
tree7ca52f0fe8e473602fc285ccf51a6c8e66a757d0 /epan/dissectors/asn1
parentba957234735b9a65ff831cf9a6b0ed1a230c19ea (diff)
UMTS RLC: Mark ciphered frames
- Updated RRC dissector to always collect ciphering sequence numbers from Security Mode Command/ Security Mode Complete - Updated RLC dissector to seek the collected info when deciding if the frame is ciphered Change-Id: I44bc61736968ef9f420782048e15ba27d6c6267f Reviewed-on: https://code.wireshark.org/review/23132 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')
-rw-r--r--epan/dissectors/asn1/rrc/packet-rrc-template.c134
-rw-r--r--epan/dissectors/asn1/rrc/packet-rrc-template.h8
-rw-r--r--epan/dissectors/asn1/rrc/rrc.cnf109
3 files changed, 168 insertions, 83 deletions
diff --git a/epan/dissectors/asn1/rrc/packet-rrc-template.c b/epan/dissectors/asn1/rrc/packet-rrc-template.c
index 82e6b67532..625741cca6 100644
--- a/epan/dissectors/asn1/rrc/packet-rrc-template.c
+++ b/epan/dissectors/asn1/rrc/packet-rrc-template.c
@@ -64,7 +64,7 @@ extern int proto_umts_mac; /*Handler to MAC*/
extern int proto_umts_rlc; /*Handler to RLC*/
GTree * hsdsch_muxed_flows = NULL;
-GTree * rrc_ciph_inf = NULL;
+GTree * rrc_ciph_info_tree = NULL;
GTree * rrc_scrambling_code_urnti = NULL;
wmem_tree_t* rrc_rach_urnti_crnti_map = NULL;
static int msg_type _U_;
@@ -90,6 +90,9 @@ typedef struct umts_rrc_private_data_t
guint32 current_u_rnti;
guint32 scrambling_code;
enum nas_sys_info_gsm_map cn_domain;
+ guint32 rbid;
+ guint32 rlc_ciphering_sqn; /* Sequence number where ciphering starts in a given bearer */
+ rrc_ciphering_info* ciphering_info;
} umts_rrc_private_data_t;
@@ -108,74 +111,110 @@ static umts_rrc_private_data_t* umts_rrc_get_private_data(asn1_ctx_t *actx)
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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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_current_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->current_u_rnti;
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ return private_data->current_u_rnti;
}
static void private_data_set_current_u_rnti(asn1_ctx_t *actx, guint32 current_u_rnti)
{
- umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
- private_data->current_u_rnti = current_u_rnti;
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->current_u_rnti = current_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;
+ 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;
+ 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;
+ 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;
+ 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 guint32 private_data_get_rbid(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->rbid;
+}
+
+static void private_data_set_rbid(asn1_ctx_t *actx, guint32 rbid)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->rbid = rbid;
+}
+
+static guint32 private_data_get_rlc_ciphering_sqn(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->rlc_ciphering_sqn;
+}
+
+static void private_data_set_rlc_ciphering_sqn(asn1_ctx_t *actx, guint32 rlc_ciphering_sqn)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->rlc_ciphering_sqn = rlc_ciphering_sqn;
+}
+
+static rrc_ciphering_info* private_data_get_ciphering_info(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->ciphering_info;
+}
+
+static void private_data_set_ciphering_info(asn1_ctx_t *actx, rrc_ciphering_info* ciphering_info)
+{
+ umts_rrc_private_data_t *private_data = (umts_rrc_private_data_t*)umts_rrc_get_private_data(actx);
+ private_data->ciphering_info = ciphering_info;
}
/*****************************************************************************/
@@ -265,9 +304,6 @@ static int flowd,type;
/*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];
-static int rbid;
-static int activation_frame;
-
/**
* Return the maximum counter, useful for initiating counters
@@ -276,14 +312,14 @@ static int activation_frame;
static int get_max_counter(int com_context){
int i;
guint32 max = 0;
- rrc_ciphering_info * c_inf;
+ rrc_ciphering_info * ciphering_info;
- if( (c_inf = g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER((gint)com_context))) == NULL ){
+ if( (ciphering_info = g_tree_lookup(rrc_ciph_info_tree, GINT_TO_POINTER((gint)com_context))) == NULL ){
return 0;
}
for(i = 0; i<31; i++){
- max = MAX(c_inf->ps_conf_counters[i][0], max);
- max = MAX(c_inf->ps_conf_counters[i][1], max);
+ max = MAX(ciphering_info->ps_conf_counters[i][0], max);
+ max = MAX(ciphering_info->ps_conf_counters[i][1], max);
}
return max;
}
@@ -304,8 +340,35 @@ static void rrc_free_key(gpointer key _U_){
static void rrc_free_value(gpointer value ){
g_free(value);
}
-#include "packet-rrc-fn.c"
+static rrc_ciphering_info*
+get_or_create_cipher_info(fp_info *fpinf, rlc_info *rlcinf) {
+ rrc_ciphering_info *cipher_info = NULL;
+ guint32 ueid;
+ int i;
+
+ ueid = rlcinf->ueid[fpinf->cur_tb];
+
+ cipher_info = (rrc_ciphering_info *)g_tree_lookup(rrc_ciph_info_tree, GINT_TO_POINTER((gint)ueid));
+ if( cipher_info == NULL ){
+ cipher_info = g_new0(rrc_ciphering_info,1);
+
+ /*Initiate tree with START_PS values.*/
+ if(!cipher_info->start_ps)
+ cipher_info->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++){
+ cipher_info->seq_no[i][0] = -1;
+ cipher_info->seq_no[i][1] = -1;
+ }
+ g_tree_insert(rrc_ciph_info_tree, GINT_TO_POINTER((gint)rlcinf->ueid[fpinf->cur_tb]), cipher_info);
+ }
+ return cipher_info;
+}
+
+#include "packet-rrc-fn.c"
static int
@@ -366,7 +429,7 @@ rrc_init(void) {
rrc_free_key,
rrc_free_value);
- rrc_ciph_inf = g_tree_new_full(rrc_key_cmp,
+ rrc_ciph_info_tree = g_tree_new_full(rrc_key_cmp,
NULL, /* data pointer, optional */
NULL,
rrc_free_value);
@@ -385,7 +448,8 @@ static void
rrc_cleanup(void) {
/*Cleanup*/
g_tree_destroy(hsdsch_muxed_flows);
- g_tree_destroy(rrc_ciph_inf);
+ g_tree_destroy(rrc_ciph_info_tree);
+ 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 72efe6c20e..8ad8229429 100644
--- a/epan/dissectors/asn1/rrc/packet-rrc-template.h
+++ b/epan/dissectors/asn1/rrc/packet-rrc-template.h
@@ -46,20 +46,20 @@ typedef struct rrc_info
} rrc_info;
/*Struct for storing ciphering information*/
-typedef struct rrc_ciph_info_
+typedef struct rrc_ciphering_info
{
- int seq_no[31][2]; /*Indicates for each Rbid when ciphering starts*/
+ int seq_no[31][2]; /*Indicates for each Rbid when ciphering starts - Indexers are [BearerID][Direction]*/
GTree * /*guint32*/ start_cs; /*Start value for CS counter*/
GTree * /*guint32*/ start_ps; /*Start value for PS counter*/
guint32 conf_algo_indicator; /*Indicates which type of ciphering algorithm used*/
guint32 int_algo_indiccator; /*Indicates which type of integrity algorithm used*/
- unsigned int setup_frame; /*Store which frame contained this information*/
+ guint32 setup_frame[2]; /*Store which frame contained this information - Indexer is [Direction]*/
guint32 ps_conf_counters[31][2]; /*This should also be made for CS*/
} rrc_ciphering_info;
extern GTree * hsdsch_muxed_flows;
-extern GTree * rrc_ciph_inf;
+extern GTree * rrc_ciph_info_tree;
extern GTree * rrc_scrambling_code_urnti;
extern wmem_tree_t* rrc_rach_urnti_crnti_map;
diff --git a/epan/dissectors/asn1/rrc/rrc.cnf b/epan/dissectors/asn1/rrc/rrc.cnf
index f1e2176ae3..2be5a30863 100644
--- a/epan/dissectors/asn1/rrc/rrc.cnf
+++ b/epan/dissectors/asn1/rrc/rrc.cnf
@@ -417,20 +417,46 @@ HandoverFromUTRANCommand-GSM-r6-IEs/gsm-message/single-GSM-Message single-GSM-Me
%(DEFAULT_BODY)s
#.FN_BODY SecurityModeCommand
+ fp_info *fpinf;
+ rlc_info *rlcinf;
+ rrc_ciphering_info *ciphering_info = NULL;
+ guint8 direction;
col_append_str(actx->pinfo->cinfo, COL_INFO, "SecurityModeCommand");
+
+ fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_fp, 0);
+ rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_umts_rlc, 0);
+
+ /*If FP info or RLC info is missing , skip all this*/
+ if(fpinf != NULL && rlcinf != NULL){
+ ciphering_info = get_or_create_cipher_info(fpinf, rlcinf);
+ private_data_set_ciphering_info(actx, ciphering_info);
+ }
%(DEFAULT_BODY)s
+ if( ciphering_info != NULL ){
+ direction = 0; /* Security Mode Command is from the RNC, direction is always downlink */
+ ciphering_info->setup_frame[direction] = actx->pinfo->num;
+ }
#.FN_BODY SecurityModeComplete
-rrc_ciphering_info * c_inf ;
-fp_info *fpinf ;
-
+ fp_info *fpinf;
+ rlc_info *rlcinf;
+ rrc_ciphering_info *ciphering_info = NULL;
+ guint8 direction;
col_append_str(actx->pinfo->cinfo, COL_INFO, "SecurityModeComplete");
-%(DEFAULT_BODY)s
-
fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_fp, 0);
- if(fpinf && ((c_inf = (rrc_ciphering_info *)g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id))) != NULL) ){
- c_inf->setup_frame = actx->pinfo->num;
+ rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_umts_rlc, 0);
+
+ /*If FP info or RLC info is missing , skip all this*/
+ if(fpinf != NULL || rlcinf != NULL){
+ ciphering_info = get_or_create_cipher_info(fpinf, rlcinf);
+ private_data_set_ciphering_info(actx, ciphering_info);
+ }
+
+%(DEFAULT_BODY)s
+ if( ciphering_info != NULL ){
+ direction = 1; /* Security Mode Complete is from the UE, direction is always uplink */
+ ciphering_info->setup_frame[direction] = actx->pinfo->num;
}
@@ -978,18 +1004,19 @@ private_data_set_scrambling_code(actx,scrambling_code);
#.FN_BODY START-Value VAL_PTR = &start_val
tvbuff_t * start_val;
fp_info *fpinf;
- rrc_ciphering_info * c_inf;
- int i;
+ rlc_info *rlcinf;
+ rrc_ciphering_info * ciphering_info;
guint32 * start;
enum nas_sys_info_gsm_map cn_domain;
%(DEFAULT_BODY)s
- /*We base this map on communication context from fp*/
- fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_fp, 0);
+ /*We base this map on User Identity from RLC*/
+ fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_fp, 0);
+ rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_umts_rlc, 0);
- /*If no info found, skip all this*/
- if(fpinf == NULL){
+ /*If FP info or RLC info is missing , skip all this*/
+ if(fpinf == NULL || rlcinf== NULL){
return offset;
}
/*Retrieve the start value for the two ciphering domains*/
@@ -1002,29 +1029,16 @@ private_data_set_scrambling_code(actx,scrambling_code);
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);
-
- /*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);
- }
+ /*Find the entry for the UE ID(taken from RLC)*/
+ ciphering_info = get_or_create_cipher_info(fpinf, rlcinf);
+ private_data_set_ciphering_info(actx, ciphering_info);
/*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)
+ if(ciphering_info && ciphering_info->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);
+ g_tree_insert(ciphering_info->start_ps, GUINT_TO_POINTER(actx->pinfo->num), start);
break;
default:
@@ -1033,36 +1047,43 @@ private_data_set_scrambling_code(actx,scrambling_code);
private_data_set_cn_domain(actx, RRC_NAS_SYS_UNKNOWN);
#.FN_BODY RB-ActivationTimeInfo
- fp_info *fpinf;
- rrc_ciphering_info * c_inf;
-
-
+ fp_info *fpinf;
+ rlc_info *rlcinf;
+ rrc_ciphering_info *ciphering_info;
+ guint32 rbid;
+ guint32 rlc_ciphering_sqn;
fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_fp, 0);
+ rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_umts_rlc, 0);
%(DEFAULT_BODY)s
- /*If no info found, skip all this*/
- if(fpinf == NULL){
+ /*If FP info or RLC info is missing , skip all this*/
+ if(fpinf == NULL || rlcinf== NULL){
return offset;
}
- /*This should not happen*/
- if( (c_inf = (rrc_ciphering_info *)g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER(fpinf->com_context_id))) == NULL ){
+
+ ciphering_info = private_data_get_ciphering_info(actx);
+ if( ciphering_info == NULL ){
return offset;
}
+
+ rbid = private_data_get_rbid(actx);
+ rlc_ciphering_sqn = private_data_get_rlc_ciphering_sqn(actx);
/*Set the ciphering activation frame information*/
- c_inf->seq_no[rbid][fpinf->is_uplink] = activation_frame;
+ ciphering_info->seq_no[rbid][fpinf->is_uplink] = rlc_ciphering_sqn;
#.FN_BODY RB-Identity VAL_PTR = &rbid
-
+guint32 rbid;
%(DEFAULT_BODY)s
+private_data_set_rbid(actx, rbid);
-
-#.FN_BODY RLC-SequenceNumber VAL_PTR = &activation_frame
-
+#.FN_BODY RLC-SequenceNumber VAL_PTR = &rlc_ciphering_sqn
+guint32 rlc_ciphering_sqn;
%(DEFAULT_BODY)s
+private_data_set_rlc_ciphering_sqn(actx, rlc_ciphering_sqn);
#.FN_BODY DL-DCCH-MessageType VAL_PTR = &msg_type
%(DEFAULT_BODY)s