aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-07-23 21:25:05 -0400
committerMichael Mann <mmann78@netscape.net>2016-08-01 15:19:59 +0000
commitedcc2f019e3729293d9410e1bb30dae6bc9b790a (patch)
treed8c31f1294cb9f5fe0ece0882e2aa66d1b63f6b3 /epan/dissectors
parentc992edc222233f7e49f975763925d1ffb3848beb (diff)
Add OSI Layer 4 to exported PDU to handle TCP and UDP payloads.
This allows for much easier anonymized captures for protocols running atop TCP/UDP. Added support for "TCP dissector data" tag within export PDU (34) so that the tcpinfo struct that TCP dissector normally passes to its subdissectors can be saved. Change-Id: Icd63c049162332e5bcb2720159e5cf8aac893788 Reviewed-on: https://code.wireshark.org/review/16285 Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-exported_pdu.c35
-rw-r--r--epan/dissectors/packet-tcp.c163
-rw-r--r--epan/dissectors/packet-tcp.h7
-rw-r--r--epan/dissectors/packet-udp.c102
4 files changed, 299 insertions, 8 deletions
diff --git a/epan/dissectors/packet-exported_pdu.c b/epan/dissectors/packet-exported_pdu.c
index dcedd3409d..d61074a4f9 100644
--- a/epan/dissectors/packet-exported_pdu.c
+++ b/epan/dissectors/packet-exported_pdu.c
@@ -30,6 +30,7 @@
#include <epan/exported_pdu.h>
#include "packet-mtp3.h"
#include "packet-dvbci.h"
+#include "packet-tcp.h"
void proto_register_exported_pdu(void);
void proto_reg_handoff_exported_pdu(void);
@@ -48,6 +49,7 @@ static int hf_exported_pdu_unknown_tag_val = -1;
static int hf_exported_pdu_prot_name = -1;
static int hf_exported_pdu_heur_prot_name = -1;
static int hf_exported_pdu_dis_table_name = -1;
+static int hf_exported_pdu_dissector_data = -1;
static int hf_exported_pdu_ipv4_src = -1;
static int hf_exported_pdu_ipv4_dst = -1;
static int hf_exported_pdu_ipv6_src = -1;
@@ -101,6 +103,7 @@ static const value_string exported_pdu_tag_vals[] = {
{ EXP_PDU_TAG_DVBCI_EVT, "DVB-CI event" },
{ EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL, "Dissector table value" },
{ EXP_PDU_TAG_COL_PROT_TEXT, "Column Protocol String" },
+ { EXP_PDU_TAG_TCP_INFO_DATA, "TCP Dissector Data" },
{ 0, NULL }
};
@@ -124,6 +127,7 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
guint8 dvb_ci_dir;
guint32 dissector_table_val=0;
dissector_table_t dis_tbl;
+ void* dissector_data = NULL;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Exported PDU");
@@ -239,6 +243,25 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
case EXP_PDU_TAG_COL_PROT_TEXT:
proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_col_proto_str, tvb, offset, tag_len, ENC_UTF_8 | ENC_NA, wmem_packet_scope(), &col_proto_str);
break;
+ case EXP_PDU_TAG_TCP_INFO_DATA:
+ {
+ struct tcpinfo* tcpdata = wmem_new0(wmem_packet_scope(), struct tcpinfo);
+ guint16 version;
+ proto_tree_add_item(tag_tree, hf_exported_pdu_dissector_data, tvb, offset, tag_len, ENC_NA);
+
+ version = tvb_get_ntohs(tvb, offset);
+ DISSECTOR_ASSERT(version == 1); /* Only version 1 is currently supported */
+
+ tcpdata->seq = tvb_get_ntohl(tvb, offset+2);
+ tcpdata->nxtseq = tvb_get_ntohl(tvb, offset+6);
+ tcpdata->lastackseq = tvb_get_ntohl(tvb, offset+10);
+ tcpdata->is_reassembled = tvb_get_guint8(tvb, offset+14);
+ tcpdata->flags = tvb_get_ntohs(tvb, offset+15);
+ tcpdata->urgent_pointer = tvb_get_ntohs(tvb, offset+17);
+
+ dissector_data = tcpdata;
+ }
+ break;
case EXP_PDU_TAG_END_OF_OPT:
break;
default:
@@ -258,7 +281,7 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
proto_handle = find_dissector(proto_name);
if (proto_handle) {
col_clear(pinfo->cinfo, COL_PROTOCOL);
- call_dissector(proto_handle, payload_tvb, pinfo, tree);
+ call_dissector_with_data(proto_handle, payload_tvb, pinfo, tree, dissector_data);
}
break;
case EXPORTED_PDU_NEXT_HEUR_PROTO_STR:
@@ -266,7 +289,7 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
heur_dtbl_entry_t *heur_diss = find_heur_dissector_by_unique_short_name(proto_name);
if (heur_diss) {
col_clear(pinfo->cinfo, COL_PROTOCOL);
- call_heur_dissector_direct(heur_diss, payload_tvb, pinfo, tree, NULL);
+ call_heur_dissector_direct(heur_diss, payload_tvb, pinfo, tree, dissector_data);
}
break;
}
@@ -278,7 +301,7 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
if (col_proto_str) {
col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "%s",col_proto_str);
}
- dissector_try_uint_new(dis_tbl, dissector_table_val, payload_tvb, pinfo, tree, FALSE, NULL);
+ dissector_try_uint_new(dis_tbl, dissector_table_val, payload_tvb, pinfo, tree, FALSE, dissector_data);
}
}
default:
@@ -328,6 +351,11 @@ proto_register_exported_pdu(void)
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL }
},
+ { &hf_exported_pdu_dissector_data,
+ { "Dissector Data", "exported_pdu.dissector_data",
+ FT_BYTES, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
{ &hf_exported_pdu_ipv4_src,
{ "IPv4 Src", "exported_pdu.ipv4_src",
FT_IPv4, BASE_NONE, NULL, 0,
@@ -442,6 +470,7 @@ proto_register_exported_pdu(void)
* want to export their PDUs, see packet-sip.c
*/
register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_3);
+ register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_4);
register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_7);
}
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index ce68526df4..bc7f4fd26c 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -37,6 +37,7 @@
#include <epan/dissector_filters.h>
#include <epan/reassemble.h>
#include <epan/decode_as.h>
+#include <epan/exported_pdu.h>
#include <epan/in_cksum.h>
#include <epan/proto_data.h>
@@ -55,6 +56,7 @@ void proto_reg_handoff_tcp(void);
static int tcp_tap = -1;
static int tcp_follow_tap = -1;
static int mptcp_tap = -1;
+static int exported_pdu_tap = -1;
/* Place TCP summary in proto tree */
static gboolean tcp_summary_in_tree = TRUE;
@@ -810,6 +812,151 @@ gchar* tcp_follow_address_filter(address* src_addr, address* dst_addr, int src_p
}
+#define EXP_PDU_TCP_INFO_DATA_LEN 19
+#define EXP_PDU_TCP_INFO_VERSION 1
+
+int exp_pdu_tcp_dissector_data_size(packet_info *pinfo _U_, void* data _U_)
+{
+ return EXP_PDU_TCP_INFO_DATA_LEN+4;
+}
+
+int exp_pdu_tcp_dissector_data_populate_data(packet_info *pinfo _U_, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ struct tcpinfo* dissector_data = (struct tcpinfo*)data;
+
+ tlv_buffer[0] = 0;
+ tlv_buffer[1] = EXP_PDU_TAG_TCP_INFO_DATA;
+ tlv_buffer[2] = 0;
+ tlv_buffer[3] = EXP_PDU_TCP_INFO_DATA_LEN; /* tag length */
+ tlv_buffer[4] = 0;
+ tlv_buffer[5] = EXP_PDU_TCP_INFO_VERSION;
+ tlv_buffer[6] = (dissector_data->seq & 0xff000000) >> 24;
+ tlv_buffer[7] = (dissector_data->seq & 0x00ff0000) >> 16;
+ tlv_buffer[8] = (dissector_data->seq & 0x0000ff00) >> 8;
+ tlv_buffer[9] = (dissector_data->seq & 0x000000ff);
+ tlv_buffer[10] = (dissector_data->nxtseq & 0xff000000) >> 24;
+ tlv_buffer[11] = (dissector_data->nxtseq & 0x00ff0000) >> 16;
+ tlv_buffer[12] = (dissector_data->nxtseq & 0x0000ff00) >> 8;
+ tlv_buffer[13] = (dissector_data->nxtseq & 0x000000ff);
+ tlv_buffer[14] = (dissector_data->lastackseq & 0xff000000) >> 24;
+ tlv_buffer[15] = (dissector_data->lastackseq & 0x00ff0000) >> 16;
+ tlv_buffer[16] = (dissector_data->lastackseq & 0x0000ff00) >> 8;
+ tlv_buffer[17] = (dissector_data->lastackseq & 0x000000ff);
+ tlv_buffer[18] = dissector_data->is_reassembled;
+ tlv_buffer[19] = (dissector_data->flags & 0xff00) >> 8;
+ tlv_buffer[20] = (dissector_data->flags & 0x00ff);
+ tlv_buffer[21] = (dissector_data->urgent_pointer & 0xff00) >> 8;
+ tlv_buffer[22] = (dissector_data->urgent_pointer & 0x00ff);
+
+ return exp_pdu_tcp_dissector_data_size(pinfo, data);
+}
+
+static void
+handle_export_pdu_dissection_table(packet_info *pinfo, tvbuff_t *tvb, guint32 port, struct tcpinfo *tcpinfo)
+{
+ if (have_tap_listener(exported_pdu_tap)) {
+ exp_pdu_data_item_t exp_pdu_data_table_value = {exp_pdu_data_dissector_table_num_value_size, exp_pdu_data_dissector_table_num_value_populate_data, NULL};
+ exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
+ const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
+ &exp_pdu_data_src_ip,
+ &exp_pdu_data_dst_ip,
+ &exp_pdu_data_port_type,
+ &exp_pdu_data_src_port,
+ &exp_pdu_data_dst_port,
+ &exp_pdu_data_orig_frame_num,
+ &exp_pdu_data_table_value,
+ &exp_pdu_data_dissector_data,
+ NULL
+ };
+
+ exp_pdu_data_t *exp_pdu_data;
+
+ exp_pdu_data_table_value.data = GUINT_TO_POINTER(port);
+ exp_pdu_data_dissector_data.data = tcpinfo;
+
+ exp_pdu_data = export_pdu_create_tags(pinfo, "tcp.port", EXP_PDU_TAG_DISSECTOR_TABLE_NAME, tcp_exp_pdu_items);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+}
+
+static void
+handle_export_pdu_heuristic(packet_info *pinfo, tvbuff_t *tvb, heur_dtbl_entry_t *hdtbl_entry, struct tcpinfo *tcpinfo)
+{
+ exp_pdu_data_t *exp_pdu_data = NULL;
+
+ if (have_tap_listener(exported_pdu_tap)) {
+ if ((!hdtbl_entry->enabled) ||
+ (hdtbl_entry->protocol != NULL && !proto_is_protocol_enabled(hdtbl_entry->protocol))) {
+ exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
+ } else if (hdtbl_entry->protocol != NULL) {
+ exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
+ const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
+ &exp_pdu_data_src_ip,
+ &exp_pdu_data_dst_ip,
+ &exp_pdu_data_port_type,
+ &exp_pdu_data_src_port,
+ &exp_pdu_data_dst_port,
+ &exp_pdu_data_orig_frame_num,
+ &exp_pdu_data_dissector_data,
+ NULL
+ };
+
+ exp_pdu_data_dissector_data.data = tcpinfo;
+
+ exp_pdu_data = export_pdu_create_tags(pinfo, hdtbl_entry->short_name, EXP_PDU_TAG_HEUR_PROTO_NAME, tcp_exp_pdu_items);
+ }
+
+ if (exp_pdu_data != NULL) {
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+ }
+}
+
+static void
+handle_export_pdu_conversation(packet_info *pinfo, tvbuff_t *tvb, int src_port, int dst_port, struct tcpinfo *tcpinfo)
+{
+ if (have_tap_listener(exported_pdu_tap)) {
+ conversation_t *conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, PT_TCP, src_port, dst_port, 0);
+ if (conversation != NULL)
+ {
+ dissector_handle_t handle = (dissector_handle_t)wmem_tree_lookup32_le(conversation->dissector_tree, pinfo->num);
+ if (handle != NULL)
+ {
+ exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
+ const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
+ &exp_pdu_data_src_ip,
+ &exp_pdu_data_dst_ip,
+ &exp_pdu_data_port_type,
+ &exp_pdu_data_src_port,
+ &exp_pdu_data_dst_port,
+ &exp_pdu_data_orig_frame_num,
+ &exp_pdu_data_dissector_data,
+ NULL
+ };
+
+ exp_pdu_data_t *exp_pdu_data;
+
+ exp_pdu_data_dissector_data.data = tcpinfo;
+
+ exp_pdu_data = export_pdu_create_tags(pinfo, dissector_handle_get_dissector_name(handle), EXP_PDU_TAG_PROTO_NAME, tcp_exp_pdu_items);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+ }
+ }
+}
+
/* TCP structs and definitions */
/* **************************************************************************
@@ -4963,6 +5110,7 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
int save_desegment_offset;
guint32 save_desegment_len;
heur_dtbl_entry_t *hdtbl_entry;
+ exp_pdu_data_t *exp_pdu_data;
/* Don't call subdissectors for keepalives. Even though they do contain
* payload "data", it's just garbage. Display any data the keepalive
@@ -4994,6 +5142,7 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
src_port, dst_port, next_tvb, pinfo, tree, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_conversation(pinfo, next_tvb, src_port, dst_port, tcpinfo);
return TRUE;
}
@@ -5001,6 +5150,7 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
/* do lookup with the heuristic subdissector table */
if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_heuristic(pinfo, next_tvb, hdtbl_entry, tcpinfo);
return TRUE;
}
}
@@ -5025,6 +5175,7 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (tcpd && tcpd->server_port != 0 &&
dissector_try_uint_new(subdissector_table, tcpd->server_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_dissection_table(pinfo, next_tvb, tcpd->server_port, tcpinfo);
return TRUE;
}
@@ -5039,11 +5190,13 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (low_port != 0 &&
dissector_try_uint_new(subdissector_table, low_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_dissection_table(pinfo, next_tvb, low_port, tcpinfo);
return TRUE;
}
if (high_port != 0 &&
dissector_try_uint_new(subdissector_table, high_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_dissection_table(pinfo, next_tvb, high_port, tcpinfo);
return TRUE;
}
@@ -5051,6 +5204,7 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
/* do lookup with the heuristic subdissector table */
if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, tcpinfo)) {
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ handle_export_pdu_heuristic(pinfo, next_tvb, hdtbl_entry, tcpinfo);
return TRUE;
}
}
@@ -5069,6 +5223,14 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
call_dissector(data_handle,next_tvb, pinfo, tree);
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
+ if (have_tap_listener(exported_pdu_tap)) {
+ exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(next_tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(next_tvb);
+ exp_pdu_data->pdu_tvb = next_tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
return FALSE;
}
@@ -7145,6 +7307,7 @@ proto_reg_handoff_tcp(void)
register_capture_dissector("ip.proto", IP_PROTO_TCP, capture_tcp, proto_tcp);
mptcp_tap = register_tap("mptcp");
+ exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_4);
}
/*
diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h
index b3a068ac54..3d51fca444 100644
--- a/epan/dissectors/packet-tcp.h
+++ b/epan/dissectors/packet-tcp.h
@@ -113,14 +113,17 @@ typedef struct tcpheader {
/*
* Private data passed from the TCP dissector to subdissectors.
+ * NOTE: This structure is used by Export PDU functionality so
+ * make sure that handling is also updated if this structure
+ * changes!
*/
struct tcpinfo {
guint32 seq; /* Sequence number of first byte in the data */
guint32 nxtseq; /* Sequence number of first byte after data */
guint32 lastackseq; /* Sequence number of last ack */
gboolean is_reassembled; /* This is reassembled data. */
- guint16 flags; /* TCP flags */
- guint16 urgent_pointer; /* Urgent pointer value for the current packet. */
+ guint16 flags; /* TCP flags */
+ guint16 urgent_pointer; /* Urgent pointer value for the current packet. */
};
/*
diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c
index 8d925ea695..937fd215aa 100644
--- a/epan/dissectors/packet-udp.c
+++ b/epan/dissectors/packet-udp.c
@@ -48,6 +48,7 @@
#include <epan/conversation.h>
#include <epan/conversation_table.h>
#include <epan/dissector_filters.h>
+#include <epan/exported_pdu.h>
#include <epan/decode_as.h>
void proto_register_udp(void);
@@ -58,6 +59,7 @@ static dissector_handle_t udplite_handle;
static int udp_tap = -1;
static int udp_follow_tap = -1;
+static int exported_pdu_tap = -1;
static header_field_info *hfi_udp = NULL;
static header_field_info *hfi_udplite = NULL;
@@ -490,6 +492,80 @@ guint32 get_udp_stream_count(void)
return udp_stream_count;
}
+static void
+handle_export_pdu_dissection_table(packet_info *pinfo, tvbuff_t *tvb, guint32 port)
+{
+ if (have_tap_listener(exported_pdu_tap)) {
+ exp_pdu_data_item_t exp_pdu_data_table_value = {exp_pdu_data_dissector_table_num_value_size, exp_pdu_data_dissector_table_num_value_populate_data, NULL};
+
+ const exp_pdu_data_item_t *udp_exp_pdu_items[] = {
+ &exp_pdu_data_src_ip,
+ &exp_pdu_data_dst_ip,
+ &exp_pdu_data_port_type,
+ &exp_pdu_data_src_port,
+ &exp_pdu_data_dst_port,
+ &exp_pdu_data_orig_frame_num,
+ &exp_pdu_data_table_value,
+ NULL
+ };
+
+ exp_pdu_data_t *exp_pdu_data;
+
+ exp_pdu_data_table_value.data = GUINT_TO_POINTER(port);
+
+ exp_pdu_data = export_pdu_create_tags(pinfo, "udp.port", EXP_PDU_TAG_DISSECTOR_TABLE_NAME, udp_exp_pdu_items);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+}
+
+static void
+handle_export_pdu_heuristic(packet_info *pinfo, tvbuff_t *tvb, heur_dtbl_entry_t *hdtbl_entry)
+{
+ exp_pdu_data_t *exp_pdu_data = NULL;
+
+ if (have_tap_listener(exported_pdu_tap)) {
+ if ((!hdtbl_entry->enabled) ||
+ (hdtbl_entry->protocol != NULL && !proto_is_protocol_enabled(hdtbl_entry->protocol))) {
+ exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
+ } else if (hdtbl_entry->protocol != NULL) {
+ exp_pdu_data = export_pdu_create_common_tags(pinfo, hdtbl_entry->short_name, EXP_PDU_TAG_HEUR_PROTO_NAME);
+ }
+
+ if (exp_pdu_data != NULL) {
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+ }
+}
+
+static void
+handle_export_pdu_conversation(packet_info *pinfo, tvbuff_t *tvb, int uh_dport, int uh_sport)
+{
+ if (have_tap_listener(exported_pdu_tap)) {
+ conversation_t *conversation = find_conversation(pinfo->num, &pinfo->dst, &pinfo->src, PT_UDP, uh_dport, uh_sport, 0);
+ if (conversation != NULL)
+ {
+ dissector_handle_t handle = (dissector_handle_t)wmem_tree_lookup32_le(conversation->dissector_tree, pinfo->num);
+ if (handle != NULL)
+ {
+ exp_pdu_data_t *exp_pdu_data = export_pdu_create_common_tags(pinfo, dissector_handle_get_dissector_name(handle), EXP_PDU_TAG_PROTO_NAME);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
+ exp_pdu_data->pdu_tvb = tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
+ }
+ }
+}
+
void
decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, int uh_sport, int uh_dport, int uh_ulen)
@@ -501,6 +577,7 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
/* Save curr_layer_num as it might be changed by subdissector */
guint8 curr_layer_num = pinfo->curr_layer_num;
heur_dtbl_entry_t *hdtbl_entry;
+ exp_pdu_data_t *exp_pdu_data;
len = tvb_captured_length_remaining(tvb, offset);
reported_len = tvb_reported_length_remaining(tvb, offset);
@@ -527,15 +604,16 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
udp_p_info = (udp_p_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, hfi_udp->id, pinfo->curr_layer_num);
if (udp_p_info) {
call_heur_dissector_direct(udp_p_info->heur_dtbl_entry, next_tvb, pinfo, tree, NULL);
+ handle_export_pdu_heuristic(pinfo, next_tvb, udp_p_info->heur_dtbl_entry);
return;
}
}
/* determine if this packet is part of a conversation and call dissector */
/* for the conversation if available */
-
if (try_conversation_dissector(&pinfo->dst, &pinfo->src, PT_UDP,
uh_dport, uh_sport, next_tvb, pinfo, tree, NULL)) {
+ handle_export_pdu_conversation(pinfo, next_tvb, uh_dport, uh_sport);
return;
}
@@ -547,6 +625,8 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
udp_p_info->heur_dtbl_entry = hdtbl_entry;
p_add_proto_data(wmem_file_scope(), pinfo, hfi_udp->id, curr_layer_num, udp_p_info);
}
+
+ handle_export_pdu_heuristic(pinfo, next_tvb, udp_p_info->heur_dtbl_entry);
return;
}
}
@@ -575,11 +655,15 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
high_port = uh_dport;
}
if ((low_port != 0) &&
- dissector_try_uint(udp_dissector_table, low_port, next_tvb, pinfo, tree))
+ dissector_try_uint(udp_dissector_table, low_port, next_tvb, pinfo, tree)) {
+ handle_export_pdu_dissection_table(pinfo, next_tvb, low_port);
return;
+ }
if ((high_port != 0) &&
- dissector_try_uint(udp_dissector_table, high_port, next_tvb, pinfo, tree))
+ dissector_try_uint(udp_dissector_table, high_port, next_tvb, pinfo, tree)) {
+ handle_export_pdu_dissection_table(pinfo, next_tvb, high_port);
return;
+ }
if (!try_heuristic_first) {
/* Do lookup with the heuristic subdissector table */
@@ -589,11 +673,22 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
udp_p_info->heur_dtbl_entry = hdtbl_entry;
p_add_proto_data(wmem_file_scope(), pinfo, hfi_udp->id, curr_layer_num, udp_p_info);
}
+
+ handle_export_pdu_heuristic(pinfo, next_tvb, udp_p_info->heur_dtbl_entry);
return;
}
}
call_data_dissector(next_tvb, pinfo, tree);
+
+ if (have_tap_listener(exported_pdu_tap)) {
+ exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
+ exp_pdu_data->tvb_captured_length = tvb_captured_length(next_tvb);
+ exp_pdu_data->tvb_reported_length = tvb_reported_length(next_tvb);
+ exp_pdu_data->pdu_tvb = next_tvb;
+
+ tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
+ }
}
int
@@ -1180,6 +1275,7 @@ proto_reg_handoff_udp(void)
udp_tap = register_tap("udp");
udp_follow_tap = register_tap("udp_follow");
+ exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_4);
}
/*