Remove unused variables to try to unbreak MAC buildbots
[metze/wireshark/wip.git] / epan / dissectors / packet-pdcp-lte.c
1 /* Routines for LTE PDCP
2  *
3  * Martin Mathieson
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33 #include <epan/expert.h>
34 #include <epan/addr_resolv.h>
35 #include <epan/wmem/wmem.h>
36
37 #ifdef HAVE_LIBGCRYPT
38 #include <epan/uat.h>
39 #include <wsutil/wsgcrypt.h>
40 #endif /* HAVE_LIBGCRYPT */
41
42 #include "packet-rlc-lte.h"
43 #include "packet-pdcp-lte.h"
44
45 void proto_register_pdcp(void);
46 void proto_reg_handoff_pdcp_lte(void);
47
48 /* Described in:
49  * 3GPP TS 36.323 Evolved Universal Terrestrial Radio Access (E-UTRA)
50  *                Packet Data Convergence Protocol (PDCP) specification v11.0.0
51  */
52
53
54 /* TODO:
55    - More deciphering. Next steps are:
56        - separate preferences to control signalling/user-plane decryption?
57        - Verify MAC authentication bytes for supported protocol(s)?
58    - Add Relay Node user plane data PDU dissection
59 */
60
61
62 /* Initialize the protocol and registered fields. */
63 int proto_pdcp_lte = -1;
64
65 extern int proto_rlc_lte;
66
67 /* Configuration (info known outside of PDU) */
68 static int hf_pdcp_lte_configuration = -1;
69 static int hf_pdcp_lte_direction = -1;
70 static int hf_pdcp_lte_ueid = -1;
71 static int hf_pdcp_lte_channel_type = -1;
72 static int hf_pdcp_lte_channel_id = -1;
73
74 static int hf_pdcp_lte_rohc_compression = -1;
75 static int hf_pdcp_lte_rohc_mode = -1;
76 static int hf_pdcp_lte_rohc_rnd = -1;
77 static int hf_pdcp_lte_rohc_udp_checksum_present = -1;
78 static int hf_pdcp_lte_rohc_profile = -1;
79
80 static int hf_pdcp_lte_no_header_pdu = -1;
81 static int hf_pdcp_lte_plane = -1;
82 static int hf_pdcp_lte_seqnum_length = -1;
83 static int hf_pdcp_lte_cid_inclusion_info = -1;
84 static int hf_pdcp_lte_large_cid_present = -1;
85
86 /* PDCP header fields */
87 static int hf_pdcp_lte_control_plane_reserved = -1;
88 static int hf_pdcp_lte_seq_num_5 = -1;
89 static int hf_pdcp_lte_seq_num_7 = -1;
90 static int hf_pdcp_lte_reserved3 = -1;
91 static int hf_pdcp_lte_seq_num_12 = -1;
92 static int hf_pdcp_lte_seq_num_15 = -1;
93 static int hf_pdcp_lte_signalling_data = -1;
94 static int hf_pdcp_lte_mac = -1;
95 static int hf_pdcp_lte_data_control = -1;
96 static int hf_pdcp_lte_user_plane_data = -1;
97 static int hf_pdcp_lte_control_pdu_type = -1;
98 static int hf_pdcp_lte_fms = -1;
99 static int hf_pdcp_lte_reserved4 = -1;
100 static int hf_pdcp_lte_fms2 = -1;
101 static int hf_pdcp_lte_bitmap = -1;
102
103
104 /* Sequence Analysis */
105 static int hf_pdcp_lte_sequence_analysis = -1;
106 static int hf_pdcp_lte_sequence_analysis_ok = -1;
107 static int hf_pdcp_lte_sequence_analysis_previous_frame = -1;
108 static int hf_pdcp_lte_sequence_analysis_next_frame = -1;
109 static int hf_pdcp_lte_sequence_analysis_expected_sn = -1;
110
111 static int hf_pdcp_lte_sequence_analysis_repeated = -1;
112 static int hf_pdcp_lte_sequence_analysis_skipped = -1;
113
114 /* Security Settings */
115 static int hf_pdcp_lte_security = -1;
116 static int hf_pdcp_lte_security_setup_frame = -1;
117 static int hf_pdcp_lte_security_integrity_algorithm = -1;
118 static int hf_pdcp_lte_security_ciphering_algorithm = -1;
119
120 static int hf_pdcp_lte_security_bearer = -1;
121 static int hf_pdcp_lte_security_direction = -1;
122 static int hf_pdcp_lte_security_count = -1;
123 static int hf_pdcp_lte_security_key = -1;
124
125
126
127 /* Protocol subtree. */
128 static int ett_pdcp = -1;
129 static int ett_pdcp_configuration = -1;
130 static int ett_pdcp_packet = -1;
131 static int ett_pdcp_lte_sequence_analysis = -1;
132 static int ett_pdcp_report_bitmap = -1;
133 static int ett_pdcp_security = -1;
134
135 static expert_field ei_pdcp_lte_sequence_analysis_wrong_sequence_number = EI_INIT;
136 static expert_field ei_pdcp_lte_reserved_bits_not_zero = EI_INIT;
137 static expert_field ei_pdcp_lte_sequence_analysis_sn_repeated = EI_INIT;
138 static expert_field ei_pdcp_lte_sequence_analysis_sn_missing = EI_INIT;
139
140 #ifdef HAVE_LIBGCRYPT
141 /*-------------------------------------
142  * UAT for UE Keys
143  *-------------------------------------
144  */
145 /* UAT entry structure. */
146 typedef struct {
147    guint16 ueid;
148    gchar   *rrcKeyString;
149    gchar   *upKeyString;
150
151    guint8   rrcBinaryKey[16];
152    gboolean rrcKeyOK;
153    guint8   upBinaryKey[16];
154    gboolean upKeyOK;
155 } uat_ue_keys_record_t;
156
157 static uat_ue_keys_record_t *uat_ue_keys_records = NULL;
158
159 static uat_t * ue_keys_uat = NULL;
160 static guint num_ue_keys_uat = 0;
161
162 /* TODO: do this better, being tolerant of spaces and dashes... */
163 static guchar hex_ascii_to_binary(gchar c)
164 {
165     if ((c >= '0') && (c <= '9')) {
166         return c - '0';
167     }
168     else if ((c >= 'a') && (c <= 'f')) {
169         return 10 + c - 'a';
170     }
171     else if ((c >= 'A') && (c <= 'F')) {
172         return 10 + c - 'A';
173     }
174     else
175         return 0;
176 }
177
178
179 static void* uat_ue_keys_record_copy_cb(void* n, const void* o, size_t siz _U_) {
180     uat_ue_keys_record_t* new_rec = (uat_ue_keys_record_t *)n;
181     const uat_ue_keys_record_t* old_rec = (const uat_ue_keys_record_t *)o;
182
183     new_rec->ueid = old_rec->ueid;
184     new_rec->rrcKeyString = (old_rec->rrcKeyString) ? g_strdup(old_rec->rrcKeyString) : NULL;
185     new_rec->upKeyString = (old_rec->upKeyString) ? g_strdup(old_rec->upKeyString) : NULL;
186
187     return new_rec;
188 }
189
190 static void uat_ue_keys_record_update_cb(void* record, const char** error _U_) {
191     uat_ue_keys_record_t* rec = (uat_ue_keys_record_t *)record;
192     int n;
193
194     /* Check and convert RRC key */
195     if (strlen(rec->rrcKeyString) != 32) {
196         rec->rrcKeyOK = FALSE;
197     }
198     else {
199         for (n=0; n < 32; n += 2) {
200             rec->rrcBinaryKey[n/2] = (hex_ascii_to_binary(rec->rrcKeyString[n]) << 4) +
201                                       hex_ascii_to_binary(rec->rrcKeyString[n+1]);
202         }
203         rec->rrcKeyOK = TRUE;
204     }
205
206     /* Check and convert User-plane key */
207     if (strlen(rec->upKeyString) != 32) {
208         rec->rrcKeyOK = FALSE;
209     }
210     else {
211         for (n=0; n < 32; n += 2) {
212             rec->upBinaryKey[n/2] = (hex_ascii_to_binary(rec->upKeyString[n]) << 4) +
213                                      hex_ascii_to_binary(rec->upKeyString[n+1]);
214         }
215         rec->upKeyOK = TRUE;
216     }
217 }
218
219
220 static void uat_ue_keys_record_free_cb(void*r) {
221     uat_ue_keys_record_t* rec = (uat_ue_keys_record_t*)r;
222
223     g_free(rec->rrcKeyString);
224     g_free(rec->upKeyString);
225 }
226
227 UAT_DEC_CB_DEF(uat_ue_keys_records, ueid, uat_ue_keys_record_t)
228 UAT_CSTRING_CB_DEF(uat_ue_keys_records, rrcKeyString, uat_ue_keys_record_t)
229 UAT_CSTRING_CB_DEF(uat_ue_keys_records, upKeyString,  uat_ue_keys_record_t)
230
231 static gboolean global_pdcp_decipher_signalling = FALSE;
232 static gboolean global_pdcp_decipher_userplane = FALSE;
233 #endif
234
235 static const value_string direction_vals[] =
236 {
237     { DIRECTION_UPLINK,      "Uplink"},
238     { DIRECTION_DOWNLINK,    "Downlink"},
239     { 0, NULL }
240 };
241
242
243 static const value_string pdcp_plane_vals[] = {
244     { SIGNALING_PLANE,    "Signalling" },
245     { USER_PLANE,         "User" },
246     { 0,   NULL }
247 };
248
249 static const value_string logical_channel_vals[] = {
250     { Channel_DCCH,  "DCCH"},
251     { Channel_BCCH,  "BCCH"},
252     { Channel_CCCH,  "CCCH"},
253     { Channel_PCCH,  "PCCH"},
254     { 0,             NULL}
255 };
256
257 static const value_string rohc_mode_vals[] = {
258     { UNIDIRECTIONAL,            "Unidirectional" },
259     { OPTIMISTIC_BIDIRECTIONAL,  "Optimistic Bidirectional" },
260     { RELIABLE_BIDIRECTIONAL,    "Reliable Bidirectional" },
261     { 0,   NULL }
262 };
263
264
265 /* Values taken from:
266    http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.txt */
267 static const value_string rohc_profile_vals[] = {
268     { 0x0000,   "ROHC uncompressed" },      /* [RFC5795] */
269     { 0x0001,   "ROHC RTP" },               /* [RFC3095] */
270     { 0x0101,   "ROHCv2 RTP" },             /* [RFC5225] */
271     { 0x0002,   "ROHC UDP" },               /* [RFC3095] */
272     { 0x0102,   "ROHCv2 UDP" },             /* [RFC5225] */
273     { 0x0003,   "ROHC ESP" },               /* [RFC3095] */
274     { 0x0103,   "ROHCv2 ESP" },             /* [RFC5225] */
275     { 0x0004,   "ROHC IP" },                /* [RFC3843] */
276     { 0x0104,   "ROHCv2 IP" },              /* [RFC5225] */
277     { 0x0005,   "ROHC LLA" },               /* [RFC4362] */
278     { 0x0105,   "ROHC LLA with R-mode" },   /* [RFC3408] */
279     { 0x0006,   "ROHC TCP" },               /* [RFC4996] */
280     { 0x0007,   "ROHC RTP/UDP-Lite" },      /* [RFC4019] */
281     { 0x0107,   "ROHCv2 RTP/UDP-Lite" },    /* [RFC5225] */
282     { 0x0008,   "ROHC UDP-Lite" },          /* [RFC4019] */
283     { 0x0108,   "ROHCv2 UDP-Lite" },        /* [RFC5225] */
284     { 0,   NULL }
285 };
286
287 static const value_string pdu_type_vals[] = {
288     { 0,   "Control PDU" },
289     { 1,   "Data PDU" },
290     { 0,   NULL }
291 };
292
293 static const value_string control_pdu_type_vals[] = {
294     { 0,   "PDCP Status report" },
295     { 1,   "Header Compression Feedback Information" },
296     { 0,   NULL }
297 };
298
299 static const value_string integrity_algorithm_vals[] = {
300     { 0,   "EIA0" },
301     { 1,   "EIA1" },
302     { 2,   "EIA2" },
303     { 0,   NULL }
304 };
305
306 static const value_string ciphering_algorithm_vals[] = {
307     { 0,   "EEA0" },
308     { 1,   "EEA1" },
309     { 2,   "EEA2" },
310     { 0,   NULL }
311 };
312
313
314 static dissector_handle_t ip_handle;
315 static dissector_handle_t ipv6_handle;
316 static dissector_handle_t rohc_handle;
317 static dissector_handle_t data_handle;
318
319
320 #define SEQUENCE_ANALYSIS_RLC_ONLY  1
321 #define SEQUENCE_ANALYSIS_PDCP_ONLY 2
322
323 /* Preference variables */
324 static gboolean global_pdcp_dissect_user_plane_as_ip = TRUE;
325 static gboolean global_pdcp_dissect_signalling_plane_as_rrc = TRUE;
326 static gint     global_pdcp_check_sequence_numbers = TRUE;
327 static gboolean global_pdcp_dissect_rohc = FALSE;
328
329 /* Which layer info to show in the info column */
330 enum layer_to_show {
331     ShowRLCLayer, ShowPDCPLayer, ShowTrafficLayer
332 };
333 static gint     global_pdcp_lte_layer_to_show = (gint)ShowRLCLayer;
334
335
336
337 /**************************************************/
338 /* Sequence number analysis                       */
339
340 /* Channel key */
341 typedef struct
342 {
343     /* Using bit fields to fit into 32 bits, so avoiding the need to allocate
344        heap memory for these structs */
345     guint           ueId : 16;
346     guint           plane : 2;
347     guint           channelId : 6;
348     guint           direction : 1;
349     guint           notUsed : 7;
350 } pdcp_channel_hash_key;
351
352 /* Channel state */
353 typedef struct
354 {
355     guint16  previousSequenceNumber;
356     guint32  previousFrameNum;
357     guint32  hfn;
358 } pdcp_channel_status;
359
360 /* The sequence analysis channel hash table.
361    Maps key -> status */
362 static GHashTable *pdcp_sequence_analysis_channel_hash = NULL;
363
364 /* Equal keys */
365 static gint pdcp_channel_equal(gconstpointer v, gconstpointer v2)
366 {
367     /* Key fits in 4 bytes, so just compare pointers! */
368     return (v == v2);
369 }
370
371 /* Compute a hash value for a given key. */
372 static guint pdcp_channel_hash_func(gconstpointer v)
373 {
374     /* Just use pointer, as the fields are all in this value */
375     return GPOINTER_TO_UINT(v);
376 }
377
378
379 /* Hash table types & functions for frame reports */
380
381 typedef struct {
382     guint32         frameNumber;
383     guint32         SN :       15;
384     guint32         plane :    2;
385     guint32         channelId: 5;
386     guint32         direction: 1;
387     guint32         notUsed :  9;
388 } pdcp_result_hash_key;
389
390 static gint pdcp_result_hash_equal(gconstpointer v, gconstpointer v2)
391 {
392     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
393     const pdcp_result_hash_key* val2 = (const pdcp_result_hash_key *)v2;
394
395     /* All fields must match */
396     return (memcmp(val1, val2, sizeof(pdcp_result_hash_key)) == 0);
397 }
398
399 /* Compute a hash value for a given key. */
400 static guint pdcp_result_hash_func(gconstpointer v)
401 {
402     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
403
404     /* TODO: This is a bit random.  */
405     return val1->frameNumber + (val1->channelId<<13) +
406                                (val1->plane<<5) +
407                                (val1->SN<<18) +
408                                (val1->direction<<9);
409 }
410
411 /* pdcp_channel_hash_key fits into the pointer, so just copy the value into
412    a guint, cast to apointer and return that as the key */
413 static gpointer get_channel_hash_key(pdcp_channel_hash_key *key)
414 {
415     guint  asInt = 0;
416     /* TODO: assert that sizeof(pdcp_channel_hash_key) <= sizeof(guint) ? */
417     memcpy(&asInt, key, sizeof(pdcp_channel_hash_key));
418     return GUINT_TO_POINTER(asInt);
419 }
420
421 /* Convenience function to get a pointer for the hash_func to work with */
422 static gpointer get_report_hash_key(guint16 SN, guint32 frameNumber,
423                                     pdcp_lte_info *p_pdcp_lte_info,
424                                     gboolean do_persist)
425 {
426     static pdcp_result_hash_key  key;
427     pdcp_result_hash_key        *p_key;
428
429     /* Only allocate a struct when will be adding entry */
430     if (do_persist) {
431         p_key = wmem_new(wmem_file_scope(), pdcp_result_hash_key);
432     }
433     else {
434         memset(&key, 0, sizeof(pdcp_result_hash_key));
435         p_key = &key;
436     }
437
438     /* Fill in details, and return pointer */
439     p_key->frameNumber = frameNumber;
440     p_key->SN = SN;
441     p_key->plane = (guint8)p_pdcp_lte_info->plane;
442     p_key->channelId = p_pdcp_lte_info->channelId;
443     p_key->direction = p_pdcp_lte_info->direction;
444     p_key->notUsed = 0;
445
446     return p_key;
447 }
448
449
450 /* Info to attach to frame when first read, recording what to show about sequence */
451 typedef enum
452 {
453     SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing
454 } sequence_state;
455 typedef struct
456 {
457     gboolean sequenceExpectedCorrect;
458     guint16  sequenceExpected;
459     guint32  previousFrameNum;
460     guint32  nextFrameNum;
461
462     guint16  firstSN;
463     guint16  lastSN;
464     guint32  hfn;
465
466     sequence_state state;
467 } pdcp_sequence_report_in_frame;
468
469 /* The sequence analysis frame report hash table.
470    Maps pdcp_result_hash_key* -> pdcp_sequence_report_in_frame* */
471 static GHashTable *pdcp_lte_sequence_analysis_report_hash = NULL;
472
473 /* Gather together security settings in order to be able to do deciphering */
474 typedef struct pdu_security_settings_t
475 {
476     gboolean valid;
477     enum security_ciphering_algorithm_e ciphering;
478     guint8* key;
479     guint32 count;
480     guint8  bearer;
481     guint8  direction;
482 } pdu_security_settings_t;
483
484
485 /* Add to the tree values associated with sequence analysis for this frame */
486 static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p,
487                                    pdcp_lte_info *p_pdcp_lte_info,
488                                    guint16   sequenceNumber,
489                                    packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
490                                    proto_tree *security_tree,
491                                    pdu_security_settings_t *pdu_security)
492 {
493     proto_tree *seqnum_tree;
494     proto_item *seqnum_ti;
495     proto_item *ti_expected_sn;
496     proto_item *ti;
497
498     /* Create subtree */
499     seqnum_ti = proto_tree_add_string_format(tree,
500                                              hf_pdcp_lte_sequence_analysis,
501                                              tvb, 0, 0,
502                                              "", "Sequence Analysis");
503     seqnum_tree = proto_item_add_subtree(seqnum_ti,
504                                          ett_pdcp_lte_sequence_analysis);
505     PROTO_ITEM_SET_GENERATED(seqnum_ti);
506
507
508     /* Previous channel frame */
509     if (p->previousFrameNum != 0) {
510         proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_previous_frame,
511                             tvb, 0, 0, p->previousFrameNum);
512     }
513
514     /* Expected sequence number */
515     ti_expected_sn = proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_expected_sn,
516                                          tvb, 0, 0, p->sequenceExpected);
517     PROTO_ITEM_SET_GENERATED(ti_expected_sn);
518
519     /* Make sure we have recognised SN length */
520     switch (p_pdcp_lte_info->seqnum_length) {
521         case PDCP_SN_LENGTH_5_BITS:
522         case PDCP_SN_LENGTH_7_BITS:
523         case PDCP_SN_LENGTH_12_BITS:
524         case PDCP_SN_LENGTH_15_BITS:
525             break;
526         default:
527             DISSECTOR_ASSERT_NOT_REACHED();
528             break;
529     }
530
531     switch (p->state) {
532         case SN_OK:
533             PROTO_ITEM_SET_HIDDEN(ti_expected_sn);
534             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
535                                         tvb, 0, 0, TRUE);
536             PROTO_ITEM_SET_GENERATED(ti);
537             proto_item_append_text(seqnum_ti, " - OK");
538
539             /* Link to next SN in channel (if known) */
540             if (p->nextFrameNum != 0) {
541                 proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_next_frame,
542                                     tvb, 0, 0, p->nextFrameNum);
543             }
544
545             /* May also be able to add key inputs to security tree here */
546             if (security_tree != NULL) {
547                 guint32              hfn_multiplier;
548                 guint32              count;
549 #if HAVE_LIBGCRYPT
550                 gchar                *key = NULL;
551                 guint                record_id;
552 #endif
553                 /* BEARER */
554                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_bearer,
555                                          tvb, 0, 0, p_pdcp_lte_info->channelId-1);
556                 PROTO_ITEM_SET_GENERATED(ti);
557                 pdu_security->bearer = p_pdcp_lte_info->channelId-1;
558
559                 /* DIRECTION */
560                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_direction,
561                                          tvb, 0, 0, p_pdcp_lte_info->direction);
562                 PROTO_ITEM_SET_GENERATED(ti);
563
564                 /* COUNT (HFN * snLength^2 + SN) */
565                 switch (p_pdcp_lte_info->seqnum_length) {
566                     case PDCP_SN_LENGTH_5_BITS:
567                         hfn_multiplier = 32;
568                         break;
569                     case PDCP_SN_LENGTH_7_BITS:
570                         hfn_multiplier = 128;
571                         break;
572                     case PDCP_SN_LENGTH_12_BITS:
573                         hfn_multiplier = 2048;
574                         break;
575                     case PDCP_SN_LENGTH_15_BITS:
576                         hfn_multiplier = 32768;
577                         break;
578                     default:
579                         DISSECTOR_ASSERT_NOT_REACHED();
580                         break;
581                 }
582                 count = (p->hfn * hfn_multiplier) + sequenceNumber;
583                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_count,
584                                          tvb, 0, 0, count);
585                 PROTO_ITEM_SET_GENERATED(ti);
586                 pdu_security->count = count;
587
588 #if HAVE_LIBGCRYPT
589                 /* KEY */
590                 for (record_id=0; record_id < num_ue_keys_uat; record_id++) {
591                     if (uat_ue_keys_records[record_id].ueid == p_pdcp_lte_info->ueid) {
592                         if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
593                             if (uat_ue_keys_records[record_id].rrcKeyOK) {
594                                 key = uat_ue_keys_records[record_id].rrcKeyString;
595                                 pdu_security->key = &(uat_ue_keys_records[record_id].rrcBinaryKey[0]);
596                                 pdu_security->valid = TRUE;
597                             }
598                         }
599                         else {
600                             if (uat_ue_keys_records[record_id].upKeyOK) {
601                                 key = uat_ue_keys_records[record_id].upKeyString;
602                                 pdu_security->key = &(uat_ue_keys_records[record_id].upBinaryKey[0]);
603                                 pdu_security->valid = TRUE;
604                             }
605                         }
606
607                         if (key != NULL) {
608                             ti = proto_tree_add_string(security_tree, hf_pdcp_lte_security_key,
609                                                        tvb, 0, 0, key);
610                             PROTO_ITEM_SET_GENERATED(ti);
611                         }
612                         break;
613                     }
614                 }
615 #endif
616                 pdu_security->direction = p_pdcp_lte_info->direction;
617             }
618             break;
619
620         case SN_Missing:
621             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
622                                         tvb, 0, 0, FALSE);
623             PROTO_ITEM_SET_GENERATED(ti);
624             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_skipped,
625                                         tvb, 0, 0, TRUE);
626             PROTO_ITEM_SET_GENERATED(ti);
627             if (p->lastSN != p->firstSN) {
628                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_missing,
629                                        "PDCP SNs (%u to %u) missing for %s on UE %u (%s-%u)",
630                                        p->firstSN, p->lastSN,
631                                        val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
632                                        p_pdcp_lte_info->ueid,
633                                        val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
634                                        p_pdcp_lte_info->channelId);
635                 proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
636                                        p->firstSN, p->lastSN);
637             }
638             else {
639                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_missing,
640                                        "PDCP SN (%u) missing for %s on UE %u (%s-%u)",
641                                        p->firstSN,
642                                        val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
643                                        p_pdcp_lte_info->ueid,
644                                        val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
645                                        p_pdcp_lte_info->channelId);
646                 proto_item_append_text(seqnum_ti, " - SN missing (%u)",
647                                        p->firstSN);
648             }
649             break;
650
651         case SN_Repeated:
652             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
653                                         tvb, 0, 0, FALSE);
654             PROTO_ITEM_SET_GENERATED(ti);
655             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_repeated,
656                                         tvb, 0, 0, TRUE);
657             PROTO_ITEM_SET_GENERATED(ti);
658             expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_repeated,
659                                    "PDCP SN (%u) repeated for %s for UE %u (%s-%u)",
660                                    p->firstSN,
661                                    val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
662                                    p_pdcp_lte_info->ueid,
663                                    val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
664                                    p_pdcp_lte_info->channelId);
665             proto_item_append_text(seqnum_ti, "- SN %u Repeated",
666                                    p->firstSN);
667             break;
668
669         default:
670             /* Incorrect sequence number */
671             expert_add_info_format(pinfo, ti_expected_sn, &ei_pdcp_lte_sequence_analysis_wrong_sequence_number,
672                                    "Wrong Sequence Number for %s on UE %u (%s-%u) - got %u, expected %u",
673                                    val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
674                                    p_pdcp_lte_info->ueid,
675                                    val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
676                                    p_pdcp_lte_info->channelId,
677                                    sequenceNumber, p->sequenceExpected);
678             break;
679     }
680 }
681
682
683 /* Update the channel status and set report for this frame */
684 static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb,
685                                      pdcp_lte_info *p_pdcp_lte_info,
686                                      guint16 sequenceNumber,
687                                      proto_tree *tree,
688                                      proto_tree *security_tree,
689                                      pdu_security_settings_t *pdu_security)
690 {
691     pdcp_channel_hash_key          channel_key;
692     pdcp_channel_status           *p_channel_status;
693     pdcp_sequence_report_in_frame *p_report_in_frame      = NULL;
694     gboolean                       createdChannel         = FALSE;
695     guint16                        expectedSequenceNumber = 0;
696     guint16                        snLimit                = 0;
697
698     /* If find stat_report_in_frame already, use that and get out */
699     if (pinfo->fd->flags.visited) {
700         p_report_in_frame =
701             (pdcp_sequence_report_in_frame*)g_hash_table_lookup(pdcp_lte_sequence_analysis_report_hash,
702                                                                 get_report_hash_key(sequenceNumber,
703                                                                                     pinfo->fd->num,
704                                                                                     p_pdcp_lte_info, FALSE));
705         if (p_report_in_frame != NULL) {
706             addChannelSequenceInfo(p_report_in_frame, p_pdcp_lte_info,
707                                    sequenceNumber,
708                                    pinfo, tree, tvb, security_tree, pdu_security);
709             return;
710         }
711         else {
712             /* Give up - we must have tried already... */
713             return;
714         }
715     }
716
717
718     /**************************************************/
719     /* Create or find an entry for this channel state */
720     channel_key.ueId = p_pdcp_lte_info->ueid;
721     channel_key.plane = p_pdcp_lte_info->plane;
722     channel_key.channelId = p_pdcp_lte_info->channelId;
723     channel_key.direction = p_pdcp_lte_info->direction;
724     channel_key.notUsed = 0;
725
726     /* Do the table lookup */
727     p_channel_status = (pdcp_channel_status*)g_hash_table_lookup(pdcp_sequence_analysis_channel_hash,
728                                                                  get_channel_hash_key(&channel_key));
729
730     /* Create table entry if necessary */
731     if (p_channel_status == NULL) {
732         createdChannel = TRUE;
733
734         /* Allocate a new value and duplicate key contents */
735         p_channel_status = wmem_new0(wmem_file_scope(), pdcp_channel_status);
736
737         /* Add entry */
738         g_hash_table_insert(pdcp_sequence_analysis_channel_hash,
739                             get_channel_hash_key(&channel_key), p_channel_status);
740     }
741
742     /* Create space for frame state_report */
743     p_report_in_frame = wmem_new(wmem_file_scope(), pdcp_sequence_report_in_frame);
744     p_report_in_frame->nextFrameNum = 0;
745
746     switch (p_pdcp_lte_info->seqnum_length) {
747         case PDCP_SN_LENGTH_5_BITS:
748             snLimit = 32;
749             break;
750         case PDCP_SN_LENGTH_7_BITS:
751             snLimit = 128;
752             break;
753         case PDCP_SN_LENGTH_12_BITS:
754             snLimit = 4096;
755             break;
756         case PDCP_SN_LENGTH_15_BITS:
757             snLimit = 32768;
758             break;
759         default:
760             DISSECTOR_ASSERT_NOT_REACHED();
761             break;
762     }
763
764     /* Work out expected sequence number */
765     if (!createdChannel) {
766         expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % snLimit;
767     }
768     else {
769         expectedSequenceNumber = sequenceNumber;
770     }
771
772     /* Set report for this frame */
773     /* For PDCP, sequence number is always expectedSequence number */
774     p_report_in_frame->sequenceExpectedCorrect = (sequenceNumber == expectedSequenceNumber);
775     p_report_in_frame->hfn = p_channel_status->hfn;
776
777     /* For wrong sequence number... */
778     if (!p_report_in_frame->sequenceExpectedCorrect) {
779
780         /* Frames are not missing if we get an earlier sequence number again */
781         if (((snLimit + expectedSequenceNumber - sequenceNumber) % snLimit) > 15) {
782             p_report_in_frame->state = SN_Missing;
783             p_report_in_frame->firstSN = expectedSequenceNumber;
784             p_report_in_frame->lastSN = (snLimit + sequenceNumber - 1) % snLimit;
785
786             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
787             p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
788
789             /* Update channel status to remember *this* frame */
790             p_channel_status->previousFrameNum = pinfo->fd->num;
791             p_channel_status->previousSequenceNumber = sequenceNumber;
792         }
793         else {
794             /* An SN has been repeated */
795             p_report_in_frame->state = SN_Repeated;
796             p_report_in_frame->firstSN = sequenceNumber;
797
798             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
799             p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
800         }
801     }
802     else {
803         /* SN was OK */
804         p_report_in_frame->state = SN_OK;
805         p_report_in_frame->sequenceExpected = expectedSequenceNumber;
806         p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
807         /* SN has rolled around, inc hfn! */
808         if (!createdChannel && (sequenceNumber == 0)) {
809             /* TODO: not worrying about HFN rolling over for now! */
810             p_channel_status->hfn++;
811             p_report_in_frame->hfn = p_channel_status->hfn;
812         }
813
814         /* Update channel status to remember *this* frame */
815         p_channel_status->previousFrameNum = pinfo->fd->num;
816         p_channel_status->previousSequenceNumber = sequenceNumber;
817
818         if (p_report_in_frame->previousFrameNum != 0) {
819             /* Get report for previous frame */
820             pdcp_sequence_report_in_frame *p_previous_report;
821             p_previous_report = (pdcp_sequence_report_in_frame*)g_hash_table_lookup(pdcp_lte_sequence_analysis_report_hash,
822                                                                                     get_report_hash_key((sequenceNumber+32767) % 32768,
823                                                                                                         p_report_in_frame->previousFrameNum,
824                                                                                                         p_pdcp_lte_info,
825                                                                                                         FALSE));
826             /* It really shouldn't be NULL... */
827             if (p_previous_report != NULL) {
828                 /* Point it forward to this one */
829                 p_previous_report->nextFrameNum = pinfo->fd->num;
830             }
831         }
832     }
833
834     /* Associate with this frame number */
835     g_hash_table_insert(pdcp_lte_sequence_analysis_report_hash,
836                         get_report_hash_key(sequenceNumber, pinfo->fd->num,
837                                             p_pdcp_lte_info, TRUE),
838                         p_report_in_frame);
839
840     /* Add state report for this frame into tree */
841     addChannelSequenceInfo(p_report_in_frame, p_pdcp_lte_info, sequenceNumber,
842                            pinfo, tree, tvb, security_tree, pdu_security);
843 }
844
845
846
847 /* Hash table for security state for a UE
848    Maps UEId -> pdcp_security_info_t*  */
849 static gint pdcp_lte_ueid_hash_equal(gconstpointer v, gconstpointer v2)
850 {
851     return (v == v2);
852 }
853 static guint pdcp_lte_ueid_hash_func(gconstpointer v)
854 {
855     return GPOINTER_TO_UINT(v);
856 }
857 static GHashTable *pdcp_security_hash = NULL;
858
859 /* Result is (ueid, framenum) -> pdcp_security_info_t*  */
860 typedef struct  ueid_frame_t {
861     guint32 framenum;
862     guint16 ueid;
863 } ueid_frame_t;
864
865 /* Convenience function to get a pointer for the hash_func to work with */
866 static gpointer get_ueid_frame_hash_key(guint16 ueid, guint32 frameNumber,
867                                         gboolean do_persist)
868 {
869     static ueid_frame_t  key;
870     ueid_frame_t        *p_key;
871
872     /* Only allocate a struct when will be adding entry */
873     if (do_persist) {
874         p_key = wmem_new(wmem_file_scope(), ueid_frame_t);
875     }
876     else {
877         memset(&key, 0, sizeof(ueid_frame_t));
878         p_key = &key;
879     }
880
881     /* Fill in details, and return pointer */
882     p_key->framenum = frameNumber;
883     p_key->ueid = ueid;
884
885     return p_key;
886 }
887
888 static gint pdcp_lte_ueid_frame_hash_equal(gconstpointer v, gconstpointer v2)
889 {
890     ueid_frame_t *ueid_frame_1 = (ueid_frame_t *)v;
891     ueid_frame_t *ueid_frame_2 = (ueid_frame_t *)v2;
892     return ((ueid_frame_1->framenum == ueid_frame_2->framenum) && (ueid_frame_1->ueid == ueid_frame_2->ueid));
893 }
894 static guint pdcp_lte_ueid_frame_hash_func(gconstpointer v)
895 {
896     ueid_frame_t *ueid_frame = (ueid_frame_t *)v;
897     return ueid_frame->framenum + 100*ueid_frame->ueid;
898 }
899 static GHashTable *pdcp_security_result_hash = NULL;
900
901
902
903
904 /* Write the given formatted text to:
905    - the info column
906    - the top-level RLC PDU item */
907 static void write_pdu_label_and_info(proto_item *pdu_ti,
908                                      packet_info *pinfo, const char *format, ...)
909 {
910     #define MAX_INFO_BUFFER 256
911     static char info_buffer[MAX_INFO_BUFFER];
912
913     va_list ap;
914
915     va_start(ap, format);
916     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
917     va_end(ap);
918
919     /* Add to indicated places */
920     col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
921     proto_item_append_text(pdu_ti, "%s", info_buffer);
922 }
923
924
925
926 /***************************************************************/
927
928
929
930 /* Show in the tree the config info attached to this frame, as generated fields */
931 static void show_pdcp_config(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
932                              pdcp_lte_info *p_pdcp_info)
933 {
934     proto_item *ti;
935     proto_tree *configuration_tree;
936     proto_item *configuration_ti = proto_tree_add_item(tree,
937                                                        hf_pdcp_lte_configuration,
938                                                        tvb, 0, 0, ENC_ASCII|ENC_NA);
939     configuration_tree = proto_item_add_subtree(configuration_ti, ett_pdcp_configuration);
940
941     /* Direction */
942     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_direction, tvb, 0, 0,
943                              p_pdcp_info->direction);
944     PROTO_ITEM_SET_GENERATED(ti);
945
946     /* Plane */
947     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_plane, tvb, 0, 0,
948                              p_pdcp_info->plane);
949     PROTO_ITEM_SET_GENERATED(ti);
950
951     /* UEId */
952     if (p_pdcp_info->ueid != 0) {
953         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_ueid, tvb, 0, 0,
954                                  p_pdcp_info->ueid);
955         PROTO_ITEM_SET_GENERATED(ti);
956     }
957
958     /* Channel type */
959     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_channel_type, tvb, 0, 0,
960                              p_pdcp_info->channelType);
961     PROTO_ITEM_SET_GENERATED(ti);
962     if (p_pdcp_info->channelId != 0) {
963         /* Channel type */
964         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_channel_id, tvb, 0, 0,
965                                  p_pdcp_info->channelId);
966         PROTO_ITEM_SET_GENERATED(ti);
967     }
968
969
970     /* User-plane-specific fields */
971     if (p_pdcp_info->plane == USER_PLANE) {
972
973         /* No Header PDU */
974         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_no_header_pdu, tvb, 0, 0,
975                                  p_pdcp_info->no_header_pdu);
976         PROTO_ITEM_SET_GENERATED(ti);
977
978         if (!p_pdcp_info->no_header_pdu) {
979
980             /* Seqnum length */
981             ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_seqnum_length, tvb, 0, 0,
982                                      p_pdcp_info->seqnum_length);
983             PROTO_ITEM_SET_GENERATED(ti);
984         }
985     }
986
987     /* ROHC compression */
988     ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_lte_rohc_compression, tvb, 0, 0,
989                                 p_pdcp_info->rohc.rohc_compression);
990     PROTO_ITEM_SET_GENERATED(ti);
991
992     /* ROHC-specific settings */
993     if (p_pdcp_info->rohc.rohc_compression) {
994
995         /* Show ROHC mode */
996         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_mode, tvb, 0, 0,
997                                  p_pdcp_info->rohc.mode);
998         PROTO_ITEM_SET_GENERATED(ti);
999
1000         /* Show RND */
1001         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_rnd, tvb, 0, 0,
1002                                  p_pdcp_info->rohc.rnd);
1003         PROTO_ITEM_SET_GENERATED(ti);
1004
1005         /* UDP Checksum */
1006         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_udp_checksum_present, tvb, 0, 0,
1007                                  p_pdcp_info->rohc.udp_checksum_present);
1008         PROTO_ITEM_SET_GENERATED(ti);
1009
1010         /* ROHC profile */
1011         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_profile, tvb, 0, 0,
1012                                  p_pdcp_info->rohc.profile);
1013         PROTO_ITEM_SET_GENERATED(ti);
1014
1015         /* CID Inclusion Info */
1016         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_cid_inclusion_info, tvb, 0, 0,
1017                                  p_pdcp_info->rohc.cid_inclusion_info);
1018         PROTO_ITEM_SET_GENERATED(ti);
1019
1020         /* Large CID */
1021         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_large_cid_present, tvb, 0, 0,
1022                                  p_pdcp_info->rohc.large_cid_present);
1023         PROTO_ITEM_SET_GENERATED(ti);
1024     }
1025
1026     /* Append summary to configuration root */
1027     proto_item_append_text(configuration_ti, "(direction=%s, plane=%s",
1028                            val_to_str_const(p_pdcp_info->direction, direction_vals, "Unknown"),
1029                            val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
1030
1031     if (p_pdcp_info->rohc.rohc_compression) {
1032         const char *mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
1033         proto_item_append_text(configuration_ti, ", mode=%c, profile=%s",
1034                                mode[0],
1035                                val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
1036     }
1037     proto_item_append_text(configuration_ti, ")");
1038     PROTO_ITEM_SET_GENERATED(configuration_ti);
1039
1040     /* Show plane in info column */
1041     col_append_fstr(pinfo->cinfo, COL_INFO, " %s: ",
1042                     val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
1043
1044 }
1045
1046
1047 /* Look for an RRC dissector for signalling data (using channel type and direction) */
1048 static dissector_handle_t lookup_rrc_dissector_handle(struct pdcp_lte_info  *p_pdcp_info)
1049 {
1050     dissector_handle_t rrc_handle = 0;
1051
1052     switch (p_pdcp_info->channelType)
1053     {
1054         case Channel_CCCH:
1055             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1056                 rrc_handle = find_dissector("lte_rrc.ul_ccch");
1057             }
1058             else {
1059                 rrc_handle = find_dissector("lte_rrc.dl_ccch");
1060             }
1061             break;
1062         case Channel_PCCH:
1063             rrc_handle = find_dissector("lte_rrc.pcch");
1064             break;
1065         case Channel_BCCH:
1066             switch (p_pdcp_info->BCCHTransport) {
1067                 case BCH_TRANSPORT:
1068                     rrc_handle = find_dissector("lte_rrc.bcch_bch");
1069                     break;
1070                 case DLSCH_TRANSPORT:
1071                     rrc_handle = find_dissector("lte_rrc.bcch_dl_sch");
1072                     break;
1073             }
1074             break;
1075         case Channel_DCCH:
1076             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1077                 rrc_handle = find_dissector("lte_rrc.ul_dcch");
1078             }
1079             else {
1080                 rrc_handle = find_dissector("lte_rrc.dl_dcch");
1081             }
1082             break;
1083
1084
1085         default:
1086             break;
1087     }
1088
1089     return rrc_handle;
1090 }
1091
1092
1093 /* Forwad declarations */
1094 static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1095
1096 /* Heuristic dissection */
1097 static gboolean global_pdcp_lte_heur = FALSE;
1098
1099 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
1100 static gboolean dissect_pdcp_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
1101                                      proto_tree *tree, void *data _U_)
1102 {
1103     gint                  offset                 = 0;
1104     struct pdcp_lte_info *p_pdcp_lte_info;
1105     tvbuff_t             *pdcp_tvb;
1106     guint8                tag                    = 0;
1107     gboolean              infoAlreadySet         = FALSE;
1108     gboolean              seqnumLengthTagPresent = FALSE;
1109
1110     /* This is a heuristic dissector, which means we get all the UDP
1111      * traffic not sent to a known dissector and not claimed by
1112      * a heuristic dissector called before us!
1113      */
1114
1115     if (!global_pdcp_lte_heur) {
1116         return FALSE;
1117     }
1118
1119     /* Do this again on re-dissection to re-discover offset of actual PDU */
1120
1121     /* Needs to be at least as long as:
1122        - the signature string
1123        - fixed header bytes
1124        - tag for data
1125        - at least one byte of PDCP PDU payload */
1126     if (tvb_length_remaining(tvb, offset) < (gint)(strlen(PDCP_LTE_START_STRING)+3+2)) {
1127         return FALSE;
1128     }
1129
1130     /* OK, compare with signature string */
1131     if (tvb_strneql(tvb, offset, PDCP_LTE_START_STRING, strlen(PDCP_LTE_START_STRING)) != 0) {
1132         return FALSE;
1133     }
1134     offset += (gint)strlen(PDCP_LTE_START_STRING);
1135
1136
1137     /* If redissecting, use previous info struct (if available) */
1138     p_pdcp_lte_info = (pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0);
1139     if (p_pdcp_lte_info == NULL) {
1140         /* Allocate new info struct for this frame */
1141         p_pdcp_lte_info = wmem_new0(wmem_file_scope(), pdcp_lte_info);
1142         infoAlreadySet = FALSE;
1143     }
1144     else {
1145         infoAlreadySet = TRUE;
1146     }
1147
1148
1149     /* Read fixed fields */
1150     p_pdcp_lte_info->no_header_pdu = (gboolean)tvb_get_guint8(tvb, offset++);
1151     p_pdcp_lte_info->plane = (enum pdcp_plane)tvb_get_guint8(tvb, offset++);
1152     p_pdcp_lte_info->rohc.rohc_compression = (gboolean)tvb_get_guint8(tvb, offset++);
1153
1154     /* Read optional fields */
1155     while (tag != PDCP_LTE_PAYLOAD_TAG) {
1156         /* Process next tag */
1157         tag = tvb_get_guint8(tvb, offset++);
1158         switch (tag) {
1159             case PDCP_LTE_SEQNUM_LENGTH_TAG:
1160                 p_pdcp_lte_info->seqnum_length = tvb_get_guint8(tvb, offset);
1161                 offset++;
1162                 seqnumLengthTagPresent = TRUE;
1163                 break;
1164             case PDCP_LTE_DIRECTION_TAG:
1165                 p_pdcp_lte_info->direction = tvb_get_guint8(tvb, offset);
1166                 offset++;
1167                 break;
1168             case PDCP_LTE_LOG_CHAN_TYPE_TAG:
1169                 p_pdcp_lte_info->channelType = (LogicalChannelType)tvb_get_guint8(tvb, offset);
1170                 offset++;
1171                 break;
1172             case PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG:
1173                 p_pdcp_lte_info->BCCHTransport = (BCCHTransportType)tvb_get_guint8(tvb, offset);
1174                 offset++;
1175                 break;
1176             case PDCP_LTE_ROHC_IP_VERSION_TAG:
1177                 p_pdcp_lte_info->rohc.rohc_ip_version = tvb_get_ntohs(tvb, offset);
1178                 offset += 2;
1179                 break;
1180             case PDCP_LTE_ROHC_CID_INC_INFO_TAG:
1181                 p_pdcp_lte_info->rohc.cid_inclusion_info = tvb_get_guint8(tvb, offset);
1182                 offset++;
1183                 break;
1184             case PDCP_LTE_ROHC_LARGE_CID_PRES_TAG:
1185                 p_pdcp_lte_info->rohc.large_cid_present = tvb_get_guint8(tvb, offset);
1186                 offset++;
1187                 break;
1188             case PDCP_LTE_ROHC_MODE_TAG:
1189                 p_pdcp_lte_info->rohc.mode = (enum rohc_mode)tvb_get_guint8(tvb, offset);
1190                 offset++;
1191                 break;
1192             case PDCP_LTE_ROHC_RND_TAG:
1193                 p_pdcp_lte_info->rohc.rnd = tvb_get_guint8(tvb, offset);
1194                 offset++;
1195                 break;
1196             case PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG:
1197                 p_pdcp_lte_info->rohc.udp_checksum_present = tvb_get_guint8(tvb, offset);
1198                 offset++;
1199                 break;
1200             case PDCP_LTE_ROHC_PROFILE_TAG:
1201                 p_pdcp_lte_info->rohc.profile = tvb_get_ntohs(tvb, offset);
1202                 offset += 2;
1203                 break;
1204             case PDCP_LTE_CHANNEL_ID_TAG:
1205                 p_pdcp_lte_info->channelId = tvb_get_ntohs(tvb, offset);
1206                 offset += 2;
1207                 break;
1208             case PDCP_LTE_UEID_TAG:
1209                 p_pdcp_lte_info->ueid = tvb_get_ntohs(tvb, offset);
1210                 offset += 2;
1211                 break;
1212
1213             case PDCP_LTE_PAYLOAD_TAG:
1214                 /* Have reached data, so get out of loop */
1215                 continue;
1216
1217             default:
1218                 /* It must be a recognised tag */
1219                 return FALSE;
1220         }
1221     }
1222
1223     if ((p_pdcp_lte_info->plane == USER_PLANE) && (seqnumLengthTagPresent == FALSE)) {
1224         /* Conditional field is not present */
1225         return FALSE;
1226     }
1227
1228     if (!infoAlreadySet) {
1229         /* Store info in packet */
1230         p_add_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0, p_pdcp_lte_info);
1231     }
1232
1233     /**************************************/
1234     /* OK, now dissect as PDCP LTE        */
1235
1236     /* Create tvb that starts at actual PDCP PDU */
1237     pdcp_tvb = tvb_new_subset_remaining(tvb, offset);
1238     dissect_pdcp_lte(pdcp_tvb, pinfo, tree);
1239     return TRUE;
1240 }
1241
1242 /* Called from control protocol to configure security algorithms for the given UE */
1243 void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_security_info_t *security_info)
1244 {
1245     /* Copy security struct */
1246     pdcp_security_info_t *p_security = wmem_new(wmem_file_scope(), pdcp_security_info_t);
1247     *p_security = *security_info;
1248
1249     /* And add into security table */
1250     g_hash_table_insert(pdcp_security_hash, GUINT_TO_POINTER((guint)ueid), p_security);
1251 }
1252
1253 #if HAVE_LIBGCRYPT
1254 /* Decipher payload if algorithm is supported and plausible inputs are available */
1255 static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset,
1256                                   pdu_security_settings_t *pdu_security_settings,
1257                                   enum pdcp_plane plane, gboolean *deciphered)
1258 {
1259     unsigned char ctr_block[16];
1260     gcry_cipher_hd_t cypher_hd;
1261     int gcrypt_err;
1262     guint8* encrypted_data;
1263     guint8* decrypted_data;
1264     gint payload_length;
1265     tvbuff_t *decrypted_tvb;
1266
1267     /* Nothing to do if no ciphering algorithm was specified */
1268     if (!pdu_security_settings->valid) {
1269         return tvb;
1270     }
1271
1272     /* Only EEA2 supported at the moment */
1273     if (pdu_security_settings->ciphering != eea2) {
1274         return tvb;
1275     }
1276
1277     /* Don't decipher if turned off in preferences */
1278     if (((plane == SIGNALING_PLANE) &&  !global_pdcp_decipher_signalling) ||
1279         ((plane == USER_PLANE) &&       !global_pdcp_decipher_userplane)) {
1280         return tvb;
1281     }
1282
1283     /* Set CTR */
1284     memset(ctr_block, 0, 16);
1285     /* Only first 5 bytes set */
1286     ctr_block[0] = (pdu_security_settings->count & 0xff000000) >> 24;
1287     ctr_block[1] = (pdu_security_settings->count & 0x00ff0000) >> 16;
1288     ctr_block[2] = (pdu_security_settings->count & 0x0000ff00) >> 8;
1289     ctr_block[3] = (pdu_security_settings->count & 0x000000ff);
1290     ctr_block[4] = (pdu_security_settings->bearer << 3) + (pdu_security_settings->direction << 2);
1291
1292     /* Open gcrypt handle */
1293     gcrypt_err = gcry_cipher_open(&cypher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0);
1294     if (gcrypt_err != 0) {
1295         return tvb;
1296     }
1297
1298     /* Set the key */
1299     gcrypt_err = gcry_cipher_setkey(cypher_hd, pdu_security_settings->key, 16);
1300     if (gcrypt_err != 0) {
1301         return tvb;
1302     }
1303
1304     /* Set the CTR */
1305     gcrypt_err = gcry_cipher_setctr(cypher_hd, ctr_block, 16);
1306     if (gcrypt_err != 0) {
1307         return tvb;
1308     }
1309
1310     /* Extract the encrypted data into a buffer */
1311     payload_length = tvb_length_remaining(tvb, *offset);
1312     encrypted_data = (guint8 *)g_malloc0(payload_length);
1313     tvb_memcpy(tvb, encrypted_data, *offset, payload_length);
1314
1315     /* Allocate memory to receive decrypted payload */
1316     decrypted_data = (guint8 *)g_malloc0(payload_length);
1317
1318     /* Decrypt the actual data */
1319     gcrypt_err = gcry_cipher_decrypt(cypher_hd,
1320                                      decrypted_data, payload_length,
1321                                      encrypted_data, payload_length);
1322     if (gcrypt_err != 0) {
1323         return tvb;
1324     }
1325
1326     /* TODO: close gcry handle!!! */
1327
1328     /* Create tvb for resulting deciphered sdu */
1329     decrypted_tvb = tvb_new_child_real_data(tvb, decrypted_data, payload_length, payload_length);
1330     tvb_set_free_cb(decrypted_tvb, g_free);
1331     add_new_data_source(pinfo, decrypted_tvb, "Deciphered Payload");
1332
1333     /* Free temp buffer */
1334     g_free(encrypted_data);
1335
1336     /* Return deciphered data, i.e. beginning of new tvb */
1337     *offset = 0;
1338     *deciphered = TRUE;
1339     return decrypted_tvb;
1340 }
1341 #else
1342 static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo _U_, int *offset _U_,
1343                                   pdu_security_settings_t *pdu_security_settings _U_,
1344                                   enum pdcp_plane plane _U_, gboolean *deciphered _U_)
1345 {
1346     return tvb;
1347 }
1348 #endif
1349
1350
1351 /******************************/
1352 /* Main dissection function.  */
1353 static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1354 {
1355     const char           *mode;
1356     proto_tree           *pdcp_tree           = NULL;
1357     proto_item           *root_ti             = NULL;
1358     gint                  offset              = 0;
1359     gint                  rohc_offset;
1360     struct pdcp_lte_info *p_pdcp_info;
1361     tvbuff_t             *rohc_tvb            = NULL;
1362
1363     pdcp_security_info_t *current_security = NULL;   /* current security for this UE */
1364     pdcp_security_info_t *pdu_security;              /* security in place for this PDU */
1365     proto_tree *security_tree = NULL;
1366     proto_item *security_ti;
1367     tvbuff_t *payload_tvb;
1368     pdu_security_settings_t  pdu_security_settings;
1369     gboolean payload_deciphered = FALSE;
1370
1371     /* Initialise security settings */
1372     pdu_security_settings.valid = FALSE;
1373
1374     /* Set protocol name. */
1375     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDCP-LTE");
1376
1377     /* Look for attached packet info! */
1378     p_pdcp_info = (struct pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0);
1379     /* Can't dissect anything without it... */
1380     if (p_pdcp_info == NULL) {
1381         return;
1382     }
1383
1384     /* Don't want to overwrite the RLC Info column if configured not to */
1385     if ((global_pdcp_lte_layer_to_show == ShowRLCLayer) &&
1386         (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) != NULL)) {
1387
1388         col_set_writable(pinfo->cinfo, FALSE);
1389     }
1390     else {
1391         /* TODO: won't help with multiple PDCP-or-traffic PDUs / frame... */
1392         col_clear(pinfo->cinfo, COL_INFO);
1393         col_set_writable(pinfo->cinfo, TRUE);
1394     }
1395
1396     /* Create pdcp tree. */
1397     if (tree) {
1398         root_ti = proto_tree_add_item(tree, proto_pdcp_lte, tvb, offset, -1, ENC_NA);
1399         pdcp_tree = proto_item_add_subtree(root_ti, ett_pdcp);
1400     }
1401
1402     /* Set mode string */
1403     mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
1404
1405     /*****************************************************/
1406     /* Show configuration (attached packet) info in tree */
1407     if (pdcp_tree) {
1408         show_pdcp_config(pinfo, tvb, pdcp_tree, p_pdcp_info);
1409     }
1410
1411     /* Show ROHC mode */
1412     if (p_pdcp_info->rohc.rohc_compression) {
1413         col_append_fstr(pinfo->cinfo, COL_INFO, " (mode=%c)", mode[0]);
1414     }
1415
1416     /***************************************/
1417     /* UE security algorithms              */
1418     if (!pinfo->fd->flags.visited) {
1419         /* Look up current state by UEID */
1420         current_security = (pdcp_security_info_t*)g_hash_table_lookup(pdcp_security_hash,
1421                                                                                             GUINT_TO_POINTER((guint)p_pdcp_info->ueid));
1422         if (current_security != NULL) {
1423             /* Store any result for this frame in the result table */
1424             pdcp_security_info_t *security_to_store = wmem_new(wmem_file_scope(), pdcp_security_info_t);
1425             *security_to_store = *current_security;
1426             g_hash_table_insert(pdcp_security_result_hash,
1427                                 get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->fd->num, TRUE),
1428                                 security_to_store);
1429         }
1430     }
1431
1432     /* Show security settings for this PDU */
1433     pdu_security = (pdcp_security_info_t*)g_hash_table_lookup(pdcp_security_result_hash, get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->fd->num, FALSE));
1434     if (pdu_security != NULL) {
1435         proto_item *ti;
1436
1437         /* Create subtree */
1438         security_ti = proto_tree_add_string_format(pdcp_tree,
1439                                                    hf_pdcp_lte_security,
1440                                                    tvb, 0, 0,
1441                                                    "", "UE Security");
1442         security_tree = proto_item_add_subtree(security_ti, ett_pdcp_security);
1443         PROTO_ITEM_SET_GENERATED(security_ti);
1444
1445         /* Setup frame */
1446         ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_setup_frame,
1447                                  tvb, 0, 0, pdu_security->configuration_frame);
1448         PROTO_ITEM_SET_GENERATED(ti);
1449
1450         /* Ciphering */
1451         ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_ciphering_algorithm,
1452                                  tvb, 0, 0, pdu_security->ciphering);
1453         PROTO_ITEM_SET_GENERATED(ti);
1454
1455         /* Integrity */
1456         ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_integrity_algorithm,
1457                                  tvb, 0, 0, pdu_security->integrity);
1458         PROTO_ITEM_SET_GENERATED(ti);
1459
1460         proto_item_append_text(security_ti, " (ciphering=%s, integrity=%s)",
1461                                val_to_str_const(pdu_security->ciphering, ciphering_algorithm_vals, "Unknown"),
1462                                val_to_str_const(pdu_security->integrity, integrity_algorithm_vals, "Unknown"));
1463
1464         pdu_security_settings.ciphering = pdu_security->ciphering;
1465     }
1466
1467
1468     /***********************************/
1469     /* Handle PDCP header (if present) */
1470     if (!p_pdcp_info->no_header_pdu) {
1471
1472         /* TODO: shouldn't need to initialise this one!! */
1473         guint16  seqnum = 0;
1474         gboolean seqnum_set = FALSE;
1475
1476         guint8  first_byte = tvb_get_guint8(tvb, offset);
1477
1478         /*****************************/
1479         /* Signalling plane messages */
1480         if (p_pdcp_info->plane == SIGNALING_PLANE) {
1481             /* Verify 3 reserved bits are 0 */
1482             guint8 reserved = (first_byte & 0xe0) >> 5;
1483             proto_item *ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_control_plane_reserved,
1484                                                  tvb, offset, 1, ENC_BIG_ENDIAN);
1485             if (reserved != 0) {
1486                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
1487                                        "PDCP signalling header reserved bits not zero");
1488             }
1489
1490             /* 5-bit sequence number */
1491             seqnum = first_byte & 0x1f;
1492             seqnum_set = TRUE;
1493             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_5, tvb, offset, 1, ENC_BIG_ENDIAN);
1494             write_pdu_label_and_info(root_ti, pinfo, " sn=%-2u ", seqnum);
1495             offset++;
1496
1497             if (tvb_length_remaining(tvb, offset) == 0) {
1498                 /* Only PDCP header was captured, stop dissection here */
1499                 return;
1500             }
1501         }
1502         else if (p_pdcp_info->plane == USER_PLANE) {
1503
1504             /**********************************/
1505             /* User-plane messages            */
1506             gboolean pdu_type = (first_byte & 0x80) >> 7;
1507
1508             /* Data/Control flag */
1509             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_data_control, tvb, offset, 1, ENC_BIG_ENDIAN);
1510
1511             if (pdu_type == 1) {
1512                 /*****************************/
1513                 /* Use-plane Data            */
1514
1515                 /* Number of sequence number bits depends upon config */
1516                 switch (p_pdcp_info->seqnum_length) {
1517                     case PDCP_SN_LENGTH_7_BITS:
1518                         seqnum = first_byte & 0x7f;
1519                         seqnum_set = TRUE;
1520                         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_7, tvb, offset, 1, ENC_BIG_ENDIAN);
1521                         offset++;
1522                         break;
1523                     case PDCP_SN_LENGTH_12_BITS:
1524                         {
1525                             proto_item *ti;
1526                             guint8 reserved_value;
1527
1528                             /* 3 reserved bits */
1529                             ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_reserved3, tvb, offset, 1, ENC_BIG_ENDIAN);
1530                             reserved_value = (first_byte & 0x70) >> 4;
1531
1532                             /* Complain if not 0 */
1533                             if (reserved_value != 0) {
1534                                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
1535                                                        "Reserved bits have value 0x%x - should be 0x0",
1536                                                        reserved_value);
1537                             }
1538
1539                             /* 12-bit sequence number */
1540                             seqnum = tvb_get_ntohs(tvb, offset) & 0x0fff;
1541                             seqnum_set = TRUE;
1542                             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_12, tvb, offset, 2, ENC_BIG_ENDIAN);
1543                             offset += 2;
1544                         }
1545                         break;
1546                     case PDCP_SN_LENGTH_15_BITS:
1547                         seqnum = tvb_get_ntohs(tvb, offset) & 0x7fff;
1548                         seqnum_set = TRUE;
1549                         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_15, tvb, offset, 2, ENC_BIG_ENDIAN);
1550                         offset += 2;
1551                         break;
1552                     default:
1553                         /* Not a recognised data format!!!!! */
1554                         return;
1555                 }
1556
1557                 write_pdu_label_and_info(root_ti, pinfo, " (SN=%u)", seqnum);
1558             }
1559             else {
1560                 /*******************************/
1561                 /* User-plane Control messages */
1562                 guint8 control_pdu_type = (first_byte & 0x70) >> 4;
1563                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_control_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1564
1565                 switch (control_pdu_type) {
1566                     case 0:    /* PDCP status report */
1567                         {
1568                             guint8  bits;
1569                             guint16 fms;
1570                             guint16 modulo;
1571                             guint   not_received = 0;
1572                             guint   sn, i, j, l;
1573                             guint32 len, bit_offset;
1574                             proto_tree *bitmap_tree;
1575                             proto_item *bitmap_ti = NULL;
1576                             gchar  *buff = NULL;
1577                             #define BUFF_SIZE 49
1578
1579                             if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_12_BITS) {
1580                                 /* First-Missing-Sequence SN */
1581                                 fms = tvb_get_ntohs(tvb, offset) & 0x0fff;
1582                                 sn = (fms + 1) % 4096;
1583                                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_fms, tvb,
1584                                                     offset, 2, ENC_BIG_ENDIAN);
1585                                 offset += 2;
1586                                 modulo = 4096;
1587                             } else {
1588                                 proto_item *ti;
1589                                 guint8 reserved_value;
1590
1591                                 /* 5 reserved bits */
1592                                 ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_reserved4, tvb, offset, 2, ENC_BIG_ENDIAN);
1593                                 reserved_value = (tvb_get_ntohs(tvb, offset) & 0x0f80)>>7;
1594                                 offset++;
1595
1596                                 /* Complain if not 0 */
1597                                 if (reserved_value != 0) {
1598                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
1599                                                            "Reserved bits have value 0x%x - should be 0x0",
1600                                                            reserved_value);
1601                                 }
1602
1603                                 /* First-Missing-Sequence SN */
1604                                 fms = tvb_get_ntohs(tvb, offset) & 0x7fff;
1605                                 sn = (fms + 1) % 32768;
1606                                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_fms2, tvb,
1607                                                     offset, 2, ENC_BIG_ENDIAN);
1608                                 offset += 2;
1609                                 modulo = 32768;
1610                             }
1611
1612                             /* Bitmap tree */
1613                             if (tvb_length_remaining(tvb, offset) > 0) {
1614                                 bitmap_ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_bitmap, tvb,
1615                                                                 offset, -1, ENC_NA);
1616                                 bitmap_tree = proto_item_add_subtree(bitmap_ti, ett_pdcp_report_bitmap);
1617
1618                                  buff = (gchar *)wmem_alloc(wmem_packet_scope(), BUFF_SIZE);
1619                                  len = tvb_length_remaining(tvb, offset);
1620                                  bit_offset = offset<<3;
1621                                 /* For each byte... */
1622                                 for (i=0; i<len; i++) {
1623                                     bits = tvb_get_bits8(tvb, bit_offset, 8);
1624                                     for (l=0, j=0; l<8; l++) {
1625                                         if ((bits << l) & 0x80) {
1626                                             j += g_snprintf(&buff[j], BUFF_SIZE-j, "%5u,", (unsigned)(sn+(8*i)+l)%modulo);
1627                                         } else {
1628                                             j += g_snprintf(&buff[j], BUFF_SIZE-j, "     ,");
1629                                             not_received++;
1630                                         }
1631                                     }
1632                                     proto_tree_add_text(bitmap_tree, tvb, bit_offset/8, 1, "%s", buff);
1633                                     bit_offset += 8;
1634                                 }
1635                             }
1636
1637                             if (bitmap_ti != NULL) {
1638                                 proto_item_append_text(bitmap_ti, " (%u SNs not received)", not_received);
1639                             }
1640                             write_pdu_label_and_info(root_ti, pinfo, " Status Report (fms=%u) not-received=%u",
1641                                                     fms, not_received);
1642                         }
1643                         return;
1644
1645                     case 1:     /* ROHC Feedback */
1646                         offset++;
1647                         break;  /* Drop-through to dissect feedback */
1648
1649                     default:    /* Reserved */
1650                         return;
1651                 }
1652             }
1653         }
1654         else {
1655             /* Invalid plane setting...! */
1656             write_pdu_label_and_info(root_ti, pinfo, " - INVALID PLANE (%u)",
1657                                      p_pdcp_info->plane);
1658             return;
1659         }
1660
1661         /* Do sequence analysis if configured to. */
1662         if (seqnum_set) {
1663             gboolean do_analysis = FALSE;
1664
1665             switch (global_pdcp_check_sequence_numbers) {
1666                 case FALSE:
1667                     break;
1668                 case SEQUENCE_ANALYSIS_RLC_ONLY:
1669                     if ((p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) != NULL) &&
1670                         !p_pdcp_info->is_retx) {
1671                         do_analysis = TRUE;
1672                     }
1673                     break;
1674                 case SEQUENCE_ANALYSIS_PDCP_ONLY:
1675                     if (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) == NULL) {
1676                         do_analysis = TRUE;
1677                     }
1678                     break;
1679             }
1680
1681             if (do_analysis) {
1682                 checkChannelSequenceInfo(pinfo, tvb, p_pdcp_info,
1683                                          (guint16)seqnum, pdcp_tree, security_tree,
1684                                          &pdu_security_settings);
1685             }
1686         }
1687     }
1688     else {
1689         /* Show that it's a no-header PDU */
1690         write_pdu_label_and_info(root_ti, pinfo, " No-Header ");
1691     }
1692
1693     /*******************************************************/
1694     /* Now deal with the payload                           */
1695     /*******************************************************/
1696
1697     /* Check pdu_security_settings - may need to do deciphering before calling
1698        further dissectors on payload */
1699     payload_tvb = decipher_payload(tvb, pinfo, &offset, &pdu_security_settings, p_pdcp_info->plane, &payload_deciphered);
1700
1701     if (p_pdcp_info->plane == SIGNALING_PLANE) {
1702         guint32 data_length;
1703         guint32 mac;
1704
1705         /* RRC data is all but last 4 bytes.
1706            Call lte-rrc dissector (according to direction and channel type) */
1707         if ((global_pdcp_dissect_signalling_plane_as_rrc) &&
1708             ((pdu_security == NULL) || (pdu_security->ciphering == 0) || payload_deciphered || !pdu_security->seen_next_ul_pdu)){
1709             /* Get appropriate dissector handle */
1710             dissector_handle_t rrc_handle = lookup_rrc_dissector_handle(p_pdcp_info);
1711
1712             if (rrc_handle != 0) {
1713                 /* Call RRC dissector if have one */
1714                 tvbuff_t *rrc_payload_tvb = tvb_new_subset(payload_tvb, offset,
1715                                                            tvb_length_remaining(payload_tvb, offset) - 4,
1716                                                            tvb_length_remaining(payload_tvb, offset) - 4);
1717                 gboolean was_writable = col_get_writable(pinfo->cinfo);
1718
1719                 /* We always want to see this in the info column */
1720                 col_set_writable(pinfo->cinfo, TRUE);
1721
1722                 call_dissector_only(rrc_handle, rrc_payload_tvb, pinfo, pdcp_tree, NULL);
1723
1724                 /* Restore to whatever it was */
1725                 col_set_writable(pinfo->cinfo, was_writable);
1726             }
1727             else {
1728                  /* Just show data */
1729                     proto_tree_add_item(pdcp_tree, hf_pdcp_lte_signalling_data, payload_tvb, offset,
1730                                         tvb_length_remaining(tvb, offset) - 4, ENC_NA);
1731             }
1732
1733             if (!pinfo->fd->flags.visited &&
1734                 (current_security != NULL) && !current_security->seen_next_ul_pdu &&
1735                 p_pdcp_info->direction == DIRECTION_UPLINK)
1736             {
1737                 /* i.e. we have already seen SecurityModeResponse! */
1738                 current_security->seen_next_ul_pdu = TRUE;
1739             }
1740
1741         }
1742         else {
1743             /* Just show as unparsed data */
1744             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_signalling_data, payload_tvb, offset,
1745                                 tvb_length_remaining(tvb, offset) - 4, ENC_NA);
1746         }
1747
1748         data_length = tvb_length_remaining(payload_tvb, offset) - 4;
1749         offset += data_length;
1750
1751         /* Last 4 bytes are MAC */
1752         mac = tvb_get_ntohl(tvb, offset);
1753         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_mac, payload_tvb, offset, 4, ENC_BIG_ENDIAN);
1754         offset += 4;
1755
1756         col_append_fstr(pinfo->cinfo, COL_INFO, " MAC=0x%08x (%u bytes data)",
1757                         mac, data_length);
1758     }
1759     else {
1760         /* User-plane payload here */
1761
1762         /* If not compressed with ROHC, show as user-plane data */
1763         if (!p_pdcp_info->rohc.rohc_compression) {
1764             gint payload_length = tvb_length_remaining(payload_tvb, offset);
1765             if (payload_length > 0) {
1766                 if (p_pdcp_info->plane == USER_PLANE) {
1767
1768                     /* Not attempting to decode payload if ciphering is enabled
1769                        (and NULL ciphering is not being used) */
1770                     if (global_pdcp_dissect_user_plane_as_ip &&
1771                         ((pdu_security == NULL) || (pdu_security->ciphering == 0) || payload_deciphered))
1772                     {
1773                         tvbuff_t *ip_payload_tvb = tvb_new_subset_remaining(payload_tvb, offset);
1774
1775                         /* Don't update info column for ROHC unless configured to */
1776                         if (global_pdcp_lte_layer_to_show != ShowTrafficLayer) {
1777                             col_set_writable(pinfo->cinfo, FALSE);
1778                         }
1779
1780                         switch (tvb_get_guint8(ip_payload_tvb, offset) & 0xf0) {
1781                             case 0x40:
1782                                 call_dissector_only(ip_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
1783                                 break;
1784                             case 0x60:
1785                                 call_dissector_only(ipv6_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
1786                                 break;
1787                             default:
1788                                 call_dissector_only(data_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
1789                                 break;
1790                         }
1791
1792                         /* Freeze the columns again because we don't want other layers writing to info */
1793                         if (global_pdcp_lte_layer_to_show == ShowTrafficLayer) {
1794                             col_set_writable(pinfo->cinfo, FALSE);
1795                         }
1796
1797                     }
1798                     else {
1799                         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_user_plane_data, payload_tvb, offset, -1, ENC_NA);
1800                     }
1801                 }
1802
1803                 write_pdu_label_and_info(root_ti, pinfo, "(%u bytes data)",
1804                                          payload_length);
1805             }
1806
1807             /* (there will be no signalling data left at this point) */
1808
1809             /* Let RLC write to columns again */
1810             col_set_writable(pinfo->cinfo, global_pdcp_lte_layer_to_show == ShowRLCLayer);
1811
1812             /* DROPPING OUT HERE IF NOT DOING ROHC! */
1813             return;
1814         }
1815         else {
1816             /***************************/
1817             /* ROHC packets            */
1818             /***************************/
1819
1820             /* Only attempt ROHC if configured to */
1821             if (!global_pdcp_dissect_rohc) {
1822                 col_append_fstr(pinfo->cinfo, COL_PROTOCOL, "|ROHC(%s)",
1823                                 val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
1824                 return;
1825             }
1826
1827             rohc_offset = offset;
1828             rohc_tvb = tvb_new_subset_remaining(payload_tvb, rohc_offset);
1829
1830             /* Only enable writing to column if configured to show ROHC */
1831             if (global_pdcp_lte_layer_to_show != ShowTrafficLayer) {
1832                 col_set_writable(pinfo->cinfo, FALSE);
1833             }
1834             else {
1835                 col_clear(pinfo->cinfo, COL_INFO);
1836             }
1837
1838             /* Call the ROHC dissector */
1839             call_dissector_with_data(rohc_handle, rohc_tvb, pinfo, tree, &p_pdcp_info->rohc);
1840
1841             /* Let RLC write to columns again */
1842             col_set_writable(pinfo->cinfo, global_pdcp_lte_layer_to_show == ShowRLCLayer);
1843         }
1844     }
1845 }
1846
1847 /* Initializes the hash tables each time a new
1848  * file is loaded or re-loaded in wireshark */
1849 static void pdcp_lte_init_protocol(void)
1850 {
1851     /* Destroy any existing hashes. */
1852     if (pdcp_sequence_analysis_channel_hash) {
1853         g_hash_table_destroy(pdcp_sequence_analysis_channel_hash);
1854     }
1855     if (pdcp_lte_sequence_analysis_report_hash) {
1856         g_hash_table_destroy(pdcp_lte_sequence_analysis_report_hash);
1857     }
1858     if (pdcp_security_hash) {
1859         g_hash_table_destroy(pdcp_security_hash);
1860     }
1861     if (pdcp_security_result_hash) {
1862         g_hash_table_destroy(pdcp_security_result_hash);
1863     }
1864
1865     /* Now create them over */
1866     pdcp_sequence_analysis_channel_hash = g_hash_table_new(pdcp_channel_hash_func, pdcp_channel_equal);
1867     pdcp_lte_sequence_analysis_report_hash = g_hash_table_new(pdcp_result_hash_func, pdcp_result_hash_equal);
1868     pdcp_security_hash = g_hash_table_new(pdcp_lte_ueid_hash_func, pdcp_lte_ueid_hash_equal);
1869     pdcp_security_result_hash = g_hash_table_new(pdcp_lte_ueid_frame_hash_func, pdcp_lte_ueid_frame_hash_equal);
1870 }
1871
1872
1873
1874 void proto_register_pdcp(void)
1875 {
1876     static hf_register_info hf[] =
1877     {
1878         { &hf_pdcp_lte_configuration,
1879             { "Configuration",
1880               "pdcp-lte.configuration", FT_STRING, BASE_NONE, NULL, 0x0,
1881               "Configuration info passed into dissector", HFILL
1882             }
1883         },
1884
1885         { &hf_pdcp_lte_rohc_compression,
1886             { "ROHC Compression",
1887               "pdcp-lte.rohc.compression", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1888               NULL, HFILL
1889             }
1890         },
1891         { &hf_pdcp_lte_rohc_mode,
1892             { "ROHC Mode",
1893               "pdcp-lte.rohc.mode", FT_UINT8, BASE_DEC, VALS(rohc_mode_vals), 0x0,
1894               NULL, HFILL
1895             }
1896         },
1897         { &hf_pdcp_lte_rohc_rnd,
1898             { "RND",
1899               "pdcp-lte.rohc.rnd", FT_UINT8, BASE_DEC, NULL, 0x0,
1900               "RND of outer ip header", HFILL
1901             }
1902         },
1903         { &hf_pdcp_lte_rohc_udp_checksum_present,
1904             { "UDP Checksum",
1905               "pdcp-lte.rohc.checksum-present", FT_UINT8, BASE_DEC, NULL, 0x0,
1906               "UDP Checksum present", HFILL
1907             }
1908         },
1909         { &hf_pdcp_lte_direction,
1910             { "Direction",
1911               "pdcp-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
1912               "Direction of message", HFILL
1913             }
1914         },
1915         { &hf_pdcp_lte_ueid,
1916             { "UE",
1917               "pdcp-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
1918               "UE Identifier", HFILL
1919             }
1920         },
1921         { &hf_pdcp_lte_channel_type,
1922             { "Channel type",
1923               "pdcp-lte.channel-type", FT_UINT8, BASE_DEC, VALS(logical_channel_vals), 0x0,
1924               NULL, HFILL
1925             }
1926         },
1927         { &hf_pdcp_lte_channel_id,
1928             { "Channel Id",
1929               "pdcp-lte.channel-id", FT_UINT8, BASE_DEC, 0, 0x0,
1930               NULL, HFILL
1931             }
1932         },
1933         { &hf_pdcp_lte_rohc_profile,
1934             { "ROHC profile",
1935               "pdcp-lte.rohc.profile", FT_UINT8, BASE_DEC, VALS(rohc_profile_vals), 0x0,
1936               "ROHC Mode", HFILL
1937             }
1938         },
1939         { &hf_pdcp_lte_no_header_pdu,
1940             { "No Header PDU",
1941               "pdcp-lte.no-header_pdu", FT_UINT8, BASE_DEC, NULL, 0x0,
1942               NULL, HFILL
1943             }
1944         },
1945         { &hf_pdcp_lte_plane,
1946             { "Plane",
1947               "pdcp-lte.plane", FT_UINT8, BASE_DEC, VALS(pdcp_plane_vals), 0x0,
1948               NULL, HFILL
1949             }
1950         },
1951         { &hf_pdcp_lte_seqnum_length,
1952             { "Seqnum length",
1953               "pdcp-lte.seqnum_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1954               "Sequence Number Length", HFILL
1955             }
1956         },
1957
1958
1959         { &hf_pdcp_lte_cid_inclusion_info,
1960             { "CID Inclusion Info",
1961               "pdcp-lte.cid-inclusion-info", FT_UINT8, BASE_DEC, NULL, 0x0,
1962               NULL, HFILL
1963             }
1964         },
1965         { &hf_pdcp_lte_large_cid_present,
1966             { "Large CID Present",
1967               "pdcp-lte.large-cid-present", FT_UINT8, BASE_DEC, NULL, 0x0,
1968               NULL, HFILL
1969             }
1970         },
1971
1972         { &hf_pdcp_lte_control_plane_reserved,
1973             { "Reserved",
1974               "pdcp-lte.reserved", FT_UINT8, BASE_DEC, NULL, 0xe0,
1975               NULL, HFILL
1976             }
1977         },
1978         { &hf_pdcp_lte_seq_num_5,
1979             { "Seq Num",
1980               "pdcp-lte.seq-num", FT_UINT8, BASE_DEC, NULL, 0x1f,
1981               "PDCP Seq num", HFILL
1982             }
1983         },
1984         { &hf_pdcp_lte_seq_num_7,
1985             { "Seq Num",
1986               "pdcp-lte.seq-num", FT_UINT8, BASE_DEC, NULL, 0x7f,
1987               "PDCP Seq num", HFILL
1988             }
1989         },
1990         { &hf_pdcp_lte_reserved3,
1991             { "Reserved",
1992               "pdcp-lte.reserved3", FT_UINT8, BASE_HEX, NULL, 0x70,
1993               "3 reserved bits", HFILL
1994             }
1995         },
1996         { &hf_pdcp_lte_seq_num_12,
1997             { "Seq Num",
1998               "pdcp-lte.seq-num", FT_UINT16, BASE_DEC, NULL, 0x0fff,
1999               "PDCP Seq num", HFILL
2000             }
2001         },
2002         { &hf_pdcp_lte_seq_num_15,
2003             { "Seq Num",
2004               "pdcp-lte.seq-num", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2005               "PDCP Seq num", HFILL
2006             }
2007         },
2008         { &hf_pdcp_lte_signalling_data,
2009             { "Signalling Data",
2010               "pdcp-lte.signalling-data", FT_BYTES, BASE_NONE, NULL, 0x0,
2011               NULL, HFILL
2012             }
2013         },
2014         { &hf_pdcp_lte_mac,
2015             { "MAC",
2016               "pdcp-lte.mac", FT_UINT32, BASE_HEX_DEC, NULL, 0x0,
2017               NULL, HFILL
2018             }
2019         },
2020         { &hf_pdcp_lte_data_control,
2021             { "PDU Type",
2022               "pdcp-lte.pdu-type", FT_UINT8, BASE_HEX, VALS(pdu_type_vals), 0x80,
2023               NULL, HFILL
2024             }
2025         },
2026         { &hf_pdcp_lte_user_plane_data,
2027             { "User-Plane Data",
2028               "pdcp-lte.user-data", FT_BYTES, BASE_NONE, NULL, 0x0,
2029               NULL, HFILL
2030             }
2031         },
2032         { &hf_pdcp_lte_control_pdu_type,
2033             { "Control PDU Type",
2034               "pdcp-lte.control-pdu-type", FT_UINT8, BASE_HEX, VALS(control_pdu_type_vals), 0x70,
2035               NULL, HFILL
2036             }
2037         },
2038         { &hf_pdcp_lte_fms,
2039             { "First Missing Sequence Number",
2040               "pdcp-lte.fms", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2041               "First Missing PDCP Sequence Number", HFILL
2042             }
2043         },
2044         { &hf_pdcp_lte_reserved4,
2045             { "Reserved",
2046               "pdcp-lte.reserved4", FT_UINT16, BASE_HEX, NULL, 0x0f80,
2047               "5 reserved bits", HFILL
2048             }
2049         },
2050         { &hf_pdcp_lte_fms2,
2051             { "First Missing Sequence Number",
2052               "pdcp-lte.fms", FT_UINT16, BASE_DEC, NULL, 0x07fff,
2053               "First Missing PDCP Sequence Number", HFILL
2054             }
2055         },
2056         { &hf_pdcp_lte_bitmap,
2057             { "Bitmap",
2058               "pdcp-lte.bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
2059               "Status report bitmap (0=error, 1=OK)", HFILL
2060             }
2061         },
2062
2063
2064         { &hf_pdcp_lte_sequence_analysis,
2065             { "Sequence Analysis",
2066               "pdcp-lte.sequence-analysis", FT_STRING, BASE_NONE, 0, 0x0,
2067               NULL, HFILL
2068             }
2069         },
2070         { &hf_pdcp_lte_sequence_analysis_ok,
2071             { "OK",
2072               "pdcp-lte.sequence-analysis.ok", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2073               NULL, HFILL
2074             }
2075         },
2076         { &hf_pdcp_lte_sequence_analysis_previous_frame,
2077             { "Previous frame for channel",
2078               "pdcp-lte.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2079               NULL, HFILL
2080             }
2081         },
2082         { &hf_pdcp_lte_sequence_analysis_next_frame,
2083             { "Next frame for channel",
2084               "pdcp-lte.sequence-analysis.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2085               NULL, HFILL
2086             }
2087         },
2088         { &hf_pdcp_lte_sequence_analysis_expected_sn,
2089             { "Expected SN",
2090               "pdcp-lte.sequence-analysis.expected-sn", FT_UINT16, BASE_DEC, 0, 0x0,
2091               NULL, HFILL
2092             }
2093         },
2094         { &hf_pdcp_lte_sequence_analysis_skipped,
2095             { "Skipped frames",
2096               "pdcp-lte.sequence-analysis.skipped-frames", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2097               NULL, HFILL
2098             }
2099         },
2100         { &hf_pdcp_lte_sequence_analysis_repeated,
2101             { "Repeated frame",
2102               "pdcp-lte.sequence-analysis.repeated-frame", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2103               NULL, HFILL
2104             }
2105         },
2106
2107         { &hf_pdcp_lte_security,
2108             { "Security Config",
2109               "pdcp-lte.security-cofig", FT_STRING, BASE_NONE, 0, 0x0,
2110               NULL, HFILL
2111             }
2112         },
2113         { &hf_pdcp_lte_security_setup_frame,
2114             { "Configuration frame",
2115               "pdcp-lte.security-config.setup-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2116               NULL, HFILL
2117             }
2118         },
2119         { &hf_pdcp_lte_security_integrity_algorithm,
2120             { "Integrity Algorithm",
2121               "pdcp-lte.security-config.integrity", FT_UINT16, BASE_DEC, VALS(integrity_algorithm_vals), 0x0,
2122               NULL, HFILL
2123             }
2124         },
2125         { &hf_pdcp_lte_security_ciphering_algorithm,
2126             { "Ciphering Algorithm",
2127               "pdcp-lte.security-config.ciphering", FT_UINT16, BASE_DEC, VALS(ciphering_algorithm_vals), 0x0,
2128               NULL, HFILL
2129             }
2130         },
2131         { &hf_pdcp_lte_security_bearer,
2132             { "BEARER",
2133               "pdcp-lte.security-config.bearer", FT_UINT8, BASE_DEC, NULL, 0x0,
2134               NULL, HFILL
2135             }
2136         },
2137         { &hf_pdcp_lte_security_direction,
2138             { "DIRECTION",
2139               "pdcp-lte.security-config.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
2140               NULL, HFILL
2141             }
2142         },
2143         { &hf_pdcp_lte_security_count,
2144             { "COUNT",
2145               "pdcp-lte.security-config.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2146               NULL, HFILL
2147             }
2148         },
2149         { &hf_pdcp_lte_security_key,
2150             { "KEY",
2151               "pdcp-lte.security-config.key", FT_STRING, BASE_NONE, NULL, 0x0,
2152               NULL, HFILL
2153             }
2154         },
2155     };
2156
2157     static gint *ett[] =
2158     {
2159         &ett_pdcp,
2160         &ett_pdcp_configuration,
2161         &ett_pdcp_packet,
2162         &ett_pdcp_lte_sequence_analysis,
2163         &ett_pdcp_report_bitmap,
2164         &ett_pdcp_security
2165     };
2166
2167     static ei_register_info ei[] = {
2168         { &ei_pdcp_lte_sequence_analysis_sn_missing, { "pdcp-lte.sequence-analysis.sn-missing", PI_SEQUENCE, PI_WARN, "PDCP SN missing", EXPFILL }},
2169         { &ei_pdcp_lte_sequence_analysis_sn_repeated, { "pdcp-lte.sequence-analysis.sn-repeated", PI_SEQUENCE, PI_WARN, "PDCP SN repeated", EXPFILL }},
2170         { &ei_pdcp_lte_sequence_analysis_wrong_sequence_number, { "pdcp-lte.sequence-analysis.wrong-sequence-number", PI_SEQUENCE, PI_WARN, "Wrong Sequence Number", EXPFILL }},
2171         { &ei_pdcp_lte_reserved_bits_not_zero, { "pdcp-lte.reserved-bits-not-zero", PI_MALFORMED, PI_ERROR, "Reserved bits not zero", EXPFILL }},
2172     };
2173
2174     static const enum_val_t sequence_analysis_vals[] = {
2175         {"no-analysis", "No-Analysis",      FALSE},
2176         {"rlc-only",    "Only-RLC-frames",  SEQUENCE_ANALYSIS_RLC_ONLY},
2177         {"pdcp-only",   "Only-PDCP-frames", SEQUENCE_ANALYSIS_PDCP_ONLY},
2178         {NULL, NULL, -1}
2179     };
2180
2181     static const enum_val_t show_info_col_vals[] = {
2182         {"show-rlc", "RLC Info", ShowRLCLayer},
2183         {"show-pdcp", "PDCP Info", ShowPDCPLayer},
2184         {"show-traffic", "Traffic Info", ShowTrafficLayer},
2185         {NULL, NULL, -1}
2186     };
2187
2188 #ifdef HAVE_LIBGCRYPT
2189   static uat_field_t ue_keys_uat_flds[] = {
2190       UAT_FLD_DEC(uat_ue_keys_records, ueid, "UEId", "UE Identifier of UE associated with keys"),
2191       UAT_FLD_CSTRING(uat_ue_keys_records, rrcKeyString, "RRC Key",        "Key for deciphering signalling messages"),
2192       UAT_FLD_CSTRING(uat_ue_keys_records, upKeyString,  "User-Plane Key", "Key for deciphering user-plane messages"),
2193       UAT_END_FIELDS
2194     };
2195 #endif
2196
2197     module_t *pdcp_lte_module;
2198     expert_module_t* expert_pdcp_lte;
2199
2200     /* Register protocol. */
2201     proto_pdcp_lte = proto_register_protocol("PDCP-LTE", "PDCP-LTE", "pdcp-lte");
2202     proto_register_field_array(proto_pdcp_lte, hf, array_length(hf));
2203     proto_register_subtree_array(ett, array_length(ett));
2204     expert_pdcp_lte = expert_register_protocol(proto_pdcp_lte);
2205     expert_register_field_array(expert_pdcp_lte, ei, array_length(ei));
2206
2207     /* Allow other dissectors to find this one by name. */
2208     register_dissector("pdcp-lte", dissect_pdcp_lte, proto_pdcp_lte);
2209
2210     pdcp_lte_module = prefs_register_protocol(proto_pdcp_lte, NULL);
2211
2212     /* Obsolete preferences */
2213     prefs_register_obsolete_preference(pdcp_lte_module, "show_feedback_option_tag_length");
2214
2215
2216     /* Dissect uncompressed user-plane data as IP */
2217     prefs_register_bool_preference(pdcp_lte_module, "show_user_plane_as_ip",
2218         "Show uncompressed User-Plane data as IP",
2219         "Show uncompressed User-Plane data as IP",
2220         &global_pdcp_dissect_user_plane_as_ip);
2221
2222     /* Dissect unciphered signalling data as RRC */
2223     prefs_register_bool_preference(pdcp_lte_module, "show_signalling_plane_as_rrc",
2224         "Show unciphered Signalling-Plane data as RRC",
2225         "Show unciphered Signalling-Plane data as RRC",
2226         &global_pdcp_dissect_signalling_plane_as_rrc);
2227
2228     /* Check for missing sequence numbers */
2229     prefs_register_enum_preference(pdcp_lte_module, "check_sequence_numbers",
2230         "Do sequence number analysis",
2231         "Do sequence number analysis",
2232         &global_pdcp_check_sequence_numbers, sequence_analysis_vals, FALSE);
2233
2234     /* Attempt to dissect ROHC messages */
2235     prefs_register_bool_preference(pdcp_lte_module, "dissect_rohc",
2236         "Attempt to decode ROHC data",
2237         "Attempt to decode ROHC data",
2238         &global_pdcp_dissect_rohc);
2239
2240     prefs_register_bool_preference(pdcp_lte_module, "heuristic_pdcp_lte_over_udp",
2241         "Try Heuristic LTE-PDCP over UDP framing",
2242         "When enabled, use heuristic dissector to find PDCP-LTE frames sent with "
2243         "UDP framing",
2244         &global_pdcp_lte_heur);
2245
2246     prefs_register_enum_preference(pdcp_lte_module, "layer_to_show",
2247         "Which layer info to show in Info column",
2248         "Can show RLC, PDCP or Traffic layer info in Info column",
2249         &global_pdcp_lte_layer_to_show, show_info_col_vals, FALSE);
2250
2251 #ifdef HAVE_LIBGCRYPT
2252     ue_keys_uat = uat_new("PDCP UE security keys",
2253               sizeof(uat_ue_keys_record_t),    /* record size */
2254               "pdcp_lte_ue_keys",              /* filename */
2255               TRUE,                            /* from_profile */
2256               (void**) &uat_ue_keys_records,   /* data_ptr */
2257               &num_ue_keys_uat,                /* numitems_ptr */
2258               UAT_AFFECTS_DISSECTION,          /* affects dissection of packets, but not set of named fields */
2259               NULL,                            /* help */
2260               uat_ue_keys_record_copy_cb,      /* copy callback */
2261               uat_ue_keys_record_update_cb,    /* update callback */
2262               uat_ue_keys_record_free_cb,      /* free callback */
2263               NULL,                            /* post update callback */
2264               ue_keys_uat_flds);               /* UAT field definitions */
2265
2266     prefs_register_uat_preference(pdcp_lte_module,
2267                                   "ue_keys_table",
2268                                   "PDCP UE Keys",
2269                                   "Preconfigured PDCP keys",
2270                                   ue_keys_uat);
2271
2272     /* Attempt to decipher RRC messages */
2273     prefs_register_bool_preference(pdcp_lte_module, "decipher_signalling",
2274         "Attempt to decipher Signalling (RRC) SDUs",
2275         "N.B. only possible if key available and configured",
2276         &global_pdcp_decipher_signalling);
2277
2278     /* Attempt to decipher user-plane messages */
2279     prefs_register_bool_preference(pdcp_lte_module, "decipher_userplane",
2280         "Attempt to decipher User-plane (IP) SDUs",
2281         "N.B. only possible if key available and configured",
2282         &global_pdcp_decipher_userplane);
2283 #endif
2284
2285     register_init_routine(&pdcp_lte_init_protocol);
2286 }
2287
2288 void proto_reg_handoff_pdcp_lte(void)
2289 {
2290     /* Add as a heuristic UDP dissector */
2291     heur_dissector_add("udp", dissect_pdcp_lte_heur, proto_pdcp_lte);
2292
2293     ip_handle   = find_dissector("ip");
2294     ipv6_handle = find_dissector("ipv6");
2295     rohc_handle = find_dissector("rohc");
2296     data_handle = find_dissector("data");
2297 }
2298
2299 /*
2300  * Editor modelines
2301  *
2302  * Local Variables:
2303  * c-basic-offset: 4
2304  * tab-width: 8
2305  * indent-tabs-mode: nil
2306  * End:
2307  *
2308  * ex: set shiftwidth=4 tabstop=8 expandtab:
2309  * :indentSize=4:tabSize=8:noTabs=true:
2310  */