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>
This commit is contained in:
Michael Mann 2016-07-23 21:25:05 -04:00
parent c992edc222
commit edcc2f019e
7 changed files with 342 additions and 10 deletions

View File

@ -541,6 +541,8 @@ libwireshark.so.0 libwireshark0 #MINVER#
expert_update_comment_count@Base 1.12.0~rc1
export_pdu_create_common_tags@Base 2.1.1
export_pdu_create_tags@Base 2.1.1
exp_pdu_data_dissector_table_num_value_size@Base 2.1.1
exp_pdu_data_dissector_table_num_value_populate_data@Base 2.1.1
ext_menubar_add_entry@Base 1.99.8
ext_menubar_add_separator@Base 1.99.8
ext_menubar_add_submenu@Base 1.99.8

View File

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

View File

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

View File

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

View File

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

View File

@ -162,6 +162,28 @@ static int exp_pdu_data_orig_frame_num_populate_data(packet_info *pinfo, void* d
return exp_pdu_data_orig_frame_num_size(pinfo, data);
}
WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_size(packet_info *pinfo _U_, void* data _U_)
{
return EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN + 4;
}
WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_populate_data(packet_info *pinfo _U_, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
{
guint32 value = GPOINTER_TO_UINT(data);
tlv_buffer[0] = 0;
tlv_buffer[1] = EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL;
tlv_buffer[2] = 0;
tlv_buffer[3] = EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN; /* tag length */
tlv_buffer[4] = (value & 0xff000000) >> 24;
tlv_buffer[5] = (value & 0x00ff0000) >> 16;
tlv_buffer[6] = (value & 0x0000ff00) >> 8;
tlv_buffer[7] = (value & 0x000000ff);
return exp_pdu_data_dissector_table_num_value_size(pinfo, data);
}
exp_pdu_data_item_t exp_pdu_data_src_ip = {exp_pdu_data_src_ip_size, exp_pdu_data_src_ip_populate_data, NULL};
exp_pdu_data_item_t exp_pdu_data_dst_ip = {exp_pdu_data_dst_ip_size, exp_pdu_data_dst_ip_populate_data, NULL};
exp_pdu_data_item_t exp_pdu_data_port_type = {exp_pdu_data_port_type_size, exp_pdu_data_port_type_populate_data, NULL};
@ -199,7 +221,7 @@ export_pdu_create_tags(packet_info *pinfo, const char* proto_name, guint16 tag_t
guint8* buffer_data;
DISSECTOR_ASSERT(proto_name != NULL);
DISSECTOR_ASSERT((tag_type == EXP_PDU_TAG_PROTO_NAME) || (tag_type == EXP_PDU_TAG_HEUR_PROTO_NAME));
DISSECTOR_ASSERT((tag_type == EXP_PDU_TAG_PROTO_NAME) || (tag_type == EXP_PDU_TAG_HEUR_PROTO_NAME) || (tag_type == EXP_PDU_TAG_DISSECTOR_TABLE_NAME));
exp_pdu_data = (exp_pdu_data_t *)g_malloc(sizeof(exp_pdu_data_t));

View File

@ -41,6 +41,7 @@ extern "C" {
* if all taps are run.
*/
#define EXPORT_PDU_TAP_NAME_LAYER_3 "OSI layer 3"
#define EXPORT_PDU_TAP_NAME_LAYER_4 "OSI layer 4"
#define EXPORT_PDU_TAP_NAME_LAYER_7 "OSI layer 7"
/* To add dynamically an export name, call the following function
@ -127,6 +128,17 @@ WS_DLL_PUBLIC GSList *get_export_pdu_tap_list(void);
* COL_PROTOCOL might not be filled in.
*/
/**< value part is structure passed into TCP subdissectors. Format is:
guint16 version Export PDU version of structure (for backwards/forwards compatibility)
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
guint8 is_reassembled This is reassembled data.
guint16 flags TCP flags
guint16 urgent_pointer Urgent pointer value for the current packet.
*/
#define EXP_PDU_TAG_TCP_INFO_DATA 34
typedef struct _exp_pdu_data_t {
guint tlv_buffer_len;
guint8 *tlv_buffer;
@ -148,6 +160,8 @@ typedef struct _exp_pdu_data_t {
#define EXP_PDU_TAG_DVBCI_EVT_LEN 1
#define EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN 4
/** Compute the size (in bytes) of a pdu item
*
@param pinfo Packet info that may contain data for the pdu item
@ -197,12 +211,15 @@ WS_DLL_PUBLIC exp_pdu_data_t *export_pdu_create_tags(packet_info *pinfo, const c
6. Original frame number
@param pinfo Packet info that may contain data for the PDU items
@param tag_type Tag type for protocol's PDU. Must be EXP_PDU_TAG_PROTO_NAME or EXP_PDU_TAG_HEUR_PROTO_NAME.
@param tag_type Tag type for protocol's PDU. Must be EXP_PDU_TAG_PROTO_NAME, EXP_PDU_TAG_HEUR_PROTO_NAME or EXP_PDU_TAG_DISSECTOR_TABLE_NAME
@param proto_name Name of protocol that is exporting PDU
@return filled exp_pdu_data_t struct
*/
WS_DLL_PUBLIC exp_pdu_data_t *export_pdu_create_common_tags(packet_info *pinfo, const char *proto_name, guint16 tag_type);
WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_size(packet_info *pinfo, void* data);
WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_populate_data(packet_info *pinfo, void* data, guint8 *tlv_buffer, guint32 buffer_size);
WS_DLL_PUBLIC exp_pdu_data_item_t exp_pdu_data_src_ip;
WS_DLL_PUBLIC exp_pdu_data_item_t exp_pdu_data_dst_ip;
WS_DLL_PUBLIC exp_pdu_data_item_t exp_pdu_data_port_type;