diff options
Diffstat (limited to 'epan/dissectors/packet-pdcp-lte.c')
-rw-r--r-- | epan/dissectors/packet-pdcp-lte.c | 391 |
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 + } } }; |