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.c185
1 files changed, 91 insertions, 94 deletions
diff --git a/epan/dissectors/packet-pdcp-lte.c b/epan/dissectors/packet-pdcp-lte.c
index 548b4ab..8252890 100644
--- a/epan/dissectors/packet-pdcp-lte.c
+++ b/epan/dissectors/packet-pdcp-lte.c
@@ -1314,11 +1314,8 @@ static gboolean dissect_pdcp_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
struct pdcp_lte_info *p_pdcp_lte_info;
tvbuff_t *pdcp_tvb;
guint8 tag = 0;
- gboolean infoAlreadySet = FALSE;
gboolean seqnumLengthTagPresent = FALSE;
- /* Do this again on re-dissection to re-discover offset of actual PDU */
-
/* Needs to be at least as long as:
- the signature string
- fixed header bytes
@@ -1340,103 +1337,103 @@ static gboolean dissect_pdcp_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
if (p_pdcp_lte_info == NULL) {
/* Allocate new info struct for this frame */
p_pdcp_lte_info = wmem_new0(wmem_file_scope(), pdcp_lte_info);
- infoAlreadySet = FALSE;
- }
- else {
- infoAlreadySet = TRUE;
- }
-
-
- /* Read fixed fields */
- p_pdcp_lte_info->no_header_pdu = (gboolean)tvb_get_guint8(tvb, offset++);
- p_pdcp_lte_info->plane = (enum pdcp_plane)tvb_get_guint8(tvb, offset++);
- if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
- p_pdcp_lte_info->seqnum_length = PDCP_SN_LENGTH_5_BITS;
- }
- p_pdcp_lte_info->rohc.rohc_compression = (gboolean)tvb_get_guint8(tvb, offset++);
-
- /* Read optional fields */
- while (tag != PDCP_LTE_PAYLOAD_TAG) {
- /* Process next tag */
- tag = tvb_get_guint8(tvb, offset++);
- switch (tag) {
- case PDCP_LTE_SEQNUM_LENGTH_TAG:
- p_pdcp_lte_info->seqnum_length = tvb_get_guint8(tvb, offset);
- offset++;
- seqnumLengthTagPresent = TRUE;
- break;
- case PDCP_LTE_DIRECTION_TAG:
- p_pdcp_lte_info->direction = tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_LOG_CHAN_TYPE_TAG:
- p_pdcp_lte_info->channelType = (LogicalChannelType)tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG:
- p_pdcp_lte_info->BCCHTransport = (BCCHTransportType)tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_IP_VERSION_TAG:
- /* RoHC IP version field is now 1 byte only; let's skip most significant byte
- to keep backward compatibility with existing UDP framing protocol */
- p_pdcp_lte_info->rohc.rohc_ip_version = tvb_get_guint8(tvb, offset+1);
- offset += 2;
- break;
- case PDCP_LTE_ROHC_CID_INC_INFO_TAG:
- p_pdcp_lte_info->rohc.cid_inclusion_info = tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_LARGE_CID_PRES_TAG:
- p_pdcp_lte_info->rohc.large_cid_present = tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_MODE_TAG:
- p_pdcp_lte_info->rohc.mode = (enum rohc_mode)tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_RND_TAG:
- p_pdcp_lte_info->rohc.rnd = tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG:
- p_pdcp_lte_info->rohc.udp_checksum_present = tvb_get_guint8(tvb, offset);
- offset++;
- break;
- case PDCP_LTE_ROHC_PROFILE_TAG:
- p_pdcp_lte_info->rohc.profile = tvb_get_ntohs(tvb, offset);
- offset += 2;
- break;
- case PDCP_LTE_CHANNEL_ID_TAG:
- p_pdcp_lte_info->channelId = tvb_get_ntohs(tvb, offset);
- offset += 2;
- break;
- case PDCP_LTE_UEID_TAG:
- p_pdcp_lte_info->ueid = tvb_get_ntohs(tvb, offset);
- offset += 2;
- break;
-
- case PDCP_LTE_PAYLOAD_TAG:
- /* Have reached data, so get out of loop */
- continue;
-
- default:
- /* It must be a recognised tag */
- report_heur_error(tree, pinfo, &ei_pdcp_lte_unknown_udp_framing_tag, tvb, offset-1, 1);
- return TRUE;
+
+ /* Read fixed fields */
+ p_pdcp_lte_info->no_header_pdu = (gboolean)tvb_get_guint8(tvb, offset++);
+ p_pdcp_lte_info->plane = (enum pdcp_plane)tvb_get_guint8(tvb, offset++);
+ if (p_pdcp_lte_info->plane == SIGNALING_PLANE) {
+ p_pdcp_lte_info->seqnum_length = PDCP_SN_LENGTH_5_BITS;
}
- }
+ p_pdcp_lte_info->rohc.rohc_compression = (gboolean)tvb_get_guint8(tvb, offset++);
+
+ /* Read optional fields */
+ while (tag != PDCP_LTE_PAYLOAD_TAG) {
+ /* Process next tag */
+ tag = tvb_get_guint8(tvb, offset++);
+ switch (tag) {
+ case PDCP_LTE_SEQNUM_LENGTH_TAG:
+ p_pdcp_lte_info->seqnum_length = tvb_get_guint8(tvb, offset);
+ offset++;
+ seqnumLengthTagPresent = TRUE;
+ break;
+ case PDCP_LTE_DIRECTION_TAG:
+ p_pdcp_lte_info->direction = tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_LOG_CHAN_TYPE_TAG:
+ p_pdcp_lte_info->channelType = (LogicalChannelType)tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG:
+ p_pdcp_lte_info->BCCHTransport = (BCCHTransportType)tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_IP_VERSION_TAG:
+ /* RoHC IP version field is now 1 byte only; let's skip most significant byte
+ to keep backward compatibility with existing UDP framing protocol */
+ p_pdcp_lte_info->rohc.rohc_ip_version = tvb_get_guint8(tvb, offset+1);
+ offset += 2;
+ break;
+ case PDCP_LTE_ROHC_CID_INC_INFO_TAG:
+ p_pdcp_lte_info->rohc.cid_inclusion_info = tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_LARGE_CID_PRES_TAG:
+ p_pdcp_lte_info->rohc.large_cid_present = tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_MODE_TAG:
+ p_pdcp_lte_info->rohc.mode = (enum rohc_mode)tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_RND_TAG:
+ p_pdcp_lte_info->rohc.rnd = tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG:
+ p_pdcp_lte_info->rohc.udp_checksum_present = tvb_get_guint8(tvb, offset);
+ offset++;
+ break;
+ case PDCP_LTE_ROHC_PROFILE_TAG:
+ p_pdcp_lte_info->rohc.profile = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ break;
+ case PDCP_LTE_CHANNEL_ID_TAG:
+ p_pdcp_lte_info->channelId = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ break;
+ case PDCP_LTE_UEID_TAG:
+ p_pdcp_lte_info->ueid = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ break;
- if ((p_pdcp_lte_info->plane == USER_PLANE) && (seqnumLengthTagPresent == FALSE)) {
- /* Conditional field is not present */
- report_heur_error(tree, pinfo, &ei_pdcp_lte_missing_udp_framing_tag, tvb, 0, offset);
- return TRUE;
- }
+ case PDCP_LTE_PAYLOAD_TAG:
+ /* Have reached data, so get out of loop */
+ p_pdcp_lte_info->pdu_length = tvb_reported_length_remaining(tvb, offset);
+ continue;
+
+ default:
+ /* It must be a recognised tag */
+ report_heur_error(tree, pinfo, &ei_pdcp_lte_unknown_udp_framing_tag, tvb, offset-1, 1);
+ wmem_free(wmem_file_scope(), p_pdcp_lte_info);
+ return TRUE;
+ }
+ }
+
+ if ((p_pdcp_lte_info->plane == USER_PLANE) && (seqnumLengthTagPresent == FALSE)) {
+ /* Conditional field is not present */
+ report_heur_error(tree, pinfo, &ei_pdcp_lte_missing_udp_framing_tag, tvb, 0, offset);
+ wmem_free(wmem_file_scope(), p_pdcp_lte_info);
+ return TRUE;
+ }
- if (!infoAlreadySet) {
/* Store info in packet */
p_add_proto_data(wmem_file_scope(), pinfo, proto_pdcp_lte, 0, p_pdcp_lte_info);
}
+ else {
+ offset = tvb_reported_length(tvb) - p_pdcp_lte_info->pdu_length;
+ }
+
/**************************************/
/* OK, now dissect as PDCP LTE */