diff options
author | Pascal Quantin <pascal.quantin@gmail.com> | 2016-01-26 11:56:35 +0100 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2016-01-26 15:55:02 +0000 |
commit | 2d1b5167ce51491d097e958fee6148014168bd24 (patch) | |
tree | cbc501b3e8aca5d5962a8ff142dcac124cfa38c0 /epan/dissectors | |
parent | 581b93781bbc3f7750f1a4de6e270f2b76fa6599 (diff) |
PDCP LTE: upgrade dissector to v13.0.0
Change-Id: Iae4a38ac7b80978d1ad02168e79c0fe0bffd8d2e
Reviewed-on: https://code.wireshark.org/review/13549
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-lte-rrc.c | 7 | ||||
-rw-r--r-- | epan/dissectors/packet-pdcp-lte.c | 133 | ||||
-rw-r--r-- | epan/dissectors/packet-pdcp-lte.h | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-rlc-lte.c | 6 |
4 files changed, 120 insertions, 27 deletions
diff --git a/epan/dissectors/packet-lte-rrc.c b/epan/dissectors/packet-lte-rrc.c index 1c24f18a52..e624ebe850 100644 --- a/epan/dissectors/packet-lte-rrc.c +++ b/epan/dissectors/packet-lte-rrc.c @@ -13062,9 +13062,16 @@ static const value_string lte_rrc_T_pdcp_SN_Size_v13xx_vals[] = { static int dissect_lte_rrc_T_pdcp_SN_Size_v13xx(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + drb_mapping_t *mapping = private_data_get_drb_mapping(actx); offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, 1, NULL, FALSE, 0, NULL); + if (mapping != NULL) { + mapping->pdcp_sn_size = 18; + mapping->pdcp_sn_size_present = TRUE; + } + + return offset; } diff --git a/epan/dissectors/packet-pdcp-lte.c b/epan/dissectors/packet-pdcp-lte.c index 7e2ed7f5f5..854cd36a3b 100644 --- a/epan/dissectors/packet-pdcp-lte.c +++ b/epan/dissectors/packet-pdcp-lte.c @@ -47,7 +47,7 @@ void proto_reg_handoff_pdcp_lte(void); /* Described in: * 3GPP TS 36.323 Evolved Universal Terrestrial Radio Access (E-UTRA) - * Packet Data Convergence Protocol (PDCP) specification v11.0.0 + * Packet Data Convergence Protocol (PDCP) specification v13.0.0 */ @@ -57,6 +57,7 @@ void proto_reg_handoff_pdcp_lte(void); - Speed up AES decryption by keeping the crypt handle around for the channel (like ESP decryption in IPSEC dissector) - Add Relay Node user plane data PDU dissection + - Add SLRB user data plane data PDU dissection */ @@ -91,6 +92,8 @@ 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_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; @@ -99,6 +102,8 @@ 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; @@ -468,7 +473,7 @@ typedef struct /* Channel state */ typedef struct { - guint16 previousSequenceNumber; + guint32 previousSequenceNumber; guint32 previousFrameNum; guint32 hfn; } pdcp_channel_status; @@ -482,11 +487,11 @@ static GHashTable *pdcp_sequence_analysis_channel_hash = NULL; typedef struct { guint32 frameNumber; - guint32 SN : 15; + guint32 SN : 18; guint32 plane : 2; guint32 channelId: 5; guint32 direction: 1; - guint32 notUsed : 9; + guint32 notUsed : 6; } pdcp_result_hash_key; static gint pdcp_result_hash_equal(gconstpointer v, gconstpointer v2) @@ -504,10 +509,10 @@ static guint pdcp_result_hash_func(gconstpointer v) const pdcp_result_hash_key* val1 = (const pdcp_result_hash_key *)v; /* TODO: This is a bit random. */ - return val1->frameNumber + (val1->channelId<<13) + - (val1->plane<<5) + - (val1->SN<<18) + - (val1->direction<<9); + return val1->frameNumber + (val1->channelId<<7) + + (val1->plane<<12) + + (val1->SN<<14) + + (val1->direction<<6); } /* pdcp_channel_hash_key fits into the pointer, so just copy the value into @@ -521,7 +526,7 @@ static gpointer get_channel_hash_key(pdcp_channel_hash_key *key) } /* Convenience function to get a pointer for the hash_func to work with */ -static gpointer get_report_hash_key(guint16 SN, guint32 frameNumber, +static gpointer get_report_hash_key(guint32 SN, guint32 frameNumber, pdcp_lte_info *p_pdcp_lte_info, gboolean do_persist) { @@ -557,12 +562,12 @@ typedef enum typedef struct { gboolean sequenceExpectedCorrect; - guint16 sequenceExpected; + guint32 sequenceExpected; guint32 previousFrameNum; guint32 nextFrameNum; - guint16 firstSN; - guint16 lastSN; + guint32 firstSN; + guint32 lastSN; guint32 hfn; sequence_state state; @@ -611,7 +616,7 @@ static uat_ue_keys_record_t* look_up_keys_record(guint16 ueid) /* Add to the tree values associated with sequence analysis for this frame */ static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p, pdcp_lte_info *p_pdcp_lte_info, - guint16 sequenceNumber, + guint32 sequenceNumber, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, proto_tree *security_tree, pdu_security_settings_t *pdu_security) @@ -649,6 +654,7 @@ static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p, case PDCP_SN_LENGTH_7_BITS: case PDCP_SN_LENGTH_12_BITS: case PDCP_SN_LENGTH_15_BITS: + case PDCP_SN_LENGTH_18_BITS: break; default: DISSECTOR_ASSERT_NOT_REACHED(); @@ -702,6 +708,9 @@ static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p, case PDCP_SN_LENGTH_15_BITS: hfn_multiplier = 32768; break; + case PDCP_SN_LENGTH_18_BITS: + hfn_multiplier = 262144; + break; default: DISSECTOR_ASSERT_NOT_REACHED(); break; @@ -821,7 +830,7 @@ static void addChannelSequenceInfo(pdcp_sequence_report_in_frame *p, /* Update the channel status and set report for this frame */ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, pdcp_lte_info *p_pdcp_lte_info, - guint16 sequenceNumber, + guint32 sequenceNumber, proto_tree *tree, proto_tree *security_tree, pdu_security_settings_t *pdu_security) @@ -830,8 +839,8 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, pdcp_channel_status *p_channel_status; pdcp_sequence_report_in_frame *p_report_in_frame = NULL; gboolean createdChannel = FALSE; - guint16 expectedSequenceNumber = 0; - guint16 snLimit = 0; + guint32 expectedSequenceNumber = 0; + guint32 snLimit = 0; /* If find stat_report_in_frame already, use that and get out */ if (pinfo->fd->flags.visited) { @@ -894,6 +903,9 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, case PDCP_SN_LENGTH_15_BITS: snLimit = 32768; break; + case PDCP_SN_LENGTH_18_BITS: + snLimit = 262144; + break; default: DISSECTOR_ASSERT_NOT_REACHED(); break; @@ -957,7 +969,7 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, /* Get report for previous frame */ pdcp_sequence_report_in_frame *p_previous_report; p_previous_report = (pdcp_sequence_report_in_frame*)g_hash_table_lookup(pdcp_lte_sequence_analysis_report_hash, - get_report_hash_key((sequenceNumber+32767) % 32768, + get_report_hash_key((sequenceNumber+262144) % 262144, p_report_in_frame->previousFrameNum, p_pdcp_lte_info, FALSE)); @@ -1821,7 +1833,7 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (!p_pdcp_info->no_header_pdu) { /* TODO: shouldn't need to initialise this one!! */ - guint16 seqnum = 0; + guint32 seqnum = 0; gboolean seqnum_set = FALSE; guint8 first_byte = tvb_get_guint8(tvb, offset); @@ -1900,6 +1912,29 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_15, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; + case PDCP_SN_LENGTH_18_BITS: + { + proto_item *ti; + guint8 reserved_value; + + /* 5 reserved bits */ + ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_reserved5, tvb, offset, 1, ENC_BIG_ENDIAN); + reserved_value = (first_byte & 0x7c) >> 2; + + /* Complain if not 0 */ + if (reserved_value != 0) { + expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero, + "Reserved bits have value 0x%x - should be 0x0", + reserved_value); + } + + /* 18-bit sequence number */ + seqnum = tvb_get_ntoh24(tvb, offset) & 0x03ffff; + seqnum_set = TRUE; + proto_tree_add_item(pdcp_tree, hf_pdcp_lte_seq_num_18, tvb, offset, 3, ENC_BIG_ENDIAN); + offset += 3; + } + break; default: /* Not a recognised data format!!!!! */ return 1; @@ -1917,15 +1952,15 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, case 0: /* PDCP status report */ { guint8 bits; - guint16 fms; - guint16 modulo; + guint32 fms; + guint32 modulo; guint not_received = 0; guint sn, i, j, l; guint32 len, bit_offset; proto_tree *bitmap_tree; proto_item *bitmap_ti = NULL; gchar *buff = NULL; - #define BUFF_SIZE 49 + #define BUFF_SIZE 57 if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_12_BITS) { /* First-Missing-Sequence SN */ @@ -1935,7 +1970,7 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, offset, 2, ENC_BIG_ENDIAN); offset += 2; modulo = 4096; - } else { + } else if (p_pdcp_info->seqnum_length == PDCP_SN_LENGTH_15_BITS) { proto_item *ti; guint8 reserved_value; @@ -1958,6 +1993,28 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, offset, 2, ENC_BIG_ENDIAN); offset += 2; modulo = 32768; + } else { + proto_item *ti; + guint8 reserved_value; + + /* 2 reserved bits */ + ti = proto_tree_add_item(pdcp_tree, hf_pdcp_lte_reserved6, tvb, offset, 1, ENC_BIG_ENDIAN); + reserved_value = (tvb_get_guint8(tvb, offset) & 0x0c)>>2; + + /* Complain if not 0 */ + if (reserved_value != 0) { + expert_add_info_format(pinfo, ti, &ei_pdcp_lte_reserved_bits_not_zero, + "Reserved bits have value 0x%x - should be 0x0", + reserved_value); + } + + /* First-Missing-Sequence SN */ + fms = tvb_get_ntoh24(tvb, offset) & 0x3ffff; + sn = (fms + 1) % 262144; + proto_tree_add_item(pdcp_tree, hf_pdcp_lte_fms3, tvb, + offset, 3, ENC_BIG_ENDIAN); + offset += 3; + modulo = 262144; } /* Bitmap tree */ @@ -1974,9 +2031,9 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bits = tvb_get_bits8(tvb, bit_offset, 8); for (l=0, j=0; l<8; l++) { if ((bits << l) & 0x80) { - j += g_snprintf(&buff[j], BUFF_SIZE-j, "%5u,", (unsigned)(sn+(8*i)+l)%modulo); + j += g_snprintf(&buff[j], BUFF_SIZE-j, "%6u,", (unsigned)(sn+(8*i)+l)%modulo); } else { - j += g_snprintf(&buff[j], BUFF_SIZE-j, " ,"); + j += g_snprintf(&buff[j], BUFF_SIZE-j, " ,"); not_received++; } } @@ -2031,7 +2088,7 @@ static int dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (do_analysis) { checkChannelSequenceInfo(pinfo, tvb, p_pdcp_info, - (guint16)seqnum, pdcp_tree, security_tree, + seqnum, pdcp_tree, security_tree, &pdu_security_settings); } } @@ -2377,6 +2434,18 @@ void proto_register_pdcp(void) "PDCP Seq num", HFILL } }, + { &hf_pdcp_lte_reserved5, + { "Reserved", + "pdcp-lte.reserved5", FT_UINT8, BASE_HEX, NULL, 0x7c, + "5 reserved bits", HFILL + } + }, + { &hf_pdcp_lte_seq_num_18, + { "Seq Num", + "pdcp-lte.seq-num", FT_UINT24, BASE_DEC, NULL, 0x3ffff, + "PDCP Seq num", HFILL + } + }, { &hf_pdcp_lte_signalling_data, { "Signalling Data", "pdcp-lte.signalling-data", FT_BYTES, BASE_NONE, NULL, 0x0, @@ -2425,6 +2494,18 @@ void proto_register_pdcp(void) "First Missing PDCP Sequence Number", HFILL } }, + { &hf_pdcp_lte_reserved6, + { "Reserved", + "pdcp-lte.reserved6", FT_UINT8, BASE_HEX, NULL, 0x0c, + "2 reserved bits", HFILL + } + }, + { &hf_pdcp_lte_fms3, + { "First Missing Sequence Number", + "pdcp-lte.fms", FT_UINT24, BASE_DEC, NULL, 0x03ffff, + "First Missing PDCP Sequence Number", HFILL + } + }, { &hf_pdcp_lte_bitmap, { "Bitmap", "pdcp-lte.bitmap", FT_NONE, BASE_NONE, NULL, 0x0, @@ -2464,7 +2545,7 @@ void proto_register_pdcp(void) }, { &hf_pdcp_lte_sequence_analysis_expected_sn, { "Expected SN", - "pdcp-lte.sequence-analysis.expected-sn", FT_UINT16, BASE_DEC, 0, 0x0, + "pdcp-lte.sequence-analysis.expected-sn", FT_UINT32, BASE_DEC, 0, 0x0, NULL, HFILL } }, diff --git a/epan/dissectors/packet-pdcp-lte.h b/epan/dissectors/packet-pdcp-lte.h index f717960ff0..d5d21a9625 100644 --- a/epan/dissectors/packet-pdcp-lte.h +++ b/epan/dissectors/packet-pdcp-lte.h @@ -51,6 +51,7 @@ typedef enum #define PDCP_SN_LENGTH_7_BITS 7 #define PDCP_SN_LENGTH_12_BITS 12 #define PDCP_SN_LENGTH_15_BITS 15 +#define PDCP_SN_LENGTH_18_BITS 18 enum security_integrity_algorithm_e { eia0, eia1, eia2, eia3 }; enum security_ciphering_algorithm_e { eea0, eea1, eea2, eea3 }; diff --git a/epan/dissectors/packet-rlc-lte.c b/epan/dissectors/packet-rlc-lte.c index 2a51be33c7..d0969b8122 100644 --- a/epan/dissectors/packet-rlc-lte.c +++ b/epan/dissectors/packet-rlc-lte.c @@ -63,12 +63,13 @@ static gint global_rlc_lte_um_sequence_analysis = SEQUENCE_ANALYSIS_MAC_ONLY; /* By default do call PDCP/RRC dissectors for SDU data */ static gboolean global_rlc_lte_call_pdcp_for_srb = TRUE; -enum pdcp_for_drb { PDCP_drb_off, PDCP_drb_SN_7, PDCP_drb_SN_12, PDCP_drb_SN_signalled, PDCP_drb_SN_15}; +enum pdcp_for_drb { PDCP_drb_off, PDCP_drb_SN_7, PDCP_drb_SN_12, PDCP_drb_SN_signalled, PDCP_drb_SN_15, PDCP_drb_SN_18}; static const enum_val_t pdcp_drb_col_vals[] = { {"pdcp-drb-off", "Off", PDCP_drb_off}, {"pdcp-drb-sn-7", "7-bit SN", PDCP_drb_SN_7}, {"pdcp-drb-sn-12", "12-bit SN", PDCP_drb_SN_12}, {"pdcp-drb-sn-15", "15-bit SN", PDCP_drb_SN_15}, + {"pdcp-drb-sn-18", "18-bit SN", PDCP_drb_SN_18}, {"pdcp-drb-sn-signalling", "Use signalled value", PDCP_drb_SN_signalled}, {NULL, NULL, -1} }; @@ -846,6 +847,9 @@ static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb case PDCP_drb_SN_15: p_pdcp_lte_info->seqnum_length = 15; break; + case PDCP_drb_SN_18: + p_pdcp_lte_info->seqnum_length = 18; + break; case PDCP_drb_SN_signalled: /* Use whatever was signalled (e.g. in RRC) */ id = (rlc_info->channelId << 16) | rlc_info->ueid; |