forked from osmocom/wireshark
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:
parent
c992edc222
commit
edcc2f019e
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue