diff options
author | Darien Spencer <cusneud@mail.com> | 2017-08-19 17:33:14 +0300 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2017-09-13 19:24:20 +0000 |
commit | bdf10a239fcf873e1fff955f0fb6d8fd41aefcf3 (patch) | |
tree | 7ca52f0fe8e473602fc285ccf51a6c8e66a757d0 /epan/dissectors/asn1/rrc | |
parent | ba957234735b9a65ff831cf9a6b0ed1a230c19ea (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/rrc')
-rw-r--r-- | epan/dissectors/asn1/rrc/packet-rrc-template.c | 134 | ||||
-rw-r--r-- | epan/dissectors/asn1/rrc/packet-rrc-template.h | 8 | ||||
-rw-r--r-- | epan/dissectors/asn1/rrc/rrc.cnf | 109 |
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 |