summaryrefslogtreecommitdiff
path: root/epan
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2016-01-26 11:56:35 +0100
committerPascal Quantin <pascal.quantin@gmail.com>2016-01-26 15:55:02 +0000
commit2d1b5167ce51491d097e958fee6148014168bd24 (patch)
treecbc501b3e8aca5d5962a8ff142dcac124cfa38c0 /epan
parent581b93781bbc3f7750f1a4de6e270f2b76fa6599 (diff)
downloadwireshark-2d1b5167ce51491d097e958fee6148014168bd24.tar.gz
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')
-rw-r--r--epan/dissectors/packet-lte-rrc.c7
-rw-r--r--epan/dissectors/packet-pdcp-lte.c133
-rw-r--r--epan/dissectors/packet-pdcp-lte.h1
-rw-r--r--epan/dissectors/packet-rlc-lte.c6
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;