diff options
-rw-r--r-- | debian/libwireshark0.symbols | 8 | ||||
-rw-r--r-- | doc/tshark.pod | 25 | ||||
-rw-r--r-- | epan/dissectors/packet-tcp.h | 3 | ||||
-rw-r--r-- | epan/dissectors/packet-udp.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-udp.h | 15 | ||||
-rw-r--r-- | epan/follow.c | 141 | ||||
-rw-r--r-- | epan/follow.h | 29 | ||||
-rw-r--r-- | ui/cli/tap-follow.c | 38 | ||||
-rw-r--r-- | ui/qt/follow_stream_dialog.cpp | 27 | ||||
-rw-r--r-- | ui/qt/follow_stream_dialog.h | 2 |
10 files changed, 194 insertions, 96 deletions
diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index 4016e2b50f..b425017e37 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -525,9 +525,9 @@ libwireshark.so.0 libwireshark0 #MINVER# find_sid_name@Base 1.9.1 find_stream_circ@Base 1.9.1 find_tap_id@Base 1.9.1 + follow_addr@Base 1.99.2 + follow_index@Base 1.99.2 follow_stats@Base 1.9.1 - follow_tcp_addr@Base 1.9.1 - follow_tcp_index@Base 1.9.1 format_text@Base 1.9.1 format_text_chr@Base 1.12.0~rc1 format_text_wsp@Base 1.9.1 @@ -654,7 +654,7 @@ libwireshark.so.0 libwireshark0 #MINVER# get_eth_hashtable@Base 1.12.0~rc1 get_ether_name@Base 1.9.1 get_export_pdu_tap_list@Base 1.99.0 - get_follow_tcp_index@Base 1.12.0~rc1 + get_follow_index@Base 1.99.2 get_host_ipaddr6@Base 1.9.1 get_host_ipaddr@Base 1.9.1 get_hostlist_filter@Base 1.99.0 @@ -679,6 +679,7 @@ libwireshark.so.0 libwireshark0 #MINVER# get_ts_23_038_7bits_string@Base 1.12.0~rc1 get_ucs_2_string@Base 1.12.0~rc1 get_ucs_4_string@Base 1.12.0~rc1 + get_udp_conversation_data@Base 1.99.2 get_udp_stream_count@Base 1.12.0~rc1 get_unichar2_string@Base 1.12.0~rc1 get_utf_16_string@Base 1.12.0~rc1 @@ -1084,6 +1085,7 @@ libwireshark.so.0 libwireshark0 #MINVER# reset_hostlist_table_data@Base 1.99.0 reset_tap_listeners@Base 1.9.1 reset_tcp_reassembly@Base 1.9.1 + reset_udp_follow@Base 1.99.2 rose_ctx_clean_data@Base 1.9.1 rose_ctx_init@Base 1.9.1 rpc_init_proc_table@Base 1.9.1 diff --git a/doc/tshark.pod b/doc/tshark.pod index f17253419e..4aea3c7e1d 100644 --- a/doc/tshark.pod +++ b/doc/tshark.pod @@ -974,23 +974,26 @@ sent by the second node is prefixed with a tab to differentiate it from the data sent by the first node. I<prot> specifies the transport protocol. It can be one of: - B<tcp> TCP - B<udp> UDP - B<ssl> SSL + + tcp TCP + udp UDP + ssl SSL I<mode> specifies the output mode. It can be one of: - B<ascii> ASCII output with dots for non-printable characters - B<hex> Hexadecimal and ASCII data with offsets - B<raw> Hexadecimal data + + ascii ASCII output with dots for non-printable characters + hex Hexadecimal and ASCII data with offsets + raw Hexadecimal data Since the output in B<ascii> mode may contain newlines, the length of each section of output plus a newline precedes each section of output. -I<filter> specifies the stream to be displayed. UDP streams are selected with -IP address plus port pairs. TCP streams are selected with either the stream -index or IP address plus port pairs. For example: - B<ip-addr0>:B<port0>,B<ip-addr1>:B<port1> - B<tcp-stream-index> +I<filter> specifies the stream to be displayed. UDP/TCP streams are selected +with either the stream index or IP address plus port pairs. SSL streams are +selected with the stream index. For example: + + ip-addr0:port0,ip-addr1:port1 + stream-index I<range> optionally specifies which "chunks" of the stream should be displayed. diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h index 13d3172cda..8f6e0450dd 100644 --- a/epan/dissectors/packet-tcp.h +++ b/epan/dissectors/packet-tcp.h @@ -28,10 +28,7 @@ extern "C" { #include "ws_symbol_export.h" -#ifndef __CONVERSATION_H__ #include <epan/conversation.h> -#endif - #include <epan/wmem/wmem.h> /* TCP flags */ diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c index 693e009d35..35301677a8 100644 --- a/epan/dissectors/packet-udp.c +++ b/epan/dissectors/packet-udp.c @@ -232,7 +232,7 @@ init_udp_conversation_data(void) return udpd; } -static struct udp_analysis * +struct udp_analysis * get_udp_conversation_data(conversation_t *conv, packet_info *pinfo) { int direction; diff --git a/epan/dissectors/packet-udp.h b/epan/dissectors/packet-udp.h index b90de18b6d..a11a0afa17 100644 --- a/epan/dissectors/packet-udp.h +++ b/epan/dissectors/packet-udp.h @@ -23,6 +23,14 @@ #ifndef __PACKET_UDP_H__ #define __PACKET_UDP_H__ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ws_symbol_export.h" + +#include <epan/conversation.h> + /* UDP structs and definitions */ typedef struct _e_udphdr { guint16 uh_sport; @@ -98,4 +106,11 @@ WS_DLL_PUBLIC guint32 get_udp_stream_count(void); WS_DLL_PUBLIC void decode_udp_ports(tvbuff_t *, int, packet_info *, proto_tree *, int, int, int); +WS_DLL_PUBLIC struct udp_analysis *get_udp_conversation_data(conversation_t *, + packet_info *); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif diff --git a/epan/follow.c b/epan/follow.c index 4b894393d9..61f73b596f 100644 --- a/epan/follow.c +++ b/epan/follow.c @@ -36,8 +36,10 @@ #include <epan/to_str.h> #include <epan/emem.h> #include <epan/dissectors/packet-tcp.h> +#include <epan/dissectors/packet-udp.h> #include "follow.h" #include <epan/conversation.h> +#include <epan/tap.h> #define MAX_IPADDR_LEN 16 @@ -55,7 +57,10 @@ FILE* data_out_file = NULL; gboolean empty_tcp_stream; gboolean incomplete_tcp_stream; -static guint32 tcp_stream_to_follow = 0; +static guint32 stream_to_follow[MAX_STREAM] = {0}; +static gboolean find_addr[MAX_STREAM] = {FALSE}; +static gboolean find_index[MAX_STREAM] = {FALSE}; +static address tcp_addr[2]; static guint8 ip_address[2][MAX_IPADDR_LEN]; static guint port[2]; static guint bytes_written[2]; @@ -87,6 +92,7 @@ build_follow_conv_filter( packet_info *pi ) { int len; conversation_t *conv=NULL; struct tcp_analysis *tcpd; + struct udp_analysis *udpd; wmem_list_frame_t* protos; int proto_id; const char* proto_name; @@ -114,11 +120,11 @@ build_follow_conv_filter( packet_info *pi ) { (pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6)) && is_tcp && (conv=find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype, pi->srcport, pi->destport, 0)) != NULL ) { - /* TCP over IPv4 */ + /* TCP over IPv4/6 */ tcpd=get_tcp_conversation_data(conv, pi); if (tcpd) { buf = g_strdup_printf("tcp.stream eq %d", tcpd->stream); - tcp_stream_to_follow = tcpd->stream; + stream_to_follow[TCP_STREAM] = tcpd->stream; if (pi->net_src.type == AT_IPv4) { len = 4; is_ipv6 = FALSE; @@ -130,27 +136,25 @@ build_follow_conv_filter( packet_info *pi ) { return NULL; } } - else if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 - && is_udp ) { - /* UDP over IPv4 */ - buf = g_strdup_printf( - "(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)", - address_to_str(pi->pool, &pi->net_src), - address_to_str(pi->pool, &pi->net_dst), - pi->srcport, pi->destport ); - len = 4; - is_ipv6 = FALSE; - } - else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 - && is_udp ) { - /* UDP over IPv6 */ - buf = g_strdup_printf( - "(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)", - address_to_str(pi->pool, &pi->net_src), - address_to_str(pi->pool, &pi->net_dst), - pi->srcport, pi->destport ); - len = 16; - is_ipv6 = TRUE; + else if( ((pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4) || + (pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6)) + && is_udp && (conv=find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype, + pi->srcport, pi->destport, 0)) != NULL ) { + /* UDP over IPv4/6 */ + udpd=get_udp_conversation_data(conv, pi); + if (udpd) { + buf = g_strdup_printf("udp.stream eq %d", udpd->stream); + stream_to_follow[UDP_STREAM] = udpd->stream; + if (pi->net_src.type == AT_IPv4) { + len = 4; + is_ipv6 = FALSE; + } else { + len = 16; + is_ipv6 = TRUE; + } + } else { + return NULL; + } } else { return NULL; @@ -162,30 +166,62 @@ build_follow_conv_filter( packet_info *pi ) { return buf; } -static gboolean find_tcp_addr; -static address tcp_addr[2]; -static gboolean find_tcp_index; +static gboolean +udp_follow_packet(void *tapdata _U_, packet_info *pinfo, + epan_dissect_t *edt _U_, const void *data _U_) +{ + if (find_addr[UDP_STREAM]) { + if (pinfo->net_src.type == AT_IPv6) { + is_ipv6 = TRUE; + } else { + is_ipv6 = FALSE; + } + memcpy(ip_address[0], pinfo->net_src.data, pinfo->net_src.len); + memcpy(ip_address[1], pinfo->net_dst.data, pinfo->net_dst.len); + port[0] = pinfo->srcport; + port[1] = pinfo->destport; + find_addr[UDP_STREAM] = FALSE; + } + + return FALSE; +} + +void +reset_udp_follow(void) { + remove_tap_listener(&stream_to_follow[UDP_STREAM]); + find_addr[UDP_STREAM] = FALSE; + find_addr[UDP_STREAM] = FALSE; +} gchar* -build_follow_index_filter(void) { +build_follow_index_filter(stream_type stream) { gchar *buf; - find_tcp_addr = TRUE; - buf = g_strdup_printf("tcp.stream eq %d", tcp_stream_to_follow); + find_addr[stream] = TRUE; + if (stream == TCP_STREAM) { + buf = g_strdup_printf("tcp.stream eq %d", stream_to_follow[TCP_STREAM]); + } else { + GString * error_string; + buf = g_strdup_printf("udp.stream eq %d", stream_to_follow[UDP_STREAM]); + error_string = register_tap_listener("udp_follow", &stream_to_follow[UDP_STREAM], buf, 0, NULL, udp_follow_packet, NULL); + if (error_string) { + g_string_free(error_string, TRUE); + } + } return buf; } /* select a tcp stream to follow via it's address/port pairs */ gboolean -follow_tcp_addr(const address *addr0, guint port0, - const address *addr1, guint port1) +follow_addr(stream_type stream, const address *addr0, guint port0, + const address *addr1, guint port1) { if (addr0 == NULL || addr1 == NULL || addr0->type != addr1->type || port0 > G_MAXUINT16 || port1 > G_MAXUINT16 ) { return FALSE; } - if (find_tcp_index || find_tcp_addr) { + if (find_index[stream] || find_addr[stream]) { return FALSE; } @@ -198,29 +234,32 @@ follow_tcp_addr(const address *addr0, guint port0, break; } - find_tcp_index = TRUE; memcpy(ip_address[0], addr0->data, addr0->len); - SET_ADDRESS(&tcp_addr[0], addr0->type, addr0->len, ip_address[0]); port[0] = port0; memcpy(ip_address[1], addr1->data, addr1->len); - SET_ADDRESS(&tcp_addr[1], addr1->type, addr1->len, ip_address[1]); port[1] = port1; + if (stream == TCP_STREAM) { + find_index[TCP_STREAM] = TRUE; + SET_ADDRESS(&tcp_addr[0], addr0->type, addr0->len, ip_address[0]); + SET_ADDRESS(&tcp_addr[1], addr1->type, addr1->len, ip_address[1]); + } + return TRUE; } -/* select a tcp stream to follow via its index */ +/* select a stream to follow via its index */ gboolean -follow_tcp_index(guint32 indx) +follow_index(stream_type stream, guint32 indx) { - if (find_tcp_index || find_tcp_addr) { + if (find_index[stream] || find_addr[stream]) { return FALSE; } - find_tcp_addr = TRUE; - tcp_stream_to_follow = indx; + find_addr[stream] = TRUE; + stream_to_follow[stream] = indx; memset(ip_address, 0, sizeof ip_address); port[0] = port[1] = 0; @@ -228,8 +267,8 @@ follow_tcp_index(guint32 indx) } guint32 -get_follow_tcp_index(void) { - return tcp_stream_to_follow; +get_follow_index(stream_type stream) { + return stream_to_follow[stream]; } /* here we are going to try and reconstruct the data portion of a TCP @@ -255,7 +294,7 @@ reassemble_tcp( guint32 tcp_stream, guint32 sequence, guint32 acknowledgement, src_index = -1; /* First, check if this packet should be processed. */ - if (find_tcp_index) { + if (find_index[TCP_STREAM]) { if ((port[0] == srcport && port[1] == dstport && ADDRESSES_EQUAL(&tcp_addr[0], net_src) && ADDRESSES_EQUAL(&tcp_addr[1], net_dst)) @@ -263,14 +302,14 @@ reassemble_tcp( guint32 tcp_stream, guint32 sequence, guint32 acknowledgement, (port[1] == srcport && port[0] == dstport && ADDRESSES_EQUAL(&tcp_addr[1], net_src) && ADDRESSES_EQUAL(&tcp_addr[0], net_dst))) { - find_tcp_index = FALSE; - tcp_stream_to_follow = tcp_stream; + find_index[TCP_STREAM] = FALSE; + stream_to_follow[TCP_STREAM] = tcp_stream; } else { return; } } - else if ( tcp_stream != tcp_stream_to_follow ) + else if ( tcp_stream != stream_to_follow[TCP_STREAM] ) return; if ((net_src->type != AT_IPv4 && net_src->type != AT_IPv6) || @@ -286,8 +325,8 @@ reassemble_tcp( guint32 tcp_stream, guint32 sequence, guint32 acknowledgement, memcpy(dstx, net_dst->data, len); /* follow_tcp_index() needs to learn address/port pairs */ - if (find_tcp_addr) { - find_tcp_addr = FALSE; + if (find_addr[TCP_STREAM]) { + find_addr[TCP_STREAM] = FALSE; memcpy(ip_address[0], net_src->data, net_src->len); port[0] = srcport; memcpy(ip_address[1], net_dst->data, net_dst->len); @@ -518,8 +557,8 @@ reset_tcp_reassembly(void) empty_tcp_stream = TRUE; incomplete_tcp_stream = FALSE; - find_tcp_addr = FALSE; - find_tcp_index = FALSE; + find_addr[TCP_STREAM] = FALSE; + find_index[TCP_STREAM] = FALSE; for( i=0; i<2; i++ ) { seq[i] = 0; memset(src_addr[i], '\0', MAX_IPADDR_LEN); diff --git a/epan/follow.h b/epan/follow.h index 173762279f..e883446949 100644 --- a/epan/follow.h +++ b/epan/follow.h @@ -34,6 +34,12 @@ extern "C" { #define MAX_IPADDR_LEN 16 +typedef enum { + TCP_STREAM = 0, + UDP_STREAM, + MAX_STREAM +} stream_type; + /* With MSVC and a libwireshark.dll, we need a special declaration. */ WS_DLL_PUBLIC gboolean empty_tcp_stream; WS_DLL_PUBLIC gboolean incomplete_tcp_stream; @@ -54,39 +60,42 @@ typedef struct _tcp_stream_chunk { WS_DLL_PUBLIC gchar* build_follow_conv_filter( packet_info * packet_info); -/** Build a follow filter based on the current TCP stream index. - * follow_tcp_index() must be called prior to calling this. +/** Build a follow filter based on the current TCP/UDP stream index. + * follow_index() must be called prior to calling this. * * @return A filter that specifies the current stream. Must be g_free()d * the caller. */ WS_DLL_PUBLIC -gchar* build_follow_index_filter(void); +gchar* build_follow_index_filter(stream_type stream); WS_DLL_PUBLIC -gboolean follow_tcp_addr( const address *, guint, const address *, guint ); +gboolean follow_addr(stream_type, const address *, guint, const address *, guint ); -/** Select a TCP stream to follow via its index. +/** Select a TCP/UDP stream to follow via its index. * * @param addr [in] The stream index to follow. * @return TRUE on success, FALSE on failure. */ WS_DLL_PUBLIC -gboolean follow_tcp_index( guint32 addr); +gboolean follow_index(stream_type stream, guint32 addr); -/** Get the current TCP index being followed. +/** Get the current TCP/UDP index being followed. * - * @return The current TCP index. The behavior is undefined - * if no TCP stream is being followed. + * @return The current TCP/UDP index. The behavior is undefined + * if no TCP/UDP stream is being followed. */ WS_DLL_PUBLIC -guint32 get_follow_tcp_index(void); +guint32 get_follow_index(stream_type stream); void reassemble_tcp( guint32, guint32, guint32, guint32, const char*, guint32, int, address *, address *, guint, guint, guint32 ); WS_DLL_PUBLIC void reset_tcp_reassembly( void ); +WS_DLL_PUBLIC +void reset_udp_follow(void); + typedef struct { guint8 ip_address[2][MAX_IPADDR_LEN]; guint32 port[2]; diff --git a/ui/cli/tap-follow.c b/ui/cli/tap-follow.c index 9c448e3255..6be940fe7b 100644 --- a/ui/cli/tap-follow.c +++ b/ui/cli/tap-follow.c @@ -150,6 +150,7 @@ followStrFilter( static char filter[512]; int len = 0; const gchar *verp; + gchar *udpfilter; gchar ip0[MAX_IP6_STR_LEN]; gchar ip1[MAX_IP6_STR_LEN]; @@ -163,6 +164,10 @@ followStrFilter( "tcp.stream eq %d", fp->index); break; case type_UDP: + udpfilter = build_follow_index_filter(UDP_STREAM); + len = g_snprintf(filter, sizeof filter, + "%s", udpfilter); + g_free(udpfilter); break; } } @@ -512,7 +517,7 @@ followDraw( g_assert(sizeof bin % BYTES_PER_LINE == 0); - if (fp->type == type_TCP) + if ((fp->type == type_TCP) || (fp->type == type_UDP)) { static const guint8 ip_zero[MAX_IPADDR_LEN] = {0}; follow_stats_t stats; @@ -888,17 +893,17 @@ followTcp( reset_tcp_reassembly(); if (fp->index != G_MAXUINT32) { - if (!follow_tcp_index(fp->index)) + if (!follow_index(TCP_STREAM, fp->index)) { - followExit("Can't follow tcp index."); + followExit("Can't follow TCP index."); } } else { - if (!follow_tcp_addr(&fp->addr[0], fp->port[0], - &fp->addr[1], fp->port[1])) + if (!follow_addr(TCP_STREAM, &fp->addr[0], fp->port[0], + &fp->addr[1], fp->port[1])) { - followExit("Can't follow tcp address/port pairs."); + followExit("Can't follow TCP address/port pairs."); } } @@ -910,7 +915,7 @@ followTcp( { followFree(fp); g_string_free(errp, TRUE); - followExit("Error registering tcp tap listener."); + followExit("Error registering TCP tap listener."); } } @@ -932,9 +937,21 @@ followUdp( followArgRange(&opt_argp, fp); followArgDone(opt_argp); + reset_udp_follow(); if (fp->index != G_MAXUINT32) { - followExit("UDP does not support index filters."); + if (!follow_index(UDP_STREAM, fp->index)) + { + followExit("Can't follow UDP index."); + } + } + else + { + if (!follow_addr(UDP_STREAM, &fp->addr[0], fp->port[0], + &fp->addr[1], fp->port[1])) + { + followExit("Can't follow UDP address/port pairs."); + } } followFileOpen(fp); @@ -945,7 +962,7 @@ followUdp( { followFree(fp); g_string_free(errp, TRUE); - followExit("Error registering udp tap listner."); + followExit("Error registering UDP tap listner."); } } @@ -967,6 +984,7 @@ followSsl( followArgRange(&opt_argp, fp); followArgDone(opt_argp); + reset_tcp_reassembly(); if (fp->index == G_MAXUINT32) { followExit("SSL only supports index filters."); @@ -980,7 +998,7 @@ followSsl( { followFree(fp); g_string_free(errp, TRUE); - followExit("Error registering ssl tap listener."); + followExit("Error registering SSL tap listener."); } } diff --git a/ui/qt/follow_stream_dialog.cpp b/ui/qt/follow_stream_dialog.cpp index 13c8f47d6b..a6f2638546 100644 --- a/ui/qt/follow_stream_dialog.cpp +++ b/ui/qt/follow_stream_dialog.cpp @@ -27,6 +27,7 @@ #include "epan/follow.h" #include "epan/dissectors/packet-tcp.h" +#include "epan/dissectors/packet-udp.h" #include "epan/prefs.h" #include "epan/addr_resolv.h" #include "epan/charsets.h" @@ -290,7 +291,7 @@ void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num) { if (stream_num >= 0) { updateWidgets(false); - follow_tcp_index(stream_num); + follow_index((follow_type_ == FOLLOW_TCP) ? TCP_STREAM : UDP_STREAM, stream_num); follow(QString(), true); updateWidgets(); } @@ -327,6 +328,7 @@ void FollowStreamDialog::resetStream() } g_list_free(follow_info_.payload); follow_info_.payload = NULL; + follow_info_.client_port = 0; } frs_return_t @@ -840,7 +842,7 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser return FRS_OK; } -bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) +bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) { int tmp_fd; QString follow_filter; @@ -880,7 +882,6 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) } break; case FOLLOW_UDP: - removeStreamControls(); if (!is_udp) { QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a UDP packet selected.")); return false; @@ -902,10 +903,13 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) /* Create a new filter that matches all packets in the TCP stream, and set the display filter entry accordingly */ reset_tcp_reassembly(); + } else { + reset_udp_follow(); } - if (use_tcp_index) { - follow_filter = gchar_free_to_qstring(build_follow_index_filter()); + if (use_stream_index) { + follow_filter = gchar_free_to_qstring( + build_follow_index_filter((follow_type_ == FOLLOW_TCP) ? TCP_STREAM : UDP_STREAM)); } else { follow_filter = gchar_free_to_qstring(build_follow_conv_filter(&cap_file_->edt->pi)); } @@ -967,7 +971,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) int stream_count = get_tcp_stream_count() - 1; ui->streamNumberSpinBox->blockSignals(true); ui->streamNumberSpinBox->setMaximum(stream_count); - ui->streamNumberSpinBox->setValue(get_follow_tcp_index()); + ui->streamNumberSpinBox->setValue(get_follow_index(TCP_STREAM)); ui->streamNumberSpinBox->blockSignals(false); ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count)); ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip()); @@ -975,6 +979,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) break; } case FOLLOW_UDP: + { /* data will be passed via tap callback*/ msg = register_tap_listener("udp_follow", &follow_info_, follow_filter.toUtf8().constData(), @@ -985,7 +990,17 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_tcp_index) msg->str); return false; } + + int stream_count = get_udp_stream_count() - 1; + ui->streamNumberSpinBox->blockSignals(true); + ui->streamNumberSpinBox->setMaximum(stream_count); + ui->streamNumberSpinBox->setValue(get_follow_index(UDP_STREAM)); + ui->streamNumberSpinBox->blockSignals(false); + ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count)); + ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip()); + break; + } case FOLLOW_SSL: /* we got ssl so we can follow */ msg = register_tap_listener("ssl", &follow_info_, diff --git a/ui/qt/follow_stream_dialog.h b/ui/qt/follow_stream_dialog.h index 1e5969b3c3..9a2fa55e37 100644 --- a/ui/qt/follow_stream_dialog.h +++ b/ui/qt/follow_stream_dialog.h @@ -68,7 +68,7 @@ public: explicit FollowStreamDialog(QWidget *parent = 0, follow_type_t type = FOLLOW_TCP, capture_file *cf = NULL); ~FollowStreamDialog(); - bool follow(QString previous_filter = QString(), bool use_tcp_index = false); + bool follow(QString previous_filter = QString(), bool use_stream_index = false); public slots: void setCaptureFile(capture_file *cf); |