Added "Follow DCCP stream" feature.
This pull request includes: * The "Follow DCCP stream" feature. * Updated docbook documentation for the "Follow DCCP stream" feature. * Test for the feature. * Corresponding packet trace for the test.
This commit is contained in:
parent
a57a32c04e
commit
2e7f2ffb7a
10
AUTHORS.src
10
AUTHORS.src
|
@ -2621,8 +2621,16 @@ Kees Cook <kees[AT]outflux.net> {
|
||||||
TiVoConnect Discovery Protocol
|
TiVoConnect Discovery Protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
Thomas Dreibholz <dreibh[AT]iem.uni-due.de> {
|
Thomas Dreibholz <dreibh[AT]iem.uni-due.de>/<dreibh[AT]simula.no> {
|
||||||
|
Calculation Application Protocol support
|
||||||
|
Component Status Protocol support
|
||||||
|
Fractal Generator Protocol support
|
||||||
|
DCCP dissector improvements
|
||||||
|
Follow DCCP stream feature
|
||||||
|
NetPerfMeter Protocol support
|
||||||
|
Ping Pong Protocol support
|
||||||
RSerPol protocol stack
|
RSerPol protocol stack
|
||||||
|
SCTP dissector improvements
|
||||||
Scripting Service Protocol support
|
Scripting Service Protocol support
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3462,6 +3462,7 @@ set(_test_group_list
|
||||||
suite_extcaps
|
suite_extcaps
|
||||||
suite_fileformats
|
suite_fileformats
|
||||||
suite_follow
|
suite_follow
|
||||||
|
suite_follow_dccp
|
||||||
suite_io
|
suite_io
|
||||||
suite_mergecap
|
suite_mergecap
|
||||||
suite_netperfmeter
|
suite_netperfmeter
|
||||||
|
|
|
@ -784,6 +784,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
||||||
get_data_source_name@Base 1.9.1
|
get_data_source_name@Base 1.9.1
|
||||||
get_data_source_tvb@Base 1.9.1
|
get_data_source_tvb@Base 1.9.1
|
||||||
get_data_source_tvb_by_name@Base 2.3.0
|
get_data_source_tvb_by_name@Base 2.3.0
|
||||||
|
get_dccp_stream_count@Base 3.5.0
|
||||||
get_dissector_names@Base 1.12.0~rc1
|
get_dissector_names@Base 1.12.0~rc1
|
||||||
get_dissector_table_param@Base 1.99.2
|
get_dissector_table_param@Base 1.99.2
|
||||||
get_dissector_table_selector_type@Base 1.9.1
|
get_dissector_table_selector_type@Base 1.9.1
|
||||||
|
|
|
@ -46,6 +46,8 @@ They previously shipped with Npcap 1.00.
|
||||||
created to dissect DLT_ETW packets so Wireshark can display the DLT_ETW packet header, its message and packet_etw dissector
|
created to dissect DLT_ETW packets so Wireshark can display the DLT_ETW packet header, its message and packet_etw dissector
|
||||||
calls packet_mbim sub_dissector if its provider matches the MBIM provider GUID.
|
calls packet_mbim sub_dissector if its provider matches the MBIM provider GUID.
|
||||||
|
|
||||||
|
* "Follow DCCP stream" feature to filter for and extract the contents of DCCP streams.
|
||||||
|
|
||||||
// === Removed Features and Support
|
// === Removed Features and Support
|
||||||
|
|
||||||
//=== Removed Dissectors
|
//=== Removed Dissectors
|
||||||
|
|
|
@ -22,7 +22,7 @@ display filter to show only the packets in a TLS or SSL stream. If so,
|
||||||
Wireshark’s ability to follow protocol streams will be useful to you.
|
Wireshark’s ability to follow protocol streams will be useful to you.
|
||||||
|
|
||||||
To filter to a particular stream,
|
To filter to a particular stream,
|
||||||
select a TCP, UDP, TLS, or HTTP packet in the packet list of the stream/connection you are
|
select a TCP, UDP, DCCP, TLS, HTTP, HTTP/2 or QUIC packet in the packet list of the stream/connection you are
|
||||||
interested in and then select the menu item menu:Analyze[Follow TCP Stream]
|
interested in and then select the menu item menu:Analyze[Follow TCP Stream]
|
||||||
(or use the context menu in the packet list). Wireshark will set an
|
(or use the context menu in the packet list). Wireshark will set an
|
||||||
appropriate display filter and display a dialog box with the data from the
|
appropriate display filter and display a dialog box with the data from the
|
||||||
|
|
|
@ -162,6 +162,9 @@ See <<ChAdvFollowStreamSection>>.
|
||||||
|menu:Follow[UDP Stream] |menu:Analyze[] |
|
|menu:Follow[UDP Stream] |menu:Analyze[] |
|
||||||
Same functionality as “Follow TCP Stream” but for UDP “streams”.
|
Same functionality as “Follow TCP Stream” but for UDP “streams”.
|
||||||
|
|
||||||
|
|menu:Follow[DCCP Stream] |menu:Analyze[] |
|
||||||
|
Same functionality as “Follow TCP Stream” but for DCCP streams.
|
||||||
|
|
||||||
|menu:Follow[TLS Stream] |menu:Analyze[] |
|
|menu:Follow[TLS Stream] |menu:Analyze[] |
|
||||||
Same functionality as “Follow TCP Stream” but for TLS or SSL streams.
|
Same functionality as “Follow TCP Stream” but for TLS or SSL streams.
|
||||||
See the wiki page on link:{wireshark-wiki-url}SSL[SSL] for instructions
|
See the wiki page on link:{wireshark-wiki-url}SSL[SSL] for instructions
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*
|
*
|
||||||
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
|
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
|
||||||
*
|
*
|
||||||
|
* Copyright 2020-2021 by Thomas Dreibholz <dreibh [AT] simula.no>
|
||||||
|
*
|
||||||
* Wireshark - Network traffic analyzer
|
* Wireshark - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@wireshark.org>
|
* By Gerald Combs <gerald@wireshark.org>
|
||||||
* Copyright 1998 Gerald Combs
|
* Copyright 1998 Gerald Combs
|
||||||
|
@ -45,8 +47,12 @@
|
||||||
#include <epan/ipproto.h>
|
#include <epan/ipproto.h>
|
||||||
#include <epan/in_cksum.h>
|
#include <epan/in_cksum.h>
|
||||||
#include <epan/prefs.h>
|
#include <epan/prefs.h>
|
||||||
|
#include <epan/follow.h>
|
||||||
#include <epan/expert.h>
|
#include <epan/expert.h>
|
||||||
#include <epan/conversation.h>
|
#include <epan/conversation.h>
|
||||||
|
#include <epan/conversation_table.h>
|
||||||
|
#include <epan/conversation_filter.h>
|
||||||
|
#include <epan/exported_pdu.h>
|
||||||
#include <epan/tap.h>
|
#include <epan/tap.h>
|
||||||
#include <wsutil/str_util.h>
|
#include <wsutil/str_util.h>
|
||||||
#include <wsutil/utf8_entities.h>
|
#include <wsutil/utf8_entities.h>
|
||||||
|
@ -181,10 +187,12 @@ static const unit_name_string units_bytes_sec = { "bytes/sec", NULL };
|
||||||
|
|
||||||
static int proto_dccp = -1;
|
static int proto_dccp = -1;
|
||||||
static int dccp_tap = -1;
|
static int dccp_tap = -1;
|
||||||
|
static int dccp_follow_tap = -1;
|
||||||
|
|
||||||
static int hf_dccp_srcport = -1;
|
static int hf_dccp_srcport = -1;
|
||||||
static int hf_dccp_dstport = -1;
|
static int hf_dccp_dstport = -1;
|
||||||
static int hf_dccp_port = -1;
|
static int hf_dccp_port = -1;
|
||||||
|
static int hf_dccp_stream = -1;
|
||||||
static int hf_dccp_data_offset = -1;
|
static int hf_dccp_data_offset = -1;
|
||||||
static int hf_dccp_ccval = -1;
|
static int hf_dccp_ccval = -1;
|
||||||
static int hf_dccp_cscov = -1;
|
static int hf_dccp_cscov = -1;
|
||||||
|
@ -246,6 +254,7 @@ static heur_dissector_list_t heur_subdissector_list;
|
||||||
static gboolean dccp_summary_in_tree = TRUE;
|
static gboolean dccp_summary_in_tree = TRUE;
|
||||||
static gboolean try_heuristic_first = FALSE;
|
static gboolean try_heuristic_first = FALSE;
|
||||||
static gboolean dccp_check_checksum = TRUE;
|
static gboolean dccp_check_checksum = TRUE;
|
||||||
|
static guint32 dccp_stream_count;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
|
@ -257,6 +266,11 @@ decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
|
|
||||||
next_tvb = tvb_new_subset_remaining(tvb, offset);
|
next_tvb = tvb_new_subset_remaining(tvb, offset);
|
||||||
|
|
||||||
|
/* If the user has a "Follow DCCP Stream" window loading, pass a pointer
|
||||||
|
to the payload tvb through the tap system. */
|
||||||
|
if (have_tap_listener(dccp_follow_tap))
|
||||||
|
tap_queue_packet(dccp_follow_tap, pinfo, next_tvb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* determine if this packet is part of a conversation and call dissector
|
* determine if this packet is part of a conversation and call dissector
|
||||||
* for the conversation if available
|
* for the conversation if available
|
||||||
|
@ -322,6 +336,251 @@ decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
call_data_dissector(next_tvb, pinfo, tree);
|
call_data_dissector(next_tvb, pinfo, tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Conversation and process code originally copied from packet-udp.c */
|
||||||
|
static struct dccp_analysis *
|
||||||
|
init_dccp_conversation_data(packet_info *pinfo)
|
||||||
|
{
|
||||||
|
struct dccp_analysis *dccpd;
|
||||||
|
|
||||||
|
/* Initialize the dccp protocol data structure to add to the dccp conversation */
|
||||||
|
dccpd = wmem_new0(wmem_file_scope(), struct dccp_analysis);
|
||||||
|
/*
|
||||||
|
dccpd->flow1.username = NULL;
|
||||||
|
dccpd->flow1.command = NULL;
|
||||||
|
dccpd->flow2.username = NULL;
|
||||||
|
dccpd->flow2.command = NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
dccpd->stream = dccp_stream_count++;
|
||||||
|
dccpd->ts_first = pinfo->abs_ts;
|
||||||
|
dccpd->ts_prev = pinfo->abs_ts;
|
||||||
|
|
||||||
|
return dccpd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dccp_analysis *
|
||||||
|
get_dccp_conversation_data(conversation_t *conv, packet_info *pinfo)
|
||||||
|
{
|
||||||
|
int direction;
|
||||||
|
struct dccp_analysis *dccpd;
|
||||||
|
|
||||||
|
/* Get the data for this conversation */
|
||||||
|
dccpd=(struct dccp_analysis *)conversation_get_proto_data(conv, proto_dccp);
|
||||||
|
|
||||||
|
/* If the conversation was just created or it matched a
|
||||||
|
* conversation with template options, dccpd will not
|
||||||
|
* have been initialized. So, initialize
|
||||||
|
* a new dccpd structure for the conversation.
|
||||||
|
*/
|
||||||
|
if (!dccpd) {
|
||||||
|
dccpd = init_dccp_conversation_data(pinfo);
|
||||||
|
conversation_add_proto_data(conv, proto_dccp, dccpd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check direction and get ua lists */
|
||||||
|
direction=cmp_address(&pinfo->src, &pinfo->dst);
|
||||||
|
/* if the addresses are equal, match the ports instead */
|
||||||
|
if (direction == 0) {
|
||||||
|
direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (direction >= 0) {
|
||||||
|
dccpd->fwd=&(dccpd->flow1);
|
||||||
|
dccpd->rev=&(dccpd->flow2);
|
||||||
|
} else {
|
||||||
|
dccpd->fwd=&(dccpd->flow2);
|
||||||
|
dccpd->rev=&(dccpd->flow1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dccpd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* dccp_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
|
||||||
|
{
|
||||||
|
if (filter == CONV_FT_SRC_PORT)
|
||||||
|
return "dccp.srcport";
|
||||||
|
|
||||||
|
if (filter == CONV_FT_DST_PORT)
|
||||||
|
return "dccp.dstport";
|
||||||
|
|
||||||
|
if (filter == CONV_FT_ANY_PORT)
|
||||||
|
return "dccp.port";
|
||||||
|
|
||||||
|
if(!conv) {
|
||||||
|
return CONV_FILTER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == CONV_FT_SRC_ADDRESS) {
|
||||||
|
if (conv->src_address.type == AT_IPv4)
|
||||||
|
return "ip.src";
|
||||||
|
if (conv->src_address.type == AT_IPv6)
|
||||||
|
return "ipv6.src";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == CONV_FT_DST_ADDRESS) {
|
||||||
|
if (conv->dst_address.type == AT_IPv4)
|
||||||
|
return "ip.dst";
|
||||||
|
if (conv->dst_address.type == AT_IPv6)
|
||||||
|
return "ipv6.dst";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == CONV_FT_ANY_ADDRESS) {
|
||||||
|
if (conv->src_address.type == AT_IPv4)
|
||||||
|
return "ip.addr";
|
||||||
|
if (conv->src_address.type == AT_IPv6)
|
||||||
|
return "ipv6.addr";
|
||||||
|
}
|
||||||
|
|
||||||
|
return CONV_FILTER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ct_dissector_info_t dccp_ct_dissector_info = {&dccp_conv_get_filter_type};
|
||||||
|
|
||||||
|
static tap_packet_status
|
||||||
|
dccpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
|
||||||
|
{
|
||||||
|
conv_hash_t *hash = (conv_hash_t*) pct;
|
||||||
|
const e_dccphdr *dccphdr=(const e_dccphdr *)vip;
|
||||||
|
|
||||||
|
add_conversation_table_data_with_conv_id(hash, &dccphdr->ip_src, &dccphdr->ip_dst, dccphdr->sport, dccphdr->dport, (conv_id_t) dccphdr->stream, 1, pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts, &dccp_ct_dissector_info, ENDPOINT_DCCP);
|
||||||
|
|
||||||
|
return TAP_PACKET_REDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* dccp_host_get_filter_type(hostlist_talker_t* host, conv_filter_type_e filter)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (filter == CONV_FT_SRC_PORT)
|
||||||
|
return "dccp.srcport";
|
||||||
|
|
||||||
|
if (filter == CONV_FT_DST_PORT)
|
||||||
|
return "dccp.dstport";
|
||||||
|
|
||||||
|
if (filter == CONV_FT_ANY_PORT)
|
||||||
|
return "dccp.port";
|
||||||
|
|
||||||
|
if(!host) {
|
||||||
|
return CONV_FILTER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (filter == CONV_FT_SRC_ADDRESS) {
|
||||||
|
if (host->myaddress.type == AT_IPv4)
|
||||||
|
return "ip.src";
|
||||||
|
if (host->myaddress.type == AT_IPv6)
|
||||||
|
return "ipv6.src";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == CONV_FT_DST_ADDRESS) {
|
||||||
|
if (host->myaddress.type == AT_IPv4)
|
||||||
|
return "ip.dst";
|
||||||
|
if (host->myaddress.type == AT_IPv6)
|
||||||
|
return "ipv6.dst";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == CONV_FT_ANY_ADDRESS) {
|
||||||
|
if (host->myaddress.type == AT_IPv4)
|
||||||
|
return "ip.addr";
|
||||||
|
if (host->myaddress.type == AT_IPv6)
|
||||||
|
return "ipv6.addr";
|
||||||
|
}
|
||||||
|
|
||||||
|
return CONV_FILTER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hostlist_dissector_info_t dccp_host_dissector_info = {&dccp_host_get_filter_type};
|
||||||
|
|
||||||
|
static tap_packet_status
|
||||||
|
dccpip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
|
||||||
|
{
|
||||||
|
conv_hash_t *hash = (conv_hash_t*) pit;
|
||||||
|
const e_dccphdr *dccphdr=(const e_dccphdr *)vip;
|
||||||
|
|
||||||
|
/* Take two "add" passes per packet, adding for each direction, ensures that all
|
||||||
|
packets are counted properly (even if address is sending to itself)
|
||||||
|
XXX - this could probably be done more efficiently inside hostlist_table */
|
||||||
|
add_hostlist_table_data(hash, &dccphdr->ip_src, dccphdr->sport, TRUE, 1, pinfo->fd->pkt_len, &dccp_host_dissector_info, ENDPOINT_DCCP);
|
||||||
|
add_hostlist_table_data(hash, &dccphdr->ip_dst, dccphdr->dport, FALSE, 1, pinfo->fd->pkt_len, &dccp_host_dissector_info, ENDPOINT_DCCP);
|
||||||
|
|
||||||
|
return TAP_PACKET_REDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current stream count */
|
||||||
|
guint32 get_dccp_stream_count(void)
|
||||||
|
{
|
||||||
|
return dccp_stream_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dccp_filter_valid(packet_info *pinfo)
|
||||||
|
{
|
||||||
|
return proto_is_frame_protocol(pinfo->layers, "dccp");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
dccp_build_filter(packet_info *pinfo)
|
||||||
|
{
|
||||||
|
if( pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4 ) {
|
||||||
|
/* DCCP over IPv4 */
|
||||||
|
return g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (dccp.port eq %d and dccp.port eq %d)",
|
||||||
|
address_to_str(pinfo->pool, &pinfo->net_src),
|
||||||
|
address_to_str(pinfo->pool, &pinfo->net_dst),
|
||||||
|
pinfo->srcport, pinfo->destport );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6 ) {
|
||||||
|
/* DCCP over IPv6 */
|
||||||
|
return g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (dccp.port eq %d and dccp.port eq %d)",
|
||||||
|
address_to_str(pinfo->pool, &pinfo->net_src),
|
||||||
|
address_to_str(pinfo->pool, &pinfo->net_dst),
|
||||||
|
pinfo->srcport, pinfo->destport );
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *dccp_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream _U_)
|
||||||
|
{
|
||||||
|
conversation_t *conv;
|
||||||
|
struct dccp_analysis *dccpd;
|
||||||
|
|
||||||
|
if( ((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
|
||||||
|
(pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6))
|
||||||
|
&& (conv=find_conversation_pinfo(pinfo, 0)) != NULL )
|
||||||
|
{
|
||||||
|
/* DCCP over IPv4/6 */
|
||||||
|
dccpd = get_dccp_conversation_data(conv, pinfo);
|
||||||
|
*stream = dccpd->stream;
|
||||||
|
return g_strdup_printf("dccp.stream eq %u", dccpd->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *dccp_follow_index_filter(guint stream, guint sub_stream _U_)
|
||||||
|
{
|
||||||
|
return g_strdup_printf("dccp.stream eq %u", stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *dccp_follow_address_filter(address *src_addr, address *dst_addr, int src_port, int dst_port)
|
||||||
|
{
|
||||||
|
const gchar *ip_version = src_addr->type == AT_IPv6 ? "v6" : "";
|
||||||
|
gchar src_addr_str[WS_INET6_ADDRSTRLEN];
|
||||||
|
gchar dst_addr_str[WS_INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
address_to_str_buf(src_addr, src_addr_str, sizeof(src_addr_str));
|
||||||
|
address_to_str_buf(dst_addr, dst_addr_str, sizeof(dst_addr_str));
|
||||||
|
|
||||||
|
return g_strdup_printf("((ip%s.src eq %s and dccp.srcport eq %d) and "
|
||||||
|
"(ip%s.dst eq %s and dccp.dstport eq %d))"
|
||||||
|
" or "
|
||||||
|
"((ip%s.src eq %s and dccp.srcport eq %d) and "
|
||||||
|
"(ip%s.dst eq %s and dccp.dstport eq %d))",
|
||||||
|
ip_version, src_addr_str, src_port,
|
||||||
|
ip_version, dst_addr_str, dst_port,
|
||||||
|
ip_version, dst_addr_str, dst_port,
|
||||||
|
ip_version, src_addr_str, src_port);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decode a variable-length number of nbytes starting at offset. Based on
|
* decode a variable-length number of nbytes starting at offset. Based on
|
||||||
* a concept by Arnaldo de Melo
|
* a concept by Arnaldo de Melo
|
||||||
|
@ -620,6 +879,7 @@ static int
|
||||||
dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||||
{
|
{
|
||||||
proto_tree *dccp_tree;
|
proto_tree *dccp_tree;
|
||||||
|
proto_item *item;
|
||||||
proto_tree *dccp_options_tree = NULL;
|
proto_tree *dccp_options_tree = NULL;
|
||||||
proto_item *dccp_item = NULL;
|
proto_item *dccp_item = NULL;
|
||||||
proto_item *hidden_item, *offset_item;
|
proto_item *hidden_item, *offset_item;
|
||||||
|
@ -632,6 +892,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
|
||||||
guint advertised_dccp_header_len = 0;
|
guint advertised_dccp_header_len = 0;
|
||||||
guint options_len = 0;
|
guint options_len = 0;
|
||||||
e_dccphdr *dccph;
|
e_dccphdr *dccph;
|
||||||
|
conversation_t *conv = NULL;
|
||||||
|
struct dccp_analysis *dccpd;
|
||||||
|
|
||||||
dccph = wmem_new0(wmem_packet_scope(), e_dccphdr);
|
dccph = wmem_new0(wmem_packet_scope(), e_dccphdr);
|
||||||
dccph->sport = tvb_get_ntohs(tvb, offset);
|
dccph->sport = tvb_get_ntohs(tvb, offset);
|
||||||
|
@ -669,6 +931,17 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
|
||||||
pinfo->srcport = dccph->sport;
|
pinfo->srcport = dccph->sport;
|
||||||
pinfo->destport = dccph->dport;
|
pinfo->destport = dccph->dport;
|
||||||
|
|
||||||
|
/* find (or create if needed) the conversation for this DCCP session */
|
||||||
|
conv = find_or_create_conversation(pinfo);
|
||||||
|
dccpd = get_dccp_conversation_data(conv, pinfo);
|
||||||
|
item = proto_tree_add_uint(dccp_tree, hf_dccp_stream, tvb, offset, 0, dccpd->stream);
|
||||||
|
proto_item_set_generated(item);
|
||||||
|
|
||||||
|
/* Copy the stream index into the header as well to make it available
|
||||||
|
* to tap listeners.
|
||||||
|
*/
|
||||||
|
dccph->stream = dccpd->stream;
|
||||||
|
|
||||||
dccph->data_offset = tvb_get_guint8(tvb, offset);
|
dccph->data_offset = tvb_get_guint8(tvb, offset);
|
||||||
advertised_dccp_header_len = dccph->data_offset * 4;
|
advertised_dccp_header_len = dccph->data_offset * 4;
|
||||||
offset_item = proto_tree_add_uint(dccp_tree, hf_dccp_data_offset, tvb, offset, 1,
|
offset_item = proto_tree_add_uint(dccp_tree, hf_dccp_data_offset, tvb, offset, 1,
|
||||||
|
@ -1028,6 +1301,12 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
|
||||||
return tvb_reported_length(tvb);
|
return tvb_reported_length(tvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dccp_init(void)
|
||||||
|
{
|
||||||
|
dccp_stream_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
proto_register_dccp(void)
|
proto_register_dccp(void)
|
||||||
{
|
{
|
||||||
|
@ -1058,6 +1337,14 @@ proto_register_dccp(void)
|
||||||
NULL, HFILL
|
NULL, HFILL
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&hf_dccp_stream,
|
||||||
|
{
|
||||||
|
"Stream index", "dccp.stream",
|
||||||
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||||
|
NULL, HFILL
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
&hf_dccp_data_offset,
|
&hf_dccp_data_offset,
|
||||||
{
|
{
|
||||||
|
@ -1328,6 +1615,13 @@ proto_register_dccp(void)
|
||||||
"Check the validity of the DCCP checksum when possible",
|
"Check the validity of the DCCP checksum when possible",
|
||||||
"Whether to check the validity of the DCCP checksum",
|
"Whether to check the validity of the DCCP checksum",
|
||||||
&dccp_check_checksum);
|
&dccp_check_checksum);
|
||||||
|
|
||||||
|
register_conversation_table(proto_dccp, FALSE, dccpip_conversation_packet, dccpip_hostlist_packet);
|
||||||
|
register_conversation_filter("dccp", "DCCP", dccp_filter_valid, dccp_build_filter);
|
||||||
|
register_follow_stream(proto_dccp, "dccp_follow", dccp_follow_conv_filter, dccp_follow_index_filter, dccp_follow_address_filter,
|
||||||
|
dccp_port_to_display, follow_tvb_tap_listener);
|
||||||
|
|
||||||
|
register_init_routine(dccp_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1338,6 +1632,7 @@ proto_reg_handoff_dccp(void)
|
||||||
dccp_handle = create_dissector_handle(dissect_dccp, proto_dccp);
|
dccp_handle = create_dissector_handle(dissect_dccp, proto_dccp);
|
||||||
dissector_add_uint("ip.proto", IP_PROTO_DCCP, dccp_handle);
|
dissector_add_uint("ip.proto", IP_PROTO_DCCP, dccp_handle);
|
||||||
dccp_tap = register_tap("dccp");
|
dccp_tap = register_tap("dccp");
|
||||||
|
dccp_follow_tap = register_tap("dccp_follow");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*
|
*
|
||||||
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
|
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
|
||||||
*
|
*
|
||||||
|
* Copyright 2020-2021 by Thomas Dreibholz <dreibh [AT] simula.no>
|
||||||
|
*
|
||||||
* template taken from packet-udp.c
|
* template taken from packet-udp.c
|
||||||
*
|
*
|
||||||
* Wireshark - Network traffic analyzer
|
* Wireshark - Network traffic analyzer
|
||||||
|
@ -18,6 +20,10 @@
|
||||||
#ifndef __PACKET_DCCP_H__
|
#ifndef __PACKET_DCCP_H__
|
||||||
#define __PACKET_DCCP_H__
|
#define __PACKET_DCCP_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* DCCP structs and definitions */
|
/* DCCP structs and definitions */
|
||||||
typedef struct _e_dccphdr {
|
typedef struct _e_dccphdr {
|
||||||
guint16 sport;
|
guint16 sport;
|
||||||
|
@ -44,10 +50,74 @@ typedef struct _e_dccphdr {
|
||||||
guint8 data2;
|
guint8 data2;
|
||||||
guint8 data3;
|
guint8 data3;
|
||||||
|
|
||||||
|
guint32 stream; /* this stream index field is included to help differentiate when address/port pairs are reused */
|
||||||
|
|
||||||
address ip_src;
|
address ip_src;
|
||||||
address ip_dst;
|
address ip_dst;
|
||||||
} e_dccphdr;
|
} e_dccphdr;
|
||||||
|
|
||||||
|
/* Conversation and process structures originally copied from packet-tcp.c */
|
||||||
|
typedef struct _dccp_flow_t {
|
||||||
|
/* Process info, currently discovered via IPFIX */
|
||||||
|
guint32 process_uid; /* UID of local process */
|
||||||
|
guint32 process_pid; /* PID of local process */
|
||||||
|
gchar *username; /* Username of the local process */
|
||||||
|
gchar *command; /* Local process name + path + args */
|
||||||
|
} dccp_flow_t;
|
||||||
|
|
||||||
|
struct dccp_analysis {
|
||||||
|
/* These two structs are managed based on comparing the source
|
||||||
|
* and destination addresses and, if they're equal, comparing
|
||||||
|
* the source and destination ports.
|
||||||
|
*
|
||||||
|
* If the source is greater than the destination, then stuff
|
||||||
|
* sent from src is in ual1.
|
||||||
|
*
|
||||||
|
* If the source is less than the destination, then stuff
|
||||||
|
* sent from src is in ual2.
|
||||||
|
*
|
||||||
|
* XXX - if the addresses and ports are equal, we don't guarantee
|
||||||
|
* the behavior.
|
||||||
|
*/
|
||||||
|
dccp_flow_t flow1;
|
||||||
|
dccp_flow_t flow2;
|
||||||
|
|
||||||
|
/* These pointers are set by get_dccp_conversation_data()
|
||||||
|
* fwd point in the same direction as the current packet
|
||||||
|
* and rev in the reverse direction
|
||||||
|
*/
|
||||||
|
dccp_flow_t *fwd;
|
||||||
|
dccp_flow_t *rev;
|
||||||
|
|
||||||
|
/* Keep track of dccp stream numbers instead of using the conversation
|
||||||
|
* index (as how it was done before). This prevents gaps in the
|
||||||
|
* stream index numbering
|
||||||
|
*/
|
||||||
|
guint32 stream;
|
||||||
|
|
||||||
|
/* Remember the timestamp of the first frame seen in this dccp
|
||||||
|
* conversation to be able to calculate a relative time compared
|
||||||
|
* to the start of this conversation
|
||||||
|
*/
|
||||||
|
nstime_t ts_first;
|
||||||
|
|
||||||
|
/* Remember the timestamp of the frame that was last seen in this
|
||||||
|
* dccp conversation to be able to calculate a delta time compared
|
||||||
|
* to previous frame in this conversation
|
||||||
|
*/
|
||||||
|
nstime_t ts_prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Get the current number of DCCP streams
|
||||||
|
*
|
||||||
|
* @return The number of DCCP streams
|
||||||
|
*/
|
||||||
|
WS_DLL_PUBLIC guint32 get_dccp_stream_count(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif /* __PACKET_DCCP_H__ */
|
#endif /* __PACKET_DCCP_H__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -42,6 +42,7 @@ typedef enum {
|
||||||
FOLLOW_TCP,
|
FOLLOW_TCP,
|
||||||
FOLLOW_TLS,
|
FOLLOW_TLS,
|
||||||
FOLLOW_UDP,
|
FOLLOW_UDP,
|
||||||
|
FOLLOW_DCCP,
|
||||||
FOLLOW_HTTP,
|
FOLLOW_HTTP,
|
||||||
FOLLOW_HTTP2,
|
FOLLOW_HTTP2,
|
||||||
FOLLOW_QUIC,
|
FOLLOW_QUIC,
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,71 @@
|
||||||
|
#
|
||||||
|
# Wireshark tests
|
||||||
|
#
|
||||||
|
# Copyright 2020-2021 by Thomas Dreibholz <dreibh [AT] simula.no>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
'''Follow DCCP Stream tests'''
|
||||||
|
|
||||||
|
import subprocesstest
|
||||||
|
import fixtures
|
||||||
|
|
||||||
|
|
||||||
|
@fixtures.mark_usefixtures('test_env')
|
||||||
|
@fixtures.uses_fixtures
|
||||||
|
class case_follow_dccp(subprocesstest.SubprocessTestCase):
|
||||||
|
def test_follow_dccp_bad_conditions(self, cmd_tshark, capture_file):
|
||||||
|
'''Checks whether Follow DCCP correctly handles some tests.'''
|
||||||
|
|
||||||
|
# Test 1:
|
||||||
|
# 1. Identification of DCCP Flow #9
|
||||||
|
# 2. Selection and decoding of DCCP Flow #9
|
||||||
|
proc = self.assertRun((cmd_tshark,
|
||||||
|
'-r', capture_file('netperfmeter-dccp.pcapng.gz'),
|
||||||
|
'-qz', 'follow,dccp,hex,9',
|
||||||
|
))
|
||||||
|
|
||||||
|
self.assertIn("""\
|
||||||
|
===================================================================
|
||||||
|
Follow: dccp,hex
|
||||||
|
Filter: dccp.stream eq 9
|
||||||
|
Node 0: 127.0.0.1:43933
|
||||||
|
Node 1: 127.0.0.1:9000
|
||||||
|
00000000 04 00 00 1a 00 00 00 09 4b cd f3 aa 30 3c 67 74 ........ K...0<gt
|
||||||
|
00000010 f2 41 ee 5f c8 10 1f 41 00 00 .A._...A ..
|
||||||
|
0000001A 05 03 27 10 00 00 00 09 f2 41 ee 5f c8 10 1f 41 ..'..... .A._...A
|
||||||
|
0000002A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||||
|
0000003A 00 00 00 00 00 00 00 00 00 05 ba 0a bf 18 68 19 ........ ......h.
|
||||||
|
0000004A 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d .. !"#$% &'()*+,-
|
||||||
|
0000005A 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d ./012345 6789:;<=
|
||||||
|
0000006A 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d >?@ABCDE FGHIJKLM
|
||||||
|
0000007A 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d NOPQRSTU VWXYZ[\]
|
||||||
|
0000008A 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d ^_`abcde fghijklm
|
||||||
|
0000009A 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d nopqrstu vwxyz{|}
|
||||||
|
000000AA 7e 7f 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b ~... !"# $%&'()*+
|
||||||
|
000000BA 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b ,-./0123 456789:;
|
||||||
|
000000CA 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b <=>?@ABC DEFGHIJK
|
||||||
|
000000DA 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b LMNOPQRS TUVWXYZ[
|
||||||
|
000000EA 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b \]^_`abc defghijk
|
||||||
|
000000FA 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b lmnopqrs tuvwxyz{
|
||||||
|
0000010A 7c 7d 7e 7f 1e 1f 20 21 22 23 24 25 26 27 28 29 |}~... ! "#$%&'()
|
||||||
|
0000011A 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 *+,-./01 23456789
|
||||||
|
""".replace("\r\n", "\n"),
|
||||||
|
proc.stdout_str)
|
||||||
|
|
||||||
|
# Test 2:
|
||||||
|
# Trying identification of not-existing DCCP Flow #10
|
||||||
|
proc = self.assertRun((cmd_tshark,
|
||||||
|
'-r', capture_file('netperfmeter-dccp.pcapng.gz'),
|
||||||
|
'-qz', 'follow,dccp,hex,10',
|
||||||
|
))
|
||||||
|
|
||||||
|
self.assertIn("""\
|
||||||
|
===================================================================
|
||||||
|
Follow: dccp,hex
|
||||||
|
Filter: dccp.stream eq 10
|
||||||
|
Node 0: :0
|
||||||
|
Node 1: :0
|
||||||
|
===================================================================
|
||||||
|
""".replace("\r\n", "\n"),
|
||||||
|
proc.stdout_str)
|
|
@ -16,6 +16,7 @@
|
||||||
#include "epan/follow.h"
|
#include "epan/follow.h"
|
||||||
#include "epan/dissectors/packet-tcp.h"
|
#include "epan/dissectors/packet-tcp.h"
|
||||||
#include "epan/dissectors/packet-udp.h"
|
#include "epan/dissectors/packet-udp.h"
|
||||||
|
#include "epan/dissectors/packet-dccp.h"
|
||||||
#include "epan/dissectors/packet-http2.h"
|
#include "epan/dissectors/packet-http2.h"
|
||||||
#include "epan/dissectors/packet-quic.h"
|
#include "epan/dissectors/packet-quic.h"
|
||||||
#include "epan/prefs.h"
|
#include "epan/prefs.h"
|
||||||
|
@ -93,6 +94,9 @@ FollowStreamDialog::FollowStreamDialog(QWidget &parent, CaptureFile &cf, follow_
|
||||||
case FOLLOW_UDP:
|
case FOLLOW_UDP:
|
||||||
follower_ = get_follow_by_name("UDP");
|
follower_ = get_follow_by_name("UDP");
|
||||||
break;
|
break;
|
||||||
|
case FOLLOW_DCCP:
|
||||||
|
follower_ = get_follow_by_name("DCCP");
|
||||||
|
break;
|
||||||
case FOLLOW_HTTP:
|
case FOLLOW_HTTP:
|
||||||
follower_ = get_follow_by_name("HTTP");
|
follower_ = get_follow_by_name("HTTP");
|
||||||
break;
|
break;
|
||||||
|
@ -519,6 +523,7 @@ FollowStreamDialog::readStream()
|
||||||
|
|
||||||
case FOLLOW_TCP :
|
case FOLLOW_TCP :
|
||||||
case FOLLOW_UDP :
|
case FOLLOW_UDP :
|
||||||
|
case FOLLOW_DCCP :
|
||||||
case FOLLOW_HTTP :
|
case FOLLOW_HTTP :
|
||||||
case FOLLOW_HTTP2:
|
case FOLLOW_HTTP2:
|
||||||
case FOLLOW_QUIC:
|
case FOLLOW_QUIC:
|
||||||
|
@ -941,6 +946,18 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FOLLOW_DCCP:
|
||||||
|
{
|
||||||
|
int stream_count = get_dccp_stream_count();
|
||||||
|
ui->streamNumberSpinBox->blockSignals(true);
|
||||||
|
ui->streamNumberSpinBox->setMaximum(stream_count-1);
|
||||||
|
ui->streamNumberSpinBox->setValue(stream_num);
|
||||||
|
ui->streamNumberSpinBox->blockSignals(false);
|
||||||
|
ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
|
||||||
|
ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case FOLLOW_HTTP2:
|
case FOLLOW_HTTP2:
|
||||||
{
|
{
|
||||||
int stream_count = get_tcp_stream_count();
|
int stream_count = get_tcp_stream_count();
|
||||||
|
|
|
@ -574,6 +574,7 @@ private slots:
|
||||||
void openFollowStreamDialogForType(follow_type_t type);
|
void openFollowStreamDialogForType(follow_type_t type);
|
||||||
void on_actionAnalyzeFollowTCPStream_triggered();
|
void on_actionAnalyzeFollowTCPStream_triggered();
|
||||||
void on_actionAnalyzeFollowUDPStream_triggered();
|
void on_actionAnalyzeFollowUDPStream_triggered();
|
||||||
|
void on_actionAnalyzeFollowDCCPStream_triggered();
|
||||||
void on_actionAnalyzeFollowTLSStream_triggered();
|
void on_actionAnalyzeFollowTLSStream_triggered();
|
||||||
void on_actionAnalyzeFollowHTTPStream_triggered();
|
void on_actionAnalyzeFollowHTTPStream_triggered();
|
||||||
void on_actionAnalyzeFollowHTTP2Stream_triggered();
|
void on_actionAnalyzeFollowHTTP2Stream_triggered();
|
||||||
|
|
|
@ -1710,6 +1710,17 @@
|
||||||
<string notr="true">Ctrl+Alt+Shift+U</string>
|
<string notr="true">Ctrl+Alt+Shift+U</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionAnalyzeFollowDCCPStream">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>DCCP Stream</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+Alt+Shift+E</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="actionAnalyzeFollowTLSStream">
|
<action name="actionAnalyzeFollowTLSStream">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ void MainWindow::recentActionTriggered() {
|
||||||
|
|
||||||
void MainWindow::setMenusForSelectedPacket()
|
void MainWindow::setMenusForSelectedPacket()
|
||||||
{
|
{
|
||||||
gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_tls = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE,
|
gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_dccp = FALSE, is_sctp = FALSE, is_tls = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE,
|
||||||
is_http = FALSE, is_http2 = FALSE, is_quic = FALSE;
|
is_http = FALSE, is_http2 = FALSE, is_quic = FALSE;
|
||||||
|
|
||||||
/* Making the menu context-sensitive allows for easier selection of the
|
/* Making the menu context-sensitive allows for easier selection of the
|
||||||
|
@ -1193,6 +1193,7 @@ void MainWindow::setMenusForSelectedPacket()
|
||||||
proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
|
proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
|
||||||
&is_ip, &is_tcp, &is_udp, &is_sctp,
|
&is_ip, &is_tcp, &is_udp, &is_sctp,
|
||||||
&is_tls, &is_rtp, &is_lte_rlc);
|
&is_tls, &is_rtp, &is_lte_rlc);
|
||||||
|
is_dccp = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "dccp");
|
||||||
is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http");
|
is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http");
|
||||||
is_http2 = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http2");
|
is_http2 = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http2");
|
||||||
is_quic = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "quic");
|
is_quic = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "quic");
|
||||||
|
@ -1237,6 +1238,7 @@ void MainWindow::setMenusForSelectedPacket()
|
||||||
|
|
||||||
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
|
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
|
||||||
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
|
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
|
||||||
|
main_ui_->actionAnalyzeFollowDCCPStream->setEnabled(is_dccp);
|
||||||
main_ui_->actionAnalyzeFollowTLSStream->setEnabled(is_tls);
|
main_ui_->actionAnalyzeFollowTLSStream->setEnabled(is_tls);
|
||||||
main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http);
|
main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http);
|
||||||
main_ui_->actionAnalyzeFollowHTTP2Stream->setEnabled(is_http2);
|
main_ui_->actionAnalyzeFollowHTTP2Stream->setEnabled(is_http2);
|
||||||
|
@ -2880,6 +2882,11 @@ void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
|
||||||
openFollowStreamDialogForType(FOLLOW_UDP);
|
openFollowStreamDialogForType(FOLLOW_UDP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionAnalyzeFollowDCCPStream_triggered()
|
||||||
|
{
|
||||||
|
openFollowStreamDialogForType(FOLLOW_DCCP);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionAnalyzeFollowTLSStream_triggered()
|
void MainWindow::on_actionAnalyzeFollowTLSStream_triggered()
|
||||||
{
|
{
|
||||||
openFollowStreamDialogForType(FOLLOW_TLS);
|
openFollowStreamDialogForType(FOLLOW_TLS);
|
||||||
|
|
|
@ -683,6 +683,7 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
|
||||||
ctx_menu->addMenu(submenu);
|
ctx_menu->addMenu(submenu);
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
|
||||||
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowDCCPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTLSStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTLSStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
|
||||||
|
|
|
@ -304,6 +304,7 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
|
||||||
ctx_menu.addMenu(submenu);
|
ctx_menu.addMenu(submenu);
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
|
||||||
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowDCCPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTLSStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTLSStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
|
||||||
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
|
||||||
|
|
Loading…
Reference in New Issue