summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-udp.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-01-08 08:25:17 -0500
committerMichael Mann <mmann78@netscape.net>2016-01-12 15:08:18 +0000
commitc62547b9510eb1a0efe08972387bfa8559f444d5 (patch)
tree6a186a7b7111c71ae64e3da965b447ed9f48d699 /epan/dissectors/packet-udp.c
parentb65d30dbd5d86092e6e4739a4da6075cf08b115d (diff)
downloadwireshark-c62547b9510eb1a0efe08972387bfa8559f444d5.tar.gz
Refactor "Follow Stream" functionality on all GUI interfaces.
Create a "registration" system for Follow functionality so most of the work can be abstracted into a dissector and GUI can just be responsible for "display". This also removes the global variables in follow.c to open up multithreading possibilities. TCP, UDP and HTTP all have the same "tap interface" for Follow functionality (passing a tvb with byte data to "follow"). SSL still has it's own behavior, so Follow structures have to take that into account. TShark through the Follow registration now has support for HTTP. The only thing possibly missing is dynamic menu generation to further reduce explicit knowledge of Follow "type" (and rely on registration) Bug: 11988 Change-Id: I559d9ee1312406ad0986d4dce9fa67ea2103b339 Reviewed-on: https://code.wireshark.org/review/13161 Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-udp.c')
-rw-r--r--epan/dissectors/packet-udp.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c
index 4a1a6dbabe..cdda182c24 100644
--- a/epan/dissectors/packet-udp.c
+++ b/epan/dissectors/packet-udp.c
@@ -34,6 +34,7 @@
#include <epan/ipproto.h>
#include <epan/in_cksum.h>
#include <epan/prefs.h>
+#include <epan/follow.h>
#include <epan/expert.h>
#include <epan/exceptions.h>
#include <epan/show_exception.h>
@@ -400,6 +401,53 @@ udp_build_filter(packet_info *pinfo)
return NULL;
}
+static gchar* udp_follow_conv_filter(packet_info *pinfo, int* stream)
+{
+ conversation_t *conv;
+ struct udp_analysis *udpd;
+
+ 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->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0)) != NULL )
+ {
+ /* UDP over IPv4/6 */
+ udpd=get_udp_conversation_data(conv, pinfo);
+ if (udpd == NULL)
+ return NULL;
+
+ *stream = udpd->stream;
+ return g_strdup_printf("udp.stream eq %d", udpd->stream);
+ }
+
+ return NULL;
+}
+
+static gchar* udp_follow_index_filter(int stream)
+{
+ return g_strdup_printf("udp.stream eq %d", stream);
+}
+
+static gchar* udp_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[MAX_IP6_STR_LEN];
+ gchar dst_addr_str[MAX_IP6_STR_LEN];
+
+ 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 udp.srcport eq %d) and "
+ "(ip%s.dst eq %s and udp.dstport eq %d))"
+ " or "
+ "((ip%s.src eq %s and udp.srcport eq %d) and "
+ "(ip%s.dst eq %s and udp.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);
+}
+
/* Attach process info to a flow */
/* XXX - We depend on the UDP dissector finding the conversation first */
@@ -1165,6 +1213,8 @@ proto_register_udp(void)
register_decode_as(&udp_da);
register_conversation_table(proto_udp, FALSE, udpip_conversation_packet, udpip_hostlist_packet);
register_conversation_filter("udp", "UDP", udp_filter_valid, udp_build_filter);
+ register_follow_stream(proto_udp, "udp_follow", udp_follow_conv_filter, udp_follow_index_filter, udp_follow_address_filter,
+ udp_port_to_display, follow_tvb_tap_listener);
register_init_routine(udp_init);