aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-pdcp-lte.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-pdcp-lte.c')
-rw-r--r--epan/dissectors/packet-pdcp-lte.c391
1 files changed, 236 insertions, 155 deletions
diff --git a/epan/dissectors/packet-pdcp-lte.c b/epan/dissectors/packet-pdcp-lte.c
index 9550e906c0..0a82586b1a 100644
--- a/epan/dissectors/packet-pdcp-lte.c
+++ b/epan/dissectors/packet-pdcp-lte.c
@@ -28,10 +28,9 @@
/* #define HAVE_SNOW3G */
/* #define HAVE_ZUC */
-#include "packet-rlc-lte.h"
#include "packet-pdcp-lte.h"
-void proto_register_pdcp(void);
+void proto_register_pdcp_lte(void);
void proto_reg_handoff_pdcp_lte(void);
/* Described in:
@@ -54,102 +53,102 @@ void proto_reg_handoff_pdcp_lte(void);
/* Initialize the protocol and registered fields. */
-int proto_pdcp_lte = -1;
+int proto_pdcp_lte;
extern int proto_rlc_lte;
/* Configuration (info known outside of PDU) */
-static int hf_pdcp_lte_configuration = -1;
-static int hf_pdcp_lte_direction = -1;
-static int hf_pdcp_lte_ueid = -1;
-static int hf_pdcp_lte_channel_type = -1;
-static int hf_pdcp_lte_channel_id = -1;
-
-static int hf_pdcp_lte_rohc_compression = -1;
-static int hf_pdcp_lte_rohc_mode = -1;
-static int hf_pdcp_lte_rohc_rnd = -1;
-static int hf_pdcp_lte_rohc_udp_checksum_present = -1;
-static int hf_pdcp_lte_rohc_profile = -1;
-
-static int hf_pdcp_lte_no_header_pdu = -1;
-static int hf_pdcp_lte_plane = -1;
-static int hf_pdcp_lte_seqnum_length = -1;
-static int hf_pdcp_lte_cid_inclusion_info = -1;
-static int hf_pdcp_lte_large_cid_present = -1;
+static int hf_pdcp_lte_configuration;
+static int hf_pdcp_lte_direction;
+static int hf_pdcp_lte_ueid;
+static int hf_pdcp_lte_channel_type;
+static int hf_pdcp_lte_channel_id;
+
+static int hf_pdcp_lte_rohc_compression;
+static int hf_pdcp_lte_rohc_mode;
+static int hf_pdcp_lte_rohc_rnd;
+static int hf_pdcp_lte_rohc_udp_checksum_present;
+static int hf_pdcp_lte_rohc_profile;
+
+static int hf_pdcp_lte_no_header_pdu;
+static int hf_pdcp_lte_plane;
+static int hf_pdcp_lte_seqnum_length;
+static int hf_pdcp_lte_cid_inclusion_info;
+static int hf_pdcp_lte_large_cid_present;
/* PDCP header fields */
-static int hf_pdcp_lte_control_plane_reserved = -1;
-static int hf_pdcp_lte_seq_num_5 = -1;
-static int hf_pdcp_lte_seq_num_7 = -1;
-static int hf_pdcp_lte_reserved3 = -1;
-static int hf_pdcp_lte_seq_num_12 = -1;
-static int hf_pdcp_lte_seq_num_15 = -1;
-static int hf_pdcp_lte_polling = -1;
-static int hf_pdcp_lte_reserved5 = -1;
-static int hf_pdcp_lte_seq_num_18 = -1;
-static int hf_pdcp_lte_signalling_data = -1;
-static int hf_pdcp_lte_mac = -1;
-static int hf_pdcp_lte_data_control = -1;
-static int hf_pdcp_lte_user_plane_data = -1;
-static int hf_pdcp_lte_control_pdu_type = -1;
-static int hf_pdcp_lte_fms = -1;
-static int hf_pdcp_lte_reserved4 = -1;
-static int hf_pdcp_lte_fms2 = -1;
-static int hf_pdcp_lte_reserved6 = -1;
-static int hf_pdcp_lte_fms3 = -1;
-static int hf_pdcp_lte_bitmap = -1;
-static int hf_pdcp_lte_bitmap_byte = -1;
-static int hf_pdcp_lte_hrw = -1;
-static int hf_pdcp_lte_nmp = -1;
-static int hf_pdcp_lte_reserved7 = -1;
-static int hf_pdcp_lte_hrw2 = -1;
-static int hf_pdcp_lte_nmp2 = -1;
-static int hf_pdcp_lte_hrw3 = -1;
-static int hf_pdcp_lte_reserved8 = -1;
-static int hf_pdcp_lte_nmp3 = -1;
-static int hf_pdcp_lte_lsn = -1;
-static int hf_pdcp_lte_lsn2 = -1;
-static int hf_pdcp_lte_lsn3 = -1;
+static int hf_pdcp_lte_control_plane_reserved;
+static int hf_pdcp_lte_seq_num_5;
+static int hf_pdcp_lte_seq_num_7;
+static int hf_pdcp_lte_reserved3;
+static int hf_pdcp_lte_seq_num_12;
+static int hf_pdcp_lte_seq_num_15;
+static int hf_pdcp_lte_polling;
+static int hf_pdcp_lte_reserved5;
+static int hf_pdcp_lte_seq_num_18;
+static int hf_pdcp_lte_signalling_data;
+static int hf_pdcp_lte_mac;
+static int hf_pdcp_lte_data_control;
+static int hf_pdcp_lte_user_plane_data;
+static int hf_pdcp_lte_control_pdu_type;
+static int hf_pdcp_lte_fms;
+static int hf_pdcp_lte_reserved4;
+static int hf_pdcp_lte_fms2;
+static int hf_pdcp_lte_reserved6;
+static int hf_pdcp_lte_fms3;
+static int hf_pdcp_lte_bitmap;
+static int hf_pdcp_lte_bitmap_byte;
+static int hf_pdcp_lte_hrw;
+static int hf_pdcp_lte_nmp;
+static int hf_pdcp_lte_reserved7;
+static int hf_pdcp_lte_hrw2;
+static int hf_pdcp_lte_nmp2;
+static int hf_pdcp_lte_hrw3;
+static int hf_pdcp_lte_reserved8;
+static int hf_pdcp_lte_nmp3;
+static int hf_pdcp_lte_lsn;
+static int hf_pdcp_lte_lsn2;
+static int hf_pdcp_lte_lsn3;
/* Sequence Analysis */
-static int hf_pdcp_lte_sequence_analysis = -1;
-static int hf_pdcp_lte_sequence_analysis_ok = -1;
-static int hf_pdcp_lte_sequence_analysis_previous_frame = -1;
-static int hf_pdcp_lte_sequence_analysis_next_frame = -1;
-static int hf_pdcp_lte_sequence_analysis_expected_sn = -1;
+static int hf_pdcp_lte_sequence_analysis;
+static int hf_pdcp_lte_sequence_analysis_ok;
+static int hf_pdcp_lte_sequence_analysis_previous_frame;
+static int hf_pdcp_lte_sequence_analysis_next_frame;
+static int hf_pdcp_lte_sequence_analysis_expected_sn;
-static int hf_pdcp_lte_sequence_analysis_repeated = -1;
-static int hf_pdcp_lte_sequence_analysis_skipped = -1;
+static int hf_pdcp_lte_sequence_analysis_repeated;
+static int hf_pdcp_lte_sequence_analysis_skipped;
/* Security Settings */
-static int hf_pdcp_lte_security = -1;
-static int hf_pdcp_lte_security_setup_frame = -1;
-static int hf_pdcp_lte_security_integrity_algorithm = -1;
-static int hf_pdcp_lte_security_ciphering_algorithm = -1;
-
-static int hf_pdcp_lte_security_bearer = -1;
-static int hf_pdcp_lte_security_direction = -1;
-static int hf_pdcp_lte_security_count = -1;
-static int hf_pdcp_lte_security_cipher_key = -1;
-static int hf_pdcp_lte_security_integrity_key = -1;
+static int hf_pdcp_lte_security;
+static int hf_pdcp_lte_security_setup_frame;
+static int hf_pdcp_lte_security_integrity_algorithm;
+static int hf_pdcp_lte_security_ciphering_algorithm;
+static int hf_pdcp_lte_security_bearer;
+static int hf_pdcp_lte_security_direction;
+static int hf_pdcp_lte_security_count;
+static int hf_pdcp_lte_security_cipher_key;
+static int hf_pdcp_lte_security_integrity_key;
+static int hf_pdcp_lte_security_deciphered_data;
/* Protocol subtree. */
-static int ett_pdcp = -1;
-static int ett_pdcp_configuration = -1;
-static int ett_pdcp_packet = -1;
-static int ett_pdcp_lte_sequence_analysis = -1;
-static int ett_pdcp_report_bitmap = -1;
-static int ett_pdcp_security = -1;
-
-static expert_field ei_pdcp_lte_sequence_analysis_wrong_sequence_number = EI_INIT;
-static expert_field ei_pdcp_lte_reserved_bits_not_zero = EI_INIT;
-static expert_field ei_pdcp_lte_sequence_analysis_sn_repeated = EI_INIT;
-static expert_field ei_pdcp_lte_sequence_analysis_sn_missing = EI_INIT;
-static expert_field ei_pdcp_lte_digest_wrong = EI_INIT;
-static expert_field ei_pdcp_lte_unknown_udp_framing_tag = EI_INIT;
-static expert_field ei_pdcp_lte_missing_udp_framing_tag = EI_INIT;
+static int ett_pdcp;
+static int ett_pdcp_configuration;
+static int ett_pdcp_packet;
+static int ett_pdcp_lte_sequence_analysis;
+static int ett_pdcp_report_bitmap;
+static int ett_pdcp_security;
+
+static expert_field ei_pdcp_lte_sequence_analysis_wrong_sequence_number;
+static expert_field ei_pdcp_lte_reserved_bits_not_zero;
+static expert_field ei_pdcp_lte_sequence_analysis_sn_repeated;
+static expert_field ei_pdcp_lte_sequence_analysis_sn_missing;
+static expert_field ei_pdcp_lte_digest_wrong;
+static expert_field ei_pdcp_lte_unknown_udp_framing_tag;
+static expert_field ei_pdcp_lte_missing_udp_framing_tag;
/*-------------------------------------
@@ -218,7 +217,7 @@ static gboolean check_valid_key_string(const char* raw_string, char* checked_str
/* Can't be valid if not long enough. */
if (length < 32) {
if (length > 0) {
- *error = g_strdup_printf("PDCP LTE: Invalid key string (%s) - should include 32 ASCII hex characters (16 bytes) but only %u chars given",
+ *error = ws_strdup_printf("PDCP LTE: Invalid key string (%s) - should include 32 ASCII hex characters (16 bytes) but only %u chars given",
raw_string, length);
}
@@ -240,18 +239,18 @@ static gboolean check_valid_key_string(const char* raw_string, char* checked_str
checked_string[written++] = c;
}
else {
- *error = g_strdup_printf("PDCP-LTE: Invalid char '%c' given in key", c);
+ *error = ws_strdup_printf("PDCP-LTE: Invalid char '%c' given in key", c);
return FALSE;
}
}
/* Must have found exactly 32 hex ascii chars for 16-byte key */
if (n<length) {
- *error = g_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but more detected", raw_string);
+ *error = ws_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but more detected", raw_string);
return FALSE;
}
if (written != 32) {
- *error = g_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but %u detected", raw_string, written);
+ *error = ws_strdup_printf("PDCP-LTE: Key (%s) should contain 32 hex characters (16 bytes) but %u detected", raw_string, written);
return FALSE;
}
else {
@@ -279,7 +278,7 @@ static void update_key_from_string(const char *stringKey, guint8 *binaryKey, gbo
}
/* Update by checking whether the 3 key strings are valid or not, and storing result */
-static gboolean uat_ue_keys_record_update_cb(void* record, char** error) {
+static bool uat_ue_keys_record_update_cb(void* record, char** error) {
uat_ue_keys_record_t* rec = (uat_ue_keys_record_t *)record;
/* Check and convert RRC key */
@@ -312,75 +311,115 @@ UAT_CSTRING_CB_DEF(uat_ue_keys_records, rrcIntegrityKeyString, uat_ue_keys_reco
/* Also supporting a hash table with entries from these functions */
-/* Table from ueid -> uat_ue_keys_record_t* */
+/* Table from ueid -> ue_key_entries_t* */
static wmem_map_t *pdcp_security_key_hash = NULL;
+typedef enum {
+ rrc_cipher,
+ rrc_integrity,
+ up_cipher,
+} ue_key_type_t;
+
+typedef struct {
+ ue_key_type_t key_type;
+ gchar *keyString;
+ guint8 binaryKey[16];
+ gboolean keyOK;
+ guint32 setup_frame;
+} key_entry_t;
+
+/* List of key entries for an individual UE */
+typedef struct {
+ #define MAX_KEY_ENTRIES_PER_UE 32
+ guint num_entries_set;
+ key_entry_t entries[MAX_KEY_ENTRIES_PER_UE];
+} ue_key_entries_t;
+
+
-void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key)
+void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key, guint32 frame_num)
{
char *err = NULL;
/* Get or create struct for this UE */
- uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
- GUINT_TO_POINTER((guint)ueid));
- if (key_record == NULL) {
+ ue_key_entries_t *key_entries = (ue_key_entries_t*)wmem_map_lookup(pdcp_security_key_hash,
+ GUINT_TO_POINTER((guint)ueid));
+ if (key_entries == NULL) {
/* Create and add to table */
- key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
- key_record->ueid = ueid;
- wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
+ key_entries = wmem_new0(wmem_file_scope(), ue_key_entries_t);
+ wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_entries);
}
- /* Check and convert RRC key */
- key_record->rrcCipherKeyString = g_strdup(key);
- update_key_from_string(key_record->rrcCipherKeyString, key_record->rrcCipherBinaryKey, &key_record->rrcCipherKeyOK, &err);
+ if (key_entries->num_entries_set == MAX_KEY_ENTRIES_PER_UE) {
+ /* No more room.. */
+ return;
+ }
+
+ key_entry_t *new_key_entry = &key_entries->entries[key_entries->num_entries_set++];
+ new_key_entry->key_type = rrc_cipher;
+ new_key_entry->keyString = g_strdup(key);
+ new_key_entry->setup_frame = frame_num;
+ update_key_from_string(new_key_entry->keyString, new_key_entry->binaryKey, &new_key_entry->keyOK, &err);
if (err) {
report_failure("%s: (RRC Ciphering Key)", err);
g_free(err);
}
}
-void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key)
+void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key, guint32 frame_num)
{
char *err = NULL;
/* Get or create struct for this UE */
- uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
- GUINT_TO_POINTER((guint)ueid));
- if (key_record == NULL) {
+ ue_key_entries_t *key_entries = (ue_key_entries_t*)wmem_map_lookup(pdcp_security_key_hash,
+ GUINT_TO_POINTER((guint)ueid));
+ if (key_entries == NULL) {
/* Create and add to table */
- key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
- key_record->ueid = ueid;
- wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
+ key_entries = wmem_new0(wmem_file_scope(), ue_key_entries_t);
+ wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_entries);
+ }
+
+ if (key_entries->num_entries_set == MAX_KEY_ENTRIES_PER_UE) {
+ /* No more room.. */
+ return;
}
- /* Check and convert RRC integrity key */
- key_record->rrcIntegrityKeyString = g_strdup(key);
- update_key_from_string(key_record->rrcIntegrityKeyString, key_record->rrcIntegrityBinaryKey, &key_record->rrcIntegrityKeyOK, &err);
+ key_entry_t *new_key_entry = &key_entries->entries[key_entries->num_entries_set++];
+ new_key_entry->key_type = rrc_integrity;
+ new_key_entry->keyString = g_strdup(key);
+ new_key_entry->setup_frame = frame_num;
+ update_key_from_string(new_key_entry->keyString, new_key_entry->binaryKey, &new_key_entry->keyOK, &err);
if (err) {
- report_failure("%s: (RRC Integrity Key)", err);
+ report_failure("%s: (RRC Ciphering Key)", err);
g_free(err);
}
}
-void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key)
+void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key, guint32 frame_num)
{
char *err = NULL;
/* Get or create struct for this UE */
- uat_ue_keys_record_t *key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
- GUINT_TO_POINTER((guint)ueid));
- if (key_record == NULL) {
+ ue_key_entries_t *key_entries = (ue_key_entries_t*)wmem_map_lookup(pdcp_security_key_hash,
+ GUINT_TO_POINTER((guint)ueid));
+ if (key_entries == NULL) {
/* Create and add to table */
- key_record = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
- key_record->ueid = ueid;
- wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_record);
+ key_entries = wmem_new0(wmem_file_scope(), ue_key_entries_t);
+ wmem_map_insert(pdcp_security_key_hash, GUINT_TO_POINTER((guint)ueid), key_entries);
+ }
+
+ if (key_entries->num_entries_set == MAX_KEY_ENTRIES_PER_UE) {
+ /* No more room.. */
+ return;
}
- /* Check and convert UP key */
- key_record->upCipherKeyString = g_strdup(key);
- update_key_from_string(key_record->upCipherKeyString, key_record->upCipherBinaryKey, &key_record->upCipherKeyOK, &err);
+ key_entry_t *new_key_entry = &key_entries->entries[key_entries->num_entries_set++];
+ new_key_entry->key_type = up_cipher;
+ new_key_entry->keyString = g_strdup(key);
+ new_key_entry->setup_frame = frame_num;
+ update_key_from_string(new_key_entry->keyString, new_key_entry->binaryKey, &new_key_entry->keyOK, &err);
if (err) {
- report_failure("%s: (UserPlane Ciphering Key)", err);
+ report_failure("%s: (RRC Ciphering Key)", err);
g_free(err);
}
}
@@ -653,17 +692,61 @@ typedef struct pdu_security_settings_t
} pdu_security_settings_t;
-static uat_ue_keys_record_t* look_up_keys_record(guint16 ueid)
+static uat_ue_keys_record_t* look_up_keys_record(guint16 ueid, guint32 frame_num,
+ guint32 *config_frame_rrc_cipher,
+ guint32 *config_frame_rrc_integrity,
+ guint32 *config_frame_up_cipher)
{
unsigned int record_id;
- /* Try hash table first (among entries added by set_pdcp_lte_xxx_key() functions) */
- uat_ue_keys_record_t* key_record = (uat_ue_keys_record_t*)wmem_map_lookup(pdcp_security_key_hash,
- GUINT_TO_POINTER((guint)ueid));
+ /* Try hash table first (among entries added by set_pdcp_nr_xxx_key() functions) */
+ ue_key_entries_t* key_record = (ue_key_entries_t*)wmem_map_lookup(pdcp_security_key_hash,
+ GUINT_TO_POINTER((guint)ueid));
if (key_record != NULL) {
- return key_record;
+ /* Will build up and return usual type */
+ uat_ue_keys_record_t *keys = wmem_new0(wmem_file_scope(), uat_ue_keys_record_t);
+
+ /* Fill in details */
+ keys->ueid = ueid;
+ /* Walk entries backwards (want last entry before frame_num) */
+ for (gint e=key_record->num_entries_set; e>0; e--) {
+ key_entry_t *entry = &key_record->entries[e-1];
+
+ if (frame_num > entry->setup_frame) {
+ /* This frame is after corresponding setup, so can adopt if don't have one */
+ switch (entry->key_type) {
+ case rrc_cipher:
+ if (!keys->rrcCipherKeyOK) {
+ keys->rrcCipherKeyString = entry->keyString;
+ memcpy(keys->rrcCipherBinaryKey, entry->binaryKey, 16);
+ keys->rrcCipherKeyOK = entry->keyOK;
+ *config_frame_rrc_cipher = entry->setup_frame;
+ }
+ break;
+ case rrc_integrity:
+ if (!keys->rrcIntegrityKeyOK) {
+ keys->rrcIntegrityKeyString = entry->keyString;
+ memcpy(keys->rrcIntegrityBinaryKey, entry->binaryKey, 16);
+ keys->rrcIntegrityKeyOK = entry->keyOK;
+ *config_frame_rrc_integrity = entry->setup_frame;
+ }
+ break;
+ case up_cipher:
+ if (!keys->upCipherKeyOK) {
+ keys->upCipherKeyString = entry->keyString;
+ memcpy(keys->upCipherBinaryKey, entry->binaryKey, 16);
+ keys->upCipherKeyOK = entry->keyOK;
+ *config_frame_up_cipher = entry->setup_frame;
+ }
+ break;
+ }
+ }
+ }
+ /* Return this struct (even if doesn't have all/any keys set..) */
+ return keys;
}
+
/* Else look up UAT entries. N.B. linear search... */
for (record_id=0; record_id < num_ue_keys_uat; record_id++) {
if (uat_ue_keys_records[record_id].ueid == ueid) {
@@ -786,7 +869,11 @@ static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p,
pdu_security->count = count;
/* KEY. Look this UE up among UEs that have keys configured */
- keys_record = look_up_keys_record(p_pdcp_lte_info->ueid);
+ guint32 config_frame_rrc_cipher=0, config_frame_rrc_integrity=0,
+ config_frame_up_cipher=0;
+ keys_record = look_up_keys_record(p_pdcp_lte_info->ueid, pinfo->num,
+ &config_frame_rrc_cipher, &config_frame_rrc_integrity,
+ &config_frame_up_cipher);
if (keys_record != NULL) {
if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
/* Get RRC ciphering key */
@@ -1113,6 +1200,8 @@ static wmem_map_t *pdcp_security_result_hash = NULL;
- the info column
- the top-level RLC PDU item */
static void write_pdu_label_and_info(proto_item *pdu_ti,
+ packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(3, 4);
+static void write_pdu_label_and_info(proto_item *pdu_ti,
packet_info *pinfo, const char *format, ...)
{
#define MAX_INFO_BUFFER 256
@@ -1121,7 +1210,7 @@ static void write_pdu_label_and_info(proto_item *pdu_ti,
va_list ap;
va_start(ap, format);
- g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
+ vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
va_end(ap);
/* Add to indicated places */
@@ -1144,7 +1233,7 @@ static void show_pdcp_config(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree
proto_tree *configuration_tree;
proto_item *configuration_ti = proto_tree_add_item(tree,
hf_pdcp_lte_configuration,
- tvb, 0, 0, ENC_ASCII|ENC_NA);
+ tvb, 0, 0, ENC_ASCII);
configuration_tree = proto_item_add_subtree(configuration_ti, ett_pdcp_configuration);
/* Direction */
@@ -1328,7 +1417,7 @@ static dissector_handle_t lookup_rrc_dissector_handle(struct pdcp_lte_info *p_p
}
-/* Forwad declarations */
+/* Forward declarations */
static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
static void report_heur_error(proto_tree *tree, packet_info *pinfo, expert_field *eiindex,
@@ -1700,8 +1789,6 @@ static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset
/* Try to calculate digest to compare with that found in frame. */
-#if defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */ || defined(HAVE_ZUC)
-/* We can calculate it for at least some integrity types */
static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings, guint8 header,
tvbuff_t *tvb, packet_info *pinfo, gint offset, gboolean *calculated)
{
@@ -1753,7 +1840,6 @@ static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings,
}
#endif
-#if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
case eia2:
{
/* AES */
@@ -1813,7 +1899,6 @@ static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings,
*calculated = TRUE;
return ((mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]);
}
-#endif
#ifdef HAVE_ZUC
case eia3:
{
@@ -1846,22 +1931,6 @@ static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings,
return 0;
}
}
-#else /* defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 || defined(HAVE_ZUC) */
-/* We can't calculate it for any integrity types other than eia0 */
-static guint32 calculate_digest(pdu_security_settings_t *pdu_security_settings, guint8 header _U_,
- tvbuff_t *tvb _U_, packet_info *pinfo _U_, gint offset _U_, gboolean *calculated)
-{
- *calculated = FALSE;
-
- if (pdu_security_settings->integrity == eia0) {
- /* Should be zero in this case */
- *calculated = TRUE;
- }
-
- /* Otherwise, we can't calculate it */
- return 0;
-}
-#endif /* defined(HAVE_SNOW3G) || GCRYPT_VERSION_NUMBER >= 0x010600 || defined(HAVE_ZUC) */
/******************************/
/* Main dissection function. */
@@ -2180,7 +2249,7 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
for (l=0, j=0; l<8; l++) {
if ((bits << l) & 0x80) {
if (bitmap_tree) {
- j += g_snprintf(&buff[j], BUFF_SIZE-j, "%6u,", (unsigned)(sn+(8*i)+l)%modulo);
+ j += snprintf(&buff[j], BUFF_SIZE-j, "%6u,", (unsigned)(sn+(8*i)+l)%modulo);
}
} else {
if (bitmap_tree) {
@@ -2408,6 +2477,12 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
payload_tvb = decipher_payload(tvb, pinfo, &offset, &pdu_security_settings, p_pdcp_info,
pdu_security ? pdu_security->seen_next_ul_pdu: FALSE, &payload_deciphered);
+ /* Add deciphered data as a filterable field */
+ if (payload_deciphered) {
+ proto_tree_add_item(pdcp_tree, hf_pdcp_lte_security_deciphered_data,
+ payload_tvb, 0, tvb_reported_length(payload_tvb), ENC_NA);
+ }
+
if (p_pdcp_info->plane == SIGNALING_PLANE) {
guint32 data_length;
guint32 mac;
@@ -2470,8 +2545,8 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (p_pdcp_info->channelType == Channel_DCCH) {
/* Last 4 bytes are MAC */
- mac = tvb_get_ntohl(payload_tvb, offset);
- mac_ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_mac, payload_tvb, offset, 4, ENC_BIG_ENDIAN);
+ mac_ti = proto_tree_add_item_ret_uint(pdcp_tree, hf_pdcp_lte_mac, payload_tvb, offset, 4,
+ ENC_BIG_ENDIAN, &mac);
offset += 4;
if (digest_was_calculated) {
@@ -2582,7 +2657,7 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
-void proto_register_pdcp(void)
+void proto_register_pdcp_lte(void)
{
static hf_register_info hf[] =
{
@@ -2643,7 +2718,7 @@ void proto_register_pdcp(void)
},
{ &hf_pdcp_lte_rohc_profile,
{ "ROHC profile",
- "pdcp-lte.rohc.profile", FT_UINT8, BASE_DEC, VALS(rohc_profile_vals), 0x0,
+ "pdcp-lte.rohc.profile", FT_UINT16, BASE_DEC, VALS(rohc_profile_vals), 0x0,
"ROHC Mode", HFILL
}
},
@@ -2970,6 +3045,12 @@ void proto_register_pdcp(void)
"pdcp-lte.security-config.integrity-key", FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL
}
+ },
+ { &hf_pdcp_lte_security_deciphered_data,
+ { "Deciphered Data",
+ "pdcp-lte.deciphered-data", FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL
+ }
}
};