GSM A DTAP: add UMTS EVS to supported codecs list IE
[metze/wireshark/wip.git] / epan / dissectors / packet-pdcp-nr.c
1 /* packet-pdcp-nr.c
2  * Routines for nr PDCP
3  *
4  * Martin Mathieson
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "config.h"
14
15
16 #include <epan/packet.h>
17 #include <epan/prefs.h>
18 #include <epan/expert.h>
19 #include <epan/uat.h>
20 #include <epan/proto_data.h>
21
22 #include <wsutil/wsgcrypt.h>
23
24
25 #include "packet-rlc-nr.h"
26 #include "packet-pdcp-nr.h"
27
28 void proto_register_pdcp_nr(void);
29 void proto_reg_handoff_pdcp_nr(void);
30
31 /* Described in:
32  * 3GPP TS 38.323 Technical Specification Group Radio Access Netowrk; NR;
33  *                Packet Data Convergence Protocol (PDCP) specification (Release 15.1.0)
34  */
35
36
37 /* TODO:
38    - Deciphering, but should refactor and share LTE implementation
39 */
40
41
42 /* Initialize the protocol and registered fields. */
43 int proto_pdcp_nr = -1;
44
45 extern int proto_rlc_nr;
46
47 /* Configuration (info known outside of PDU) */
48 static int hf_pdcp_nr_configuration = -1;
49 static int hf_pdcp_nr_direction = -1;
50 static int hf_pdcp_nr_ueid = -1;
51 static int hf_pdcp_nr_bearer_type = -1;
52 static int hf_pdcp_nr_bearer_id = -1;
53 static int hf_pdcp_nr_plane = -1;
54 static int hf_pdcp_nr_seqnum_length = -1;
55
56 static int hf_pdcp_nr_rohc_compression = -1;
57 static int hf_pdcp_nr_rohc_mode = -1;
58 static int hf_pdcp_nr_rohc_rnd = -1;
59 static int hf_pdcp_nr_rohc_udp_checksum_present = -1;
60 static int hf_pdcp_nr_rohc_profile = -1;
61 static int hf_pdcp_nr_cid_inclusion_info = -1;
62 static int hf_pdcp_nr_large_cid_present = -1;
63
64 /* PDCP header fields */
65 static int hf_pdcp_nr_control_plane_reserved = -1;
66 static int hf_pdcp_nr_reserved3 = -1;
67 static int hf_pdcp_nr_seq_num_12 = -1;
68 static int hf_pdcp_nr_reserved5 = -1;
69 static int hf_pdcp_nr_seq_num_18 = -1;
70 static int hf_pdcp_nr_signalling_data = -1;
71 static int hf_pdcp_nr_mac = -1;
72 static int hf_pdcp_nr_data_control = -1;
73 static int hf_pdcp_nr_user_plane_data = -1;
74 static int hf_pdcp_nr_control_pdu_type = -1;
75 static int hf_pdcp_nr_fmc = -1;
76 static int hf_pdcp_nr_reserved4 = -1;
77 static int hf_pdcp_nr_bitmap = -1;
78 static int hf_pdcp_nr_bitmap_byte = -1;
79
80 /* Sequence Analysis */
81 static int hf_pdcp_nr_sequence_analysis = -1;
82 static int hf_pdcp_nr_sequence_analysis_ok = -1;
83 static int hf_pdcp_nr_sequence_analysis_previous_frame = -1;
84 static int hf_pdcp_nr_sequence_analysis_next_frame = -1;
85 static int hf_pdcp_nr_sequence_analysis_expected_sn = -1;
86 static int hf_pdcp_nr_sequence_analysis_repeated = -1;
87 static int hf_pdcp_nr_sequence_analysis_skipped = -1;
88
89
90 /* Protocol subtree. */
91 static int ett_pdcp = -1;
92 static int ett_pdcp_configuration = -1;
93 static int ett_pdcp_packet = -1;
94 static int ett_pdcp_nr_sequence_analysis = -1;
95 static int ett_pdcp_report_bitmap = -1;
96
97 static expert_field ei_pdcp_nr_sequence_analysis_wrong_sequence_number = EI_INIT;
98 static expert_field ei_pdcp_nr_reserved_bits_not_zero = EI_INIT;
99 static expert_field ei_pdcp_nr_sequence_analysis_sn_repeated = EI_INIT;
100 static expert_field ei_pdcp_nr_sequence_analysis_sn_missing = EI_INIT;
101 static expert_field ei_pdcp_nr_unknown_udp_framing_tag = EI_INIT;
102 static expert_field ei_pdcp_nr_missing_udp_framing_tag = EI_INIT;
103
104
105
106 static const value_string direction_vals[] =
107 {
108     { PDCP_NR_DIRECTION_UPLINK,      "Uplink"},
109     { PDCP_NR_DIRECTION_DOWNLINK,    "Downlink"},
110     { 0, NULL }
111 };
112
113
114 static const value_string pdcp_plane_vals[] = {
115     { NR_SIGNALING_PLANE,    "Signalling" },
116     { NR_USER_PLANE,         "User" },
117     { 0,   NULL }
118 };
119
120 static const value_string bearer_type_vals[] = {
121     { Bearer_DCCH,        "DCCH"},
122     { Bearer_BCCH_BCH,    "BCCH_BCH"},
123     { Bearer_BCCH_DL_SCH, "BCCH_DL_SCH"},
124     { Bearer_CCCH,        "CCCH"},
125     { Bearer_PCCH,        "PCCH"},
126     { 0,                  NULL}
127 };
128
129 static const value_string rohc_mode_vals[] = {
130     { UNIDIRECTIONAL,            "Unidirectional" },
131     { OPTIMISTIC_BIDIRECTIONAL,  "Optimistic Bidirectional" },
132     { RELIABLE_BIDIRECTIONAL,    "Reliable Bidirectional" },
133     { 0,   NULL }
134 };
135
136
137 /* Entries taken from Table 5.7.1-1.
138    Descriptions from http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.txt */
139 static const value_string rohc_profile_vals[] = {
140     { 0x0000,   "ROHC uncompressed" },      /* [RFC5795] */
141     { 0x0001,   "ROHC RTP" },               /* [RFC3095] */
142     { 0x0002,   "ROHC UDP" },               /* [RFC3095] */
143     { 0x0003,   "ROHC ESP" },               /* [RFC3095] */
144     { 0x0004,   "ROHC IP" },                /* [RFC3843] */
145     { 0x0006,   "ROHC TCP" },               /* [RFC4996] */
146
147     { 0x0101,   "ROHCv2 RTP" },             /* [RFC5225] */
148     { 0x0102,   "ROHCv2 UDP" },             /* [RFC5225] */
149     { 0x0103,   "ROHCv2 ESP" },             /* [RFC5225] */
150     { 0x0104,   "ROHCv2 IP" },              /* [RFC5225] */
151     { 0,   NULL }
152 };
153
154 static const true_false_string pdu_type_bit = {
155     "Data PDU",
156     "Control PDU"
157 };
158
159
160 static const value_string control_pdu_type_vals[] = {
161     { 0,   "PDCP status report" },
162     { 1,   "Interspersed ROHC feedback packet" },
163     { 0,   NULL }
164 };
165
166 #if 0
167 static const value_string integrity_algorithm_vals[] = {
168     { 0,   "NIA0" },
169     { 1,   "NIA1" },
170     { 2,   "NIA2" },
171     { 3,   "NIA3" },
172     { 0,   NULL }
173 };
174
175 static const value_string ciphering_algorithm_vals[] = {
176     { 0,   "NEA0" },
177     { 1,   "NEA1" },
178     { 2,   "NEA2" },
179     { 3,   "NEA3" },
180     { 0,   NULL }
181 };
182 #endif
183
184
185 /* SDAP header fields and tree */
186 static int proto_sdap = -1;
187 static int hf_sdap_rdi = -1;
188 static int hf_sdap_rqi = -1;
189 static int hf_sdap_qfi = -1;
190 static int hf_sdap_data_control = -1;
191 static int hf_sdap_reserved = -1;
192 static gint ett_sdap = -1;
193
194 static const true_false_string sdap_rdi = {
195     "To store QoS flow to DRB mapping rule",
196     "No action"
197 };
198
199 static const true_false_string sdap_rqi = {
200     "To inform NAS that RQI bit is set to 1",
201     "No action"
202 };
203
204
205 static dissector_handle_t ip_handle;
206 static dissector_handle_t ipv6_handle;
207 static dissector_handle_t rohc_handle;
208
209
210 #define SEQUENCE_ANALYSIS_RLC_ONLY  1
211 #define SEQUENCE_ANALYSIS_PDCP_ONLY 2
212
213 /* Preference variables */
214 static gboolean global_pdcp_dissect_user_plane_as_ip = TRUE;
215 static gboolean global_pdcp_dissect_signalling_plane_as_rrc = TRUE;
216 static gint     global_pdcp_check_sequence_numbers = TRUE;
217 static gboolean global_pdcp_dissect_rohc = FALSE;
218
219 /* Which layer info to show in the info column */
220 enum layer_to_show {
221     ShowRLCLayer, ShowPDCPLayer, ShowTrafficLayer
222 };
223 static gint     global_pdcp_nr_layer_to_show = (gint)ShowRLCLayer;
224
225
226 /* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
227 pdcp_nr_info *get_pdcp_nr_proto_data(packet_info *pinfo)
228 {
229     return (pdcp_nr_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_nr, 0);
230 }
231
232 /* Function to be called from outside this module (e.g. in a plugin) to set per-packet data */
233 void set_pdcp_nr_proto_data(packet_info *pinfo, pdcp_nr_info *p_pdcp_nr_info)
234 {
235     p_add_proto_data(wmem_file_scope(), pinfo, proto_pdcp_nr, 0, p_pdcp_nr_info);
236 }
237
238
239
240 /**************************************************/
241 /* Sequence number analysis                       */
242
243 /* Bearer key */
244 typedef struct
245 {
246     /* Using bit fields to fit into 32 bits, so avoiding the need to allocate
247        heap memory for these structs */
248     guint           ueId : 16;
249     guint           plane : 2;
250     guint           bearerId : 6;
251     guint           direction : 1;
252     guint           notUsed : 7;
253 } pdcp_bearer_hash_key;
254
255 /* Bearer state */
256 typedef struct
257 {
258     guint32  previousSequenceNumber;
259     guint32  previousFrameNum;
260     guint32  hfn;
261 } pdcp_bearer_status;
262
263 /* The sequence analysis bearer hash table.
264    Maps key -> status */
265 static wmem_map_t *pdcp_sequence_analysis_bearer_hash = NULL;
266
267
268 /* Hash table types & functions for frame reports */
269
270 typedef struct {
271     guint32         frameNumber;
272     guint32         SN :       18;
273     guint32         plane :    2;
274     guint32         bearerId: 5;
275     guint32         direction: 1;
276     guint32         notUsed :  6;
277 } pdcp_result_hash_key;
278
279 static gint pdcp_result_hash_equal(gconstpointer v, gconstpointer v2)
280 {
281     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
282     const pdcp_result_hash_key* val2 = (const pdcp_result_hash_key *)v2;
283
284     /* All fields must match */
285     return (memcmp(val1, val2, sizeof(pdcp_result_hash_key)) == 0);
286 }
287
288 /* Compute a hash value for a given key. */
289 static guint pdcp_result_hash_func(gconstpointer v)
290 {
291     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
292
293     /* TODO: This is a bit random.  */
294     return val1->frameNumber + (val1->bearerId<<7) +
295                                (val1->plane<<12) +
296                                (val1->SN<<14) +
297                                (val1->direction<<6);
298 }
299
300 /* pdcp_bearer_hash_key fits into the pointer, so just copy the value into
301    a guint, cast to a pointer and return that as the key */
302 static gpointer get_bearer_hash_key(pdcp_bearer_hash_key *key)
303 {
304     guint  asInt = 0;
305     /* TODO: assert that sizeof(pdcp_bearer_hash_key) <= sizeof(guint) ? */
306     memcpy(&asInt, key, sizeof(pdcp_bearer_hash_key));
307     return GUINT_TO_POINTER(asInt);
308 }
309
310 /* Convenience function to get a pointer for the hash_func to work with */
311 static gpointer get_report_hash_key(guint32 SN, guint32 frameNumber,
312                                     pdcp_nr_info *p_pdcp_nr_info,
313                                     gboolean do_persist)
314 {
315     static pdcp_result_hash_key  key;
316     pdcp_result_hash_key        *p_key;
317
318     /* Only allocate a struct when will be adding entry */
319     if (do_persist) {
320         p_key = wmem_new(wmem_file_scope(), pdcp_result_hash_key);
321     }
322     else {
323         memset(&key, 0, sizeof(pdcp_result_hash_key));
324         p_key = &key;
325     }
326
327     /* Fill in details, and return pointer */
328     p_key->frameNumber = frameNumber;
329     p_key->SN = SN;
330     p_key->plane = (guint8)p_pdcp_nr_info->plane;
331     p_key->bearerId = p_pdcp_nr_info->bearerId;
332     p_key->direction = p_pdcp_nr_info->direction;
333     p_key->notUsed = 0;
334
335     return p_key;
336 }
337
338
339 /* Info to attach to frame when first read, recording what to show about sequence */
340 typedef enum
341 {
342     SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing
343 } sequence_state;
344 typedef struct
345 {
346     gboolean sequenceExpectedCorrect;
347     guint32  sequenceExpected;
348     guint32  previousFrameNum;
349     guint32  nextFrameNum;
350
351     guint32  firstSN;
352     guint32  lastSN;
353     guint32  hfn;
354
355     sequence_state state;
356 } pdcp_sequence_report_in_frame;
357
358 /* The sequence analysis frame report hash table.
359    Maps pdcp_result_hash_key* -> pdcp_sequence_report_in_frame* */
360 static wmem_map_t *pdcp_nr_sequence_analysis_report_hash = NULL;
361
362
363 /* Add to the tree values associated with sequence analysis for this frame */
364 static void addBearerSequenceInfo(pdcp_sequence_report_in_frame *p,
365                                    pdcp_nr_info *p_pdcp_nr_info,
366                                    guint32   sequenceNumber,
367                                    packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb)
368 {
369     proto_tree *seqnum_tree;
370     proto_item *seqnum_ti;
371     proto_item *ti_expected_sn;
372     proto_item *ti;
373
374     /* Create subtree */
375     seqnum_ti = proto_tree_add_string_format(tree,
376                                              hf_pdcp_nr_sequence_analysis,
377                                              tvb, 0, 0,
378                                              "", "Sequence Analysis");
379     seqnum_tree = proto_item_add_subtree(seqnum_ti,
380                                          ett_pdcp_nr_sequence_analysis);
381     PROTO_ITEM_SET_GENERATED(seqnum_ti);
382
383
384     /* Previous bearer frame */
385     if (p->previousFrameNum != 0) {
386         proto_tree_add_uint(seqnum_tree, hf_pdcp_nr_sequence_analysis_previous_frame,
387                             tvb, 0, 0, p->previousFrameNum);
388     }
389
390     /* Expected sequence number */
391     ti_expected_sn = proto_tree_add_uint(seqnum_tree, hf_pdcp_nr_sequence_analysis_expected_sn,
392                                          tvb, 0, 0, p->sequenceExpected);
393     PROTO_ITEM_SET_GENERATED(ti_expected_sn);
394
395     /* Make sure we have recognised SN length */
396     switch (p_pdcp_nr_info->seqnum_length) {
397         case PDCP_NR_SN_LENGTH_12_BITS:
398         case PDCP_NR_SN_LENGTH_18_BITS:
399             break;
400         default:
401             DISSECTOR_ASSERT_NOT_REACHED();
402             break;
403     }
404
405     switch (p->state) {
406         case SN_OK:
407             PROTO_ITEM_SET_HIDDEN(ti_expected_sn);
408             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_nr_sequence_analysis_ok,
409                                         tvb, 0, 0, TRUE);
410             PROTO_ITEM_SET_GENERATED(ti);
411             proto_item_append_text(seqnum_ti, " - OK");
412
413             /* Link to next SN in bearer (if known) */
414             if (p->nextFrameNum != 0) {
415                 proto_tree_add_uint(seqnum_tree, hf_pdcp_nr_sequence_analysis_next_frame,
416                                     tvb, 0, 0, p->nextFrameNum);
417             }
418
419             break;
420
421         case SN_Missing:
422             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_nr_sequence_analysis_ok,
423                                         tvb, 0, 0, FALSE);
424             PROTO_ITEM_SET_GENERATED(ti);
425             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_nr_sequence_analysis_skipped,
426                                         tvb, 0, 0, TRUE);
427             PROTO_ITEM_SET_GENERATED(ti);
428             if (p->lastSN != p->firstSN) {
429                 expert_add_info_format(pinfo, ti, &ei_pdcp_nr_sequence_analysis_sn_missing,
430                                        "PDCP SNs (%u to %u) missing for %s on UE %u (%s-%u)",
431                                        p->firstSN, p->lastSN,
432                                        val_to_str_const(p_pdcp_nr_info->direction, direction_vals, "Unknown"),
433                                        p_pdcp_nr_info->ueid,
434                                        val_to_str_const(p_pdcp_nr_info->bearerType, bearer_type_vals, "Unknown"),
435                                        p_pdcp_nr_info->bearerId);
436                 proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
437                                        p->firstSN, p->lastSN);
438             }
439             else {
440                 expert_add_info_format(pinfo, ti, &ei_pdcp_nr_sequence_analysis_sn_missing,
441                                        "PDCP SN (%u) missing for %s on UE %u (%s-%u)",
442                                        p->firstSN,
443                                        val_to_str_const(p_pdcp_nr_info->direction, direction_vals, "Unknown"),
444                                        p_pdcp_nr_info->ueid,
445                                        val_to_str_const(p_pdcp_nr_info->bearerType, bearer_type_vals, "Unknown"),
446                                        p_pdcp_nr_info->bearerId);
447                 proto_item_append_text(seqnum_ti, " - SN missing (%u)",
448                                        p->firstSN);
449             }
450             break;
451
452         case SN_Repeated:
453             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_nr_sequence_analysis_ok,
454                                         tvb, 0, 0, FALSE);
455             PROTO_ITEM_SET_GENERATED(ti);
456             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_nr_sequence_analysis_repeated,
457                                         tvb, 0, 0, TRUE);
458             PROTO_ITEM_SET_GENERATED(ti);
459             expert_add_info_format(pinfo, ti, &ei_pdcp_nr_sequence_analysis_sn_repeated,
460                                    "PDCP SN (%u) repeated for %s for UE %u (%s-%u)",
461                                    p->firstSN,
462                                    val_to_str_const(p_pdcp_nr_info->direction, direction_vals, "Unknown"),
463                                    p_pdcp_nr_info->ueid,
464                                    val_to_str_const(p_pdcp_nr_info->bearerType, bearer_type_vals, "Unknown"),
465                                    p_pdcp_nr_info->bearerId);
466             proto_item_append_text(seqnum_ti, "- SN %u Repeated",
467                                    p->firstSN);
468             break;
469
470         default:
471             /* Incorrect sequence number */
472             expert_add_info_format(pinfo, ti_expected_sn, &ei_pdcp_nr_sequence_analysis_wrong_sequence_number,
473                                    "Wrong Sequence Number for %s on UE %u (%s-%u) - got %u, expected %u",
474                                    val_to_str_const(p_pdcp_nr_info->direction, direction_vals, "Unknown"),
475                                    p_pdcp_nr_info->ueid,
476                                    val_to_str_const(p_pdcp_nr_info->bearerType, bearer_type_vals, "Unknown"),
477                                    p_pdcp_nr_info->bearerId,
478                                    sequenceNumber, p->sequenceExpected);
479             break;
480     }
481 }
482
483
484 /* Update the bearer status and set report for this frame */
485 static void checkBearerSequenceInfo(packet_info *pinfo, tvbuff_t *tvb,
486                                      pdcp_nr_info *p_pdcp_nr_info,
487                                      guint32 sequenceNumber,
488                                      proto_tree *tree)
489 {
490     pdcp_bearer_hash_key          bearer_key;
491     pdcp_bearer_status           *p_bearer_status;
492     pdcp_sequence_report_in_frame *p_report_in_frame      = NULL;
493     gboolean                       createdBearer          = FALSE;
494     guint32                        expectedSequenceNumber = 0;
495     guint32                        snLimit                = 0;
496
497     /* If find stat_report_in_frame already, use that and get out */
498     if (pinfo->fd->flags.visited) {
499         p_report_in_frame =
500             (pdcp_sequence_report_in_frame*)wmem_map_lookup(pdcp_nr_sequence_analysis_report_hash,
501                                                             get_report_hash_key(sequenceNumber,
502                                                                                 pinfo->num,
503                                                                                 p_pdcp_nr_info, FALSE));
504         if (p_report_in_frame != NULL) {
505             addBearerSequenceInfo(p_report_in_frame, p_pdcp_nr_info,
506                                    sequenceNumber,
507                                    pinfo, tree, tvb);
508             return;
509         }
510         else {
511             /* Give up - we must have tried already... */
512             return;
513         }
514     }
515
516
517     /**************************************************/
518     /* Create or find an entry for this bearer state */
519     bearer_key.ueId = p_pdcp_nr_info->ueid;
520     bearer_key.plane = p_pdcp_nr_info->plane;
521     bearer_key.bearerId = p_pdcp_nr_info->bearerId;
522     bearer_key.direction = p_pdcp_nr_info->direction;
523     bearer_key.notUsed = 0;
524
525     /* Do the table lookup */
526     p_bearer_status = (pdcp_bearer_status*)wmem_map_lookup(pdcp_sequence_analysis_bearer_hash,
527                                                              get_bearer_hash_key(&bearer_key));
528
529     /* Create table entry if necessary */
530     if (p_bearer_status == NULL) {
531         createdBearer = TRUE;
532
533         /* Allocate a new value and duplicate key contents */
534         p_bearer_status = wmem_new0(wmem_file_scope(), pdcp_bearer_status);
535
536         /* Add entry */
537         wmem_map_insert(pdcp_sequence_analysis_bearer_hash,
538                         get_bearer_hash_key(&bearer_key), p_bearer_status);
539     }
540
541     /* Create space for frame state_report */
542     p_report_in_frame = wmem_new(wmem_file_scope(), pdcp_sequence_report_in_frame);
543     p_report_in_frame->nextFrameNum = 0;
544
545     switch (p_pdcp_nr_info->seqnum_length) {
546         case PDCP_NR_SN_LENGTH_12_BITS:
547             snLimit = 4096;
548             break;
549         case PDCP_NR_SN_LENGTH_18_BITS:
550             snLimit = 262144;
551             break;
552         default:
553             DISSECTOR_ASSERT_NOT_REACHED();
554             break;
555     }
556
557     /* Work out expected sequence number */
558     if (!createdBearer) {
559         expectedSequenceNumber = (p_bearer_status->previousSequenceNumber + 1) % snLimit;
560     }
561     else {
562         expectedSequenceNumber = sequenceNumber;
563     }
564
565     /* Set report for this frame */
566     /* For PDCP, sequence number is always expectedSequence number */
567     p_report_in_frame->sequenceExpectedCorrect = (sequenceNumber == expectedSequenceNumber);
568     p_report_in_frame->hfn = p_bearer_status->hfn;
569
570     /* For wrong sequence number... */
571     if (!p_report_in_frame->sequenceExpectedCorrect) {
572
573         /* Frames are not missing if we get an earlier sequence number again */
574         if (((snLimit + expectedSequenceNumber - sequenceNumber) % snLimit) > 15) {
575             p_report_in_frame->state = SN_Missing;
576             p_report_in_frame->firstSN = expectedSequenceNumber;
577             p_report_in_frame->lastSN = (snLimit + sequenceNumber - 1) % snLimit;
578
579             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
580             p_report_in_frame->previousFrameNum = p_bearer_status->previousFrameNum;
581
582             /* Update Bearer status to remember *this* frame */
583             p_bearer_status->previousFrameNum = pinfo->num;
584             p_bearer_status->previousSequenceNumber = sequenceNumber;
585         }
586         else {
587             /* An SN has been repeated */
588             p_report_in_frame->state = SN_Repeated;
589             p_report_in_frame->firstSN = sequenceNumber;
590
591             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
592             p_report_in_frame->previousFrameNum = p_bearer_status->previousFrameNum;
593         }
594     }
595     else {
596         /* SN was OK */
597         p_report_in_frame->state = SN_OK;
598         p_report_in_frame->sequenceExpected = expectedSequenceNumber;
599         p_report_in_frame->previousFrameNum = p_bearer_status->previousFrameNum;
600         /* SN has rolled around, inc hfn! */
601         if (!createdBearer && (sequenceNumber == 0)) {
602             /* TODO: not worrying about HFN rolling over for now! */
603             p_bearer_status->hfn++;
604             p_report_in_frame->hfn = p_bearer_status->hfn;
605         }
606
607         /* Update Bearer status to remember *this* frame */
608         p_bearer_status->previousFrameNum = pinfo->num;
609         p_bearer_status->previousSequenceNumber = sequenceNumber;
610
611         if (p_report_in_frame->previousFrameNum != 0) {
612             /* Get report for previous frame */
613             pdcp_sequence_report_in_frame *p_previous_report;
614             p_previous_report = (pdcp_sequence_report_in_frame*)wmem_map_lookup(pdcp_nr_sequence_analysis_report_hash,
615                                                                                 get_report_hash_key((sequenceNumber+262144) % 262144,
616                                                                                                     p_report_in_frame->previousFrameNum,
617                                                                                                     p_pdcp_nr_info,
618                                                                                                     FALSE));
619             /* It really shouldn't be NULL... */
620             if (p_previous_report != NULL) {
621                 /* Point it forward to this one */
622                 p_previous_report->nextFrameNum = pinfo->num;
623             }
624         }
625     }
626
627     /* Associate with this frame number */
628     wmem_map_insert(pdcp_nr_sequence_analysis_report_hash,
629                     get_report_hash_key(sequenceNumber, pinfo->num,
630                                         p_pdcp_nr_info, TRUE),
631                     p_report_in_frame);
632
633     /* Add state report for this frame into tree */
634     addBearerSequenceInfo(p_report_in_frame, p_pdcp_nr_info, sequenceNumber,
635                            pinfo, tree, tvb);
636 }
637
638
639
640
641 /* Result is (ueid, framenum) -> pdcp_security_info_t*  */
642 typedef struct  ueid_frame_t {
643     guint32 framenum;
644     guint16 ueid;
645 } ueid_frame_t;
646
647
648
649 /* Write the given formatted text to:
650    - the info column
651    - the top-level RLC PDU item */
652 static void write_pdu_label_and_info(proto_item *pdu_ti,
653                                      packet_info *pinfo, const char *format, ...)
654 {
655     #define MAX_INFO_BUFFER 256
656     static char info_buffer[MAX_INFO_BUFFER];
657
658     va_list ap;
659
660     va_start(ap, format);
661     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
662     va_end(ap);
663
664     /* Add to indicated places */
665     col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
666     /* TODO: gets called a lot, so a shame there isn't a proto_item_append_string() */
667     proto_item_append_text(pdu_ti, "%s", info_buffer);
668 }
669
670
671
672 /***************************************************************/
673
674
675
676 /* Show in the tree the config info attached to this frame, as generated fields */
677 static void show_pdcp_config(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
678                              pdcp_nr_info *p_pdcp_info)
679 {
680     proto_item *ti;
681     proto_tree *configuration_tree;
682     proto_item *configuration_ti = proto_tree_add_item(tree,
683                                                        hf_pdcp_nr_configuration,
684                                                        tvb, 0, 0, ENC_ASCII|ENC_NA);
685     configuration_tree = proto_item_add_subtree(configuration_ti, ett_pdcp_configuration);
686
687     /* Direction */
688     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_direction, tvb, 0, 0,
689                              p_pdcp_info->direction);
690     PROTO_ITEM_SET_GENERATED(ti);
691
692     /* Plane */
693     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_plane, tvb, 0, 0,
694                              p_pdcp_info->plane);
695     PROTO_ITEM_SET_GENERATED(ti);
696
697     /* UEId */
698     if (p_pdcp_info->ueid != 0) {
699         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_ueid, tvb, 0, 0,
700                                  p_pdcp_info->ueid);
701         PROTO_ITEM_SET_GENERATED(ti);
702         write_pdu_label_and_info(configuration_ti, pinfo, "UEId=%3u", p_pdcp_info->ueid);
703     }
704
705     /* Bearer type */
706     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_bearer_type, tvb, 0, 0,
707                              p_pdcp_info->bearerType);
708     PROTO_ITEM_SET_GENERATED(ti);
709     if (p_pdcp_info->bearerId != 0) {
710         /* Bearer type */
711         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_bearer_id, tvb, 0, 0,
712                                  p_pdcp_info->bearerId);
713         PROTO_ITEM_SET_GENERATED(ti);
714     }
715
716     /* Show channel type in root/Info */
717     if (p_pdcp_info->bearerType == Bearer_DCCH) {
718         write_pdu_label_and_info(configuration_ti, pinfo, "   %s-%u  ",
719                                  (p_pdcp_info->plane == NR_SIGNALING_PLANE) ? "SRB" : "DRB",
720                                  p_pdcp_info->bearerId);
721     }
722     else {
723         write_pdu_label_and_info(configuration_ti, pinfo, "   %s",
724                                  val_to_str_const(p_pdcp_info->bearerType, bearer_type_vals, "Unknown"));
725     }
726
727     if (p_pdcp_info->plane == NR_USER_PLANE) {
728         /* Seqnum length */
729         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_seqnum_length, tvb, 0, 0,
730                                  p_pdcp_info->seqnum_length);
731         PROTO_ITEM_SET_GENERATED(ti);
732
733         /* ROHC compression */
734         ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_nr_rohc_compression, tvb, 0, 0,
735                                     p_pdcp_info->rohc.rohc_compression);
736         PROTO_ITEM_SET_GENERATED(ti);
737
738         /* ROHC-specific settings */
739         if (p_pdcp_info->rohc.rohc_compression) {
740
741             /* Show ROHC mode */
742             ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_rohc_mode, tvb, 0, 0,
743                                      p_pdcp_info->rohc.mode);
744             PROTO_ITEM_SET_GENERATED(ti);
745
746             /* Show RND */
747             ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_nr_rohc_rnd, tvb, 0, 0,
748                                         p_pdcp_info->rohc.rnd);
749             PROTO_ITEM_SET_GENERATED(ti);
750
751             /* UDP Checksum */
752             ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_nr_rohc_udp_checksum_present, tvb, 0, 0,
753                                         p_pdcp_info->rohc.udp_checksum_present);
754             PROTO_ITEM_SET_GENERATED(ti);
755
756             /* ROHC profile */
757             ti = proto_tree_add_uint(configuration_tree, hf_pdcp_nr_rohc_profile, tvb, 0, 0,
758                                      p_pdcp_info->rohc.profile);
759             PROTO_ITEM_SET_GENERATED(ti);
760
761             /* CID Inclusion Info */
762             ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_nr_cid_inclusion_info, tvb, 0, 0,
763                                         p_pdcp_info->rohc.cid_inclusion_info);
764             PROTO_ITEM_SET_GENERATED(ti);
765
766             /* Large CID */
767             ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_nr_large_cid_present, tvb, 0, 0,
768                                         p_pdcp_info->rohc.large_cid_present);
769             PROTO_ITEM_SET_GENERATED(ti);
770         }
771     }
772
773     /* Append summary to configuration root */
774     proto_item_append_text(configuration_ti, "(direction=%s, plane=%s",
775                            val_to_str_const(p_pdcp_info->direction, direction_vals, "Unknown"),
776                            val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
777
778     if (p_pdcp_info->rohc.rohc_compression) {
779         const char *mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
780         proto_item_append_text(configuration_ti, ", mode=%c, profile=%s",
781                                mode[0],
782                                val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
783     }
784     proto_item_append_text(configuration_ti, ")");
785     PROTO_ITEM_SET_GENERATED(configuration_ti);
786
787     /* Show plane in info column */
788     col_append_fstr(pinfo->cinfo, COL_INFO, " %s: ",
789                     val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
790
791 }
792
793
794 /* Look for an RRC dissector for signalling data (using Bearer type and direction) */
795 static dissector_handle_t lookup_rrc_dissector_handle(struct pdcp_nr_info  *p_pdcp_info)
796 {
797     dissector_handle_t rrc_handle = 0;
798
799     /* TODO: add as they become available */
800     switch (p_pdcp_info->bearerType)
801     {
802         case Bearer_CCCH:
803             break;
804         case Bearer_PCCH:
805             break;
806         case Bearer_BCCH_BCH:
807             break;
808         case Bearer_BCCH_DL_SCH:
809             break;
810         case Bearer_DCCH:
811             break;
812
813         default:
814             break;
815     }
816
817     return rrc_handle;
818 }
819
820
821 /* Forwad declarations */
822 static int dissect_pdcp_nr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
823
824 static void report_heur_error(proto_tree *tree, packet_info *pinfo, expert_field *eiindex,
825                               tvbuff_t *tvb, gint start, gint length)
826 {
827     proto_item *ti;
828     proto_tree *subtree;
829
830     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDCP-NR");
831     col_clear(pinfo->cinfo, COL_INFO);
832     ti = proto_tree_add_item(tree, proto_pdcp_nr, tvb, 0, -1, ENC_NA);
833     subtree = proto_item_add_subtree(ti, ett_pdcp);
834     proto_tree_add_expert(subtree, pinfo, eiindex, tvb, start, length);
835 }
836
837 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
838 static gboolean dissect_pdcp_nr_heur(tvbuff_t *tvb, packet_info *pinfo,
839                                      proto_tree *tree, void *data _U_)
840 {
841     gint                  offset                 = 0;
842     struct pdcp_nr_info *p_pdcp_nr_info;
843     tvbuff_t             *pdcp_tvb;
844     guint8                tag                    = 0;
845     gboolean              seqnumLengthTagPresent = FALSE;
846
847     /* Needs to be at least as long as:
848        - the signature string
849        - fixed header byte(s)
850        - tag for data
851        - at least one byte of PDCP PDU payload.
852       However, let attempted dissection show if there are any tags at all. */
853     gint min_length = (gint)(strlen(PDCP_NR_START_STRING) + 3); /* signature */
854
855     if (tvb_captured_length_remaining(tvb, offset) < min_length) {
856         return FALSE;
857     }
858
859     /* OK, compare with signature string */
860     if (tvb_strneql(tvb, offset, PDCP_NR_START_STRING, strlen(PDCP_NR_START_STRING)) != 0) {
861         return FALSE;
862     }
863     offset += (gint)strlen(PDCP_NR_START_STRING);
864
865
866     /* If redissecting, use previous info struct (if available) */
867     p_pdcp_nr_info = (pdcp_nr_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_nr, 0);
868     if (p_pdcp_nr_info == NULL) {
869         /* Allocate new info struct for this frame */
870         p_pdcp_nr_info = wmem_new0(wmem_file_scope(), pdcp_nr_info);
871
872         /* Read fixed fields */
873         p_pdcp_nr_info->plane = (enum pdcp_nr_plane)tvb_get_guint8(tvb, offset++);
874         if (p_pdcp_nr_info->plane == NR_SIGNALING_PLANE) {
875             /* Signalling plane always has 12 SN bits */
876             p_pdcp_nr_info->seqnum_length = PDCP_NR_SN_LENGTH_12_BITS;
877         }
878
879         /* Read tagged fields */
880         while (tag != PDCP_NR_PAYLOAD_TAG) {
881             /* Process next tag */
882             tag = tvb_get_guint8(tvb, offset++);
883             switch (tag) {
884                 case PDCP_NR_SEQNUM_LENGTH_TAG:
885                     p_pdcp_nr_info->seqnum_length = tvb_get_guint8(tvb, offset);
886                     offset++;
887                     seqnumLengthTagPresent = TRUE;
888                     break;
889                 case PDCP_NR_DIRECTION_TAG:
890                     p_pdcp_nr_info->direction = tvb_get_guint8(tvb, offset);
891                     offset++;
892                     break;
893                 case PDCP_NR_BEARER_TYPE_TAG:
894                     p_pdcp_nr_info->bearerType = (NRBearerType)tvb_get_guint8(tvb, offset);
895                     offset++;
896                     break;
897                 case PDCP_NR_BEARER_ID_TAG:
898                     p_pdcp_nr_info->bearerId = tvb_get_guint8(tvb, offset);
899                     offset++;
900                     break;
901                 case PDCP_NR_UEID_TAG:
902                     p_pdcp_nr_info->ueid = tvb_get_ntohs(tvb, offset);
903                     offset += 2;
904                     break;
905                 case PDCP_NR_ROHC_COMPRESSION_TAG:
906                     p_pdcp_nr_info->rohc.rohc_compression = TRUE;
907                     break;
908                 case PDCP_NR_ROHC_IP_VERSION_TAG:
909                     p_pdcp_nr_info->rohc.rohc_ip_version = tvb_get_guint8(tvb, offset);
910                     offset++;
911                     break;
912                 case PDCP_NR_ROHC_CID_INC_INFO_TAG:
913                     p_pdcp_nr_info->rohc.cid_inclusion_info = TRUE;
914                     break;
915                 case PDCP_NR_ROHC_LARGE_CID_PRES_TAG:
916                     p_pdcp_nr_info->rohc.large_cid_present = TRUE;
917                     break;
918                 case PDCP_NR_ROHC_MODE_TAG:
919                     p_pdcp_nr_info->rohc.mode = (enum rohc_mode)tvb_get_guint8(tvb, offset);
920                     offset++;
921                     break;
922                 case PDCP_NR_ROHC_RND_TAG:
923                     p_pdcp_nr_info->rohc.rnd = TRUE;
924                     break;
925                 case PDCP_NR_ROHC_UDP_CHECKSUM_PRES_TAG:
926                     p_pdcp_nr_info->rohc.udp_checksum_present = TRUE;
927                     break;
928                 case PDCP_NR_ROHC_PROFILE_TAG:
929                     p_pdcp_nr_info->rohc.profile = tvb_get_ntohs(tvb, offset);
930                     offset += 2;
931                     break;
932                 case PDCP_NR_MACI_PRES_TAG:
933                     p_pdcp_nr_info->maci_present = TRUE;
934                     break;
935                 case PDCP_NR_SDAP_HEADER_TAG:
936                     p_pdcp_nr_info->sdap_header = tvb_get_guint8(tvb, offset) & 0x03;
937                     offset++;
938                     break;
939
940                 case PDCP_NR_PAYLOAD_TAG:
941                     /* Have reached data, so get out of loop */
942                     p_pdcp_nr_info->pdu_length = tvb_reported_length_remaining(tvb, offset);
943                     continue;
944
945                 default:
946                     /* It must be a recognised tag */
947                     report_heur_error(tree, pinfo, &ei_pdcp_nr_unknown_udp_framing_tag, tvb, offset-1, 1);
948                     wmem_free(wmem_file_scope(), p_pdcp_nr_info);
949                     return TRUE;
950             }
951         }
952
953         if ((p_pdcp_nr_info->plane == NR_USER_PLANE) && (seqnumLengthTagPresent == FALSE)) {
954             /* Conditional field is not present */
955             report_heur_error(tree, pinfo, &ei_pdcp_nr_missing_udp_framing_tag, tvb, 0, offset);
956             wmem_free(wmem_file_scope(), p_pdcp_nr_info);
957             return TRUE;
958         }
959
960         /* Store info in packet */
961         p_add_proto_data(wmem_file_scope(), pinfo, proto_pdcp_nr, 0, p_pdcp_nr_info);
962     }
963     else {
964         offset = tvb_reported_length(tvb) - p_pdcp_nr_info->pdu_length;
965     }
966
967     /**************************************/
968     /* OK, now dissect as PDCP nr         */
969
970     /* Create tvb that starts at actual PDCP PDU */
971     pdcp_tvb = tvb_new_subset_remaining(tvb, offset);
972     dissect_pdcp_nr(pdcp_tvb, pinfo, tree, data);
973     return TRUE;
974 }
975
976
977 /******************************/
978 /* Main dissection function.  */
979 static int dissect_pdcp_nr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
980 {
981     const char           *mode;
982     proto_tree           *pdcp_tree          = NULL;
983     proto_item           *root_ti            = NULL;
984     proto_item           *ti;
985     gint                 offset              = 0;
986     struct pdcp_nr_info  *p_pdcp_info;
987     tvbuff_t             *rohc_tvb           = NULL;
988
989     tvbuff_t *payload_tvb;
990
991     /* Set protocol name. */
992     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDCP-NR");
993
994     /* Look for attached packet info! */
995     p_pdcp_info = (struct pdcp_nr_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_nr, 0);
996     /* Can't dissect anything without it... */
997     if (p_pdcp_info == NULL) {
998         if (!data) {
999             return 0;
1000         }
1001         p_pdcp_info = (struct pdcp_nr_info *)data;
1002     }
1003
1004     /* Don't want to overwrite the RLC Info column if configured not to */
1005     if ((global_pdcp_nr_layer_to_show == ShowRLCLayer) &&
1006         (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_nr, 0) != NULL)) {
1007
1008         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
1009     }
1010     else {
1011         /* TODO: won't help with multiple PDCP-or-traffic PDUs / frame... */
1012         col_clear(pinfo->cinfo, COL_INFO);
1013         col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
1014     }
1015
1016     /* Create pdcp tree. */
1017     if (tree) {
1018         root_ti = proto_tree_add_item(tree, proto_pdcp_nr, tvb, offset, -1, ENC_NA);
1019         pdcp_tree = proto_item_add_subtree(root_ti, ett_pdcp);
1020     }
1021
1022     /* Set mode string */
1023     mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
1024
1025     /*****************************************************/
1026     /* Show configuration (attached packet) info in tree */
1027     if (pdcp_tree) {
1028         show_pdcp_config(pinfo, tvb, pdcp_tree, p_pdcp_info);
1029     }
1030
1031     /* Show ROHC mode */
1032     if (p_pdcp_info->rohc.rohc_compression) {
1033         col_append_fstr(pinfo->cinfo, COL_INFO, " (mode=%c)", mode[0]);
1034     }
1035
1036
1037     /***********************************/
1038     /* Handle PDCP header              */
1039
1040     guint32  seqnum = 0;
1041     gboolean seqnum_set = FALSE;
1042
1043     guint8  first_byte = tvb_get_guint8(tvb, offset);
1044
1045     /*****************************/
1046     /* Signalling plane messages */
1047     if (p_pdcp_info->plane == NR_SIGNALING_PLANE) {
1048         /* Always 12 bits SN */
1049         /* Verify 4 reserved bits are 0 */
1050         guint8 reserved = (first_byte & 0xf0) >> 4;
1051         ti = proto_tree_add_item(pdcp_tree, hf_pdcp_nr_control_plane_reserved,
1052                                  tvb, offset, 1, ENC_BIG_ENDIAN);
1053         if (reserved != 0) {
1054             expert_add_info_format(pinfo, ti, &ei_pdcp_nr_reserved_bits_not_zero,
1055                                    "PDCP signalling header reserved bits not zero");
1056         }
1057
1058         /* 12-bit sequence number */
1059         proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_seq_num_12, tvb, offset, 2, ENC_BIG_ENDIAN, &seqnum);
1060         seqnum_set = TRUE;
1061         write_pdu_label_and_info(root_ti, pinfo, " (SN=%-4u)", seqnum);
1062         offset += 2;
1063
1064         if (tvb_captured_length_remaining(tvb, offset) == 0) {
1065             /* Only PDCP header was captured, stop dissection here */
1066             return offset;
1067         }
1068     }
1069     else if (p_pdcp_info->plane == NR_USER_PLANE) {
1070
1071         /**********************************/
1072         /* User-plane messages            */
1073         gboolean is_user_plane;
1074
1075         /* Data/Control flag */
1076         proto_tree_add_item_ret_boolean(pdcp_tree, hf_pdcp_nr_data_control, tvb, offset, 1, ENC_BIG_ENDIAN, &is_user_plane);
1077
1078         if (is_user_plane) {
1079             /*****************************/
1080             /* User-plane Data           */
1081             guint32 reserved_value;
1082
1083             /* Number of sequence number bits depends upon config */
1084             switch (p_pdcp_info->seqnum_length) {
1085             case PDCP_NR_SN_LENGTH_12_BITS:
1086                 /* 3 reserved bits */
1087                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_reserved3, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
1088
1089                 /* Complain if not 0 */
1090                 if (reserved_value != 0) {
1091                     expert_add_info_format(pinfo, ti, &ei_pdcp_nr_reserved_bits_not_zero,
1092                                            "Reserved bits have value 0x%x - should be 0x0",
1093                                            reserved_value);
1094                 }
1095
1096                 /* 12-bit sequence number */
1097                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_seq_num_12, tvb, offset, 2, ENC_BIG_ENDIAN, &seqnum);
1098                 seqnum_set = TRUE;
1099                 offset += 2;
1100                 break;
1101             case PDCP_NR_SN_LENGTH_18_BITS:
1102                 /* 5 reserved bits */
1103                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_reserved5, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
1104
1105                 /* Complain if not 0 */
1106                 if (reserved_value != 0) {
1107                     expert_add_info_format(pinfo, ti, &ei_pdcp_nr_reserved_bits_not_zero,
1108                                            "Reserved bits have value 0x%x - should be 0x0",
1109                                            reserved_value);
1110                 }
1111
1112                 /* 18-bit sequence number */
1113                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_seq_num_18, tvb, offset, 3, ENC_BIG_ENDIAN, &seqnum);
1114                 seqnum_set = TRUE;
1115                 offset += 3;
1116                 break;
1117             default:
1118                 /* Not a recognised data format!!!!! */
1119                 return 1;
1120             }
1121
1122             write_pdu_label_and_info(root_ti, pinfo, " (SN=%-6u)", seqnum);
1123         }
1124         else {
1125             /*******************************/
1126             /* User-plane Control messages */
1127             guint32 control_pdu_type;
1128             proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_control_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN, &control_pdu_type);
1129
1130             switch (control_pdu_type) {
1131             case 0:    /* PDCP status report */
1132             {
1133                 guint32 fmc;
1134                 guint   not_received = 0;
1135                 guint   i, j, l;
1136                 guint32 len, bit_offset;
1137                 proto_tree *bitmap_tree;
1138                 proto_item *bitmap_ti = NULL;
1139                 gchar  *buff = NULL;
1140 #define BUFF_SIZE 89
1141                 guint32 reserved_value;
1142
1143                 /* 4 bits reserved */
1144                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_reserved4, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
1145
1146                 /* Complain if not 0 */
1147                 if (reserved_value != 0) {
1148                     expert_add_info_format(pinfo, ti, &ei_pdcp_nr_reserved_bits_not_zero,
1149                                            "Reserved bits have value 0x%x - should be 0x0",
1150                                            reserved_value);
1151                 }
1152                 offset++;
1153
1154                 /* First-Missing-Count */
1155                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_nr_fmc, tvb, offset, 4, ENC_BIG_ENDIAN, &fmc);
1156                 offset += 4;
1157
1158
1159                 /* Bitmap tree */
1160                 if (tvb_reported_length_remaining(tvb, offset) > 0) {
1161                     bitmap_ti = proto_tree_add_item(pdcp_tree, hf_pdcp_nr_bitmap, tvb,
1162                                                     offset, -1, ENC_NA);
1163                     bitmap_tree = proto_item_add_subtree(bitmap_ti, ett_pdcp_report_bitmap);
1164
1165                     buff = (gchar *)wmem_alloc(wmem_packet_scope(), BUFF_SIZE);
1166                     len = tvb_reported_length_remaining(tvb, offset);
1167                     bit_offset = offset<<3;
1168
1169                     /* For each byte... */
1170                     for (i=0; i<len; i++) {
1171                         guint8 bits = tvb_get_bits8(tvb, bit_offset, 8);
1172                         for (l=0, j=0; l<8; l++) {
1173                             if ((bits << l) & 0x80) {
1174                                 if (bitmap_tree) {
1175                                     // TODO: better to do mod and show as SN instead?
1176                                     j += g_snprintf(&buff[j], BUFF_SIZE-j, "%10u,", (unsigned)(fmc+(8*i)+l+1));
1177                                 }
1178                             } else {
1179                                 if (bitmap_tree) {
1180                                     j += (guint)g_strlcpy(&buff[j], "          ,", BUFF_SIZE-j);
1181                                 }
1182                                 not_received++;
1183                             }
1184                         }
1185                         if (bitmap_tree) {
1186                             proto_tree_add_uint_format(bitmap_tree, hf_pdcp_nr_bitmap_byte, tvb, bit_offset/8, 1, bits, "%s", buff);
1187                         }
1188                         bit_offset += 8;
1189                     }
1190                 }
1191
1192                 if (bitmap_ti != NULL) {
1193                     proto_item_append_text(bitmap_ti, " (%u SNs not received)", not_received);
1194                 }
1195                 write_pdu_label_and_info(root_ti, pinfo, " Status Report (fmc=%u) not-received=%u",
1196                                          fmc, not_received);
1197             }
1198                 return 1;
1199
1200             case 1:     /* ROHC Feedback */
1201                 offset++;
1202                 break;  /* Drop-through to dissect feedback */
1203             }
1204         }
1205     }
1206     else {
1207         /* Invalid plane setting...! */
1208         write_pdu_label_and_info(root_ti, pinfo, " - INVALID PLANE (%u)",
1209                                  p_pdcp_info->plane);
1210         return 1;
1211     }
1212
1213     /* Do sequence analysis if configured to. */
1214     if (seqnum_set) {
1215         gboolean do_analysis = FALSE;
1216
1217         switch (global_pdcp_check_sequence_numbers) {
1218         case FALSE:
1219             break;
1220         case SEQUENCE_ANALYSIS_RLC_ONLY:
1221             if ((p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_nr, 0) != NULL) &&
1222                     !p_pdcp_info->is_retx) {
1223                 do_analysis = TRUE;
1224             }
1225             break;
1226         case SEQUENCE_ANALYSIS_PDCP_ONLY:
1227             if (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_nr, 0) == NULL) {
1228                 do_analysis = TRUE;
1229             }
1230             break;
1231         }
1232
1233         if (do_analysis) {
1234             checkBearerSequenceInfo(pinfo, tvb, p_pdcp_info,
1235                                      seqnum, pdcp_tree);
1236         }
1237     }
1238
1239
1240     /*******************************************************/
1241     /* Now deal with the payload                           */
1242     /*******************************************************/
1243
1244     payload_tvb = tvb;
1245
1246     if (p_pdcp_info->plane == NR_SIGNALING_PLANE) {
1247         guint32 data_length;
1248
1249         /* Compute payload length (no MAC on common control Bearers) */
1250         data_length = tvb_reported_length_remaining(payload_tvb, offset)-4;
1251
1252
1253         /* RRC data is all but last 4 bytes.
1254            Call nr-rrc dissector (according to direction and Bearer type) if we have valid data */
1255         if (global_pdcp_dissect_signalling_plane_as_rrc) {
1256             /* Get appropriate dissector handle */
1257             dissector_handle_t rrc_handle = lookup_rrc_dissector_handle(p_pdcp_info);
1258
1259             if (rrc_handle != 0) {
1260                 /* Call RRC dissector if have one */
1261                 tvbuff_t *rrc_payload_tvb = tvb_new_subset_length(payload_tvb, offset, data_length);
1262                 gboolean was_writable = col_get_writable(pinfo->cinfo, COL_INFO);
1263
1264                 /* We always want to see this in the info column */
1265                 col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
1266
1267                 call_dissector_only(rrc_handle, rrc_payload_tvb, pinfo, pdcp_tree, NULL);
1268
1269                 /* Restore to whatever it was */
1270                 col_set_writable(pinfo->cinfo, COL_INFO, was_writable);
1271             }
1272             else {
1273                  /* Just show data */
1274                     proto_tree_add_item(pdcp_tree, hf_pdcp_nr_signalling_data, payload_tvb, offset,
1275                                         data_length, ENC_NA);
1276             }
1277         }
1278         else {
1279             /* Just show as unparsed data */
1280             proto_tree_add_item(pdcp_tree, hf_pdcp_nr_signalling_data, payload_tvb, offset,
1281                                 data_length, ENC_NA);
1282         }
1283
1284         if (p_pdcp_info->bearerType == Bearer_DCCH) {
1285             p_pdcp_info->maci_present = TRUE;
1286         } else {
1287             col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes data)", data_length);
1288         }
1289     }
1290     else if (tvb_captured_length_remaining(payload_tvb, offset)) {
1291         /* User-plane payload here. */
1292         gint payload_length = tvb_reported_length_remaining(payload_tvb, offset) - ((p_pdcp_info->maci_present) ? 4 : 0);
1293
1294         if ((p_pdcp_info->direction == PDCP_NR_DIRECTION_UPLINK &&
1295              p_pdcp_info->sdap_header & PDCP_NR_UL_SDAP_HEADER_PRESENT) ||
1296             (p_pdcp_info->direction == PDCP_NR_DIRECTION_DOWNLINK &&
1297              p_pdcp_info->sdap_header & PDCP_NR_DL_SDAP_HEADER_PRESENT)) {
1298             proto_item *sdap_ti;
1299             proto_tree *sdap_tree;
1300
1301             sdap_ti = proto_tree_add_item(pdcp_tree, proto_sdap, payload_tvb, offset, 1, ENC_NA);
1302             sdap_tree = proto_item_add_subtree(sdap_ti, ett_sdap);
1303             if (p_pdcp_info->direction == PDCP_NR_DIRECTION_UPLINK) {
1304                 proto_tree_add_item(sdap_tree, hf_sdap_data_control, payload_tvb, offset, 1, ENC_NA);
1305                 proto_tree_add_item(sdap_tree, hf_sdap_reserved, payload_tvb, offset, 1, ENC_NA);
1306             } else {
1307                 proto_tree_add_item(sdap_tree, hf_sdap_rdi, payload_tvb, offset, 1, ENC_NA);
1308                 proto_tree_add_item(sdap_tree, hf_sdap_rqi, payload_tvb, offset, 1, ENC_NA);
1309             }
1310             proto_tree_add_item(sdap_tree, hf_sdap_qfi, payload_tvb, offset, 1, ENC_NA);
1311             offset++;
1312             payload_length--;
1313         }
1314
1315         if (payload_length > 0) {
1316             /* If not compressed with ROHC, show as user-plane data */
1317             if (!p_pdcp_info->rohc.rohc_compression) {
1318                 /* Not attempting to decode payload if ciphering is enabled
1319                   (and NULL ciphering is not being used) */
1320                 if (global_pdcp_dissect_user_plane_as_ip) {
1321                     tvbuff_t *ip_payload_tvb = tvb_new_subset_length(payload_tvb, offset, payload_length);
1322
1323                     /* Don't update info column for ROHC unless configured to */
1324                     if (global_pdcp_nr_layer_to_show != ShowTrafficLayer) {
1325                         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
1326                     }
1327
1328                     switch (tvb_get_guint8(ip_payload_tvb, 0) & 0xf0) {
1329                         case 0x40:
1330                             call_dissector_only(ip_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
1331                             break;
1332                         case 0x60:
1333                             call_dissector_only(ipv6_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
1334                             break;
1335                         default:
1336                             call_data_dissector(ip_payload_tvb, pinfo, pdcp_tree);
1337                             break;
1338                     }
1339
1340                     /* Freeze the columns again because we don't want other layers writing to info */
1341                     if (global_pdcp_nr_layer_to_show == ShowTrafficLayer) {
1342                         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
1343                     }
1344
1345                 }
1346                 else {
1347                     proto_tree_add_item(pdcp_tree, hf_pdcp_nr_user_plane_data, payload_tvb, offset, payload_length, ENC_NA);
1348                 }
1349             }
1350             else {
1351                 /***************************/
1352                 /* ROHC packets            */
1353                 /***************************/
1354
1355                 /* Only attempt ROHC if configured to */
1356                 if (!global_pdcp_dissect_rohc) {
1357                     col_append_fstr(pinfo->cinfo, COL_PROTOCOL, "|ROHC(%s)",
1358                                     val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
1359                     proto_tree_add_item(pdcp_tree, hf_pdcp_nr_user_plane_data, payload_tvb, offset, payload_length, ENC_NA);
1360                 }
1361                 else {
1362                     rohc_tvb = tvb_new_subset_length(payload_tvb, offset, payload_length);
1363
1364                     /* Only enable writing to column if configured to show ROHC */
1365                     if (global_pdcp_nr_layer_to_show != ShowTrafficLayer) {
1366                         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
1367                     }
1368                     else {
1369                         col_clear(pinfo->cinfo, COL_INFO);
1370                     }
1371
1372                     /* Call the ROHC dissector */
1373                     call_dissector_with_data(rohc_handle, rohc_tvb, pinfo, tree, &p_pdcp_info->rohc);
1374                 }
1375             }
1376         }
1377     }
1378
1379     /* MAC */
1380     if (p_pdcp_info->maci_present) {
1381         /* Last 4 bytes are MAC */
1382         gint mac_offset = tvb_reported_length(tvb)-4;
1383         guint32 mac = tvb_get_ntohl(payload_tvb, mac_offset);
1384         proto_tree_add_item(pdcp_tree, hf_pdcp_nr_mac, payload_tvb, mac_offset, 4, ENC_BIG_ENDIAN);
1385
1386         col_append_fstr(pinfo->cinfo, COL_INFO, " MAC=0x%08x", mac);
1387     }
1388
1389     /* Let RLC write to columns again */
1390     col_set_writable(pinfo->cinfo, COL_INFO, global_pdcp_nr_layer_to_show == ShowRLCLayer);
1391
1392     return tvb_captured_length(tvb);
1393 }
1394
1395
1396 void proto_register_pdcp_nr(void)
1397 {
1398     static hf_register_info hf_pdcp[] =
1399     {
1400         { &hf_pdcp_nr_configuration,
1401             { "Configuration",
1402               "pdcp-nr.configuration", FT_STRING, BASE_NONE, NULL, 0x0,
1403               "Configuration info passed into dissector", HFILL
1404             }
1405         },
1406         { &hf_pdcp_nr_direction,
1407             { "Direction",
1408               "pdcp-nr.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
1409               "Direction of message", HFILL
1410             }
1411         },
1412         { &hf_pdcp_nr_ueid,
1413             { "UE",
1414               "pdcp-nr.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
1415               "UE Identifier", HFILL
1416             }
1417         },
1418         { &hf_pdcp_nr_bearer_type,
1419             { "Bearer type",
1420               "pdcp-nr.Bearer-type", FT_UINT8, BASE_DEC, VALS(bearer_type_vals), 0x0,
1421               NULL, HFILL
1422             }
1423         },
1424         { &hf_pdcp_nr_bearer_id,
1425             { "Bearer Id",
1426               "pdcp-nr.bearer-id", FT_UINT8, BASE_DEC, 0, 0x0,
1427               NULL, HFILL
1428             }
1429         },
1430         { &hf_pdcp_nr_plane,
1431             { "Plane",
1432               "pdcp-nr.plane", FT_UINT8, BASE_DEC, VALS(pdcp_plane_vals), 0x0,
1433               NULL, HFILL
1434             }
1435         },
1436         { &hf_pdcp_nr_seqnum_length,
1437             { "Seqnum length",
1438               "pdcp-nr.seqnum_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1439               "Sequence Number Length", HFILL
1440             }
1441         },
1442
1443         { &hf_pdcp_nr_rohc_compression,
1444             { "ROHC Compression",
1445               "pdcp-nr.rohc.compression", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1446               NULL, HFILL
1447             }
1448         },
1449         { &hf_pdcp_nr_rohc_mode,
1450             { "ROHC Mode",
1451               "pdcp-nr.rohc.mode", FT_UINT8, BASE_DEC, VALS(rohc_mode_vals), 0x0,
1452               NULL, HFILL
1453             }
1454         },
1455         { &hf_pdcp_nr_rohc_rnd,
1456             { "RND",
1457               "pdcp-nr.rohc.rnd", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1458               "RND of outer ip header", HFILL
1459             }
1460         },
1461         { &hf_pdcp_nr_rohc_udp_checksum_present,
1462             { "UDP Checksum",
1463               "pdcp-nr.rohc.checksum-present", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1464               "UDP Checksum present", HFILL
1465             }
1466         },
1467         { &hf_pdcp_nr_rohc_profile,
1468             { "ROHC profile",
1469               "pdcp-nr.rohc.profile", FT_UINT8, BASE_DEC, VALS(rohc_profile_vals), 0x0,
1470               "ROHC Mode", HFILL
1471             }
1472         },
1473         { &hf_pdcp_nr_cid_inclusion_info,
1474             { "CID Inclusion Info",
1475               "pdcp-nr.cid-inclusion-info", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1476               NULL, HFILL
1477             }
1478         },
1479         { &hf_pdcp_nr_large_cid_present,
1480             { "Large CID Present",
1481               "pdcp-nr.large-cid-present", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1482               NULL, HFILL
1483             }
1484         },
1485
1486         { &hf_pdcp_nr_control_plane_reserved,
1487             { "Reserved",
1488               "pdcp-nr.reserved", FT_UINT8, BASE_DEC, NULL, 0xf0,
1489               NULL, HFILL
1490             }
1491         },
1492         { &hf_pdcp_nr_reserved3,
1493             { "Reserved",
1494               "pdcp-nr.reserved3", FT_UINT8, BASE_HEX, NULL, 0x70,
1495               "3 reserved bits", HFILL
1496             }
1497         },
1498         { &hf_pdcp_nr_seq_num_12,
1499             { "Seq Num",
1500               "pdcp-nr.seq-num", FT_UINT16, BASE_DEC, NULL, 0x0fff,
1501               "PDCP Seq num", HFILL
1502             }
1503         },
1504         { &hf_pdcp_nr_reserved5,
1505             { "Reserved",
1506               "pdcp-nr.reserved5", FT_UINT8, BASE_HEX, NULL, 0x7c,
1507               "5 reserved bits", HFILL
1508             }
1509         },
1510         { &hf_pdcp_nr_seq_num_18,
1511             { "Seq Num",
1512               "pdcp-nr.seq-num", FT_UINT24, BASE_DEC, NULL, 0x3ffff,
1513               "PDCP Seq num", HFILL
1514             }
1515         },
1516         { &hf_pdcp_nr_signalling_data,
1517             { "Signalling Data",
1518               "pdcp-nr.signalling-data", FT_BYTES, BASE_NONE, NULL, 0x0,
1519               NULL, HFILL
1520             }
1521         },
1522         { &hf_pdcp_nr_mac,
1523             { "MAC",
1524               "pdcp-nr.mac", FT_UINT32, BASE_HEX, NULL, 0x0,
1525               NULL, HFILL
1526             }
1527         },
1528         { &hf_pdcp_nr_data_control,
1529             { "PDU Type",
1530               "pdcp-nr.pdu-type", FT_BOOLEAN, 8, TFS(&pdu_type_bit), 0x80,
1531               NULL, HFILL
1532             }
1533         },
1534         { &hf_pdcp_nr_user_plane_data,
1535             { "User-Plane Data",
1536               "pdcp-nr.user-data", FT_BYTES, BASE_NONE, NULL, 0x0,
1537               NULL, HFILL
1538             }
1539         },
1540         { &hf_pdcp_nr_control_pdu_type,
1541             { "Control PDU Type",
1542               "pdcp-nr.control-pdu-type", FT_UINT8, BASE_HEX, VALS(control_pdu_type_vals), 0x70,
1543               NULL, HFILL
1544             }
1545         },
1546         { &hf_pdcp_nr_fmc,
1547             { "First Missing Count",
1548               "pdcp-nr.fmc", FT_UINT32, BASE_DEC, NULL, 0x0,
1549               NULL, HFILL
1550             }
1551         },
1552         { &hf_pdcp_nr_reserved4,
1553             { "Reserved",
1554               "pdcp-nr.reserved4", FT_UINT8, BASE_HEX, NULL, 0x0f,
1555               "4 reserved bits", HFILL
1556             }
1557         },
1558         { &hf_pdcp_nr_bitmap,
1559             { "Bitmap",
1560               "pdcp-nr.bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
1561               "Status report bitmap (0=error, 1=OK)", HFILL
1562             }
1563         },
1564         { &hf_pdcp_nr_bitmap_byte,
1565             { "Bitmap byte",
1566               "pdcp-nr.bitmap.byte", FT_UINT8, BASE_HEX, NULL, 0x0,
1567               NULL, HFILL
1568             }
1569         },
1570
1571         { &hf_pdcp_nr_sequence_analysis,
1572             { "Sequence Analysis",
1573               "pdcp-nr.sequence-analysis", FT_STRING, BASE_NONE, 0, 0x0,
1574               NULL, HFILL
1575             }
1576         },
1577         { &hf_pdcp_nr_sequence_analysis_ok,
1578             { "OK",
1579               "pdcp-nr.sequence-analysis.ok", FT_BOOLEAN, BASE_NONE, 0, 0x0,
1580               NULL, HFILL
1581             }
1582         },
1583         { &hf_pdcp_nr_sequence_analysis_previous_frame,
1584             { "Previous frame for Bearer",
1585               "pdcp-nr.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
1586               NULL, HFILL
1587             }
1588         },
1589         { &hf_pdcp_nr_sequence_analysis_next_frame,
1590             { "Next frame for Bearer",
1591               "pdcp-nr.sequence-analysis.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
1592               NULL, HFILL
1593             }
1594         },
1595         { &hf_pdcp_nr_sequence_analysis_expected_sn,
1596             { "Expected SN",
1597               "pdcp-nr.sequence-analysis.expected-sn", FT_UINT32, BASE_DEC, 0, 0x0,
1598               NULL, HFILL
1599             }
1600         },
1601         { &hf_pdcp_nr_sequence_analysis_skipped,
1602             { "Skipped frames",
1603               "pdcp-nr.sequence-analysis.skipped-frames", FT_BOOLEAN, BASE_NONE, 0, 0x0,
1604               NULL, HFILL
1605             }
1606         },
1607         { &hf_pdcp_nr_sequence_analysis_repeated,
1608             { "Repeated frame",
1609               "pdcp-nr.sequence-analysis.repeated-frame", FT_BOOLEAN, BASE_NONE, 0, 0x0,
1610               NULL, HFILL
1611             }
1612         },
1613     };
1614
1615     static hf_register_info hf_sdap[] =
1616     {
1617         { &hf_sdap_rdi,
1618             { "RDI",
1619               "sdap.rdi", FT_BOOLEAN, 8, TFS(&sdap_rdi), 0x80,
1620               NULL, HFILL
1621             }
1622         },
1623         { &hf_sdap_rqi,
1624             { "RQI",
1625               "sdap.rqi", FT_BOOLEAN, 8, TFS(&sdap_rqi), 0x40,
1626               NULL, HFILL
1627             }
1628         },
1629         { &hf_sdap_qfi,
1630             { "QFI",
1631               "sdap.qfi", FT_UINT8, BASE_DEC, NULL, 0x3f,
1632               NULL, HFILL
1633             }
1634         },
1635         { &hf_sdap_data_control,
1636             { "PDU Type",
1637               "sdap.reserved", FT_BOOLEAN, 8, TFS(&pdu_type_bit), 0x80,
1638               NULL, HFILL
1639             }
1640         },
1641         { &hf_sdap_reserved,
1642             { "Reserved",
1643               "sdap.reserved", FT_UINT8, BASE_HEX, NULL, 0x40,
1644               NULL, HFILL
1645             }
1646         }
1647     };
1648
1649     static gint *ett[] =
1650     {
1651         &ett_pdcp,
1652         &ett_pdcp_configuration,
1653         &ett_pdcp_packet,
1654         &ett_pdcp_nr_sequence_analysis,
1655         &ett_pdcp_report_bitmap,
1656         &ett_sdap
1657     };
1658
1659     static ei_register_info ei[] = {
1660         { &ei_pdcp_nr_sequence_analysis_sn_missing, { "pdcp-nr.sequence-analysis.sn-missing", PI_SEQUENCE, PI_WARN, "PDCP SN missing", EXPFILL }},
1661         { &ei_pdcp_nr_sequence_analysis_sn_repeated, { "pdcp-nr.sequence-analysis.sn-repeated", PI_SEQUENCE, PI_WARN, "PDCP SN repeated", EXPFILL }},
1662         { &ei_pdcp_nr_sequence_analysis_wrong_sequence_number, { "pdcp-nr.sequence-analysis.wrong-sequence-number", PI_SEQUENCE, PI_WARN, "Wrong Sequence Number", EXPFILL }},
1663         { &ei_pdcp_nr_reserved_bits_not_zero, { "pdcp-nr.reserved-bits-not-zero", PI_MALFORMED, PI_ERROR, "Reserved bits not zero", EXPFILL }},
1664         { &ei_pdcp_nr_unknown_udp_framing_tag, { "pdcp-nr.unknown-udp-framing-tag", PI_UNDECODED, PI_WARN, "Unknown UDP framing tag, aborting dissection", EXPFILL }},
1665         { &ei_pdcp_nr_missing_udp_framing_tag, { "pdcp-nr.missing-udp-framing-tag", PI_UNDECODED, PI_WARN, "Missing UDP framing conditional tag, aborting dissection", EXPFILL }}
1666     };
1667
1668     static const enum_val_t sequence_analysis_vals[] = {
1669         {"no-analysis", "No-Analysis",      FALSE},
1670         {"rlc-only",    "Only-RLC-frames",  SEQUENCE_ANALYSIS_RLC_ONLY},
1671         {"pdcp-only",   "Only-PDCP-frames", SEQUENCE_ANALYSIS_PDCP_ONLY},
1672         {NULL, NULL, -1}
1673     };
1674
1675     static const enum_val_t show_info_col_vals[] = {
1676         {"show-rlc", "RLC Info", ShowRLCLayer},
1677         {"show-pdcp", "PDCP Info", ShowPDCPLayer},
1678         {"show-traffic", "Traffic Info", ShowTrafficLayer},
1679         {NULL, NULL, -1}
1680     };
1681
1682     module_t *pdcp_nr_module;
1683     expert_module_t* expert_pdcp_nr;
1684
1685     /* Register protocol. */
1686     proto_pdcp_nr = proto_register_protocol("PDCP-NR", "PDCP-NR", "pdcp-nr");
1687     proto_register_field_array(proto_pdcp_nr, hf_pdcp, array_length(hf_pdcp));
1688     proto_register_subtree_array(ett, array_length(ett));
1689     expert_pdcp_nr = expert_register_protocol(proto_pdcp_nr);
1690     expert_register_field_array(expert_pdcp_nr, ei, array_length(ei));
1691     proto_sdap = proto_register_protocol("SDAP", "SDAP", "sdap");
1692     proto_register_field_array(proto_sdap, hf_sdap, array_length(hf_sdap));
1693
1694     /* Allow other dissectors to find this one by name. */
1695     register_dissector("pdcp-nr", dissect_pdcp_nr, proto_pdcp_nr);
1696
1697     pdcp_nr_module = prefs_register_protocol(proto_pdcp_nr, NULL);
1698
1699     /* Dissect uncompressed user-plane data as IP */
1700     prefs_register_bool_preference(pdcp_nr_module, "show_user_plane_as_ip",
1701         "Show uncompressed User-Plane data as IP",
1702         "Show uncompressed User-Plane data as IP",
1703         &global_pdcp_dissect_user_plane_as_ip);
1704
1705     /* Dissect unciphered signalling data as RRC */
1706     prefs_register_bool_preference(pdcp_nr_module, "show_signalling_plane_as_rrc",
1707         "Show unciphered Signalling-Plane data as RRC",
1708         "Show unciphered Signalling-Plane data as RRC",
1709         &global_pdcp_dissect_signalling_plane_as_rrc);
1710
1711     /* Check for missing sequence numbers */
1712     prefs_register_enum_preference(pdcp_nr_module, "check_sequence_numbers",
1713         "Do sequence number analysis",
1714         "Do sequence number analysis",
1715         &global_pdcp_check_sequence_numbers, sequence_analysis_vals, FALSE);
1716
1717     /* Attempt to dissect ROHC messages */
1718     prefs_register_bool_preference(pdcp_nr_module, "dissect_rohc",
1719         "Attempt to decode ROHC data",
1720         "Attempt to decode ROHC data",
1721         &global_pdcp_dissect_rohc);
1722
1723     prefs_register_obsolete_preference(pdcp_nr_module, "heuristic_pdcp_nr_over_udp");
1724
1725     prefs_register_enum_preference(pdcp_nr_module, "layer_to_show",
1726         "Which layer info to show in Info column",
1727         "Can show RLC, PDCP or Traffic layer info in Info column",
1728         &global_pdcp_nr_layer_to_show, show_info_col_vals, FALSE);
1729
1730
1731     pdcp_sequence_analysis_bearer_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
1732     pdcp_nr_sequence_analysis_report_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), pdcp_result_hash_func, pdcp_result_hash_equal);
1733 }
1734
1735 void proto_reg_handoff_pdcp_nr(void)
1736 {
1737     /* Add as a heuristic UDP dissector */
1738     heur_dissector_add("udp", dissect_pdcp_nr_heur, "PDCP-NR over UDP", "pdcp_nr_udp", proto_pdcp_nr, HEURISTIC_DISABLE);
1739
1740     ip_handle              = find_dissector_add_dependency("ip", proto_pdcp_nr);
1741     ipv6_handle            = find_dissector_add_dependency("ipv6", proto_pdcp_nr);
1742     rohc_handle            = find_dissector_add_dependency("rohc", proto_pdcp_nr);
1743 }
1744
1745 /*
1746  * Editor modelines
1747  *
1748  * Local Variables:
1749  * c-basic-offset: 4
1750  * tab-width: 8
1751  * indent-tabs-mode: nil
1752  * End:
1753  *
1754  * ex: set shiftwidth=4 tabstop=8 expandtab:
1755  * :indentSize=4:tabSize=8:noTabs=true:
1756  */