PDCP LTE: reuse existing pdcp_lte_info structure after first pass

Change-Id: I3fbd95cbdbf958d4b6b93f0b7511be9ee772608c
Reviewed-on: https://code.wireshark.org/review/26932
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
This commit is contained in:
Pascal Quantin 2018-04-13 20:26:20 +02:00
parent 0ca6fda9f0
commit a892493e49
2 changed files with 93 additions and 93 deletions

View File

@ -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++);
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;
}
/* 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 */
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 */

View File

@ -81,6 +81,9 @@ typedef struct pdcp_lte_info
rohc_info rohc;
guint8 is_retx;
/* Used by heuristic dissector only */
guint16 pdu_length;
} pdcp_lte_info;