Coverage Report

Created: 2025-02-15 06:25

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