1 /* packet-pdcp-lte.c
2  * Routines for LTE PDCP
3  *
4  * Martin Mathieson
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "config.h"
14 
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
18 #include <epan/uat.h>
19 #include <epan/proto_data.h>
20 
21 #include <wsutil/wsgcrypt.h>
22 #include <wsutil/report_message.h>
23 
24 /* Define these symbols if you have working implementations of SNOW3G/ZUC f8() and f9() available.
25    Note that the use of these algorithms is restricted, so a version of Wireshark with these
26    ciphering algorithms enabled would not be distributable. */
27 
28 /* #define HAVE_SNOW3G */
29 /* #define HAVE_ZUC */
30 
31 #include "packet-rlc-lte.h"
32 #include "packet-pdcp-lte.h"
33 
34 void proto_register_pdcp_lte(void);
35 void proto_reg_handoff_pdcp_lte(void);
36 
37 /* Described in:
38  * 3GPP TS 36.323 Evolved Universal Terrestrial Radio Access (E-UTRA)
39  *                Packet Data Convergence Protocol (PDCP) specification v14.3.0
40  */
41 
42 
43 /* TODO:
44    - Decipher even if sequence analysis isn't 'OK'?
45       - know SN, but might be unsure about HFN.
46    - Speed up AES decryption by keeping the crypt handle around for the channel
47      (like ESP decryption in IPSEC dissector).  N.B. do lazily when it needs to be used.
48      CTR will need to be applied before each frame.
49    - Add Relay Node user plane data PDU dissection
50    - Add SLRB user data plane data PDU dissection
51    - Break out security and sequence analysis into a separate common file to be
52      shared with pdcp-nr
53 */
54 
55 
56 /* Initialize the protocol and registered fields. */
57 int proto_pdcp_lte = -1;
58 
59 extern int proto_rlc_lte;
60 
61 /* Configuration (info known outside of PDU) */
62 static int hf_pdcp_lte_configuration = -1;
63 static int hf_pdcp_lte_direction = -1;
64 static int hf_pdcp_lte_ueid = -1;
65 static int hf_pdcp_lte_channel_type = -1;
66 static int hf_pdcp_lte_channel_id = -1;
67 
68 static int hf_pdcp_lte_rohc_compression = -1;
69 static int hf_pdcp_lte_rohc_mode = -1;
70 static int hf_pdcp_lte_rohc_rnd = -1;
71 static int hf_pdcp_lte_rohc_udp_checksum_present = -1;
72 static int hf_pdcp_lte_rohc_profile = -1;
73 
74 static int hf_pdcp_lte_no_header_pdu = -1;
75 static int hf_pdcp_lte_plane = -1;
76 static int hf_pdcp_lte_seqnum_length = -1;
77 static int hf_pdcp_lte_cid_inclusion_info = -1;
78 static int hf_pdcp_lte_large_cid_present = -1;
79 
80 /* PDCP header fields */
81 static int hf_pdcp_lte_control_plane_reserved = -1;
82 static int hf_pdcp_lte_seq_num_5 = -1;
83 static int hf_pdcp_lte_seq_num_7 = -1;
84 static int hf_pdcp_lte_reserved3 = -1;
85 static int hf_pdcp_lte_seq_num_12 = -1;
86 static int hf_pdcp_lte_seq_num_15 = -1;
87 static int hf_pdcp_lte_polling = -1;
88 static int hf_pdcp_lte_reserved5 = -1;
89 static int hf_pdcp_lte_seq_num_18 = -1;
90 static int hf_pdcp_lte_signalling_data = -1;
91 static int hf_pdcp_lte_mac = -1;
92 static int hf_pdcp_lte_data_control = -1;
93 static int hf_pdcp_lte_user_plane_data = -1;
94 static int hf_pdcp_lte_control_pdu_type = -1;
95 static int hf_pdcp_lte_fms = -1;
96 static int hf_pdcp_lte_reserved4 = -1;
97 static int hf_pdcp_lte_fms2 = -1;
98 static int hf_pdcp_lte_reserved6 = -1;
99 static int hf_pdcp_lte_fms3 = -1;
100 static int hf_pdcp_lte_bitmap = -1;
101 static int hf_pdcp_lte_bitmap_byte = -1;
102 static int hf_pdcp_lte_hrw = -1;
103 static int hf_pdcp_lte_nmp = -1;
104 static int hf_pdcp_lte_reserved7 = -1;
105 static int hf_pdcp_lte_hrw2 = -1;
106 static int hf_pdcp_lte_nmp2 = -1;
107 static int hf_pdcp_lte_hrw3 = -1;
108 static int hf_pdcp_lte_reserved8 = -1;
109 static int hf_pdcp_lte_nmp3 = -1;
110 static int hf_pdcp_lte_lsn = -1;
111 static int hf_pdcp_lte_lsn2 = -1;
112 static int hf_pdcp_lte_lsn3 = -1;
113 
114 /* Sequence Analysis */
115 static int hf_pdcp_lte_sequence_analysis = -1;
116 static int hf_pdcp_lte_sequence_analysis_ok = -1;
117 static int hf_pdcp_lte_sequence_analysis_previous_frame = -1;
118 static int hf_pdcp_lte_sequence_analysis_next_frame = -1;
119 static int hf_pdcp_lte_sequence_analysis_expected_sn = -1;
120 
121 static int hf_pdcp_lte_sequence_analysis_repeated = -1;
122 static int hf_pdcp_lte_sequence_analysis_skipped = -1;
123 
124 /* Security Settings */
125 static int hf_pdcp_lte_security = -1;
126 static int hf_pdcp_lte_security_setup_frame = -1;
127 static int hf_pdcp_lte_security_integrity_algorithm = -1;
128 static int hf_pdcp_lte_security_ciphering_algorithm = -1;
129 
130 static int hf_pdcp_lte_security_bearer = -1;
131 static int hf_pdcp_lte_security_direction = -1;
132 static int hf_pdcp_lte_security_count = -1;
133 static int hf_pdcp_lte_security_cipher_key = -1;
134 static int hf_pdcp_lte_security_integrity_key = -1;
135 
136 
137 
138 /* Protocol subtree. */
139 static int ett_pdcp = -1;
140 static int ett_pdcp_configuration = -1;
141 static int ett_pdcp_packet = -1;
142 static int ett_pdcp_lte_sequence_analysis = -1;
143 static int ett_pdcp_report_bitmap = -1;
144 static int ett_pdcp_security = -1;
145 
146 static expert_field ei_pdcp_lte_sequence_analysis_wrong_sequence_number = EI_INIT;
147 static expert_field ei_pdcp_lte_reserved_bits_not_zero = EI_INIT;
148 static expert_field ei_pdcp_lte_sequence_analysis_sn_repeated = EI_INIT;
149 static expert_field ei_pdcp_lte_sequence_analysis_sn_missing = EI_INIT;
150 static expert_field ei_pdcp_lte_digest_wrong = EI_INIT;
151 static expert_field ei_pdcp_lte_unknown_udp_framing_tag = EI_INIT;
152 static expert_field ei_pdcp_lte_missing_udp_framing_tag = EI_INIT;
153 
154 
155 /*-------------------------------------
156  * UAT for UE Keys
157  *-------------------------------------
158  */
159 /* UAT entry structure. */
160 typedef struct {
161    guint32 ueid;
162    gchar   *rrcCipherKeyString;
163    gchar   *upCipherKeyString;
164    gchar   *rrcIntegrityKeyString;
165 
166    guint8   rrcCipherBinaryKey[16];
167    gboolean rrcCipherKeyOK;
168    guint8   upCipherBinaryKey[16];
169    gboolean upCipherKeyOK;
170    guint8   rrcIntegrityBinaryKey[16];
171    gboolean rrcIntegrityKeyOK;
172 } uat_ue_keys_record_t;
173 
174 /* N.B. this is an array/table of the struct above, where ueid is the key */
175 static uat_ue_keys_record_t *uat_ue_keys_records = NULL;
176 
177 /* Entries added by UAT */
178 static uat_t * ue_keys_uat = NULL;
179 static guint num_ue_keys_uat = 0;
180 
181 /* Convert an ascii hex character into a digit.  Should only be given valid
182    hex ascii characters */
hex_ascii_to_binary(gchar c)183 static guchar hex_ascii_to_binary(gchar c)
184 {
185     if ((c >= '0') && (c <= '9')) {
186         return c - '0';
187     }
188     else if ((c >= 'a') && (c <= 'f')) {
189         return 10 + c - 'a';
190     }
191     else if ((c >= 'A') && (c <= 'F')) {
192         return 10 + c - 'A';
193     }
194     else {
195         return 0;
196     }
197 }
198 
uat_ue_keys_record_copy_cb(void * n,const void * o,size_t siz _U_)199 static void* uat_ue_keys_record_copy_cb(void* n, const void* o, size_t siz _U_) {
200     uat_ue_keys_record_t* new_rec = (uat_ue_keys_record_t *)n;
201     const uat_ue_keys_record_t* old_rec = (const uat_ue_keys_record_t *)o;
202 
203     new_rec->ueid = old_rec->ueid;
204     new_rec->rrcCipherKeyString = g_strdup(old_rec->rrcCipherKeyString);
205     new_rec->upCipherKeyString = g_strdup(old_rec->upCipherKeyString);
206     new_rec->rrcIntegrityKeyString = g_strdup(old_rec->rrcIntegrityKeyString);
207 
208     return new_rec;
209 }
210 
211 /* If raw_string is a valid key, set check_string & return TRUE.  Can be spaced out with ' ' or '-' */
check_valid_key_string(const char * raw_string,char * checked_string,char ** error)212 static gboolean check_valid_key_string(const char* raw_string, char* checked_string, char **error)
213 {
214     guint n;
215     guint written = 0;
216     guint length = (gint)strlen(raw_string);
217 
218     /* Can't be valid if not long enough. */
219     if (length < 32) {
220         if (length > 0) {
221             *error = g_strdup_printf("PDCP LTE: Invalid key string (%s) - should include 32 ASCII hex characters (16 bytes) but only %u chars given",
222                                      raw_string, length);
223         }
224 
225         return FALSE;
226     }
227 
228     for (n=0; (n < length) && (written < 32); n++) {
229         char c = raw_string[n];
230 
231         /* Skipping past allowed 'padding' characters */
232         if ((c == ' ') || (c == '-')) {
233             continue;
234         }
235 
236         /* Other characters must be hex digits, otherwise string is invalid */
237         if (((c >= '0') && (c <= '9')) ||
238             ((c >= 'a') && (c <= 'f')) ||
239             ((c >= 'A') && (c <= 'F'))) {
240             checked_string[written++] = c;
241         }
242         else {
243             *error = g_strdup_printf("PDCP-LTE: Invalid char '%c' given in key", c);
244             return FALSE;
245         }
246     }
247 
248     /* Must have found exactly 32 hex ascii chars for 16-byte key */
249     if (n<length) {
250         *error = g_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but more detected", raw_string);
251         return FALSE;
252     }
253     if (written != 32) {
254         *error = g_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but %u detected", raw_string, written);
255         return FALSE;
256     }
257     else {
258         return TRUE;
259     }
260 
261 }
262 
263 /* Write binary key by converting each nibble from the string version */
update_key_from_string(const char * stringKey,guint8 * binaryKey,gboolean * pKeyOK,char ** error)264 static void update_key_from_string(const char *stringKey, guint8 *binaryKey, gboolean *pKeyOK, char **error)
265 {
266     int  n;
267     char cleanString[32];
268 
269     if (!check_valid_key_string(stringKey, cleanString, error)) {
270         *pKeyOK = FALSE;
271     }
272     else {
273         for (n=0; n < 32; n += 2) {
274             binaryKey[n/2] = (hex_ascii_to_binary(cleanString[n]) << 4) +
275                               hex_ascii_to_binary(cleanString[n+1]);
276         }
277         *pKeyOK = TRUE;
278     }
279 }
280 
281 /* Update by checking whether the 3 key strings are valid or not, and storing result */
uat_ue_keys_record_update_cb(void * record,char ** error)282 static gboolean uat_ue_keys_record_update_cb(void* record, char** error) {
283     uat_ue_keys_record_t* rec = (uat_ue_keys_record_t *)record;
284 
285     /* Check and convert RRC key */
286     update_key_from_string(rec->rrcCipherKeyString, rec->rrcCipherBinaryKey, &rec->rrcCipherKeyOK, error);
287 
288     /* Check and convert User-plane key */
289     update_key_from_string(rec->upCipherKeyString, rec->upCipherBinaryKey, &rec->upCipherKeyOK, error);
290 
291     /* Check and convert Integrity key */
292     update_key_from_string(rec->rrcIntegrityKeyString, rec->rrcIntegrityBinaryKey, &rec->rrcIntegrityKeyOK, error);
293 
294     /* Return TRUE only if *error has not been set by checking code. */
295     return *error == NULL;
296 }
297 
298 /* Free heap parts of record */
uat_ue_keys_record_free_cb(void * r)299 static void uat_ue_keys_record_free_cb(void*r) {
300     uat_ue_keys_record_t* rec = (uat_ue_keys_record_t*)r;
301 
302     g_free(rec->rrcCipherKeyString);
303     g_free(rec->upCipherKeyString);
304     g_free(rec->rrcIntegrityKeyString);
305 }
306 
307 UAT_DEC_CB_DEF(uat_ue_keys_records, ueid, uat_ue_keys_record_t)
308 UAT_CSTRING_CB_DEF(uat_ue_keys_records, rrcCipherKeyString, uat_ue_keys_record_t)
309 UAT_CSTRING_CB_DEF(uat_ue_keys_records, upCipherKeyString,  uat_ue_keys_record_t)
310 UAT_CSTRING_CB_DEF(uat_ue_keys_records, rrcIntegrityKeyString,  uat_ue_keys_record_t)
311 
312 
313 /* Also supporting a hash table with entries from these functions */
314 
315 /* Table from ueid -> uat_ue_keys_record_t* */
316 static wmem_map_t *pdcp_security_key_hash = NULL;
317 
318 
set_pdcp_lte_rrc_ciphering_key(guint16 ueid,const char * key)319 void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key)
320 {
321     char *err = NULL;
322 
323     /* Get or create struct for this UE */
324     uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
325                                                                               GUINT_TO_POINTER((guint)ueid));
326     if (key_record == NULL) {
327         /* Create and add to table */
328         key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
329         key_record->ueid = ueid;
330         wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
331     }
332 
333     /* Check and convert RRC key */
334     key_record->rrcCipherKeyString = g_strdup(key);
335     update_key_from_string(key_record->rrcCipherKeyString, key_record->rrcCipherBinaryKey, &key_record->rrcCipherKeyOK, &err);
336     if (err) {
337         report_failure("%s: (RRC Ciphering Key)", err);
338         g_free(err);
339     }
340 }
341 
set_pdcp_lte_rrc_integrity_key(guint16 ueid,const char * key)342 void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key)
343 {
344     char *err = NULL;
345 
346     /* Get or create struct for this UE */
347     uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
348                                                                               GUINT_TO_POINTER((guint)ueid));
349     if (key_record == NULL) {
350         /* Create and add to table */
351         key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
352         key_record->ueid = ueid;
353         wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
354     }
355 
356     /* Check and convert RRC integrity key */
357     key_record->rrcIntegrityKeyString = g_strdup(key);
358     update_key_from_string(key_record->rrcIntegrityKeyString, key_record->rrcIntegrityBinaryKey, &key_record->rrcIntegrityKeyOK, &err);
359     if (err) {
360         report_failure("%s: (RRC Integrity Key)", err);
361         g_free(err);
362     }
363 }
364 
set_pdcp_lte_up_ciphering_key(guint16 ueid,const char * key)365 void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key)
366 {
367     char *err = NULL;
368 
369     /* Get or create struct for this UE */
370     uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
371                                                                               GUINT_TO_POINTER((guint)ueid));
372     if (key_record == NULL) {
373         /* Create and add to table */
374         key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
375         key_record->ueid = ueid;
376         wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
377     }
378 
379     /* Check and convert UP key */
380     key_record->upCipherKeyString = g_strdup(key);
381     update_key_from_string(key_record->upCipherKeyString, key_record->upCipherBinaryKey, &key_record->upCipherKeyOK, &err);
382     if (err) {
383         report_failure("%s: (UserPlane Ciphering Key)", err);
384         g_free(err);
385     }
386 }
387 
388 
389 /* Preference settings for deciphering and integrity checking. */
390 static gboolean global_pdcp_decipher_signalling = TRUE;
391 static gboolean global_pdcp_decipher_userplane = FALSE;  /* Can be slow, so default to FALSE */
392 static gboolean global_pdcp_check_integrity = TRUE;
393 static gboolean global_pdcp_ignore_sec = FALSE;          /* Ignore Set Security Algo calls */
394 
395 /* Use these values where we know the keys but may have missed the algorithm,
396    e.g. when handing over and RRCReconfigurationRequest goes to target cell only */
397 static enum lte_security_ciphering_algorithm_e global_default_ciphering_algorithm = eea0;
398 static enum lte_security_integrity_algorithm_e global_default_integrity_algorithm = eia0;
399 
400 
401 static const value_string direction_vals[] =
402 {
403     { DIRECTION_UPLINK,      "Uplink"},
404     { DIRECTION_DOWNLINK,    "Downlink"},
405     { 0, NULL }
406 };
407 
408 
409 static const value_string pdcp_plane_vals[] = {
410     { SIGNALING_PLANE,    "Signalling" },
411     { USER_PLANE,         "User" },
412     { 0,   NULL }
413 };
414 
415 static const value_string logical_channel_vals[] = {
416     { Channel_DCCH,  "DCCH"},
417     { Channel_BCCH,  "BCCH"},
418     { Channel_CCCH,  "CCCH"},
419     { Channel_PCCH,  "PCCH"},
420     { 0,             NULL}
421 };
422 
423 static const value_string rohc_mode_vals[] = {
424     { UNIDIRECTIONAL,            "Unidirectional" },
425     { OPTIMISTIC_BIDIRECTIONAL,  "Optimistic Bidirectional" },
426     { RELIABLE_BIDIRECTIONAL,    "Reliable Bidirectional" },
427     { 0,   NULL }
428 };
429 
430 
431 /* Values taken from:
432    http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.txt */
433 static const value_string rohc_profile_vals[] = {
434     { 0x0000,   "ROHC uncompressed" },      /* [RFC5795] */
435     { 0x0001,   "ROHC RTP" },               /* [RFC3095] */
436     { 0x0002,   "ROHC UDP" },               /* [RFC3095] */
437     { 0x0003,   "ROHC ESP" },               /* [RFC3095] */
438     { 0x0004,   "ROHC IP" },                /* [RFC3843] */
439     { 0x0005,   "ROHC LLA" },               /* [RFC4362] */
440     { 0x0006,   "ROHC TCP" },               /* [RFC4996] */
441     { 0x0007,   "ROHC RTP/UDP-Lite" },      /* [RFC4019] */
442     { 0x0008,   "ROHC UDP-Lite" },          /* [RFC4019] */
443     { 0x0101,   "ROHCv2 RTP" },             /* [RFC5225] */
444     { 0x0102,   "ROHCv2 UDP" },             /* [RFC5225] */
445     { 0x0103,   "ROHCv2 ESP" },             /* [RFC5225] */
446     { 0x0104,   "ROHCv2 IP" },              /* [RFC5225] */
447     { 0x0105,   "ROHC LLA with R-mode" },   /* [RFC3408] */
448     { 0x0107,   "ROHCv2 RTP/UDP-Lite" },    /* [RFC5225] */
449     { 0x0108,   "ROHCv2 UDP-Lite" },        /* [RFC5225] */
450     { 0,   NULL }
451 };
452 
453 static const true_false_string pdu_type_bit = {
454     "Data PDU",
455     "Control PDU"
456 };
457 
458 static const value_string control_pdu_type_vals[] = {
459     { 0,   "PDCP status report" },
460     { 1,   "Interspersed ROHC feedback packet" },
461     { 2,   "LWA status report" },
462     { 3,   "LWA end-marker packet"},
463     { 0,   NULL }
464 };
465 
466 static const value_string integrity_algorithm_vals[] = {
467     { eia0,   "EIA0 (NULL)" },
468     { eia1,   "EIA1 (SNOW3G)" },
469     { eia2,   "EIA2 (AES)" },
470     { eia3,   "EIA3 (ZUC)" },
471     { 0,   NULL }
472 };
473 
474 static const value_string ciphering_algorithm_vals[] = {
475     { eea0,   "EEA0 (NULL)" },
476     { eea1,   "EEA1 (SNOW3G)" },
477     { eea2,   "EEA2 (AES)" },
478     { eea3,   "EEA3 (ZUC)" },
479     { 0,   NULL }
480 };
481 
482 
483 static dissector_handle_t ip_handle;
484 static dissector_handle_t ipv6_handle;
485 static dissector_handle_t rohc_handle;
486 static dissector_handle_t lte_rrc_ul_ccch;
487 static dissector_handle_t lte_rrc_dl_ccch;
488 static dissector_handle_t lte_rrc_pcch;
489 static dissector_handle_t lte_rrc_bcch_bch;
490 static dissector_handle_t lte_rrc_bcch_dl_sch;
491 static dissector_handle_t lte_rrc_ul_dcch;
492 static dissector_handle_t lte_rrc_dl_dcch;
493 static dissector_handle_t lte_rrc_ul_ccch_nb;
494 static dissector_handle_t lte_rrc_dl_ccch_nb;
495 static dissector_handle_t lte_rrc_pcch_nb;
496 static dissector_handle_t lte_rrc_bcch_bch_nb;
497 static dissector_handle_t lte_rrc_bcch_dl_sch_nb;
498 static dissector_handle_t lte_rrc_ul_dcch_nb;
499 static dissector_handle_t lte_rrc_dl_dcch_nb;
500 
501 
502 #define SEQUENCE_ANALYSIS_RLC_ONLY  1
503 #define SEQUENCE_ANALYSIS_PDCP_ONLY 2
504 
505 /* Preference variables */
506 static gboolean global_pdcp_dissect_user_plane_as_ip = TRUE;
507 static gboolean global_pdcp_dissect_signalling_plane_as_rrc = TRUE;
508 static gint     global_pdcp_check_sequence_numbers = TRUE;
509 static gboolean global_pdcp_dissect_rohc = FALSE;
510 
511 /* Which layer info to show in the info column */
512 enum layer_to_show {
513     ShowRLCLayer, ShowPDCPLayer, ShowTrafficLayer
514 };
515 static gint     global_pdcp_lte_layer_to_show = (gint)ShowRLCLayer;
516 
517 
518 
519 /**************************************************/
520 /* Sequence number analysis                       */
521 
522 /* Channel key */
523 typedef struct
524 {
525     /* Using bit fields to fit into 32 bits, so avoiding the need to allocate
526        heap memory for these structs */
527     guint           ueId : 16;
528     guint           plane : 2;
529     guint           channelId : 6;
530     guint           direction : 1;
531     guint           notUsed : 7;
532 } pdcp_channel_hash_key;
533 
534 /* Channel state */
535 typedef struct
536 {
537     guint32  previousSequenceNumber;
538     guint32  previousFrameNum;
539     guint32  hfn;
540 } pdcp_channel_status;
541 
542 /* The sequence analysis channel hash table.
543    Maps key -> status */
544 static wmem_map_t *pdcp_sequence_analysis_channel_hash = NULL;
545 
546 
547 /* Hash table types & functions for frame reports */
548 
549 typedef struct {
550     guint32         frameNumber;
551     guint32         SN :       18;
552     guint32         plane :    2;
553     guint32         channelId: 5;
554     guint32         direction: 1;
555     guint32         notUsed :  6;
556 } pdcp_result_hash_key;
557 
pdcp_result_hash_equal(gconstpointer v,gconstpointer v2)558 static gint pdcp_result_hash_equal(gconstpointer v, gconstpointer v2)
559 {
560     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
561     const pdcp_result_hash_key* val2 = (const pdcp_result_hash_key *)v2;
562 
563     /* All fields must match */
564     return (memcmp(val1, val2, sizeof(pdcp_result_hash_key)) == 0);
565 }
566 
567 /* Compute a hash value for a given key. */
pdcp_result_hash_func(gconstpointer v)568 static guint pdcp_result_hash_func(gconstpointer v)
569 {
570     const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v;
571 
572     /* TODO: This is a bit random.  */
573     return val1->frameNumber + (val1->channelId<<7) +
574                                (val1->plane<<12) +
575                                (val1->SN<<14) +
576                                (val1->direction<<6);
577 }
578 
579 /* pdcp_channel_hash_key fits into the pointer, so just copy the value into
580    a guint, cast to a pointer and return that as the key */
get_channel_hash_key(pdcp_channel_hash_key * key)581 static gpointer get_channel_hash_key(pdcp_channel_hash_key *key)
582 {
583     guint  asInt = 0;
584     /* TODO: assert that sizeof(pdcp_channel_hash_key) <= sizeof(guint) ? */
585     memcpy(&asInt, key, sizeof(pdcp_channel_hash_key));
586     return GUINT_TO_POINTER(asInt);
587 }
588 
589 /* Convenience function to get a pointer for the hash_func to work with */
get_report_hash_key(guint32 SN,guint32 frameNumber,pdcp_lte_info * p_pdcp_lte_info,gboolean do_persist)590 static gpointer get_report_hash_key(guint32 SN, guint32 frameNumber,
591                                     pdcp_lte_info *p_pdcp_lte_info,
592                                     gboolean do_persist)
593 {
594     static pdcp_result_hash_key  key;
595     pdcp_result_hash_key        *p_key;
596 
597     /* Only allocate a struct when will be adding entry */
598     if (do_persist) {
599         p_key = wmem_new(wmem_file_scope(), pdcp_result_hash_key);
600     }
601     else {
602         memset(&key, 0, sizeof(pdcp_result_hash_key));
603         p_key = &key;
604     }
605 
606     /* Fill in details, and return pointer */
607     p_key->frameNumber = frameNumber;
608     p_key->SN = SN;
609     p_key->plane = (guint8)p_pdcp_lte_info->plane;
610     p_key->channelId = p_pdcp_lte_info->channelId;
611     p_key->direction = p_pdcp_lte_info->direction;
612     p_key->notUsed = 0;
613 
614     return p_key;
615 }
616 
617 
618 /* Info to attach to frame when first read, recording what to show about sequence */
619 typedef enum
620 {
621     SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing
622 } sequence_state;
623 typedef struct
624 {
625     gboolean sequenceExpectedCorrect;
626     guint32  sequenceExpected;
627     guint32  previousFrameNum;
628     guint32  nextFrameNum;
629 
630     guint32  firstSN;
631     guint32  lastSN;
632     guint32  hfn;
633 
634     sequence_state state;
635 } pdcp_sequence_report_in_frame;
636 
637 /* The sequence analysis frame report hash table.
638    Maps pdcp_result_hash_key* -> pdcp_sequence_report_in_frame* */
639 static wmem_map_t *pdcp_lte_sequence_analysis_report_hash = NULL;
640 
641 /* Gather together security settings in order to be able to do deciphering */
642 typedef struct pdu_security_settings_t
643 {
644     enum lte_security_ciphering_algorithm_e ciphering;
645     enum lte_security_integrity_algorithm_e integrity;
646     guint8* cipherKey;
647     guint8* integrityKey;
648     gboolean cipherKeyValid;
649     gboolean integrityKeyValid;
650     guint32 count;
651     guint8  bearer;
652     guint8  direction;
653 } pdu_security_settings_t;
654 
655 
look_up_keys_record(guint16 ueid)656 static uat_ue_keys_record_t* look_up_keys_record(guint16 ueid)
657 {
658     unsigned int record_id;
659 
660     /* Try hash table first (among entries added by set_pdcp_lte_xxx_key() functions) */
661     uat_ue_keys_record_t* key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
662                                                                               GUINT_TO_POINTER((guint)ueid));
663     if (key_record != NULL) {
664         return key_record;
665     }
666 
667     /* Else look up UAT entries. N.B. linear search... */
668     for (record_id=0; record_id < num_ue_keys_uat; record_id++) {
669         if (uat_ue_keys_records[record_id].ueid == ueid) {
670             return &uat_ue_keys_records[record_id];
671         }
672     }
673 
674     /* No match at all - return NULL */
675     return NULL;
676 }
677 
678 /* Add to the tree values associated with sequence analysis for this frame */
addChannelSequenceInfo(pdcp_sequence_report_in_frame * p,pdcp_lte_info * p_pdcp_lte_info,guint32 sequenceNumber,packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,proto_tree * security_tree,pdu_security_settings_t * pdu_security)679 static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p,
680                                    pdcp_lte_info *p_pdcp_lte_info,
681                                    guint32   sequenceNumber,
682                                    packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
683                                    proto_tree *security_tree,
684                                    pdu_security_settings_t *pdu_security)
685 {
686     proto_tree *seqnum_tree;
687     proto_item *seqnum_ti;
688     proto_item *ti_expected_sn;
689     proto_item *ti;
690     uat_ue_keys_record_t *keys_record;
691 
692     /* Create subtree */
693     seqnum_ti = proto_tree_add_string_format(tree,
694                                              hf_pdcp_lte_sequence_analysis,
695                                              tvb, 0, 0,
696                                              "", "Sequence Analysis");
697     seqnum_tree = proto_item_add_subtree(seqnum_ti,
698                                          ett_pdcp_lte_sequence_analysis);
699     proto_item_set_generated(seqnum_ti);
700 
701 
702     /* Previous channel frame */
703     if (p->previousFrameNum != 0) {
704         proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_previous_frame,
705                             tvb, 0, 0, p->previousFrameNum);
706     }
707 
708     /* Expected sequence number */
709     ti_expected_sn = proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_expected_sn,
710                                          tvb, 0, 0, p->sequenceExpected);
711     proto_item_set_generated(ti_expected_sn);
712 
713     /* Make sure we have recognised SN length */
714     switch (p_pdcp_lte_info->seqnum_length) {
715         case PDCP_SN_LENGTH_5_BITS:
716         case PDCP_SN_LENGTH_7_BITS:
717         case PDCP_SN_LENGTH_12_BITS:
718         case PDCP_SN_LENGTH_15_BITS:
719         case PDCP_SN_LENGTH_18_BITS:
720             break;
721         default:
722             DISSECTOR_ASSERT_NOT_REACHED();
723             break;
724     }
725 
726     switch (p->state) {
727         case SN_OK:
728             proto_item_set_hidden(ti_expected_sn);
729             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
730                                         tvb, 0, 0, TRUE);
731             proto_item_set_generated(ti);
732             proto_item_append_text(seqnum_ti, " - OK");
733 
734             /* Link to next SN in channel (if known) */
735             if (p->nextFrameNum != 0) {
736                 proto_tree_add_uint(seqnum_tree, hf_pdcp_lte_sequence_analysis_next_frame,
737                                     tvb, 0, 0, p->nextFrameNum);
738             }
739 
740             /* May also be able to add key inputs to security tree here */
741             if ((pdu_security->ciphering != eea0) ||
742                 (pdu_security->integrity != eia0)) {
743 
744                 guint32              hfn_multiplier;
745                 guint32              count;
746                 gchar                *cipher_key = NULL;
747                 gchar                *integrity_key = NULL;
748 
749                 /* BEARER */
750                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_bearer,
751                                          tvb, 0, 0, p_pdcp_lte_info->channelId-1);
752                 proto_item_set_generated(ti);
753 
754                 pdu_security->bearer = p_pdcp_lte_info->channelId-1;
755 
756                 /* DIRECTION */
757                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_direction,
758                                          tvb, 0, 0, p_pdcp_lte_info->direction);
759                 proto_item_set_generated(ti);
760 
761                 /* COUNT (HFN * snLength^2 + SN) */
762                 switch (p_pdcp_lte_info->seqnum_length) {
763                     case PDCP_SN_LENGTH_5_BITS:
764                         hfn_multiplier = 32;
765                         break;
766                     case PDCP_SN_LENGTH_7_BITS:
767                         hfn_multiplier = 128;
768                         break;
769                     case PDCP_SN_LENGTH_12_BITS:
770                         hfn_multiplier = 4096;
771                         break;
772                     case PDCP_SN_LENGTH_15_BITS:
773                         hfn_multiplier = 32768;
774                         break;
775                     case PDCP_SN_LENGTH_18_BITS:
776                         hfn_multiplier = 262144;
777                         break;
778                     default:
779                         DISSECTOR_ASSERT_NOT_REACHED();
780                         break;
781                 }
782                 count = (p->hfn * hfn_multiplier) + sequenceNumber;
783                 ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_count,
784                                          tvb, 0, 0, count);
785                 proto_item_set_generated(ti);
786                 pdu_security->count = count;
787 
788                 /* KEY.  Look this UE up among UEs that have keys configured */
789                 keys_record = look_up_keys_record(p_pdcp_lte_info->ueid);
790                 if (keys_record != NULL) {
791                     if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
792                         /* Get RRC ciphering key */
793                         if (keys_record->rrcCipherKeyOK) {
794                             cipher_key = keys_record->rrcCipherKeyString;
795                             pdu_security->cipherKey = &(keys_record->rrcCipherBinaryKey[0]);
796                             pdu_security->cipherKeyValid = TRUE;
797                         }
798                         /* Get RRC integrity key */
799                         if (keys_record->rrcIntegrityKeyOK) {
800                             integrity_key = keys_record->rrcIntegrityKeyString;
801                             pdu_security->integrityKey = &(keys_record->rrcIntegrityBinaryKey[0]);
802                             pdu_security->integrityKeyValid = TRUE;
803                         }
804                     }
805                     else {
806                         /* Get userplane ciphering key */
807                         if (keys_record->upCipherKeyOK) {
808                             cipher_key = keys_record->upCipherKeyString;
809                             pdu_security->cipherKey = &(keys_record->upCipherBinaryKey[0]);
810                             pdu_security->cipherKeyValid = TRUE;
811                         }
812                     }
813 
814                     /* Show keys where known and valid */
815                     if (cipher_key != NULL) {
816                         ti = proto_tree_add_string(security_tree, hf_pdcp_lte_security_cipher_key,
817                                                    tvb, 0, 0, cipher_key);
818                         proto_item_set_generated(ti);
819                     }
820                     if (integrity_key != NULL) {
821                         ti = proto_tree_add_string(security_tree, hf_pdcp_lte_security_integrity_key,
822                                                    tvb, 0, 0, integrity_key);
823                         proto_item_set_generated(ti);
824                     }
825 
826                     pdu_security->direction = p_pdcp_lte_info->direction;
827                 }
828             }
829             break;
830 
831         case SN_Missing:
832             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
833                                         tvb, 0, 0, FALSE);
834             proto_item_set_generated(ti);
835             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_skipped,
836                                         tvb, 0, 0, TRUE);
837             proto_item_set_generated(ti);
838             if (p->lastSN != p->firstSN) {
839                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_missing,
840                                        "PDCP SNs (%u to %u) missing for %s on UE %u (%s-%u)",
841                                        p->firstSN, p->lastSN,
842                                        val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
843                                        p_pdcp_lte_info->ueid,
844                                        val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
845                                        p_pdcp_lte_info->channelId);
846                 proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
847                                        p->firstSN, p->lastSN);
848             }
849             else {
850                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_missing,
851                                        "PDCP SN (%u) missing for %s on UE %u (%s-%u)",
852                                        p->firstSN,
853                                        val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
854                                        p_pdcp_lte_info->ueid,
855                                        val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
856                                        p_pdcp_lte_info->channelId);
857                 proto_item_append_text(seqnum_ti, " - SN missing (%u)",
858                                        p->firstSN);
859             }
860             break;
861 
862         case SN_Repeated:
863             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_ok,
864                                         tvb, 0, 0, FALSE);
865             proto_item_set_generated(ti);
866             ti = proto_tree_add_boolean(seqnum_tree, hf_pdcp_lte_sequence_analysis_repeated,
867                                         tvb, 0, 0, TRUE);
868             proto_item_set_generated(ti);
869             expert_add_info_format(pinfo, ti, &ei_pdcp_lte_sequence_analysis_sn_repeated,
870                                    "PDCP SN (%u) repeated for %s for UE %u (%s-%u)",
871                                    p->firstSN,
872                                    val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
873                                    p_pdcp_lte_info->ueid,
874                                    val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
875                                    p_pdcp_lte_info->channelId);
876             proto_item_append_text(seqnum_ti, "- SN %u Repeated",
877                                    p->firstSN);
878             break;
879 
880         default:
881             /* Incorrect sequence number */
882             expert_add_info_format(pinfo, ti_expected_sn, &ei_pdcp_lte_sequence_analysis_wrong_sequence_number,
883                                    "Wrong Sequence Number for %s on UE %u (%s-%u) - got %u, expected %u",
884                                    val_to_str_const(p_pdcp_lte_info->direction, direction_vals, "Unknown"),
885                                    p_pdcp_lte_info->ueid,
886                                    val_to_str_const(p_pdcp_lte_info->channelType, logical_channel_vals, "Unknown"),
887                                    p_pdcp_lte_info->channelId,
888                                    sequenceNumber, p->sequenceExpected);
889             break;
890     }
891 }
892 
893 
894 /* Update the channel status and set report for this frame */
checkChannelSequenceInfo(packet_info * pinfo,tvbuff_t * tvb,pdcp_lte_info * p_pdcp_lte_info,guint32 sequenceNumber,proto_tree * tree,proto_tree * security_tree,pdu_security_settings_t * pdu_security)895 static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb,
896                                      pdcp_lte_info *p_pdcp_lte_info,
897                                      guint32 sequenceNumber,
898                                      proto_tree *tree,
899                                      proto_tree *security_tree,
900                                      pdu_security_settings_t *pdu_security)
901 {
902     pdcp_channel_hash_key          channel_key;
903     pdcp_channel_status           *p_channel_status;
904     pdcp_sequence_report_in_frame *p_report_in_frame      = NULL;
905     gboolean                       createdChannel         = FALSE;
906     guint32                        expectedSequenceNumber = 0;
907     guint32                        snLimit                = 0;
908 
909     /* If find stat_report_in_frame already, use that and get out */
910     if (PINFO_FD_VISITED(pinfo)) {
911         p_report_in_frame =
912             (pdcp_sequence_report_in_frame*)wmem_map_lookup(pdcp_lte_sequence_analysis_report_hash,
913                                                             get_report_hash_key(sequenceNumber,
914                                                                                 pinfo->num,
915                                                                                 p_pdcp_lte_info, FALSE));
916         if (p_report_in_frame != NULL) {
917             addChannelSequenceInfo(p_report_in_frame, p_pdcp_lte_info,
918                                    sequenceNumber,
919                                    pinfo, tree, tvb, security_tree, pdu_security);
920             return;
921         }
922         else {
923             /* Give up - we must have tried already... */
924             return;
925         }
926     }
927 
928 
929     /**************************************************/
930     /* Create or find an entry for this channel state */
931     channel_key.ueId = p_pdcp_lte_info->ueid;
932     channel_key.plane = p_pdcp_lte_info->plane;
933     channel_key.channelId = p_pdcp_lte_info->channelId;
934     channel_key.direction = p_pdcp_lte_info->direction;
935     channel_key.notUsed = 0;
936 
937     /* Do the table lookup */
938     p_channel_status = (pdcp_channel_status*)wmem_map_lookup(pdcp_sequence_analysis_channel_hash,
939                                                              get_channel_hash_key(&channel_key));
940 
941     /* Create table entry if necessary */
942     if (p_channel_status == NULL) {
943         createdChannel = TRUE;
944 
945         /* Allocate a new value and duplicate key contents */
946         p_channel_status = wmem_new0(wmem_file_scope(), pdcp_channel_status);
947 
948         /* Add entry */
949         wmem_map_insert(pdcp_sequence_analysis_channel_hash,
950                         get_channel_hash_key(&channel_key), p_channel_status);
951     }
952 
953     /* Create space for frame state_report */
954     p_report_in_frame = wmem_new(wmem_file_scope(), pdcp_sequence_report_in_frame);
955     p_report_in_frame->nextFrameNum = 0;
956 
957     switch (p_pdcp_lte_info->seqnum_length) {
958         case PDCP_SN_LENGTH_5_BITS:
959             snLimit = 32;
960             break;
961         case PDCP_SN_LENGTH_7_BITS:
962             snLimit = 128;
963             break;
964         case PDCP_SN_LENGTH_12_BITS:
965             snLimit = 4096;
966             break;
967         case PDCP_SN_LENGTH_15_BITS:
968             snLimit = 32768;
969             break;
970         case PDCP_SN_LENGTH_18_BITS:
971             snLimit = 262144;
972             break;
973         default:
974             DISSECTOR_ASSERT_NOT_REACHED();
975             break;
976     }
977 
978     /* Work out expected sequence number */
979     if (!createdChannel) {
980         expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % snLimit;
981     }
982     else {
983         expectedSequenceNumber = sequenceNumber;
984     }
985 
986     /* Set report for this frame */
987     /* For PDCP, sequence number is always expectedSequence number */
988     p_report_in_frame->sequenceExpectedCorrect = (sequenceNumber == expectedSequenceNumber);
989     p_report_in_frame->hfn = p_channel_status->hfn;
990 
991     /* For wrong sequence number... */
992     if (!p_report_in_frame->sequenceExpectedCorrect) {
993 
994         /* Frames are not missing if we get an earlier sequence number again */
995         if (((snLimit + expectedSequenceNumber - sequenceNumber) % snLimit) > 15) {
996             p_report_in_frame->state = SN_Missing;
997             p_report_in_frame->firstSN = expectedSequenceNumber;
998             p_report_in_frame->lastSN = (snLimit + sequenceNumber - 1) % snLimit;
999 
1000             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1001             p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1002 
1003             /* Update channel status to remember *this* frame */
1004             p_channel_status->previousFrameNum = pinfo->num;
1005             p_channel_status->previousSequenceNumber = sequenceNumber;
1006         }
1007         else {
1008             /* An SN has been repeated */
1009             p_report_in_frame->state = SN_Repeated;
1010             p_report_in_frame->firstSN = sequenceNumber;
1011 
1012             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1013             p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1014         }
1015     }
1016     else {
1017         /* SN was OK */
1018         p_report_in_frame->state = SN_OK;
1019         p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1020         p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1021         /* SN has rolled around, inc hfn! */
1022         if (!createdChannel && (sequenceNumber == 0)) {
1023             /* TODO: not worrying about HFN rolling over for now! */
1024             p_channel_status->hfn++;
1025             p_report_in_frame->hfn = p_channel_status->hfn;
1026         }
1027 
1028         /* Update channel status to remember *this* frame */
1029         p_channel_status->previousFrameNum = pinfo->num;
1030         p_channel_status->previousSequenceNumber = sequenceNumber;
1031 
1032         if (p_report_in_frame->previousFrameNum != 0) {
1033             /* Get report for previous frame */
1034             pdcp_sequence_report_in_frame *p_previous_report;
1035             p_previous_report = (pdcp_sequence_report_in_frame*)wmem_map_lookup(pdcp_lte_sequence_analysis_report_hash,
1036                                                                                 get_report_hash_key((sequenceNumber+262144) % 262144,
1037                                                                                                     p_report_in_frame->previousFrameNum,
1038                                                                                                     p_pdcp_lte_info,
1039                                                                                                     FALSE));
1040             /* It really shouldn't be NULL... */
1041             if (p_previous_report != NULL) {
1042                 /* Point it forward to this one */
1043                 p_previous_report->nextFrameNum = pinfo->num;
1044             }
1045         }
1046     }
1047 
1048     /* Associate with this frame number */
1049     wmem_map_insert(pdcp_lte_sequence_analysis_report_hash,
1050                     get_report_hash_key(sequenceNumber, pinfo->num,
1051                                         p_pdcp_lte_info, TRUE),
1052                     p_report_in_frame);
1053 
1054     /* Add state report for this frame into tree */
1055     addChannelSequenceInfo(p_report_in_frame, p_pdcp_lte_info, sequenceNumber,
1056                            pinfo, tree, tvb, security_tree, pdu_security);
1057 }
1058 
1059 
1060 
1061 /* Hash table for security state for a UE
1062    Maps UEId -> pdcp_security_info_t*  */
1063 static wmem_map_t *pdcp_security_hash = NULL;
1064 
1065 /* Result is (ueid, framenum) -> pdcp_security_info_t*  */
1066 typedef struct  ueid_frame_t {
1067     guint32 framenum;
1068     guint16 ueid;
1069 } ueid_frame_t;
1070 
1071 /* Convenience function to get a pointer for the hash_func to work with */
get_ueid_frame_hash_key(guint16 ueid,guint32 frameNumber,gboolean do_persist)1072 static gpointer get_ueid_frame_hash_key(guint16 ueid, guint32 frameNumber,
1073                                         gboolean do_persist)
1074 {
1075     static ueid_frame_t  key;
1076     ueid_frame_t        *p_key;
1077 
1078     /* Only allocate a struct when will be adding entry */
1079     if (do_persist) {
1080         p_key = wmem_new(wmem_file_scope(), ueid_frame_t);
1081     }
1082     else {
1083         /* Only looking up, so just use static */
1084         memset(&key, 0, sizeof(ueid_frame_t));
1085         p_key = &key;
1086     }
1087 
1088     /* Fill in details, and return pointer */
1089     p_key->framenum = frameNumber;
1090     p_key->ueid = ueid;
1091 
1092     return p_key;
1093 }
1094 
pdcp_lte_ueid_frame_hash_equal(gconstpointer v,gconstpointer v2)1095 static gint pdcp_lte_ueid_frame_hash_equal(gconstpointer v, gconstpointer v2)
1096 {
1097     const ueid_frame_t *ueid_frame_1 = (const ueid_frame_t *)v;
1098     const ueid_frame_t *ueid_frame_2 = (const ueid_frame_t *)v2;
1099     return ((ueid_frame_1->framenum == ueid_frame_2->framenum) &&
1100             (ueid_frame_1->ueid == ueid_frame_2->ueid));
1101 }
pdcp_lte_ueid_frame_hash_func(gconstpointer v)1102 static guint pdcp_lte_ueid_frame_hash_func(gconstpointer v)
1103 {
1104     const ueid_frame_t *ueid_frame = (const ueid_frame_t *)v;
1105     return ueid_frame->framenum + 100*ueid_frame->ueid;
1106 }
1107 static wmem_map_t *pdcp_security_result_hash = NULL;
1108 
1109 
1110 
1111 
1112 /* Write the given formatted text to:
1113    - the info column
1114    - the top-level RLC PDU item */
write_pdu_label_and_info(proto_item * pdu_ti,packet_info * pinfo,const char * format,...)1115 static void write_pdu_label_and_info(proto_item *pdu_ti,
1116                                      packet_info *pinfo, const char *format, ...)
1117 {
1118     #define MAX_INFO_BUFFER 256
1119     static char info_buffer[MAX_INFO_BUFFER];
1120 
1121     va_list ap;
1122 
1123     va_start(ap, format);
1124     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
1125     va_end(ap);
1126 
1127     /* Add to indicated places */
1128     col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1129     /* TODO: gets called a lot, so a shame there isn't a proto_item_append_string() */
1130     proto_item_append_text(pdu_ti, "%s", info_buffer);
1131 }
1132 
1133 
1134 
1135 /***************************************************************/
1136 
1137 
1138 
1139 /* Show in the tree the config info attached to this frame, as generated fields */
show_pdcp_config(packet_info * pinfo,tvbuff_t * tvb,proto_tree * tree,pdcp_lte_info * p_pdcp_info)1140 static void show_pdcp_config(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
1141                              pdcp_lte_info *p_pdcp_info)
1142 {
1143     proto_item *ti;
1144     proto_tree *configuration_tree;
1145     proto_item *configuration_ti = proto_tree_add_item(tree,
1146                                                        hf_pdcp_lte_configuration,
1147                                                        tvb, 0, 0, ENC_ASCII|ENC_NA);
1148     configuration_tree = proto_item_add_subtree(configuration_ti, ett_pdcp_configuration);
1149 
1150     /* Direction */
1151     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_direction, tvb, 0, 0,
1152                              p_pdcp_info->direction);
1153     proto_item_set_generated(ti);
1154 
1155     /* Plane */
1156     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_plane, tvb, 0, 0,
1157                              p_pdcp_info->plane);
1158     proto_item_set_generated(ti);
1159 
1160     /* UEId */
1161     if (p_pdcp_info->ueid != 0) {
1162         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_ueid, tvb, 0, 0,
1163                                  p_pdcp_info->ueid);
1164         proto_item_set_generated(ti);
1165     }
1166 
1167     /* Channel type */
1168     ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_channel_type, tvb, 0, 0,
1169                              p_pdcp_info->channelType);
1170     proto_item_set_generated(ti);
1171     if (p_pdcp_info->channelId != 0) {
1172         /* Channel type */
1173         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_channel_id, tvb, 0, 0,
1174                                  p_pdcp_info->channelId);
1175         proto_item_set_generated(ti);
1176     }
1177 
1178 
1179     /* User-plane-specific fields */
1180     if (p_pdcp_info->plane == USER_PLANE) {
1181 
1182         /* No Header PDU */
1183         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_no_header_pdu, tvb, 0, 0,
1184                                  p_pdcp_info->no_header_pdu);
1185         proto_item_set_generated(ti);
1186 
1187         if (!p_pdcp_info->no_header_pdu) {
1188 
1189             /* Seqnum length */
1190             ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_seqnum_length, tvb, 0, 0,
1191                                      p_pdcp_info->seqnum_length);
1192             proto_item_set_generated(ti);
1193         }
1194     }
1195 
1196     /* ROHC compression */
1197     ti = proto_tree_add_boolean(configuration_tree, hf_pdcp_lte_rohc_compression, tvb, 0, 0,
1198                                 p_pdcp_info->rohc.rohc_compression);
1199     proto_item_set_generated(ti);
1200 
1201     /* ROHC-specific settings */
1202     if (p_pdcp_info->rohc.rohc_compression) {
1203 
1204         /* Show ROHC mode */
1205         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_mode, tvb, 0, 0,
1206                                  p_pdcp_info->rohc.mode);
1207         proto_item_set_generated(ti);
1208 
1209         /* Show RND */
1210         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_rnd, tvb, 0, 0,
1211                                  p_pdcp_info->rohc.rnd);
1212         proto_item_set_generated(ti);
1213 
1214         /* UDP Checksum */
1215         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_udp_checksum_present, tvb, 0, 0,
1216                                  p_pdcp_info->rohc.udp_checksum_present);
1217         proto_item_set_generated(ti);
1218 
1219         /* ROHC profile */
1220         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_rohc_profile, tvb, 0, 0,
1221                                  p_pdcp_info->rohc.profile);
1222         proto_item_set_generated(ti);
1223 
1224         /* CID Inclusion Info */
1225         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_cid_inclusion_info, tvb, 0, 0,
1226                                  p_pdcp_info->rohc.cid_inclusion_info);
1227         proto_item_set_generated(ti);
1228 
1229         /* Large CID */
1230         ti = proto_tree_add_uint(configuration_tree, hf_pdcp_lte_large_cid_present, tvb, 0, 0,
1231                                  p_pdcp_info->rohc.large_cid_present);
1232         proto_item_set_generated(ti);
1233     }
1234 
1235     /* Append summary to configuration root */
1236     proto_item_append_text(configuration_ti, "(direction=%s, plane=%s",
1237                            val_to_str_const(p_pdcp_info->direction, direction_vals, "Unknown"),
1238                            val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
1239 
1240     if (p_pdcp_info->rohc.rohc_compression) {
1241         const char *mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
1242         proto_item_append_text(configuration_ti, ", mode=%c, profile=%s",
1243                                mode[0],
1244                                val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
1245     }
1246     proto_item_append_text(configuration_ti, ")");
1247     proto_item_set_generated(configuration_ti);
1248 
1249     /* Show plane in info column */
1250     col_append_fstr(pinfo->cinfo, COL_INFO, " %s: ",
1251                     val_to_str_const(p_pdcp_info->plane, pdcp_plane_vals, "Unknown"));
1252 
1253 }
1254 
1255 
1256 /* Look for an RRC dissector for signalling data (using channel type and direction) */
lookup_rrc_dissector_handle(struct pdcp_lte_info * p_pdcp_info)1257 static dissector_handle_t lookup_rrc_dissector_handle(struct pdcp_lte_info  *p_pdcp_info)
1258 {
1259     dissector_handle_t rrc_handle = 0;
1260 
1261     switch (p_pdcp_info->channelType)
1262     {
1263         case Channel_CCCH:
1264             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1265                 rrc_handle = lte_rrc_ul_ccch;
1266             }
1267             else {
1268                 rrc_handle = lte_rrc_dl_ccch;
1269             }
1270             break;
1271         case Channel_PCCH:
1272             rrc_handle = lte_rrc_pcch;
1273             break;
1274         case Channel_BCCH:
1275             switch (p_pdcp_info->BCCHTransport) {
1276                 case BCH_TRANSPORT:
1277                     rrc_handle = lte_rrc_bcch_bch;
1278                     break;
1279                 case DLSCH_TRANSPORT:
1280                     rrc_handle = lte_rrc_bcch_dl_sch;
1281                     break;
1282             }
1283             break;
1284         case Channel_DCCH:
1285             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1286                 rrc_handle = lte_rrc_ul_dcch;
1287             }
1288             else {
1289                 rrc_handle = lte_rrc_dl_dcch;
1290             }
1291             break;
1292         case Channel_CCCH_NB:
1293             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1294                 rrc_handle = lte_rrc_ul_ccch_nb;
1295             }
1296             else {
1297                 rrc_handle = lte_rrc_dl_ccch_nb;
1298             }
1299             break;
1300         case Channel_PCCH_NB:
1301             rrc_handle = lte_rrc_pcch_nb;
1302             break;
1303         case Channel_BCCH_NB:
1304             switch (p_pdcp_info->BCCHTransport) {
1305                 case BCH_TRANSPORT:
1306                     rrc_handle = lte_rrc_bcch_bch_nb;
1307                     break;
1308                 case DLSCH_TRANSPORT:
1309                     rrc_handle = lte_rrc_bcch_dl_sch_nb;
1310                     break;
1311             }
1312             break;
1313         case Channel_DCCH_NB:
1314             if (p_pdcp_info->direction == DIRECTION_UPLINK) {
1315                 rrc_handle = lte_rrc_ul_dcch_nb;
1316             }
1317             else {
1318                 rrc_handle = lte_rrc_dl_dcch_nb;
1319             }
1320             break;
1321 
1322 
1323         default:
1324             break;
1325     }
1326 
1327     return rrc_handle;
1328 }
1329 
1330 
1331 /* Forwad declarations */
1332 static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
1333 
report_heur_error(proto_tree * tree,packet_info * pinfo,expert_field * eiindex,tvbuff_t * tvb,gint start,gint length)1334 static void report_heur_error(proto_tree *tree, packet_info *pinfo, expert_field *eiindex,
1335                               tvbuff_t *tvb, gint start, gint length)
1336 {
1337     proto_item *ti;
1338     proto_tree *subtree;
1339 
1340     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDCP-LTE");
1341     col_clear(pinfo->cinfo, COL_INFO);
1342     ti = proto_tree_add_item(tree, proto_pdcp_lte, tvb, 0, -1, ENC_NA);
1343     subtree = proto_item_add_subtree(ti, ett_pdcp);
1344     proto_tree_add_expert(subtree, pinfo, eiindex, tvb, start, length);
1345 }
1346 
1347 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
dissect_pdcp_lte_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1348 static gboolean dissect_pdcp_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
1349                                      proto_tree *tree, void *data _U_)
1350 {
1351     gint                  offset                 = 0;
1352     struct pdcp_lte_info *p_pdcp_lte_info;
1353     tvbuff_t             *pdcp_tvb;
1354     guint8                tag                    = 0;
1355     gboolean              seqnumLengthTagPresent = FALSE;
1356 
1357     /* Needs to be at least as long as:
1358        - the signature string
1359        - fixed header bytes
1360        - tag for data
1361        - at least one byte of PDCP PDU payload */
1362     if (tvb_captured_length_remaining(tvb, offset) < (gint)(strlen(PDCP_LTE_START_STRING)+3+2)) {
1363         return FALSE;
1364     }
1365 
1366     /* OK, compare with signature string */
1367     if (tvb_strneql(tvb, offset, PDCP_LTE_START_STRING, strlen(PDCP_LTE_START_STRING)) != 0) {
1368         return FALSE;
1369     }
1370     offset += (gint)strlen(PDCP_LTE_START_STRING);
1371 
1372 
1373     /* If redissecting, use previous info struct (if available) */
1374     p_pdcp_lte_info = (pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0);
1375     if (p_pdcp_lte_info == NULL) {
1376         /* Allocate new info struct for this frame */
1377         p_pdcp_lte_info = wmem_new0(wmem_file_scope(), pdcp_lte_info);
1378 
1379         /* Read fixed fields */
1380         p_pdcp_lte_info->no_header_pdu = (gboolean)tvb_get_guint8(tvb, offset++);
1381         p_pdcp_lte_info->plane = (enum pdcp_plane)tvb_get_guint8(tvb, offset++);
1382         if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
1383             p_pdcp_lte_info->seqnum_length = PDCP_SN_LENGTH_5_BITS;
1384         }
1385         p_pdcp_lte_info->rohc.rohc_compression = (gboolean)tvb_get_guint8(tvb, offset++);
1386 
1387         /* Read optional fields */
1388         while (tag != PDCP_LTE_PAYLOAD_TAG) {
1389             /* Process next tag */
1390             tag = tvb_get_guint8(tvb, offset++);
1391             switch (tag) {
1392                 case PDCP_LTE_SEQNUM_LENGTH_TAG:
1393                     p_pdcp_lte_info->seqnum_length = tvb_get_guint8(tvb, offset);
1394                     offset++;
1395                     seqnumLengthTagPresent = TRUE;
1396                     break;
1397                 case PDCP_LTE_DIRECTION_TAG:
1398                     p_pdcp_lte_info->direction = tvb_get_guint8(tvb, offset);
1399                     offset++;
1400                     break;
1401                 case PDCP_LTE_LOG_CHAN_TYPE_TAG:
1402                     p_pdcp_lte_info->channelType = (LogicalChannelType)tvb_get_guint8(tvb, offset);
1403                     offset++;
1404                     break;
1405                 case PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG:
1406                     p_pdcp_lte_info->BCCHTransport = (BCCHTransportType)tvb_get_guint8(tvb, offset);
1407                     offset++;
1408                     break;
1409                 case PDCP_LTE_ROHC_IP_VERSION_TAG:
1410                     /* RoHC IP version field is now 1 byte only; let's skip most significant byte
1411                        to keep backward compatibility with existing UDP framing protocol */
1412                     p_pdcp_lte_info->rohc.rohc_ip_version = tvb_get_guint8(tvb, offset+1);
1413                     offset += 2;
1414                     break;
1415                 case PDCP_LTE_ROHC_CID_INC_INFO_TAG:
1416                     p_pdcp_lte_info->rohc.cid_inclusion_info = tvb_get_guint8(tvb, offset);
1417                     offset++;
1418                     break;
1419                 case PDCP_LTE_ROHC_LARGE_CID_PRES_TAG:
1420                     p_pdcp_lte_info->rohc.large_cid_present = tvb_get_guint8(tvb, offset);
1421                     offset++;
1422                     break;
1423                 case PDCP_LTE_ROHC_MODE_TAG:
1424                     p_pdcp_lte_info->rohc.mode = (enum rohc_mode)tvb_get_guint8(tvb, offset);
1425                     offset++;
1426                     break;
1427                 case PDCP_LTE_ROHC_RND_TAG:
1428                     p_pdcp_lte_info->rohc.rnd = tvb_get_guint8(tvb, offset);
1429                     offset++;
1430                     break;
1431                 case PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG:
1432                     p_pdcp_lte_info->rohc.udp_checksum_present = tvb_get_guint8(tvb, offset);
1433                     offset++;
1434                     break;
1435                 case PDCP_LTE_ROHC_PROFILE_TAG:
1436                     p_pdcp_lte_info->rohc.profile = tvb_get_ntohs(tvb, offset);
1437                     offset += 2;
1438                     break;
1439                 case PDCP_LTE_CHANNEL_ID_TAG:
1440                     p_pdcp_lte_info->channelId = tvb_get_ntohs(tvb, offset);
1441                     offset += 2;
1442                     break;
1443                 case PDCP_LTE_UEID_TAG:
1444                     p_pdcp_lte_info->ueid = tvb_get_ntohs(tvb, offset);
1445                     offset += 2;
1446                     break;
1447 
1448                 case PDCP_LTE_PAYLOAD_TAG:
1449                     /* Have reached data, so get out of loop */
1450                     p_pdcp_lte_info->pdu_length = tvb_reported_length_remaining(tvb, offset);
1451                     continue;
1452 
1453                 default:
1454                     /* It must be a recognised tag */
1455                     report_heur_error(tree, pinfo, &ei_pdcp_lte_unknown_udp_framing_tag, tvb, offset-1, 1);
1456                     wmem_free(wmem_file_scope(), p_pdcp_lte_info);
1457                     return TRUE;
1458             }
1459         }
1460 
1461         if ((p_pdcp_lte_info->plane == USER_PLANE) && (seqnumLengthTagPresent == FALSE)) {
1462             /* Conditional field is not present */
1463             report_heur_error(tree, pinfo, &ei_pdcp_lte_missing_udp_framing_tag, tvb, 0, offset);
1464             wmem_free(wmem_file_scope(), p_pdcp_lte_info);
1465             return TRUE;
1466         }
1467 
1468         /* Store info in packet */
1469         p_add_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0, p_pdcp_lte_info);
1470     }
1471     else {
1472         offset = tvb_reported_length(tvb) - p_pdcp_lte_info->pdu_length;
1473     }
1474 
1475 
1476     /**************************************/
1477     /* OK, now dissect as PDCP LTE        */
1478 
1479     /* Create tvb that starts at actual PDCP PDU */
1480     pdcp_tvb = tvb_new_subset_remaining(tvb, offset);
1481     dissect_pdcp_lte(pdcp_tvb, pinfo, tree, data);
1482     return TRUE;
1483 }
1484 
1485 /* Called from control protocol to configure security algorithms for the given UE */
set_pdcp_lte_security_algorithms(guint16 ueid,pdcp_lte_security_info_t * security_info)1486 void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_lte_security_info_t *security_info)
1487 {
1488     /* Use for this frame so can check integrity on SecurityCommandRequest frame */
1489     /* N.B. won't work for internal, non-RRC signalling methods... */
1490     pdcp_lte_security_info_t *p_frame_security;
1491 
1492     /* Disable this entire sub-routine with the Preference */
1493     /* Used when the capture is already deciphered */
1494     if (global_pdcp_ignore_sec) {
1495         return;
1496     }
1497 
1498     /* Create or update current settings, by UEID */
1499     pdcp_lte_security_info_t* ue_security =
1500         (pdcp_lte_security_info_t*)wmem_map_lookup(pdcp_security_hash,
1501                                                    GUINT_TO_POINTER((guint)ueid));
1502     if (ue_security == NULL) {
1503         /* Copy whole security struct */
1504         ue_security = wmem_new(wmem_file_scope(), pdcp_lte_security_info_t);
1505         *ue_security = *security_info;
1506 
1507         /* And add into security table */
1508         wmem_map_insert(pdcp_security_hash, GUINT_TO_POINTER((guint)ueid), ue_security);
1509     }
1510     else {
1511         /* Just update existing entry already in table */
1512         ue_security->previous_configuration_frame = ue_security->configuration_frame;
1513         ue_security->previous_integrity = ue_security->integrity;
1514         ue_security->previous_ciphering = ue_security->ciphering;
1515 
1516         ue_security->configuration_frame = security_info->configuration_frame;
1517         ue_security->integrity = security_info->integrity;
1518         ue_security->ciphering = security_info->ciphering;
1519         ue_security->seen_next_ul_pdu = FALSE;
1520     }
1521 
1522     /* Also add an entry for this PDU already to use these settings, as otherwise it won't be present
1523        when we query it on the first pass. */
1524     p_frame_security = wmem_new(wmem_file_scope(), pdcp_lte_security_info_t);
1525     *p_frame_security = *ue_security;
1526     wmem_map_insert(pdcp_security_result_hash,
1527                     get_ueid_frame_hash_key(ueid, ue_security->configuration_frame, TRUE),
1528                     p_frame_security);
1529 }
1530 
1531 /* UE failed to process SecurityModeCommand so go back to previous security settings */
set_pdcp_lte_security_algorithms_failed(guint16 ueid)1532 void set_pdcp_lte_security_algorithms_failed(guint16 ueid)
1533 {
1534     /* Look up current state by UEID */
1535     pdcp_lte_security_info_t* ue_security =
1536         (pdcp_lte_security_info_t*)wmem_map_lookup(pdcp_security_hash,
1537                                                    GUINT_TO_POINTER((guint)ueid));
1538     if (ue_security != NULL) {
1539         /* TODO: could remove from table if previous_configuration_frame is 0 */
1540         /* Go back to previous state */
1541         ue_security->configuration_frame = ue_security->previous_configuration_frame;
1542         ue_security->integrity = ue_security->previous_integrity;
1543         ue_security->ciphering = ue_security->previous_ciphering;
1544     }
1545 }
1546 
1547 /* Decipher payload if algorithm is supported and plausible inputs are available */
decipher_payload(tvbuff_t * tvb,packet_info * pinfo,int * offset,pdu_security_settings_t * pdu_security_settings,struct pdcp_lte_info * p_pdcp_info,gboolean will_be_deciphered,gboolean * deciphered)1548 static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset,
1549                                   pdu_security_settings_t *pdu_security_settings,
1550                                   struct pdcp_lte_info *p_pdcp_info, gboolean will_be_deciphered,
1551                                   gboolean *deciphered)
1552 {
1553     guint8* decrypted_data = NULL;
1554     gint payload_length = 0;
1555     tvbuff_t *decrypted_tvb;
1556 
1557     /* Nothing to do if NULL ciphering */
1558     if (pdu_security_settings->ciphering == eea0) {
1559         return tvb;
1560     }
1561 
1562     /* Nothing to do if don't have valid cipher key */
1563     if (!pdu_security_settings->cipherKeyValid) {
1564         return tvb;
1565     }
1566 
1567     /* Check whether algorithm supported (only drop through and process if we do) */
1568     if (pdu_security_settings->ciphering == eea1) {
1569 #ifndef HAVE_SNOW3G
1570         return tvb;
1571 #endif
1572     }
1573     else if (pdu_security_settings->ciphering == eea3) {
1574 #ifndef HAVE_ZUC
1575         return tvb;
1576 #endif
1577     }
1578     else if (pdu_security_settings->ciphering != eea2) {
1579         /* An algorithm we don't support at all! */
1580         return tvb;
1581     }
1582 
1583     /* Don't decipher if turned off in preferences */
1584     if (((p_pdcp_info->plane == SIGNALING_PLANE) &&  !global_pdcp_decipher_signalling) ||
1585         ((p_pdcp_info->plane == USER_PLANE) &&       !global_pdcp_decipher_userplane)) {
1586         return tvb;
1587     }
1588 
1589     /* Don't decipher user-plane control messages */
1590     if ((p_pdcp_info->plane == USER_PLANE) && ((tvb_get_guint8(tvb, 0) & 0x80) == 0x00)) {
1591         return tvb;
1592     }
1593 
1594     /* Don't decipher common control messages */
1595     if ((p_pdcp_info->plane == SIGNALING_PLANE) && (p_pdcp_info->channelType != Channel_DCCH)) {
1596         return tvb;
1597     }
1598 
1599     /* Don't decipher if not yet past SecurityModeResponse */
1600     if (!will_be_deciphered) {
1601         return tvb;
1602     }
1603 
1604     /* AES */
1605     if (pdu_security_settings->ciphering == eea2) {
1606         unsigned char ctr_block[16];
1607         gcry_cipher_hd_t cypher_hd;
1608         int gcrypt_err;
1609 
1610         /* TS 33.401 B.1.3 */
1611 
1612         /* Set CTR */
1613         memset(ctr_block, 0, 16);
1614         /* Only first 5 bytes set */
1615         ctr_block[0] = (pdu_security_settings->count & 0xff000000) >> 24;
1616         ctr_block[1] = (pdu_security_settings->count & 0x00ff0000) >> 16;
1617         ctr_block[2] = (pdu_security_settings->count & 0x0000ff00) >> 8;
1618         ctr_block[3] = (pdu_security_settings->count & 0x000000ff);
1619         ctr_block[4] = (pdu_security_settings->bearer << 3) + (pdu_security_settings->direction << 2);
1620 
1621         /* Open gcrypt handle */
1622         gcrypt_err = gcry_cipher_open(&cypher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0);
1623         if (gcrypt_err != 0) {
1624             return tvb;
1625         }
1626 
1627         /* Set the key */
1628         gcrypt_err = gcry_cipher_setkey(cypher_hd, pdu_security_settings->cipherKey, 16);
1629         if (gcrypt_err != 0) {
1630             gcry_cipher_close(cypher_hd);
1631             return tvb;
1632         }
1633 
1634         /* Set the CTR */
1635         gcrypt_err = gcry_cipher_setctr(cypher_hd, ctr_block, 16);
1636         if (gcrypt_err != 0) {
1637             gcry_cipher_close(cypher_hd);
1638             return tvb;
1639         }
1640 
1641         /* Extract the encrypted data into a buffer */
1642         payload_length = tvb_captured_length_remaining(tvb, *offset);
1643         decrypted_data = (guint8 *)tvb_memdup(pinfo->pool, tvb, *offset, payload_length);
1644 
1645         /* Decrypt the actual data */
1646         gcrypt_err = gcry_cipher_decrypt(cypher_hd,
1647                                          decrypted_data, payload_length,
1648                                          NULL, 0);
1649         if (gcrypt_err != 0) {
1650             gcry_cipher_close(cypher_hd);
1651             return tvb;
1652         }
1653 
1654         /* Close gcrypt handle */
1655         gcry_cipher_close(cypher_hd);
1656     }
1657 
1658 #ifdef HAVE_SNOW3G
1659     /* SNOW-3G */
1660     if (pdu_security_settings->ciphering == eea1) {
1661         /* Extract the encrypted data into a buffer */
1662         payload_length = tvb_captured_length_remaining(tvb, *offset);
1663         decrypted_data = (guint8 *)tvb_memdup(pinfo->pool, tvb, *offset, payload_length);
1664 
1665         /* Do the algorithm */
1666         snow3g_f8(pdu_security_settings->cipherKey,
1667                   pdu_security_settings->count,
1668                   pdu_security_settings->bearer,
1669                   pdu_security_settings->direction,
1670                   decrypted_data, payload_length*8);
1671     }
1672 #endif
1673 
1674 #ifdef HAVE_ZUC
1675     /* ZUC */
1676     if (pdu_security_settings->ciphering == eea3) {
1677         /* Extract the encrypted data into a buffer */
1678         payload_length = tvb_captured_length_remaining(tvb, *offset);
1679         decrypted_data = (guint8 *)tvb_memdup(pinfo->pool, tvb, *offset, payload_length);
1680 
1681         /* Do the algorithm.  Assuming implementation works in-place */
1682         zuc_f8(pdu_security_settings->cipherKey,
1683                pdu_security_settings->count,
1684                pdu_security_settings->bearer,
1685                pdu_security_settings->direction,
1686                payload_length*8,                   /* Length is in bits */
1687                (guint32*)decrypted_data, (guint32*)decrypted_data);
1688     }
1689 #endif
1690 
1691     /* Create tvb for resulting deciphered sdu */
1692     decrypted_tvb = tvb_new_child_real_data(tvb, decrypted_data, payload_length, payload_length);
1693     add_new_data_source(pinfo, decrypted_tvb, "Deciphered Payload");
1694 
1695     /* Return deciphered data, i.e. beginning of new tvb */
1696     *offset = 0;
1697     *deciphered = TRUE;
1698     return decrypted_tvb;
1699 }
1700 
1701 
1702 /* Try to calculate digest to compare with that found in frame. */
1703 #if defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */ || defined(HAVE_ZUC)
1704 /* We can calculate it for at least some integrity types */
calculate_digest(pdu_security_settings_t * pdu_security_settings,guint8 header,tvbuff_t * tvb,packet_info * pinfo,gint offset,gboolean * calculated)1705 static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings, guint8 header,
1706                                 tvbuff_t *tvb, packet_info *pinfo, gint offset, gboolean *calculated)
1707 {
1708     *calculated = FALSE;
1709 
1710     if (pdu_security_settings->integrity == eia0) {
1711         /* Should be zero in this case */
1712         *calculated = TRUE;
1713         return 0;
1714     }
1715 
1716     /* Can't calculate if don't have valid integrity key */
1717     if (!pdu_security_settings->integrityKeyValid) {
1718         return 0;
1719     }
1720 
1721     /* Can only do if indicated in preferences */
1722     if (!global_pdcp_check_integrity) {
1723         return 0;
1724     }
1725 
1726     switch (pdu_security_settings->integrity) {
1727 
1728 #ifdef HAVE_SNOW3G
1729         case eia1:
1730             {
1731                 /* SNOW3G */
1732                 guint8  *mac;
1733                 gint message_length = tvb_captured_length_remaining(tvb, offset) - 4;
1734                 guint8 *message_data = (guint8 *)wmem_alloc0(pinfo->pool, message_length+5);
1735 
1736                 /* TS 33.401 B.2.2 */
1737 
1738                 /* Data is header byte */
1739                 message_data[0] = header;
1740                 /* Followed by the decrypted message (but not the digest bytes) */
1741                 tvb_memcpy(tvb, message_data+1, offset, message_length);
1742 
1743                 mac = (u8*)snow3g_f9(pdu_security_settings->integrityKey,
1744                                      pdu_security_settings->count,
1745                                      /* 'Fresh' is the bearer bits then zeros */
1746                                      pdu_security_settings->bearer << 27,
1747                                      pdu_security_settings->direction,
1748                                      message_data,
1749                                      (message_length+1)*8);
1750 
1751                 *calculated = TRUE;
1752                 return ((mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]);
1753             }
1754 #endif
1755 
1756 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
1757         case eia2:
1758             {
1759                 /* AES */
1760                 gcry_mac_hd_t mac_hd;
1761                 int gcrypt_err;
1762                 gint message_length;
1763                 guint8 *message_data;
1764                 guint8  mac[4];
1765                 size_t read_digest_length = 4;
1766 
1767                 /* Open gcrypt handle */
1768                 gcrypt_err = gcry_mac_open(&mac_hd, GCRY_MAC_CMAC_AES, 0, NULL);
1769                 if (gcrypt_err != 0) {
1770                     return 0;
1771                 }
1772 
1773                 /* Set the key */
1774                 gcrypt_err = gcry_mac_setkey(mac_hd, pdu_security_settings->integrityKey, 16);
1775                 if (gcrypt_err != 0) {
1776                     gcry_mac_close(mac_hd);
1777                     return 0;
1778                 }
1779 
1780                 /* TS 33.401 B.2.3 */
1781 
1782                 /* Extract the encrypted data into a buffer */
1783                 message_length = tvb_captured_length_remaining(tvb, offset) - 4;
1784                 message_data = (guint8 *)wmem_alloc0(pinfo->pool, message_length+9);
1785                 message_data[0] = (pdu_security_settings->count & 0xff000000) >> 24;
1786                 message_data[1] = (pdu_security_settings->count & 0x00ff0000) >> 16;
1787                 message_data[2] = (pdu_security_settings->count & 0x0000ff00) >> 8;
1788                 message_data[3] = (pdu_security_settings->count & 0x000000ff);
1789                 message_data[4] = (pdu_security_settings->bearer << 3) + (pdu_security_settings->direction << 2);
1790                 /* rest of first 8 bytes are left as zeroes... */
1791                 /* Now the header byte */
1792                 message_data[8] = header;
1793                 /* Followed by the decrypted message (but not the digest bytes) */
1794                 tvb_memcpy(tvb, message_data+9, offset, message_length);
1795 
1796                 /* Pass in the message */
1797                 gcrypt_err = gcry_mac_write(mac_hd, message_data, message_length+9);
1798                 if (gcrypt_err != 0) {
1799                     gcry_mac_close(mac_hd);
1800                     return 0;
1801                 }
1802 
1803                 /* Read out the digest */
1804                 gcrypt_err = gcry_mac_read(mac_hd, mac, &read_digest_length);
1805                 if (gcrypt_err != 0) {
1806                     gcry_mac_close(mac_hd);
1807                     return 0;
1808                 }
1809 
1810                 /* Now close the mac handle */
1811                 gcry_mac_close(mac_hd);
1812 
1813                 *calculated = TRUE;
1814                 return ((mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]);
1815             }
1816 #endif
1817 #ifdef HAVE_ZUC
1818         case eia3:
1819             {
1820                 /* ZUC */
1821                 guint32  mac;
1822                 gint message_length = tvb_captured_length_remaining(tvb, offset) - 4;
1823                 guint8 *message_data = (guint8 *)wmem_alloc0(pinfo->pool, message_length+5);
1824 
1825                 /* Data is header byte */
1826                 message_data[0] = header;
1827                 /* Followed by the decrypted message (but not the digest bytes) */
1828                 tvb_memcpy(tvb, message_data+1, offset, message_length);
1829 
1830                 zuc_f9(pdu_security_settings->integrityKey,
1831                        pdu_security_settings->count,
1832                        pdu_security_settings->direction,
1833                        pdu_security_settings->bearer,
1834                        (message_length+1)*8,
1835                        (guint32*)message_data,
1836                        &mac);
1837 
1838                 *calculated = TRUE;
1839                 return mac;
1840             }
1841 #endif
1842 
1843         default:
1844             /* Can't calculate */
1845             *calculated = FALSE;
1846             return 0;
1847     }
1848 }
1849 #else /* defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 || defined(HAVE_ZUC) */
1850 /* We can't calculate it for any integrity types other than eia0 */
calculate_digest(pdu_security_settings_t * pdu_security_settings,guint8 header _U_,tvbuff_t * tvb _U_,packet_info * pinfo _U_,gint offset _U_,gboolean * calculated)1851 static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings, guint8 header _U_,
1852                                 tvbuff_t *tvb _U_, packet_info *pinfo _U_, gint offset _U_, gboolean *calculated)
1853 {
1854     *calculated = FALSE;
1855 
1856     if (pdu_security_settings->integrity == eia0) {
1857         /* Should be zero in this case */
1858         *calculated = TRUE;
1859     }
1860 
1861     /* Otherwise, we can't calculate it */
1862     return 0;
1863 }
1864 #endif /* defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 || defined(HAVE_ZUC) */
1865 
1866 /******************************/
1867 /* Main dissection function.  */
dissect_pdcp_lte(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1868 static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1869 {
1870     const char           *mode;
1871     proto_tree           *pdcp_tree           = NULL;
1872     proto_item           *root_ti             = NULL;
1873     proto_item           *ti                  = NULL;
1874     gint                  offset              = 0;
1875     struct pdcp_lte_info *p_pdcp_info;
1876     tvbuff_t             *rohc_tvb            = NULL;
1877     guint32               reserved_value;
1878     guint32               seqnum = 0;
1879 
1880     pdcp_lte_security_info_t *current_security = NULL;   /* current security for this UE */
1881     pdcp_lte_security_info_t *pdu_security;              /* security in place for this PDU */
1882     proto_tree *security_tree = NULL;
1883     proto_item *security_ti;
1884     tvbuff_t *payload_tvb;
1885     pdu_security_settings_t  pdu_security_settings;
1886     gboolean payload_deciphered = FALSE;
1887 
1888     /* Initialise security settings */
1889     memset(&pdu_security_settings, 0, sizeof(pdu_security_settings));
1890 
1891     /* Set protocol name. */
1892     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDCP-LTE");
1893 
1894     /* Look for attached packet info! */
1895     p_pdcp_info = (struct pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0);
1896     /* Can't dissect anything without it... */
1897     if (p_pdcp_info == NULL) {
1898         return 0;
1899     }
1900 
1901     /* Don't want to overwrite the RLC Info column if configured not to */
1902     if ((global_pdcp_lte_layer_to_show == ShowRLCLayer) &&
1903         (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) != NULL)) {
1904 
1905         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
1906     }
1907     else {
1908         /* TODO: won't help with multiple PDCP-or-traffic PDUs / frame... */
1909         col_clear(pinfo->cinfo, COL_INFO);
1910         col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
1911     }
1912 
1913     /* Create pdcp tree. */
1914     if (tree) {
1915         root_ti = proto_tree_add_item(tree, proto_pdcp_lte, tvb, offset, -1, ENC_NA);
1916         pdcp_tree = proto_item_add_subtree(root_ti, ett_pdcp);
1917     }
1918 
1919     /* Set mode string */
1920     mode = val_to_str_const(p_pdcp_info->rohc.mode, rohc_mode_vals, "Error");
1921 
1922     /*****************************************************/
1923     /* Show configuration (attached packet) info in tree */
1924     if (pdcp_tree) {
1925         show_pdcp_config(pinfo, tvb, pdcp_tree, p_pdcp_info);
1926     }
1927 
1928     /* Show ROHC mode */
1929     if (p_pdcp_info->rohc.rohc_compression) {
1930         col_append_fstr(pinfo->cinfo, COL_INFO, " (mode=%c)", mode[0]);
1931     }
1932 
1933     /***************************************/
1934     /* UE security algorithms              */
1935     if (!PINFO_FD_VISITED(pinfo)) {
1936         /* Look up current state by UEID */
1937         current_security = (pdcp_lte_security_info_t*)wmem_map_lookup(pdcp_security_hash,
1938                                                                       GUINT_TO_POINTER((guint)p_pdcp_info->ueid));
1939         if (current_security != NULL) {
1940             /* Store any result for this frame in the result table */
1941             pdcp_lte_security_info_t *security_to_store = wmem_new(wmem_file_scope(), pdcp_lte_security_info_t);
1942             /* Take a deep copy of the settings */
1943             *security_to_store = *current_security;
1944             wmem_map_insert(pdcp_security_result_hash,
1945                             get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->num, TRUE),
1946                             security_to_store);
1947         }
1948         else {
1949             /* No entry added from RRC, but still use configured defaults */
1950             if ((global_default_ciphering_algorithm != eea0) ||
1951                 (global_default_integrity_algorithm != eia0)) {
1952                 /* Copy algorithms from preference defaults */
1953                 pdcp_lte_security_info_t *security_to_store = wmem_new0(wmem_file_scope(), pdcp_lte_security_info_t);
1954                 security_to_store->ciphering = global_default_ciphering_algorithm;
1955                 security_to_store->integrity = global_default_integrity_algorithm;
1956                 security_to_store->seen_next_ul_pdu = TRUE;
1957                 wmem_map_insert(pdcp_security_result_hash,
1958                                 get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->num, TRUE),
1959                                 security_to_store);
1960             }
1961         }
1962     }
1963 
1964     /* Show security settings for this PDU */
1965     pdu_security = (pdcp_lte_security_info_t*)wmem_map_lookup(pdcp_security_result_hash,
1966                                                               get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->num, FALSE));
1967     if (pdu_security != NULL) {
1968         /* Create subtree */
1969         security_ti = proto_tree_add_string_format(pdcp_tree,
1970                                                    hf_pdcp_lte_security,
1971                                                    tvb, 0, 0,
1972                                                    "", "UE Security");
1973         security_tree = proto_item_add_subtree(security_ti, ett_pdcp_security);
1974         proto_item_set_generated(security_ti);
1975 
1976         /* Setup frame */
1977         if (pinfo->num > pdu_security->configuration_frame) {
1978             ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_setup_frame,
1979                                      tvb, 0, 0, pdu_security->configuration_frame);
1980             proto_item_set_generated(ti);
1981         }
1982 
1983         /* Ciphering */
1984         ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_ciphering_algorithm,
1985                                  tvb, 0, 0, pdu_security->ciphering);
1986         proto_item_set_generated(ti);
1987 
1988         /* Integrity */
1989         ti = proto_tree_add_uint(security_tree, hf_pdcp_lte_security_integrity_algorithm,
1990                                  tvb, 0, 0, pdu_security->integrity);
1991         proto_item_set_generated(ti);
1992 
1993         /* Show algorithms in security root */
1994         proto_item_append_text(security_ti, " (ciphering=%s, integrity=%s)",
1995                                val_to_str_const(pdu_security->ciphering, ciphering_algorithm_vals, "Unknown"),
1996                                val_to_str_const(pdu_security->integrity, integrity_algorithm_vals, "Unknown"));
1997 
1998         pdu_security_settings.ciphering = pdu_security->ciphering;
1999         pdu_security_settings.integrity = pdu_security->integrity;
2000     }
2001 
2002 
2003     /***********************************/
2004     /* Handle PDCP header (if present) */
2005     if (!p_pdcp_info->no_header_pdu) {
2006 
2007         seqnum = 0;
2008         gboolean seqnum_set = FALSE;
2009 
2010         guint8  first_byte = tvb_get_guint8(tvb, offset);
2011 
2012         /*****************************/
2013         /* Signalling plane messages */
2014         if (p_pdcp_info->plane == SIGNALING_PLANE) {
2015             /* Verify 3 reserved bits are 0 */
2016             guint8 reserved = (first_byte & 0xe0) >> 5;
2017             ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_control_plane_reserved,
2018                                      tvb, offset, 1, ENC_BIG_ENDIAN);
2019             if (reserved != 0) {
2020                 expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2021                                        "PDCP signalling header reserved bits not zero");
2022             }
2023 
2024             /* 5-bit sequence number */
2025             proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_seq_num_5, tvb, offset, 1, ENC_BIG_ENDIAN, &seqnum);
2026             seqnum_set = TRUE;
2027             write_pdu_label_and_info(root_ti, pinfo, " sn=%-2u ", seqnum);
2028             offset++;
2029 
2030             if (tvb_captured_length_remaining(tvb, offset) == 0) {
2031                 /* Only PDCP header was captured, stop dissection here */
2032                 return offset;
2033             }
2034         }
2035         else if (p_pdcp_info->plane == USER_PLANE) {
2036 
2037             /**********************************/
2038             /* User-plane messages            */
2039             guint8 pdu_type = (first_byte & 0x80) >> 7;
2040 
2041             /* Data/Control flag */
2042             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_data_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2043 
2044             if (pdu_type == 1) {
2045                 /*****************************/
2046                 /* User-plane Data            */
2047 
2048                 /* Number of sequence number bits depends upon config */
2049                 switch (p_pdcp_info->seqnum_length) {
2050                     case PDCP_SN_LENGTH_7_BITS:
2051                         proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_seq_num_7, tvb, offset, 1, ENC_BIG_ENDIAN, &seqnum);
2052                         seqnum_set = TRUE;
2053                         offset++;
2054                         break;
2055                     case PDCP_SN_LENGTH_12_BITS:
2056                         /* 3 reserved bits */
2057                         ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved3, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2058 
2059                         /* Complain if not 0 */
2060                         if (reserved_value != 0) {
2061                             expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2062                                                    "Reserved bits have value 0x%x - should be 0x0",
2063                                                    reserved_value);
2064                         }
2065 
2066                         /* 12-bit sequence number */
2067                         proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_seq_num_12, tvb, offset, 2, ENC_BIG_ENDIAN, &seqnum);
2068                         seqnum_set = TRUE;
2069                         offset += 2;
2070                         break;
2071                     case PDCP_SN_LENGTH_15_BITS:
2072                         proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_seq_num_15, tvb, offset, 2, ENC_BIG_ENDIAN, &seqnum);
2073                         seqnum_set = TRUE;
2074                         offset += 2;
2075                         break;
2076                     case PDCP_SN_LENGTH_18_BITS:
2077                         /* Polling bit */
2078                         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_polling, tvb, offset, 1, ENC_BIG_ENDIAN);
2079 
2080                         /* 4 reserved bits */
2081                         ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved5, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2082 
2083                         /* Complain if not 0 */
2084                         if (reserved_value != 0) {
2085                             expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2086                                                    "Reserved bits have value 0x%x - should be 0x0",
2087                                                    reserved_value);
2088                         }
2089 
2090                         /* 18-bit sequence number */
2091                         proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_seq_num_18, tvb, offset, 3, ENC_BIG_ENDIAN, &seqnum);
2092                         seqnum_set = TRUE;
2093                         offset += 3;
2094                         break;
2095                     default:
2096                         /* Not a recognised data format!!!!! */
2097                         return 1;
2098                 }
2099 
2100                 write_pdu_label_and_info(root_ti, pinfo, " (SN=%u)", seqnum);
2101             }
2102             else {
2103                 /*******************************/
2104                 /* User-plane Control messages */
2105                 guint32 control_pdu_type;
2106                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_control_pdu_type, tvb,
2107                                              offset, 1, ENC_BIG_ENDIAN, &control_pdu_type);
2108 
2109                 switch (control_pdu_type) {
2110                     case 0:    /* PDCP status report */
2111                         {
2112                             guint32 fms;
2113                             guint32 modulo;
2114                             guint   not_received = 0;
2115                             guint   sn, i, j, l;
2116                             guint32 len, bit_offset;
2117                             proto_tree *bitmap_tree;
2118                             proto_item *bitmap_ti = NULL;
2119                             gchar  *buff = NULL;
2120                             #define BUFF_SIZE 57
2121 
2122                             if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_12_BITS) {
2123                                 /* First-Missing-Sequence SN */
2124                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms, tvb,
2125                                                              offset, 2, ENC_BIG_ENDIAN, &fms);
2126                                 sn = (fms + 1) % 4096;
2127                                 offset += 2;
2128                                 modulo = 4096;
2129                             } else if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_15_BITS) {
2130 
2131                                 /* 5 reserved bits */
2132                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved4, tvb, offset, 2, ENC_BIG_ENDIAN, &reserved_value);
2133                                 offset++;
2134 
2135                                 /* Complain if not 0 */
2136                                 if (reserved_value != 0) {
2137                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2138                                                            "Reserved bits have value 0x%x - should be 0x0",
2139                                                            reserved_value);
2140                                 }
2141 
2142                                 /* First-Missing-Sequence SN */
2143                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms2, tvb,
2144                                                              offset, 2, ENC_BIG_ENDIAN, &fms);
2145                                 sn = (fms + 1) % 32768;
2146                                 offset += 2;
2147                                 modulo = 32768;
2148                             } else {
2149                                 /* 2 reserved bits */
2150                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved6, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2151 
2152                                 /* Complain if not 0 */
2153                                 if (reserved_value != 0) {
2154                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2155                                                            "Reserved bits have value 0x%x - should be 0x0",
2156                                                            reserved_value);
2157                                 }
2158 
2159                                 /* First-Missing-Sequence SN */
2160                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms3, tvb,
2161                                                              offset, 3, ENC_BIG_ENDIAN, &fms);
2162                                 sn = (fms + 1) % 262144;
2163                                 offset += 3;
2164                                 modulo = 262144;
2165                             }
2166 
2167                             /* Bitmap tree */
2168                             if (tvb_reported_length_remaining(tvb, offset) > 0) {
2169                                 bitmap_ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_bitmap, tvb,
2170                                                                 offset, -1, ENC_NA);
2171                                 bitmap_tree = proto_item_add_subtree(bitmap_ti, ett_pdcp_report_bitmap);
2172 
2173                                 buff = (gchar *)wmem_alloc(pinfo->pool, BUFF_SIZE);
2174                                 len = tvb_reported_length_remaining(tvb, offset);
2175                                 bit_offset = offset<<3;
2176 
2177                                 /* For each byte... */
2178                                 for (i=0; i<len; i++) {
2179                                     guint8 bits = tvb_get_bits8(tvb, bit_offset, 8);
2180                                     for (l=0, j=0; l<8; l++) {
2181                                         if ((bits << l) & 0x80) {
2182                                             if (bitmap_tree) {
2183                                                 j += g_snprintf(&buff[j], BUFF_SIZE-j, "%6u,", (unsigned)(sn+(8*i)+l)%modulo);
2184                                             }
2185                                         } else {
2186                                             if (bitmap_tree) {
2187                                                 j += (guint)g_strlcpy(&buff[j], "      ,", BUFF_SIZE-j);
2188                                             }
2189                                             not_received++;
2190                                         }
2191                                     }
2192                                     if (bitmap_tree) {
2193                                         proto_tree_add_uint_format(bitmap_tree, hf_pdcp_lte_bitmap_byte, tvb, bit_offset/8, 1, bits, "%s", buff);
2194                                     }
2195                                     bit_offset += 8;
2196                                 }
2197                             }
2198 
2199                             if (bitmap_ti != NULL) {
2200                                 proto_item_append_text(bitmap_ti, " (%u SNs not received)", not_received);
2201                             }
2202                             write_pdu_label_and_info(root_ti, pinfo, " Status Report (fms=%u) not-received=%u",
2203                                                     fms, not_received);
2204                         }
2205                         return 1;
2206 
2207                     case 1:     /* ROHC Feedback */
2208                         offset++;
2209                         break;  /* Drop-through to dissect feedback */
2210 
2211 
2212                     case 2:     /* LWA status report */
2213                         {
2214                             guint32 fms;
2215                             guint32 nmp;
2216 
2217                             if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_12_BITS) {
2218                                 /* First-Missing-Sequence SN */
2219                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms, tvb,
2220                                                              offset, 2, ENC_BIG_ENDIAN, &fms);
2221                                 offset += 2;
2222 
2223                                 /* HRW */
2224                                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_hrw, tvb,
2225                                                     offset, 2, ENC_BIG_ENDIAN);
2226                                 offset += 1;
2227 
2228                                 /* NMP */
2229                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_nmp, tvb,
2230                                                              offset, 2, ENC_BIG_ENDIAN, &nmp);
2231                                 offset += 2;
2232                             } else if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_15_BITS) {
2233                                 /* 5 reserved bits */
2234                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved4, tvb,
2235                                                                   offset, 2, ENC_BIG_ENDIAN, &reserved_value);
2236                                 offset++;
2237                                 /* Complain if not 0 */
2238                                 if (reserved_value != 0) {
2239                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2240                                                            "Reserved bits have value 0x%x - should be 0x0",
2241                                                            reserved_value);
2242                                 }
2243 
2244                                 /* First-Missing-Sequence SN */
2245                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms2, tvb,
2246                                                              offset, 2, ENC_BIG_ENDIAN, &fms);
2247                                 offset += 2;
2248 
2249                                 /* 1 reserved bit */
2250                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved7, tvb,
2251                                                                   offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2252                                 /* Complain if not 0 */
2253                                 if (reserved_value) {
2254                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2255                                                            "Reserved bits have value 0x1 - should be 0x0");
2256                                 }
2257 
2258                                 /* HRW */
2259                                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_hrw2, tvb,
2260                                                     offset, 2, ENC_BIG_ENDIAN);
2261                                 offset += 2;
2262 
2263                                 /* 1 reserved bit */
2264                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved7, tvb,
2265                                                                   offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2266                                 /* Complain if not 0 */
2267                                 if (reserved_value) {
2268                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2269                                                            "Reserved bits have value 0x1 - should be 0x0");
2270                                 }
2271 
2272                                 /* NMP */
2273                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_nmp2, tvb,
2274                                                     offset, 2, ENC_BIG_ENDIAN, &nmp);
2275                                 offset += 2;
2276                             } else {
2277                                 /* 2 reserved bits */
2278                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved6,
2279                                                                   tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2280                                 /* Complain if not 0 */
2281                                 if (reserved_value != 0) {
2282                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2283                                                            "Reserved bits have value 0x%x - should be 0x0",
2284                                                            reserved_value);
2285                                 }
2286 
2287                                 /* First-Missing-Sequence SN */
2288                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_fms3, tvb,
2289                                                              offset, 3, ENC_BIG_ENDIAN, &fms);
2290                                 offset += 3;
2291 
2292                                 /* HRW */
2293                                 proto_tree_add_item(pdcp_tree, hf_pdcp_lte_hrw3, tvb,
2294                                                     offset, 3, ENC_BIG_ENDIAN);
2295                                 offset += 2;
2296 
2297                                 /* 4 reserved bits */
2298                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved8,
2299                                                                   tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2300                                 /* Complain if not 0 */
2301                                 if (reserved_value != 0) {
2302                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2303                                                            "Reserved bits have value 0x%x - should be 0x0",
2304                                                            reserved_value);
2305                                 }
2306 
2307                                 /* NMP */
2308                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_nmp3, tvb,
2309                                                     offset, 3, ENC_BIG_ENDIAN, &nmp);
2310                                 offset += 3;
2311                             }
2312 
2313                             write_pdu_label_and_info(root_ti, pinfo, " LWA Status Report (fms=%u) not-received=%u",
2314                                                      fms, nmp);
2315                         }
2316                         return 1;
2317 
2318                     case 3:     /* LWA end-marker packet */
2319                         {
2320                             guint32 lsn;
2321 
2322                             if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_12_BITS) {
2323                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_lsn, tvb,
2324                                                              offset, 2, ENC_BIG_ENDIAN, &lsn);
2325                                 offset += 2;
2326                             } else if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_15_BITS) {
2327                                 /* 5 reserved bits */
2328                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved4, tvb,
2329                                                                   offset, 2, ENC_BIG_ENDIAN, &reserved_value);
2330                                 offset++;
2331                                 /* Complain if not 0 */
2332                                 if (reserved_value != 0) {
2333                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2334                                                            "Reserved bits have value 0x%x - should be 0x0",
2335                                                            reserved_value);
2336                                 }
2337 
2338                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_lsn2, tvb,
2339                                                              offset, 2, ENC_BIG_ENDIAN, &lsn);
2340                                 offset += 2;
2341                             } else {
2342                                 /* 2 reserved bits */
2343                                 ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_reserved6,
2344                                                                   tvb, offset, 1, ENC_BIG_ENDIAN, &reserved_value);
2345                                 /* Complain if not 0 */
2346                                 if (reserved_value != 0) {
2347                                     expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero,
2348                                                            "Reserved bits have value 0x%x - should be 0x0",
2349                                                            reserved_value);
2350                                 }
2351 
2352                                 proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_lsn3, tvb,
2353                                                              offset, 3, ENC_BIG_ENDIAN, &lsn);
2354                                 offset += 3;
2355                             }
2356 
2357                             write_pdu_label_and_info(root_ti, pinfo, " LWA End-Marker Packet (lsn=%u)", lsn);
2358                         }
2359                         return 1;
2360                     default:    /* Reserved */
2361                         return 1;
2362                 }
2363             }
2364         }
2365         else {
2366             /* Invalid plane setting...! */
2367             write_pdu_label_and_info(root_ti, pinfo, " - INVALID PLANE (%u)",
2368                                      p_pdcp_info->plane);
2369             return 1;
2370         }
2371 
2372         /* Do sequence analysis if configured to. */
2373         if (seqnum_set) {
2374             gboolean do_analysis = FALSE;
2375 
2376             switch (global_pdcp_check_sequence_numbers) {
2377                 case FALSE:
2378                     break;
2379                 case SEQUENCE_ANALYSIS_RLC_ONLY:
2380                     if ((p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) != NULL) &&
2381                         !p_pdcp_info->is_retx) {
2382                         do_analysis = TRUE;
2383                     }
2384                     break;
2385                 case SEQUENCE_ANALYSIS_PDCP_ONLY:
2386                     if (p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0) == NULL) {
2387                         do_analysis = TRUE;
2388                     }
2389                     break;
2390             }
2391 
2392             if (do_analysis) {
2393                 checkChannelSequenceInfo(pinfo, tvb, p_pdcp_info,
2394                                          seqnum, pdcp_tree, security_tree,
2395                                          &pdu_security_settings);
2396             }
2397         }
2398     }
2399     else {
2400         /* Show that it's a no-header PDU */
2401         write_pdu_label_and_info(root_ti, pinfo, " No-Header ");
2402     }
2403 
2404     /*******************************************************/
2405     /* Now deal with the payload                           */
2406     /*******************************************************/
2407 
2408     payload_tvb = decipher_payload(tvb, pinfo, &offset, &pdu_security_settings, p_pdcp_info,
2409                                    pdu_security ? pdu_security->seen_next_ul_pdu: FALSE, &payload_deciphered);
2410 
2411     if (p_pdcp_info->plane == SIGNALING_PLANE) {
2412         guint32 data_length;
2413         guint32 mac;
2414         proto_item *mac_ti;
2415         guint32  calculated_digest = 0;
2416         gboolean digest_was_calculated = FALSE;
2417 
2418         /* Compute payload length (no MAC on common control channels) */
2419         data_length = tvb_reported_length_remaining(payload_tvb, offset) - ((p_pdcp_info->channelType == Channel_DCCH) ? 4 : 0);
2420 
2421         /* Try to calculate digest so we can check it */
2422         if (global_pdcp_check_integrity && (p_pdcp_info->channelType == Channel_DCCH)) {
2423             calculated_digest = calculate_digest(&pdu_security_settings, tvb_get_guint8(tvb, 0), payload_tvb,
2424                                                  pinfo, offset, &digest_was_calculated);
2425         }
2426 
2427         /* RRC data is all but last 4 bytes.
2428            Call lte-rrc dissector (according to direction and channel type) if we have valid data */
2429         if ((global_pdcp_dissect_signalling_plane_as_rrc) &&
2430             ((pdu_security == NULL) || (pdu_security->ciphering == eea0) || payload_deciphered || !pdu_security->seen_next_ul_pdu)) {
2431 
2432             /* Get appropriate dissector handle */
2433             dissector_handle_t rrc_handle = lookup_rrc_dissector_handle(p_pdcp_info);
2434 
2435             if (rrc_handle != 0) {
2436                 /* Call RRC dissector if have one */
2437                 tvbuff_t *rrc_payload_tvb = tvb_new_subset_length(payload_tvb, offset, data_length);
2438                 gboolean was_writable = col_get_writable(pinfo->cinfo, COL_INFO);
2439 
2440                 /* We always want to see this in the info column */
2441                 col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
2442 
2443                 call_dissector_only(rrc_handle, rrc_payload_tvb, pinfo, pdcp_tree, NULL);
2444 
2445                 /* Restore to whatever it was */
2446                 col_set_writable(pinfo->cinfo, COL_INFO, was_writable);
2447             }
2448             else {
2449                  /* Just show data */
2450                  proto_tree_add_item(pdcp_tree, hf_pdcp_lte_signalling_data, payload_tvb, offset,
2451                                      data_length, ENC_NA);
2452             }
2453 
2454             if (!PINFO_FD_VISITED(pinfo) &&
2455                 (current_security != NULL) && !current_security->seen_next_ul_pdu &&
2456                 p_pdcp_info->direction == DIRECTION_UPLINK)
2457             {
2458                 /* i.e. we have already seen SecurityModeResponse! */
2459                 current_security->seen_next_ul_pdu = TRUE;
2460             }
2461 
2462         }
2463         else {
2464             /* Just show as unparsed data */
2465             proto_tree_add_item(pdcp_tree, hf_pdcp_lte_signalling_data, payload_tvb, offset,
2466                                 data_length, ENC_NA);
2467         }
2468 
2469         offset += data_length;
2470 
2471         if (p_pdcp_info->channelType == Channel_DCCH) {
2472             /* Last 4 bytes are MAC */
2473             mac = tvb_get_ntohl(payload_tvb, offset);
2474             mac_ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_mac, payload_tvb, offset, 4, ENC_BIG_ENDIAN);
2475             offset += 4;
2476 
2477             if (digest_was_calculated) {
2478                 /* Compare what was found with calculated value! */
2479                 if (mac != calculated_digest) {
2480                     expert_add_info_format(pinfo, mac_ti, &ei_pdcp_lte_digest_wrong,
2481                                            "MAC-I Digest wrong - calculated %08x but found %08x",
2482                                            calculated_digest, mac);
2483                     proto_item_append_text(mac_ti, " (but calculated %08x !)", calculated_digest);
2484                 }
2485                 else {
2486                     proto_item_append_text(mac_ti, " [Matches calculated result]");
2487                 }
2488             }
2489 
2490             col_append_fstr(pinfo->cinfo, COL_INFO, " MAC=0x%08x (%u bytes data)",
2491                             mac, data_length);
2492         } else {
2493             col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes data)", data_length);
2494         }
2495     }
2496     else if (tvb_captured_length_remaining(payload_tvb, offset)) {
2497         /* User-plane payload here */
2498 
2499         /* If not compressed with ROHC, show as user-plane data */
2500         if (!p_pdcp_info->rohc.rohc_compression) {
2501             gint payload_length = tvb_reported_length_remaining(payload_tvb, offset);
2502             if (payload_length > 0) {
2503                 if (p_pdcp_info->plane == USER_PLANE) {
2504 
2505                     /* Not attempting to decode payload if ciphering is enabled
2506                        (and NULL ciphering is not being used) */
2507                     if (global_pdcp_dissect_user_plane_as_ip &&
2508                         ((pdu_security == NULL) || (pdu_security->ciphering == eea0) || payload_deciphered))
2509                     {
2510                         tvbuff_t *ip_payload_tvb = tvb_new_subset_remaining(payload_tvb, offset);
2511 
2512                         /* Don't update info column for ROHC unless configured to */
2513                         if (global_pdcp_lte_layer_to_show != ShowTrafficLayer) {
2514                             col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
2515                         }
2516 
2517                         switch (tvb_get_guint8(ip_payload_tvb, 0) & 0xf0) {
2518                             case 0x40:
2519                                 call_dissector_only(ip_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
2520                                 break;
2521                             case 0x60:
2522                                 call_dissector_only(ipv6_handle, ip_payload_tvb, pinfo, pdcp_tree, NULL);
2523                                 break;
2524                             default:
2525                                 call_data_dissector(ip_payload_tvb, pinfo, pdcp_tree);
2526                                 break;
2527                         }
2528 
2529                         /* Freeze the columns again because we don't want other layers writing to info */
2530                         if (global_pdcp_lte_layer_to_show == ShowTrafficLayer) {
2531                             col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
2532                         }
2533 
2534                     }
2535                     else {
2536                         proto_tree_add_item(pdcp_tree, hf_pdcp_lte_user_plane_data, payload_tvb, offset, -1, ENC_NA);
2537                     }
2538                 }
2539 
2540                 write_pdu_label_and_info(root_ti, pinfo, "(%u bytes data)",
2541                                          payload_length);
2542             }
2543 
2544             /* (there will be no signalling data left at this point) */
2545 
2546             /* Let RLC write to columns again */
2547             col_set_writable(pinfo->cinfo, COL_INFO, global_pdcp_lte_layer_to_show == ShowRLCLayer);
2548 
2549             /* DROPPING OUT HERE IF NOT DOING ROHC! */
2550             return tvb_captured_length(tvb);
2551         }
2552         else {
2553             /***************************/
2554             /* ROHC packets            */
2555             /***************************/
2556 
2557             /* Only attempt ROHC if configured to */
2558             if (!global_pdcp_dissect_rohc) {
2559                 col_append_fstr(pinfo->cinfo, COL_PROTOCOL, "|ROHC(%s)",
2560                                 val_to_str_const(p_pdcp_info->rohc.profile, rohc_profile_vals, "Unknown"));
2561                 return 1;
2562             }
2563 
2564             rohc_tvb = tvb_new_subset_remaining(payload_tvb, offset);
2565 
2566             /* Only enable writing to column if configured to show ROHC */
2567             if (global_pdcp_lte_layer_to_show != ShowTrafficLayer) {
2568                 col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
2569             }
2570             else {
2571                 col_clear(pinfo->cinfo, COL_INFO);
2572             }
2573 
2574             /* Call the ROHC dissector */
2575             call_dissector_with_data(rohc_handle, rohc_tvb, pinfo, tree, &p_pdcp_info->rohc);
2576 
2577             /* Let RLC write to columns again */
2578             col_set_writable(pinfo->cinfo, COL_INFO, global_pdcp_lte_layer_to_show == ShowRLCLayer);
2579         }
2580     }
2581     return tvb_captured_length(tvb);
2582 }
2583 
2584 
proto_register_pdcp_lte(void)2585 void proto_register_pdcp_lte(void)
2586 {
2587     static hf_register_info hf[] =
2588     {
2589         { &hf_pdcp_lte_configuration,
2590             { "Configuration",
2591               "pdcp-lte.configuration", FT_STRING, BASE_NONE, NULL, 0x0,
2592               "Configuration info passed into dissector", HFILL
2593             }
2594         },
2595 
2596         { &hf_pdcp_lte_rohc_compression,
2597             { "ROHC Compression",
2598               "pdcp-lte.rohc.compression", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2599               NULL, HFILL
2600             }
2601         },
2602         { &hf_pdcp_lte_rohc_mode,
2603             { "ROHC Mode",
2604               "pdcp-lte.rohc.mode", FT_UINT8, BASE_DEC, VALS(rohc_mode_vals), 0x0,
2605               NULL, HFILL
2606             }
2607         },
2608         { &hf_pdcp_lte_rohc_rnd,
2609             { "RND",
2610               "pdcp-lte.rohc.rnd", FT_UINT8, BASE_DEC, NULL, 0x0,
2611               "RND of outer ip header", HFILL
2612             }
2613         },
2614         { &hf_pdcp_lte_rohc_udp_checksum_present,
2615             { "UDP Checksum",
2616               "pdcp-lte.rohc.checksum-present", FT_UINT8, BASE_DEC, NULL, 0x0,
2617               "UDP Checksum present", HFILL
2618             }
2619         },
2620         { &hf_pdcp_lte_direction,
2621             { "Direction",
2622               "pdcp-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
2623               "Direction of message", HFILL
2624             }
2625         },
2626         { &hf_pdcp_lte_ueid,
2627             { "UE",
2628               "pdcp-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
2629               "UE Identifier", HFILL
2630             }
2631         },
2632         { &hf_pdcp_lte_channel_type,
2633             { "Channel type",
2634               "pdcp-lte.channel-type", FT_UINT8, BASE_DEC, VALS(logical_channel_vals), 0x0,
2635               NULL, HFILL
2636             }
2637         },
2638         { &hf_pdcp_lte_channel_id,
2639             { "Channel Id",
2640               "pdcp-lte.channel-id", FT_UINT8, BASE_DEC, 0, 0x0,
2641               NULL, HFILL
2642             }
2643         },
2644         { &hf_pdcp_lte_rohc_profile,
2645             { "ROHC profile",
2646               "pdcp-lte.rohc.profile", FT_UINT8, BASE_DEC, VALS(rohc_profile_vals), 0x0,
2647               "ROHC Mode", HFILL
2648             }
2649         },
2650         { &hf_pdcp_lte_no_header_pdu,
2651             { "No Header PDU",
2652               "pdcp-lte.no-header_pdu", FT_UINT8, BASE_DEC, NULL, 0x0,
2653               NULL, HFILL
2654             }
2655         },
2656         { &hf_pdcp_lte_plane,
2657             { "Plane",
2658               "pdcp-lte.plane", FT_UINT8, BASE_DEC, VALS(pdcp_plane_vals), 0x0,
2659               NULL, HFILL
2660             }
2661         },
2662         { &hf_pdcp_lte_seqnum_length,
2663             { "Seqnum length",
2664               "pdcp-lte.seqnum_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2665               "Sequence Number Length", HFILL
2666             }
2667         },
2668 
2669 
2670         { &hf_pdcp_lte_cid_inclusion_info,
2671             { "CID Inclusion Info",
2672               "pdcp-lte.cid-inclusion-info", FT_UINT8, BASE_DEC, NULL, 0x0,
2673               NULL, HFILL
2674             }
2675         },
2676         { &hf_pdcp_lte_large_cid_present,
2677             { "Large CID Present",
2678               "pdcp-lte.large-cid-present", FT_UINT8, BASE_DEC, NULL, 0x0,
2679               NULL, HFILL
2680             }
2681         },
2682 
2683         { &hf_pdcp_lte_control_plane_reserved,
2684             { "Reserved",
2685               "pdcp-lte.reserved", FT_UINT8, BASE_DEC, NULL, 0xe0,
2686               NULL, HFILL
2687             }
2688         },
2689         { &hf_pdcp_lte_seq_num_5,
2690             { "Seq Num",
2691               "pdcp-lte.seq-num", FT_UINT8, BASE_DEC, NULL, 0x1f,
2692               "PDCP Seq num", HFILL
2693             }
2694         },
2695         { &hf_pdcp_lte_seq_num_7,
2696             { "Seq Num",
2697               "pdcp-lte.seq-num", FT_UINT8, BASE_DEC, NULL, 0x7f,
2698               "PDCP Seq num", HFILL
2699             }
2700         },
2701         { &hf_pdcp_lte_reserved3,
2702             { "Reserved",
2703               "pdcp-lte.reserved3", FT_UINT8, BASE_HEX, NULL, 0x70,
2704               "3 reserved bits", HFILL
2705             }
2706         },
2707         { &hf_pdcp_lte_seq_num_12,
2708             { "Seq Num",
2709               "pdcp-lte.seq-num", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2710               "PDCP Seq num", HFILL
2711             }
2712         },
2713         { &hf_pdcp_lte_seq_num_15,
2714             { "Seq Num",
2715               "pdcp-lte.seq-num", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2716               "PDCP Seq num", HFILL
2717             }
2718         },
2719         { &hf_pdcp_lte_polling,
2720             { "Polling",
2721               "pdcp-lte.polling", FT_BOOLEAN, 8, NULL, 0x40,
2722               NULL, HFILL
2723             }
2724         },
2725         { &hf_pdcp_lte_reserved5,
2726             { "Reserved",
2727               "pdcp-lte.reserved5", FT_UINT8, BASE_HEX, NULL, 0x3c,
2728               "4 reserved bits", HFILL
2729             }
2730         },
2731         { &hf_pdcp_lte_seq_num_18,
2732             { "Seq Num",
2733               "pdcp-lte.seq-num", FT_UINT24, BASE_DEC, NULL, 0x03ffff,
2734               "PDCP Seq num", HFILL
2735             }
2736         },
2737         { &hf_pdcp_lte_signalling_data,
2738             { "Signalling Data",
2739               "pdcp-lte.signalling-data", FT_BYTES, BASE_NONE, NULL, 0x0,
2740               NULL, HFILL
2741             }
2742         },
2743         { &hf_pdcp_lte_mac,
2744             { "MAC",
2745               "pdcp-lte.mac", FT_UINT32, BASE_HEX, NULL, 0x0,
2746               NULL, HFILL
2747             }
2748         },
2749         { &hf_pdcp_lte_data_control,
2750             { "PDU Type",
2751               "pdcp-lte.pdu-type", FT_BOOLEAN, 8, TFS(& pdu_type_bit), 0x80,
2752               NULL, HFILL
2753             }
2754         },
2755         { &hf_pdcp_lte_user_plane_data,
2756             { "User-Plane Data",
2757               "pdcp-lte.user-data", FT_BYTES, BASE_NONE, NULL, 0x0,
2758               NULL, HFILL
2759             }
2760         },
2761         { &hf_pdcp_lte_control_pdu_type,
2762             { "Control PDU Type",
2763               "pdcp-lte.control-pdu-type", FT_UINT8, BASE_HEX, VALS(control_pdu_type_vals), 0x70,
2764               NULL, HFILL
2765             }
2766         },
2767         { &hf_pdcp_lte_fms,
2768             { "First Missing Sequence Number",
2769               "pdcp-lte.fms", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2770               "First Missing PDCP Sequence Number", HFILL
2771             }
2772         },
2773         { &hf_pdcp_lte_reserved4,
2774             { "Reserved",
2775               "pdcp-lte.reserved4", FT_UINT16, BASE_HEX, NULL, 0x0f80,
2776               "5 reserved bits", HFILL
2777             }
2778         },
2779         { &hf_pdcp_lte_fms2,
2780             { "First Missing Sequence Number",
2781               "pdcp-lte.fms", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2782               "First Missing PDCP Sequence Number", HFILL
2783             }
2784         },
2785         { &hf_pdcp_lte_reserved6,
2786             { "Reserved",
2787               "pdcp-lte.reserved6", FT_UINT8, BASE_HEX, NULL, 0x0c,
2788               "2 reserved bits", HFILL
2789             }
2790         },
2791         { &hf_pdcp_lte_fms3,
2792             { "First Missing Sequence Number",
2793               "pdcp-lte.fms", FT_UINT24, BASE_DEC, NULL, 0x03ffff,
2794               "First Missing PDCP Sequence Number", HFILL
2795             }
2796         },
2797         { &hf_pdcp_lte_bitmap,
2798             { "Bitmap",
2799               "pdcp-lte.bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
2800               "Status report bitmap (0=error, 1=OK)", HFILL
2801             }
2802         },
2803         { &hf_pdcp_lte_bitmap_byte,
2804             { "Bitmap byte",
2805               "pdcp-lte.bitmap.byte", FT_UINT8, BASE_HEX, NULL, 0x0,
2806               NULL, HFILL
2807             }
2808         },
2809         { &hf_pdcp_lte_hrw,
2810             { "Highest Received Sequence Number on WLAN",
2811               "pdcp-lte.hwr", FT_UINT16, BASE_DEC, NULL, 0xfff0,
2812               NULL, HFILL
2813             }
2814         },
2815         { &hf_pdcp_lte_nmp,
2816             { "Number of Missing PDCP SDUs",
2817               "pdcp-lte.nmp", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2818               NULL, HFILL
2819             }
2820         },
2821         { &hf_pdcp_lte_reserved7,
2822             { "Reserved",
2823               "pdcp-lte.reserved7", FT_UINT8, BASE_HEX, NULL, 0x80,
2824               "1 reserved bit", HFILL
2825             }
2826         },
2827         { &hf_pdcp_lte_hrw2,
2828             { "Highest Received Sequence Number on WLAN",
2829               "pdcp-lte.hwr", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2830               NULL, HFILL
2831             }
2832         },
2833         { &hf_pdcp_lte_nmp2,
2834             { "Number of Missing PDCP SDUs",
2835               "pdcp-lte.nmp", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2836               NULL, HFILL
2837             }
2838         },
2839         { &hf_pdcp_lte_hrw3,
2840             { "Highest Received Sequence Number on WLAN",
2841               "pdcp-lte.hwr", FT_UINT24, BASE_DEC, NULL, 0xffffc0,
2842               NULL, HFILL
2843             }
2844         },
2845         { &hf_pdcp_lte_reserved8,
2846             { "Reserved",
2847               "pdcp-lte.reserved8", FT_UINT8, BASE_HEX, NULL, 0x3c,
2848               "4 reserved bits", HFILL
2849             }
2850         },
2851         { &hf_pdcp_lte_nmp3,
2852             { "Number of Missing PDCP SDUs",
2853               "pdcp-lte.nmp", FT_UINT24, BASE_DEC, NULL, 0x03ffff,
2854               NULL, HFILL
2855             }
2856         },
2857         { &hf_pdcp_lte_lsn,
2858             { "Last PDCP PDU SN ciphered with previous key",
2859               "pdcp-lte.lsn", FT_UINT16, BASE_DEC, NULL, 0x0fff,
2860               NULL, HFILL
2861             }
2862         },
2863         { &hf_pdcp_lte_lsn2,
2864             { "Last PDCP PDU SN ciphered with previous key",
2865               "pdcp-lte.lsn", FT_UINT16, BASE_DEC, NULL, 0x7fff,
2866               NULL, HFILL
2867             }
2868         },
2869         { &hf_pdcp_lte_lsn3,
2870             { "Last PDCP PDU SN ciphered with previous key",
2871               "pdcp-lte.lsn", FT_UINT24, BASE_DEC, NULL, 0x03ffff,
2872               NULL, HFILL
2873             }
2874         },
2875 
2876         { &hf_pdcp_lte_sequence_analysis,
2877             { "Sequence Analysis",
2878               "pdcp-lte.sequence-analysis", FT_STRING, BASE_NONE, 0, 0x0,
2879               NULL, HFILL
2880             }
2881         },
2882         { &hf_pdcp_lte_sequence_analysis_ok,
2883             { "OK",
2884               "pdcp-lte.sequence-analysis.ok", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2885               NULL, HFILL
2886             }
2887         },
2888         { &hf_pdcp_lte_sequence_analysis_previous_frame,
2889             { "Previous frame for channel",
2890               "pdcp-lte.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2891               NULL, HFILL
2892             }
2893         },
2894         { &hf_pdcp_lte_sequence_analysis_next_frame,
2895             { "Next frame for channel",
2896               "pdcp-lte.sequence-analysis.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2897               NULL, HFILL
2898             }
2899         },
2900         { &hf_pdcp_lte_sequence_analysis_expected_sn,
2901             { "Expected SN",
2902               "pdcp-lte.sequence-analysis.expected-sn", FT_UINT32, BASE_DEC, 0, 0x0,
2903               NULL, HFILL
2904             }
2905         },
2906         { &hf_pdcp_lte_sequence_analysis_skipped,
2907             { "Skipped frames",
2908               "pdcp-lte.sequence-analysis.skipped-frames", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2909               NULL, HFILL
2910             }
2911         },
2912         { &hf_pdcp_lte_sequence_analysis_repeated,
2913             { "Repeated frame",
2914               "pdcp-lte.sequence-analysis.repeated-frame", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2915               NULL, HFILL
2916             }
2917         },
2918 
2919         /* Security fields */
2920         { &hf_pdcp_lte_security,
2921             { "Security Config",
2922               "pdcp-lte.security-config", FT_STRING, BASE_NONE, 0, 0x0,
2923               NULL, HFILL
2924             }
2925         },
2926         { &hf_pdcp_lte_security_setup_frame,
2927             { "Configuration frame",
2928               "pdcp-lte.security-config.setup-frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2929               NULL, HFILL
2930             }
2931         },
2932         { &hf_pdcp_lte_security_integrity_algorithm,
2933             { "Integrity Algorithm",
2934               "pdcp-lte.security-config.integrity", FT_UINT16, BASE_DEC, VALS(integrity_algorithm_vals), 0x0,
2935               NULL, HFILL
2936             }
2937         },
2938         { &hf_pdcp_lte_security_ciphering_algorithm,
2939             { "Ciphering Algorithm",
2940               "pdcp-lte.security-config.ciphering", FT_UINT16, BASE_DEC, VALS(ciphering_algorithm_vals), 0x0,
2941               NULL, HFILL
2942             }
2943         },
2944         { &hf_pdcp_lte_security_bearer,
2945             { "BEARER",
2946               "pdcp-lte.security-config.bearer", FT_UINT8, BASE_DEC, NULL, 0x0,
2947               NULL, HFILL
2948             }
2949         },
2950         { &hf_pdcp_lte_security_direction,
2951             { "DIRECTION",
2952               "pdcp-lte.security-config.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
2953               NULL, HFILL
2954             }
2955         },
2956         { &hf_pdcp_lte_security_count,
2957             { "COUNT",
2958               "pdcp-lte.security-config.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2959               NULL, HFILL
2960             }
2961         },
2962         { &hf_pdcp_lte_security_cipher_key,
2963             { "CIPHER KEY",
2964               "pdcp-lte.security-config.cipher-key", FT_STRING, BASE_NONE, NULL, 0x0,
2965               NULL, HFILL
2966             }
2967         },
2968         { &hf_pdcp_lte_security_integrity_key,
2969             { "INTEGRITY KEY",
2970               "pdcp-lte.security-config.integrity-key", FT_STRING, BASE_NONE, NULL, 0x0,
2971               NULL, HFILL
2972             }
2973         }
2974     };
2975 
2976     static gint *ett[] =
2977     {
2978         &ett_pdcp,
2979         &ett_pdcp_configuration,
2980         &ett_pdcp_packet,
2981         &ett_pdcp_lte_sequence_analysis,
2982         &ett_pdcp_report_bitmap,
2983         &ett_pdcp_security
2984     };
2985 
2986     static ei_register_info ei[] = {
2987         { &ei_pdcp_lte_sequence_analysis_sn_missing, { "pdcp-lte.sequence-analysis.sn-missing", PI_SEQUENCE, PI_WARN, "PDCP SN missing", EXPFILL }},
2988         { &ei_pdcp_lte_sequence_analysis_sn_repeated, { "pdcp-lte.sequence-analysis.sn-repeated", PI_SEQUENCE, PI_WARN, "PDCP SN repeated", EXPFILL }},
2989         { &ei_pdcp_lte_sequence_analysis_wrong_sequence_number, { "pdcp-lte.sequence-analysis.wrong-sequence-number", PI_SEQUENCE, PI_WARN, "Wrong Sequence Number", EXPFILL }},
2990         { &ei_pdcp_lte_reserved_bits_not_zero, { "pdcp-lte.reserved-bits-not-zero", PI_MALFORMED, PI_ERROR, "Reserved bits not zero", EXPFILL }},
2991         { &ei_pdcp_lte_digest_wrong, { "pdcp-lte.maci-wrong", PI_SEQUENCE, PI_ERROR, "MAC-I doesn't match expected value", EXPFILL }},
2992         { &ei_pdcp_lte_unknown_udp_framing_tag, { "pdcp-lte.unknown-udp-framing-tag", PI_UNDECODED, PI_WARN, "Unknown UDP framing tag, aborting dissection", EXPFILL }},
2993         { &ei_pdcp_lte_missing_udp_framing_tag, { "pdcp-lte.missing-udp-framing-tag", PI_UNDECODED, PI_WARN, "Missing UDP framing conditional tag, aborting dissection", EXPFILL }}
2994     };
2995 
2996     static const enum_val_t sequence_analysis_vals[] = {
2997         {"no-analysis", "No-Analysis",      FALSE},
2998         {"rlc-only",    "Only-RLC-frames",  SEQUENCE_ANALYSIS_RLC_ONLY},
2999         {"pdcp-only",   "Only-PDCP-frames", SEQUENCE_ANALYSIS_PDCP_ONLY},
3000         {NULL, NULL, -1}
3001     };
3002 
3003     static const enum_val_t show_info_col_vals[] = {
3004         {"show-rlc", "RLC Info", ShowRLCLayer},
3005         {"show-pdcp", "PDCP Info", ShowPDCPLayer},
3006         {"show-traffic", "Traffic Info", ShowTrafficLayer},
3007         {NULL, NULL, -1}
3008     };
3009 
3010     static const enum_val_t default_ciphering_algorithm_vals[] = {
3011         {"eea0", "EEA0 (NULL)",   eea0},
3012         {"eea1", "EEA1 (SNOW3G)", eea1},
3013         {"eea2", "EEA2 (AES)",    eea2},
3014         {"eea3", "EEA3 (ZUC)",    eea3},
3015         {NULL, NULL, -1}
3016     };
3017 
3018     static const enum_val_t default_integrity_algorithm_vals[] = {
3019         {"eia0", "EIA0 (NULL)",   eia0},
3020         {"eia1", "EIA1 (SNOW3G)", eia1},
3021         {"eia2", "EIA2 (AES)",    eia2},
3022         {"eia3", "EIA3 (ZUC)",    eia3},
3023         {NULL, NULL, -1}
3024     };
3025 
3026   static uat_field_t ue_keys_uat_flds[] = {
3027       UAT_FLD_DEC(uat_ue_keys_records, ueid, "UEId", "UE Identifier of UE associated with keys"),
3028       UAT_FLD_CSTRING(uat_ue_keys_records, rrcCipherKeyString, "RRC Cipher Key",        "Key for deciphering signalling messages"),
3029       UAT_FLD_CSTRING(uat_ue_keys_records, upCipherKeyString,  "User-Plane Cipher Key", "Key for deciphering user-plane messages"),
3030       UAT_FLD_CSTRING(uat_ue_keys_records, rrcIntegrityKeyString,  "RRC Integrity Key", "Key for calculating integrity MAC"),
3031       UAT_END_FIELDS
3032     };
3033 
3034     module_t *pdcp_lte_module;
3035     expert_module_t* expert_pdcp_lte;
3036 
3037     /* Register protocol. */
3038     proto_pdcp_lte = proto_register_protocol("PDCP-LTE", "PDCP-LTE", "pdcp-lte");
3039     proto_register_field_array(proto_pdcp_lte, hf, array_length(hf));
3040     proto_register_subtree_array(ett, array_length(ett));
3041     expert_pdcp_lte = expert_register_protocol(proto_pdcp_lte);
3042     expert_register_field_array(expert_pdcp_lte, ei, array_length(ei));
3043 
3044     /* Allow other dissectors to find this one by name. */
3045     register_dissector("pdcp-lte", dissect_pdcp_lte, proto_pdcp_lte);
3046 
3047     pdcp_lte_module = prefs_register_protocol(proto_pdcp_lte, NULL);
3048 
3049     /* Obsolete preferences */
3050     prefs_register_obsolete_preference(pdcp_lte_module, "show_feedback_option_tag_length");
3051 
3052     /* Dissect uncompressed user-plane data as IP */
3053     prefs_register_bool_preference(pdcp_lte_module, "show_user_plane_as_ip",
3054         "Show uncompressed User-Plane data as IP",
3055         "Show uncompressed User-Plane data as IP",
3056         &global_pdcp_dissect_user_plane_as_ip);
3057 
3058     /* Dissect unciphered signalling data as RRC */
3059     prefs_register_bool_preference(pdcp_lte_module, "show_signalling_plane_as_rrc",
3060         "Show unciphered Signalling-Plane data as RRC",
3061         "Show unciphered Signalling-Plane data as RRC",
3062         &global_pdcp_dissect_signalling_plane_as_rrc);
3063 
3064     /* Check for missing sequence numbers */
3065     prefs_register_enum_preference(pdcp_lte_module, "check_sequence_numbers",
3066         "Do sequence number analysis",
3067         "Do sequence number analysis",
3068         &global_pdcp_check_sequence_numbers, sequence_analysis_vals, FALSE);
3069 
3070     /* Attempt to dissect ROHC messages */
3071     prefs_register_bool_preference(pdcp_lte_module, "dissect_rohc",
3072         "Attempt to decode ROHC data",
3073         "Attempt to decode ROHC data",
3074         &global_pdcp_dissect_rohc);
3075 
3076     prefs_register_obsolete_preference(pdcp_lte_module, "heuristic_pdcp_lte_over_udp");
3077 
3078     prefs_register_enum_preference(pdcp_lte_module, "layer_to_show",
3079         "Which layer info to show in Info column",
3080         "Can show RLC, PDCP or Traffic layer info in Info column",
3081         &global_pdcp_lte_layer_to_show, show_info_col_vals, FALSE);
3082 
3083     ue_keys_uat = uat_new("PDCP UE security keys",
3084               sizeof(uat_ue_keys_record_t),    /* record size */
3085               "pdcp_lte_ue_keys",              /* filename */
3086               TRUE,                            /* from_profile */
3087               &uat_ue_keys_records,            /* data_ptr */
3088               &num_ue_keys_uat,                /* numitems_ptr */
3089               UAT_AFFECTS_DISSECTION,          /* affects dissection of packets, but not set of named fields */
3090               NULL,                            /* help */
3091               uat_ue_keys_record_copy_cb,      /* copy callback */
3092               uat_ue_keys_record_update_cb,    /* update callback */
3093               uat_ue_keys_record_free_cb,      /* free callback */
3094               NULL,                            /* post update callback */
3095               NULL,                            /* reset callback */
3096               ue_keys_uat_flds);               /* UAT field definitions */
3097 
3098     prefs_register_uat_preference(pdcp_lte_module,
3099                                   "ue_keys_table",
3100                                   "PDCP UE Keys",
3101                                   "Preconfigured PDCP keys",
3102                                   ue_keys_uat);
3103 
3104     prefs_register_enum_preference(pdcp_lte_module, "default_ciphering_algorithm",
3105         "Ciphering algorithm to use if not signalled",
3106         "If RRC Security Info not seen, e.g. in Handover",
3107         (gint*)&global_default_ciphering_algorithm, default_ciphering_algorithm_vals, FALSE);
3108 
3109     prefs_register_enum_preference(pdcp_lte_module, "default_integrity_algorithm",
3110         "Integrity algorithm to use if not signalled",
3111         "If RRC Security Info not seen, e.g. in Handover",
3112         (gint*)&global_default_integrity_algorithm, default_integrity_algorithm_vals, FALSE);
3113 
3114     /* Attempt to decipher RRC messages */
3115     prefs_register_bool_preference(pdcp_lte_module, "decipher_signalling",
3116         "Attempt to decipher Signalling (RRC) SDUs",
3117         "N.B. only possible if build with algorithm support, and have key available and configured",
3118         &global_pdcp_decipher_signalling);
3119 
3120     /* Attempt to decipher user-plane messages */
3121     prefs_register_bool_preference(pdcp_lte_module, "decipher_userplane",
3122         "Attempt to decipher User-plane (IP) SDUs",
3123         "N.B. only possible if build with algorithm support, and have key available and configured",
3124         &global_pdcp_decipher_userplane);
3125 
3126     /* Attempt to verify RRC integrity/authentication digest */
3127     prefs_register_bool_preference(pdcp_lte_module, "verify_integrity",
3128         "Attempt to check integrity calculation",
3129         "N.B. only possible if build with algorithm support, and have key available and configured",
3130         &global_pdcp_check_integrity);
3131 
3132     prefs_register_bool_preference(pdcp_lte_module, "ignore_rrc_sec_params",
3133         "Ignore RRC security parameters",
3134         "Ignore the LTE RRC security algorithm configuration, to be used when PDCP is already deciphered in the capture",
3135         &global_pdcp_ignore_sec);
3136 
3137     pdcp_sequence_analysis_channel_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
3138     pdcp_lte_sequence_analysis_report_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), pdcp_result_hash_func, pdcp_result_hash_equal);
3139     pdcp_security_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
3140     pdcp_security_result_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), pdcp_lte_ueid_frame_hash_func, pdcp_lte_ueid_frame_hash_equal);
3141     pdcp_security_key_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
3142 }
3143 
proto_reg_handoff_pdcp_lte(void)3144 void proto_reg_handoff_pdcp_lte(void)
3145 {
3146     /* Add as a heuristic UDP dissector */
3147     heur_dissector_add("udp", dissect_pdcp_lte_heur, "PDCP-LTE over UDP", "pdcp_lte_udp", proto_pdcp_lte, HEURISTIC_DISABLE);
3148 
3149     ip_handle              = find_dissector_add_dependency("ip", proto_pdcp_lte);
3150     ipv6_handle            = find_dissector_add_dependency("ipv6", proto_pdcp_lte);
3151     rohc_handle            = find_dissector_add_dependency("rohc", proto_pdcp_lte);
3152     lte_rrc_ul_ccch        = find_dissector_add_dependency("lte_rrc.ul_ccch", proto_pdcp_lte);
3153     lte_rrc_dl_ccch        = find_dissector_add_dependency("lte_rrc.dl_ccch", proto_pdcp_lte);
3154     lte_rrc_pcch           = find_dissector_add_dependency("lte_rrc.pcch", proto_pdcp_lte);
3155     lte_rrc_bcch_bch       = find_dissector_add_dependency("lte_rrc.bcch_bch", proto_pdcp_lte);
3156     lte_rrc_bcch_dl_sch    = find_dissector_add_dependency("lte_rrc.bcch_dl_sch", proto_pdcp_lte);
3157     lte_rrc_ul_dcch        = find_dissector_add_dependency("lte_rrc.ul_dcch", proto_pdcp_lte);
3158     lte_rrc_dl_dcch        = find_dissector_add_dependency("lte_rrc.dl_dcch", proto_pdcp_lte);
3159     lte_rrc_ul_ccch_nb     = find_dissector_add_dependency("lte_rrc.ul_ccch.nb", proto_pdcp_lte);
3160     lte_rrc_dl_ccch_nb     = find_dissector_add_dependency("lte_rrc.dl_ccch.nb", proto_pdcp_lte);
3161     lte_rrc_pcch_nb        = find_dissector_add_dependency("lte_rrc.pcch.nb", proto_pdcp_lte);
3162     lte_rrc_bcch_bch_nb    = find_dissector_add_dependency("lte_rrc.bcch_bch.nb", proto_pdcp_lte);
3163     lte_rrc_bcch_dl_sch_nb = find_dissector_add_dependency("lte_rrc.bcch_dl_sch.nb", proto_pdcp_lte);
3164     lte_rrc_ul_dcch_nb     = find_dissector_add_dependency("lte_rrc.ul_dcch.nb", proto_pdcp_lte);
3165     lte_rrc_dl_dcch_nb     = find_dissector_add_dependency("lte_rrc.dl_dcch.nb", proto_pdcp_lte);
3166 }
3167 
3168 /*
3169  * Editor modelines
3170  *
3171  * Local Variables:
3172  * c-basic-offset: 4
3173  * tab-width: 8
3174  * indent-tabs-mode: nil
3175  * End:
3176  *
3177  * ex: set shiftwidth=4 tabstop=8 expandtab:
3178  * :indentSize=4:tabSize=8:noTabs=true:
3179  */
3180