2 * Routines for Universal Mobile Telecommunications System (UMTS);
3 * Radio Resource Control (RRC) protocol specification
4 * (3GPP TS 25.331 packet dissection)
5 * Copyright 2006-2010, Anders Broman <anders.broman@ericsson.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
13 * Ref: 3GPP TS 25.331 V17.1.0 (2022-06)
19 * - Fix ciphering information for circuit switched stuff
24 #include <epan/packet.h>
25 #include <epan/asn1.h>
26 #include <epan/conversation.h>
27 #include <epan/expert.h>
28 #include <epan/proto_data.h>
29 #include <epan/prefs.h>
31 #include <wsutil/array.h>
33 #include "packet-ber.h"
34 #include "packet-per.h"
35 #include "packet-rrc.h"
36 #include "packet-gsm_a_common.h"
37 #include "packet-nbap.h"
38 #include "packet-umts_fp.h"
39 #include "packet-umts_mac.h"
40 #include "packet-umts_rlc.h"
43 /* disable: "warning C4049: compiler limit : terminating line number emission" */
44 #pragma warning(disable:4049)
45 /* disable: "warning C4146: unary minus operator applied to unsigned type, result still unsigned" */
46 #pragma warning(disable:4146)
49 #define PNAME "Radio Resource Control (RRC) protocol"
53 extern int proto_fp
; /*Handler to FP*/
54 extern int proto_umts_mac
; /*Handler to MAC*/
55 extern int proto_umts_rlc
; /*Handler to RLC*/
57 GTree
* hsdsch_muxed_flows
;
58 GTree
* rrc_ciph_info_tree
;
59 wmem_tree_t
* rrc_global_urnti_crnti_map
;
60 static int msg_type _U_
;
61 static bool rrc_nas_in_root_tree
;
63 enum rrc_sib_segment_type
{
64 RRC_SIB_SEG_NO_SEGMENT
= 0,
65 RRC_SIB_SEG_FIRST
= 1,
66 RRC_SIB_SEG_SUBSEQUENT
= 2,
67 RRC_SIB_SEG_LAST_SHORT
= 3,
68 RRC_SIB_SEG_LAST_AND_FIRST
= 4,
69 RRC_SIB_SEG_LAST_AND_COMP
= 5,
70 RRC_SIB_SEG_LAST_AND_COMP_AND_FIRST
= 6,
71 RRC_SIB_SEG_COMP_LIST
= 7,
72 RRC_SIB_SEG_COMP_AND_FIRST
= 8,
73 RRC_SIB_SEG_COMP
= 10,
76 /*****************************************************************************/
77 /* Packet private data */
78 /* For this dissector, all access to actx->private_data should be made */
79 /* through this API, which ensures that they will not overwrite each other!! */
80 /*****************************************************************************/
82 typedef struct umts_rrc_private_data_t
84 uint32_t s_rnc_id
; /* The S-RNC ID part of a U-RNTI */
85 uint32_t s_rnti
; /* The S-RNTI part of a U-RNTI */
87 uint32_t current_u_rnti
;
88 uint32_t scrambling_code
;
89 enum nas_sys_info_gsm_map cn_domain
;
90 wmem_strbuf_t
* digits_strbuf
; /* A collection of digits in a string. Used for reconstructing IMSIs or MCC-MNC pairs */
91 wmem_strbuf_t
* last_mcc_strbuf
; /* Last seen MCC digits string */
92 bool digits_strbuf_parsing_failed_flag
; /* Whether an error occurred when creating the IMSI/MCC-MNC pair string */
94 uint32_t rlc_ciphering_sqn
; /* Sequence number where ciphering starts in a given bearer */
95 rrc_ciphering_info
* ciphering_info
;
96 enum rrc_ue_state rrc_state_indicator
;
97 enum rrc_sib_segment_type curr_sib_segment_type
;
98 uint32_t curr_sib_type
;
99 } umts_rrc_private_data_t
;
102 /* Helper function to get or create a struct that will be actx->private_data */
103 static umts_rrc_private_data_t
* umts_rrc_get_private_data(asn1_ctx_t
*actx
)
105 if (actx
->private_data
== NULL
) {
106 actx
->private_data
= wmem_new0(actx
->pinfo
->pool
, umts_rrc_private_data_t
);
108 return (umts_rrc_private_data_t
*)actx
->private_data
;
111 static uint32_t private_data_get_s_rnc_id(asn1_ctx_t
*actx
)
113 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
114 return private_data
->s_rnc_id
;
117 static void private_data_set_s_rnc_id(asn1_ctx_t
*actx
, uint32_t s_rnc_id
)
119 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
120 private_data
->s_rnc_id
= s_rnc_id
;
123 static uint32_t private_data_get_s_rnti(asn1_ctx_t
*actx
)
125 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
126 return private_data
->s_rnti
;
129 static void private_data_set_s_rnti(asn1_ctx_t
*actx
, uint32_t s_rnti
)
131 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
132 private_data
->s_rnti
= s_rnti
;
135 static uint32_t private_data_get_new_u_rnti(asn1_ctx_t
*actx
)
137 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
138 return private_data
->new_u_rnti
;
141 static void private_data_set_new_u_rnti(asn1_ctx_t
*actx
, uint32_t new_u_rnti
)
143 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
144 private_data
->new_u_rnti
= new_u_rnti
;
147 static uint32_t private_data_get_current_u_rnti(asn1_ctx_t
*actx
)
149 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
150 return private_data
->current_u_rnti
;
153 static void private_data_set_current_u_rnti(asn1_ctx_t
*actx
, uint32_t current_u_rnti
)
155 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
156 private_data
->current_u_rnti
= current_u_rnti
;
159 static uint32_t private_data_get_scrambling_code(asn1_ctx_t
*actx
)
161 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
162 return private_data
->scrambling_code
;
165 static void private_data_set_scrambling_code(asn1_ctx_t
*actx
, uint32_t scrambling_code
)
167 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
168 private_data
->scrambling_code
= scrambling_code
;
171 static enum nas_sys_info_gsm_map
private_data_get_cn_domain(asn1_ctx_t
*actx
)
173 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
174 return private_data
->cn_domain
;
177 static void private_data_set_cn_domain(asn1_ctx_t
*actx
, enum nas_sys_info_gsm_map cn_domain
)
179 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
180 private_data
->cn_domain
= cn_domain
;
183 static wmem_strbuf_t
* private_data_get_digits_strbuf(asn1_ctx_t
*actx
)
185 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
186 return private_data
->digits_strbuf
;
189 static void private_data_set_digits_strbuf(asn1_ctx_t
*actx
, wmem_strbuf_t
* digits_strbuf
)
191 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
192 private_data
->digits_strbuf
= digits_strbuf
;
195 static bool private_data_get_digits_strbuf_parsing_failed_flag(asn1_ctx_t
*actx
)
197 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
198 return private_data
->digits_strbuf_parsing_failed_flag
;
201 static void private_data_set_digits_strbuf_parsing_failed_flag(asn1_ctx_t
*actx
, bool digits_strbuf_parsing_failed_flag
)
203 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
204 private_data
->digits_strbuf_parsing_failed_flag
= digits_strbuf_parsing_failed_flag
;
207 static wmem_strbuf_t
* private_data_get_last_mcc_strbuf(asn1_ctx_t
*actx
)
209 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
210 return private_data
->last_mcc_strbuf
;
213 static void private_data_set_last_mcc_strbuf(asn1_ctx_t
*actx
, wmem_strbuf_t
* last_mcc_strbuf
)
215 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
216 private_data
->last_mcc_strbuf
= last_mcc_strbuf
;
219 static uint32_t private_data_get_rbid(asn1_ctx_t
*actx
)
221 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
222 return private_data
->rbid
;
225 static void private_data_set_rbid(asn1_ctx_t
*actx
, uint32_t rbid
)
227 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
228 private_data
->rbid
= rbid
;
231 static uint32_t private_data_get_rlc_ciphering_sqn(asn1_ctx_t
*actx
)
233 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
234 return private_data
->rlc_ciphering_sqn
;
237 static void private_data_set_rlc_ciphering_sqn(asn1_ctx_t
*actx
, uint32_t rlc_ciphering_sqn
)
239 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
240 private_data
->rlc_ciphering_sqn
= rlc_ciphering_sqn
;
243 static rrc_ciphering_info
* private_data_get_ciphering_info(asn1_ctx_t
*actx
)
245 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
246 return private_data
->ciphering_info
;
249 static void private_data_set_ciphering_info(asn1_ctx_t
*actx
, rrc_ciphering_info
* ciphering_info
)
251 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
252 private_data
->ciphering_info
= ciphering_info
;
255 static enum rrc_ue_state
private_data_get_rrc_state_indicator(asn1_ctx_t
*actx
)
257 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
258 return private_data
->rrc_state_indicator
;
261 static void private_data_set_rrc_state_indicator(asn1_ctx_t
*actx
, enum rrc_ue_state rrc_state_indicator
)
263 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
264 private_data
->rrc_state_indicator
= rrc_state_indicator
;
267 static enum rrc_sib_segment_type
private_data_get_curr_sib_segment_type(asn1_ctx_t
*actx
)
269 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
270 return private_data
->curr_sib_segment_type
;
273 static void private_data_set_curr_sib_segment_type(asn1_ctx_t
*actx
, enum rrc_sib_segment_type curr_sib_segment_type
)
275 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
276 private_data
->curr_sib_segment_type
= curr_sib_segment_type
;
279 static uint32_t private_data_get_curr_sib_type(asn1_ctx_t
*actx
)
281 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
282 return private_data
->curr_sib_type
;
285 static void private_data_set_curr_sib_type(asn1_ctx_t
*actx
, uint32_t curr_sib_type
)
287 umts_rrc_private_data_t
*private_data
= (umts_rrc_private_data_t
*)umts_rrc_get_private_data(actx
);
288 private_data
->curr_sib_type
= curr_sib_type
;
291 /*****************************************************************************/
293 static dissector_handle_t gsm_a_dtap_handle
;
294 static dissector_handle_t rrc_ue_radio_access_cap_info_handle
;
295 static dissector_handle_t rrc_pcch_handle
;
296 static dissector_handle_t rrc_ul_ccch_handle
;
297 static dissector_handle_t rrc_dl_ccch_handle
;
298 static dissector_handle_t rrc_ul_dcch_handle
;
299 static dissector_handle_t rrc_dl_dcch_handle
;
300 static dissector_handle_t rrc_bcch_fach_handle
;
301 static dissector_handle_t lte_rrc_ue_eutra_cap_handle
;
302 static dissector_handle_t lte_rrc_dl_dcch_handle
;
303 static dissector_handle_t gsm_rlcmac_dl_handle
;
305 /* Forward declarations */
306 void proto_register_rrc(void);
307 void proto_reg_handoff_rrc(void);
308 static int dissect_UE_RadioAccessCapabilityInfo_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *);
309 static int dissect_SysInfoType11bis_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *);
310 static int dissect_SysInfoType11ter_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *);
311 static int dissect_SysInfoType22_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *);
313 /* Include constants */
314 #include "packet-rrc-val.h"
316 /* Initialize the protocol and registered fields */
320 static int hf_urnti_new
;
321 static int hf_urnti_current
;
322 #include "packet-rrc-hf.c"
324 /* Initialize the subtree pointers */
327 #include "packet-rrc-ett.c"
329 static int ett_rrc_eutraFeatureGroupIndicators
;
330 static int ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo
;
331 static int ett_rrc_ims_info
;
332 static int ett_rrc_cellIdentity
;
333 static int ett_rrc_sib_data_var
;
335 static expert_field ei_rrc_no_hrnti
;
337 /* Global variables */
338 static proto_tree
*top_tree
;
340 static int hf_rrc_eutra_feat_group_ind_1
;
341 static int hf_rrc_eutra_feat_group_ind_2
;
342 static int hf_rrc_eutra_feat_group_ind_3
;
343 static int hf_rrc_eutra_feat_group_ind_4
;
344 static int hf_rrc_ims_info_atgw_trans_det_cont_type
;
345 static int hf_rrc_ims_info_atgw_udp_port
;
346 static int hf_rrc_ims_info_atgw_ipv4
;
347 static int hf_rrc_ims_info_atgw_ipv6
;
348 static int hf_rrc_cellIdentity_rnc_id
;
349 static int hf_rrc_cellIdentity_c_id
;
351 static const true_false_string rrc_eutra_feat_group_ind_1_val
= {
352 "UTRA CELL_PCH to EUTRA RRC_IDLE cell reselection - Supported",
353 "UTRA CELL_PCH to EUTRA RRC_IDLE cell reselection - Not supported"
355 static const true_false_string rrc_eutra_feat_group_ind_2_val
= {
356 "EUTRAN measurements and reporting in connected mode - Supported",
357 "EUTRAN measurements and reporting in connected mode - Not supported"
359 static const true_false_string rrc_eutra_feat_group_ind_3_val
= {
360 "UTRA CELL_FACH absolute priority cell reselection for high priority layers - Supported",
361 "UTRA CELL_FACH absolute priority cell reselection for high priority layers - Not supported"
363 static const true_false_string rrc_eutra_feat_group_ind_4_val
= {
364 "UTRA CELL_FACH absolute priority cell reselection for all layers - Supported",
365 "UTRA CELL_FACH absolute priority cell reselection for all layers - Not supported"
367 static const value_string rrc_ims_info_atgw_trans_det_cont_type
[] = {
368 {0, "ATGW-IPv4-address-and-port"},
369 {1, "ATGW-IPv6-address-and-port"},
370 {2, "ATGW-not-available"},
373 static int flowd
,type
;
375 /*Stores how many channels we have detected for a HS-DSCH MAC-flow*/
376 #define RRC_MAX_NUM_HSDHSCH_MACDFLOW 8
377 static uint8_t num_chans_per_flow
[RRC_MAX_NUM_HSDHSCH_MACDFLOW
];
380 * Return the maximum counter, useful for initiating counters
383 static int get_max_counter(int com_context
){
386 rrc_ciphering_info
* ciphering_info
;
388 if( (ciphering_info
= g_tree_lookup(rrc_ciph_info_tree
, GINT_TO_POINTER((int)com_context
))) == NULL
){
391 for(i
= 0; i
<31; i
++){
392 max
= MAX(ciphering_info
->ps_conf_counters
[i
][0], max
);
393 max
= MAX(ciphering_info
->ps_conf_counters
[i
][1], max
);
398 /** Utility functions used for various comparisons/cleanups in tree **/
399 static int rrc_key_cmp(const void *b_ptr
, const void *a_ptr
, void *ignore _U_
){
400 if( GPOINTER_TO_INT(a_ptr
) > GPOINTER_TO_INT(b_ptr
) ){
403 return GPOINTER_TO_INT(a_ptr
) < GPOINTER_TO_INT(b_ptr
);
406 static void rrc_free_value(void *value
){
410 static rrc_ciphering_info
*
411 get_or_create_cipher_info(fp_info
*fpinf
, rlc_info
*rlcinf
) {
412 rrc_ciphering_info
*cipher_info
= NULL
;
416 if (!fpinf
|| !rlcinf
)
419 ueid
= rlcinf
->ueid
[fpinf
->cur_tb
];
420 cipher_info
= (rrc_ciphering_info
*)g_tree_lookup(rrc_ciph_info_tree
, GINT_TO_POINTER((int)ueid
));
422 if( cipher_info
== NULL
){
423 cipher_info
= g_new0(rrc_ciphering_info
,1);
425 /*Initiate tree with START_PS values.*/
426 if(!cipher_info
->start_ps
)
427 cipher_info
->start_ps
= g_tree_new_full(rrc_key_cmp
,
428 NULL
,NULL
,rrc_free_value
);
430 /*Clear and initialize seq_no matrix*/
431 for(i
= 0; i
< 31; i
++){
432 cipher_info
->seq_no
[i
][0] = -1;
433 cipher_info
->seq_no
[i
][1] = -1;
436 /* Set algorithms to 'unknown' since 0s are valid values */
437 cipher_info
->ciphering_algorithm
= -1;
438 cipher_info
->integrity_algorithm
= -1;
440 g_tree_insert(rrc_ciph_info_tree
, GINT_TO_POINTER((int)rlcinf
->ueid
[fpinf
->cur_tb
]), cipher_info
);
445 /* Try to find the NBAP C-RNC Context and, if found, pair it with a given U-RNTI */
447 rrc_try_map_urnti_to_crncc(uint32_t u_rnti
, asn1_ctx_t
*actx
)
449 uint32_t scrambling_code
, crnc_context
;
450 /* Getting the user's Uplink Scrambling Code*/
451 scrambling_code
= private_data_get_scrambling_code(actx
);
452 if (u_rnti
!= 0 && scrambling_code
!= 0) {
453 /* Looking for the C-RNC Context mapped to this Scrambling Code */
454 crnc_context
= GPOINTER_TO_UINT(wmem_tree_lookup32(nbap_scrambling_code_crncc_map
,scrambling_code
));
455 if (crnc_context
!= 0) {
456 /* Mapping the U-RNTI to the C-RNC context*/
457 wmem_tree_insert32(nbap_crncc_urnti_map
,crnc_context
,GUINT_TO_POINTER(u_rnti
));
462 #include "packet-rrc-fn.c"
466 dissect_rrc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
468 /* FIX ME Currently don't know the 'starting point' of this protocol
469 * exported DL-DCCH-Message is the entry point.
471 proto_item
*rrc_item
= NULL
;
472 proto_tree
*rrc_tree
= NULL
;
473 struct rrc_info
*rrcinf
;
477 rrcinf
= (struct rrc_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_rrc
, 0);
478 fpinf
= (fp_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_fp
, 0);
480 /* make entry in the Protocol column on summary display */
481 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RRC");
484 memset(num_chans_per_flow
,0,sizeof(uint8_t)*RRC_MAX_NUM_HSDHSCH_MACDFLOW
);
486 /* create the rrc protocol tree */
487 rrc_item
= proto_tree_add_item(tree
, proto_rrc
, tvb
, 0, -1, ENC_NA
);
488 rrc_tree
= proto_item_add_subtree(rrc_item
, ett_rrc
);
490 if (rrcinf
&& fpinf
) {
491 switch (rrcinf
->msgtype
[fpinf
->cur_tb
]) {
492 case RRC_MESSAGE_TYPE_PCCH
:
493 call_dissector(rrc_pcch_handle
, tvb
, pinfo
, rrc_tree
);
495 case RRC_MESSAGE_TYPE_UL_CCCH
:
496 call_dissector(rrc_ul_ccch_handle
, tvb
, pinfo
, rrc_tree
);
498 case RRC_MESSAGE_TYPE_DL_CCCH
:
499 call_dissector(rrc_dl_ccch_handle
, tvb
, pinfo
, rrc_tree
);
501 case RRC_MESSAGE_TYPE_UL_DCCH
:
502 call_dissector(rrc_ul_dcch_handle
, tvb
, pinfo
, rrc_tree
);
504 case RRC_MESSAGE_TYPE_DL_DCCH
:
505 call_dissector(rrc_dl_dcch_handle
, tvb
, pinfo
, rrc_tree
);
507 case RRC_MESSAGE_TYPE_BCCH_FACH
:
508 call_dissector(rrc_bcch_fach_handle
, tvb
, pinfo
, rrc_tree
);
514 return tvb_captured_length(tvb
);
519 /*Initialize structure for muxed flow indication*/
520 hsdsch_muxed_flows
= g_tree_new_full(rrc_key_cmp
,
521 NULL
, /* data pointer, optional */
525 rrc_ciph_info_tree
= g_tree_new_full(rrc_key_cmp
,
526 NULL
, /* data pointer, optional */
534 g_tree_destroy(hsdsch_muxed_flows
);
535 g_tree_destroy(rrc_ciph_info_tree
);
538 /*--- proto_register_rrc -------------------------------------------*/
539 void proto_register_rrc(void) {
542 static hf_register_info hf
[] = {
544 #include "packet-rrc-hfarr.c"
546 { "RAB Test", "rrc.RAB.test",
547 FT_UINT8
, BASE_DEC
, NULL
, 0,
548 "rrc.RAB_Info_r6", HFILL
}},
550 { "U-RNTI", "rrc.urnti",
551 FT_UINT32
, BASE_HEX
, NULL
, 0,
554 { "New U-RNTI", "rrc.urnti_new",
555 FT_UINT32
, BASE_HEX
, NULL
, 0,
558 { "Current U-RNTI", "rrc.urnti_current",
559 FT_UINT32
, BASE_HEX
, NULL
, 0,
561 { &hf_rrc_eutra_feat_group_ind_1
,
562 { "Indicator 1", "rrc.eutra_feat_group_ind_1",
563 FT_BOOLEAN
, BASE_NONE
, TFS(&rrc_eutra_feat_group_ind_1_val
), 0,
564 "EUTRA Feature Group Indicator 1", HFILL
}},
565 { &hf_rrc_eutra_feat_group_ind_2
,
566 { "Indicator 2", "rrc.eutra_feat_group_ind_2",
567 FT_BOOLEAN
, BASE_NONE
, TFS(&rrc_eutra_feat_group_ind_2_val
), 0,
568 "EUTRA Feature Group Indicator 2", HFILL
}},
569 { &hf_rrc_eutra_feat_group_ind_3
,
570 { "Indicator 3", "rrc.eutra_feat_group_ind_3",
571 FT_BOOLEAN
, BASE_NONE
, TFS(&rrc_eutra_feat_group_ind_3_val
), 0,
572 "EUTRA Feature Group Indicator 3", HFILL
}},
573 { &hf_rrc_eutra_feat_group_ind_4
,
574 { "Indicator 4", "rrc.eutra_feat_group_ind_4",
575 FT_BOOLEAN
, BASE_NONE
, TFS(&rrc_eutra_feat_group_ind_4_val
), 0,
576 "EUTRA Feature Group Indicator 4", HFILL
}},
577 { &hf_rrc_ims_info_atgw_trans_det_cont_type
,
578 { "ATGW transfer details content type", "rrc.rsrvcc_info.ims_info_atgw_trans_det_cont",
579 FT_UINT8
, BASE_DEC
, VALS(rrc_ims_info_atgw_trans_det_cont_type
), 0x3,
580 "rSR-VCC IMS information ATGW transfer details content type", HFILL
}},
581 {&hf_rrc_ims_info_atgw_udp_port
,
582 {"ATGW UDP port","rrc.rsrvcc_info.ims_info_atgw_udp_port",
583 FT_UINT16
,BASE_DEC
, NULL
, 0x0,
584 "rSR-VCC IMS information ATGW UDP port", HFILL
}},
585 { &hf_rrc_ims_info_atgw_ipv4
,
586 {"ATGW IPv4", "rrc.rsrvcc_info.ims_info_atgw_ipv4",
587 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
588 "rSR-VCC IMS information ATGW IPv4", HFILL
}},
589 { &hf_rrc_ims_info_atgw_ipv6
,
590 {"ATGW IPv6", "rrc.rsrvcc_info.ims_info_atgw_ipv6",
591 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
592 "rSR-VCC IMS information ATGW IPv6", HFILL
}},
593 { &hf_rrc_cellIdentity_rnc_id
,
594 {"RNC Identifier", "rrc.cellIdentity.rnc_id",
595 FT_UINT32
, BASE_DEC
, NULL
, 0,
596 "The RNC Identifier (RNC-Id) part of the Cell Identity", HFILL
}},
597 { &hf_rrc_cellIdentity_c_id
,
598 {"Cell Identifier", "rrc.cellIdentity.c_id",
599 FT_UINT32
, BASE_DEC
, NULL
, 0,
600 "The Cell Identifier (C-Id) part of the Cell Identity", HFILL
}}
603 /* List of subtrees */
604 static int *ett
[] = {
606 #include "packet-rrc-ettarr.c"
607 &ett_rrc_eutraFeatureGroupIndicators
,
608 &ett_rrc_cn_CommonGSM_MAP_NAS_SysInfo
,
610 &ett_rrc_cellIdentity
,
611 &ett_rrc_sib_data_var
,
614 static ei_register_info ei
[] = {
615 { &ei_rrc_no_hrnti
, { "rrc.no_hrnti", PI_SEQUENCE
, PI_NOTE
, "Did not detect any H-RNTI", EXPFILL
}},
618 expert_module_t
* expert_rrc
;
619 module_t
*rrc_module
;
621 /* Register protocol */
622 proto_rrc
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
623 /* Register fields and subtrees */
624 proto_register_field_array(proto_rrc
, hf
, array_length(hf
));
625 proto_register_subtree_array(ett
, array_length(ett
));
626 expert_rrc
= expert_register_protocol(proto_rrc
);
627 expert_register_field_array(expert_rrc
, ei
, array_length(ei
));
629 register_dissector("rrc", dissect_rrc
, proto_rrc
);
631 #include "packet-rrc-dis-reg.c"
633 register_init_routine(rrc_init
);
634 register_cleanup_routine(rrc_cleanup
);
636 /* Register configuration preferences */
637 rrc_module
= prefs_register_protocol(proto_rrc
, NULL
);
638 prefs_register_bool_preference(rrc_module
, "nas_in_root_tree",
639 "Show NAS PDU in root packet details",
640 "Whether the NAS PDU should be shown in the root packet details tree",
641 &rrc_nas_in_root_tree
);
643 /* Global U-RNTI / C-RNTI map to be used in RACH channels */
644 rrc_global_urnti_crnti_map
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
648 /*--- proto_reg_handoff_rrc ---------------------------------------*/
650 proto_reg_handoff_rrc(void)
652 gsm_a_dtap_handle
= find_dissector_add_dependency("gsm_a_dtap", proto_rrc
);
653 rrc_pcch_handle
= find_dissector("rrc.pcch");
654 rrc_ul_ccch_handle
= find_dissector("rrc.ul.ccch");
655 rrc_dl_ccch_handle
= find_dissector("rrc.dl.ccch");
656 rrc_ul_dcch_handle
= find_dissector("rrc.ul.dcch");
657 rrc_dl_dcch_handle
= find_dissector("rrc.dl.dcch");
658 rrc_ue_radio_access_cap_info_handle
= find_dissector("rrc.ue_radio_access_cap_info");
659 rrc_dl_dcch_handle
= find_dissector("rrc.dl.dcch");
660 lte_rrc_ue_eutra_cap_handle
= find_dissector_add_dependency("lte-rrc.ue_eutra_cap", proto_rrc
);
661 lte_rrc_dl_dcch_handle
= find_dissector_add_dependency("lte-rrc.dl.dcch", proto_rrc
);
662 rrc_bcch_fach_handle
= find_dissector("rrc.bcch.fach");
663 gsm_rlcmac_dl_handle
= find_dissector_add_dependency("gsm_rlcmac_dl", proto_rrc
);