#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/prefs.h>
+#include <epan/tap.h>
#include "packet-rlc-lte.h"
#include "packet-pdcp-lte.h"
/* Initialize the protocol and registered fields. */
int proto_rlc_lte = -1;
+static int rlc_lte_tap = -1;
+
/* Decoding context */
static int hf_rlc_lte_context_mode = -1;
static int hf_rlc_lte_context_direction = -1;
proto_tree *tree,
int offset,
rlc_lte_info *p_rlc_lte_info,
- proto_item *top_ti)
+ proto_item *top_ti,
+ rlc_lte_tap_info *tap_info)
{
guint64 framing_info;
gboolean first_includes_start;
return;
}
+ tap_info->sequenceNumber = sn;
+
/* Show SN in info column */
col_append_fstr(pinfo->cinfo, COL_INFO, " SN=%04u", (guint16)sn);
proto_tree *tree,
proto_item *status_ti,
int offset,
- proto_item *top_ti)
+ proto_item *top_ti,
+ rlc_lte_tap_info *tap_info)
{
guint8 cpt;
guint64 ack_sn, nack_sn;
col_append_fstr(pinfo->cinfo, COL_INFO, " ACK_SN=%u", (guint16)ack_sn);
proto_item_append_text(top_ti, " ACK_SN=%u", (guint16)ack_sn);
proto_item_append_text(status_ti, " ACK_SN=%u", (guint16)ack_sn);
+ tap_info->ACKNo = ack_sn;
/* E1 */
proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
bit_offset += 10;
col_append_fstr(pinfo->cinfo, COL_INFO, " NACK_SN=%u", (guint16)nack_sn);
proto_item_append_text(top_ti, " NACK_SN=%u", (guint16)nack_sn);
+ tap_info->NACKs[nack_count] = nack_sn;
/* E1 */
proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
if (nack_count > 0) {
proto_item_append_text(status_ti, " (%u NACKs)", nack_count);
+ tap_info->noOfNACKs = nack_count;
}
/* Check that we've reached the end of the PDU. If not, show malformed */
proto_tree *tree,
int offset,
rlc_lte_info *p_rlc_lte_info,
- proto_item *top_ti)
+ proto_item *top_ti,
+ rlc_lte_tap_info *tap_info)
{
guint8 is_data;
guint8 is_segment;
/* First bit is Data/Control flag */
is_data = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
proto_tree_add_item(am_header_tree, hf_rlc_lte_am_data_control, tvb, offset, 1, FALSE);
+ tap_info->isControlPDU = !is_data;
/**************************************************/
if (!is_data) {
proto_item_append_text(top_ti, " [CONTROL]");
/* Control PDUs are a completely separate format */
- dissect_rlc_lte_am_status_pdu(tvb, pinfo, am_header_tree, am_header_ti, offset, top_ti);
+ dissect_rlc_lte_am_status_pdu(tvb, pinfo, am_header_tree, am_header_ti,
+ offset, top_ti, tap_info);
return;
}
/* Re-segmentation Flag (RF) field */
is_segment = (tvb_get_guint8(tvb, offset) & 0x40) >> 6;
proto_tree_add_item(am_header_tree, hf_rlc_lte_am_rf, tvb, offset, 1, FALSE);
+ tap_info->isResegmented = is_segment;
col_append_str(pinfo->cinfo, COL_INFO, (is_segment) ? " [DATA-SEGMENT]" : " [DATA]");
proto_item_append_text(top_ti, (is_segment) ? " [DATA-SEGMENT]" : " [DATA]");
sn = tvb_get_ntohs(tvb, offset) & 0x03ff;
proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fixed_sn, tvb, offset, 2, FALSE);
offset += 2;
+ tap_info->sequenceNumber = sn;
col_append_fstr(pinfo->cinfo, COL_INFO, "sn=%u", sn);
proto_item_append_text(top_ti, " (SN=%u)", sn);
gint offset = 0;
struct rlc_lte_info *p_rlc_lte_info = NULL;
+ /* Zero out tap */
+ static rlc_lte_tap_info tap_info;
+ memset(&tap_info, 0, sizeof(rlc_lte_tap_info));
+
/* Set protocol name */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC-LTE");
p_rlc_lte_info->channelId);
}
+ /* Set context-info parts of tap struct */
+ tap_info.rlcMode = p_rlc_lte_info->rlcMode;
+ tap_info.direction = p_rlc_lte_info->direction;
+ tap_info.priority = p_rlc_lte_info->priority;
+ tap_info.ueid = p_rlc_lte_info->ueid;
+ tap_info.channelType = p_rlc_lte_info->channelType;
+ tap_info.channelId = p_rlc_lte_info->channelId;
+ tap_info.pduLength = p_rlc_lte_info->pduLength;
+ tap_info.UMSequenceNumberLength = p_rlc_lte_info->UMSequenceNumberLength;
+
/* Reset this count */
s_number_of_extensions = 0;
break;
case RLC_UM_MODE:
- dissect_rlc_lte_um(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti);
+ dissect_rlc_lte_um(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
+ &tap_info);
break;
case RLC_AM_MODE:
- dissect_rlc_lte_am(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti);
+ dissect_rlc_lte_am(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
+ &tap_info);
break;
case RLC_PREDEF:
"Unrecognised RLC Mode set (%u)", p_rlc_lte_info->rlcMode);
break;
}
+
+ /* Queue tap info */
+ if (!pinfo->in_error_pkt) {
+ tap_queue_packet(rlc_lte_tap, pinfo, &tap_info);
+ }
}
/* Allow other dissectors to find this one by name. */
register_dissector("rlc-lte", dissect_rlc_lte, proto_rlc_lte);
+ /* Register the tap name */
+ rlc_lte_tap = register_tap("rlc-lte");
+
/* Preferences */
rlc_lte_module = prefs_register_protocol(proto_rlc_lte, NULL);