aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2007-08-16 22:03:10 +0000
committerUlf Lamping <ulf.lamping@web.de>2007-08-16 22:03:10 +0000
commit4b215597ae8c4c05f590224b390cfbc218a93166 (patch)
tree67b6b711075666eeec4286bee850b3f84b0d3416
parent1ac635cd7dcbbe6f35f5632c6a0a58026ba6d017 (diff)
experimental feature: dissector filters
add the possibility, that a dissector writer can provide (usually non-trivial) display filters specific for the protocol in question (with an example in packet-dcerpc-pn-io.c), that will appear in the GUI svn path=/trunk/; revision=22530
-rw-r--r--epan/Makefile.common2
-rw-r--r--epan/dissector_filters.c49
-rw-r--r--epan/dissector_filters.h60
-rw-r--r--epan/libwireshark.def2
-rw-r--r--gtk/gui_stat_menu.h4
-rw-r--r--gtk/menu.c82
-rw-r--r--gtk/tcp_graph.c2
-rw-r--r--plugins/profinet/packet-dcerpc-pn-io.c57
-rw-r--r--stat_menu.h3
9 files changed, 247 insertions, 14 deletions
diff --git a/epan/Makefile.common b/epan/Makefile.common
index 22108570b6..919ebebf25 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -43,6 +43,7 @@ LIBWIRESHARK_SRC = \
crc32.c \
crc6.c \
crcdrm.c \
+ dissector_filters.c \
emem.c \
epan.c \
ex-opt.c \
@@ -152,6 +153,7 @@ LIBWIRESHARK_INCLUDES = \
crc32.h \
crcdrm.h \
diam_dict.h \
+ dissector_filters.h \
dtd.h \
dtd_parse.h \
emem.h \
diff --git a/epan/dissector_filters.c b/epan/dissector_filters.c
new file mode 100644
index 0000000000..681f0c4301
--- /dev/null
+++ b/epan/dissector_filters.c
@@ -0,0 +1,49 @@
+/* dissector_filters.c
+ * Routines for dissector generated display filters
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include "packet.h"
+
+#include "dissector_filters.h"
+
+
+GList *dissector_filter_list = NULL;
+
+
+void register_dissector_filter(const char *name, is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string) {
+ dissector_filter_t *entry;
+
+ entry = g_malloc(sizeof(dissector_filter_t));
+
+ entry->name = name;
+ entry->is_filter_valid = is_filter_valid;
+ entry->build_filter_string = build_filter_string;
+
+ dissector_filter_list = g_list_append(dissector_filter_list, entry);
+}
+
diff --git a/epan/dissector_filters.h b/epan/dissector_filters.h
new file mode 100644
index 0000000000..b19a8135cc
--- /dev/null
+++ b/epan/dissector_filters.h
@@ -0,0 +1,60 @@
+/* dissector_filters.h
+ * Routines for dissector generated display filters
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __DISSECTOR_FILTERS_H__
+#define __DISSECTOR_FILTERS_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* callback function definition: is a filter available for this packet? */
+typedef gboolean (*is_filter_valid_func)(packet_info *pinfo);
+
+/* callback function definition: return the available filter for this packet or NULL if no filter is available */
+typedef const gchar* (*build_filter_string_func)(packet_info *pinfo);
+
+
+/* register a dissector filter */
+extern void register_dissector_filter(const char *name, is_filter_valid_func is_filter_valid, build_filter_string_func build_filter_string);
+
+
+
+/*** THE FOLLOWING SHOULD NOT BE USED BY ANY DISSECTORS!!! ***/
+
+typedef struct dissector_filter_s {
+ const char * name;
+ is_filter_valid_func is_filter_valid;
+ build_filter_string_func build_filter_string;
+} dissector_filter_t;
+
+WS_VAR_IMPORT GList *dissector_filter_list;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* dissector_filters.h */
diff --git a/epan/libwireshark.def b/epan/libwireshark.def
index 1078991801..2527ac302d 100644
--- a/epan/libwireshark.def
+++ b/epan/libwireshark.def
@@ -137,6 +137,7 @@ dissector_change_string
dissector_delete
dissector_delete_string
dissector_dump_decodes
+dissector_filter_list DATA
dissector_get_port_handle
dissector_get_string_handle
dissector_handle_get_protocol_index
@@ -678,6 +679,7 @@ register_ber_syntax_dissector
register_count
register_dissector
register_dissector_table
+register_dissector_filter
register_final_registration_routine
register_giop_user
register_giop_user_module
diff --git a/gtk/gui_stat_menu.h b/gtk/gui_stat_menu.h
index 40124c1d49..72cbb75a05 100644
--- a/gtk/gui_stat_menu.h
+++ b/gtk/gui_stat_menu.h
@@ -65,8 +65,8 @@ extern void register_stat_menu_item(
const char *name,
register_stat_group_t group,
GtkItemFactoryCallback callback,
- gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
- gboolean (*selected_tree_row_enabled)(field_info *),
+ gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
+ gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
gpointer callback_data);
#ifdef __cplusplus
diff --git a/gtk/menu.c b/gtk/menu.c
index 0483dcf101..8307f033f2 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -40,6 +40,7 @@
#include <epan/tap.h>
#include <epan/timestamp.h>
#include <epan/ipproto.h>
+#include <epan/dissector_filters.h>
#include "about_dlg.h"
#include "capture_dlg.h"
@@ -99,8 +100,8 @@ typedef struct _menu_item {
gboolean enabled;
GtkItemFactoryCallback callback;
gpointer callback_data;
- gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *);
- gboolean (*selected_tree_row_enabled)(field_info *);
+ gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data);
+ gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data);
GList *children;
} menu_item_t;
@@ -855,6 +856,59 @@ main_menu_new(GtkAccelGroup ** table) {
return menubar;
}
+
+void menu_dissector_filter_cb( GtkWidget *widget,
+ gpointer callback_data,
+ guint callback_action)
+{
+ dissector_filter_t *filter_entry = callback_data;
+ GtkWidget *filter_te;
+ const char *buf;
+
+
+ filter_te = OBJECT_GET_DATA(popup_menu_object, E_DFILTER_TE_KEY);
+
+ /* XXX - this gets the packet_info of the last dissected packet, */
+ /* which is not necessarily the last selected packet */
+ /* e.g. "Update list of packets in real time" won't work correct */
+ buf = filter_entry->build_filter_string(&cfile.edt->pi);
+
+ gtk_entry_set_text(GTK_ENTRY(filter_te), buf);
+
+ /* Run the display filter so it goes in effect - even if it's the
+ same as the previous display filter. */
+ main_filter_packets(&cfile, buf, TRUE);
+
+ g_free( (void *) buf);
+}
+
+gboolean menu_dissector_filter_spe_cb(frame_data *fd, epan_dissect_t *edt, gpointer callback_data) {
+ dissector_filter_t *filter_entry = callback_data;
+
+ /* XXX - this gets the packet_info of the last dissected packet, */
+ /* which is not necessarily the last selected packet */
+ /* e.g. "Update list of packets in real time" won't work correct */
+ return (edt != NULL) ? filter_entry->is_filter_valid(&edt->pi) : FALSE;
+}
+
+void menu_dissector_filter(void) {
+ GList *list_entry = dissector_filter_list;
+ dissector_filter_t *filter_entry;
+
+ while(list_entry != NULL) {
+ filter_entry = list_entry->data;
+
+ register_stat_menu_item(filter_entry->name, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER,
+ menu_dissector_filter_cb,
+ menu_dissector_filter_spe_cb,
+ NULL /* selected_tree_row_enabled */,
+ filter_entry);
+
+ list_entry = g_list_next(list_entry);
+ }
+}
+
+
static void
menus_init(void) {
if (initialize) {
@@ -888,6 +942,7 @@ menus_init(void) {
}
#endif
+ menu_dissector_filter();
merge_all_tap_menus(tap_menu_tree_root);
/* Initialize enabled/disabled state of menu items */
@@ -926,8 +981,8 @@ static GList * tap_menu_item_add(
char *name,
gint group,
GtkItemFactoryCallback callback,
- gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
- gboolean (*selected_tree_row_enabled)(field_info *),
+ gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
+ gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
gpointer callback_data,
GList *curnode)
{
@@ -980,8 +1035,8 @@ register_stat_menu_item(
const char *name,
register_stat_group_t group,
GtkItemFactoryCallback callback,
- gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
- gboolean (*selected_tree_row_enabled)(field_info *),
+ gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
+ gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
gpointer callback_data)
{
/*static const char toolspath[] = "/Statistics/";*/
@@ -1006,6 +1061,7 @@ register_stat_menu_item(
case(REGISTER_STAT_GROUP_TELEPHONY): toolspath = "/Statistics/"; break;
case(REGISTER_STAT_GROUP_NONE): toolspath = "/Statistics/"; break;
case(REGISTER_ANALYZE_GROUP_NONE): toolspath = "/Analyze/"; break;
+ case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER): toolspath = "/Analyze/Conversation Filter/"; break;
#ifdef HAVE_LUA_5_1
case(REGISTER_TOOLS_GROUP_NONE):
toolspath = "/Tools/";
@@ -1137,6 +1193,8 @@ static guint merge_tap_menus_layered(GList *node, gint group) {
break;
case(REGISTER_ANALYZE_GROUP_NONE):
break;
+ case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER):
+ break;
#ifdef HAVE_LUA_5_1
case(REGISTER_TOOLS_GROUP_NONE):
break;
@@ -1145,7 +1203,7 @@ static guint merge_tap_menus_layered(GList *node, gint group) {
g_assert_not_reached();
}
#endif
- gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, 2);
+ gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, /* callback_type */ 2);
set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
added++;
}
@@ -1213,6 +1271,10 @@ void merge_all_tap_menus(GList *node) {
entry->path = "/Analyze/";
/*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
}
+ if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER)) {
+ entry->path = "/Analyze/Conversation Filter/";
+ /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+ }
#ifdef HAVE_LUA_5_1
if (merge_tap_menus_layered(node, REGISTER_TOOLS_GROUP_NONE)) {
/*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
@@ -2308,7 +2370,7 @@ walk_menu_tree_for_selected_packet(GList *node, frame_data *fd,
* based on its return value.
*/
if (node_data->selected_packet_enabled != NULL)
- node_data->enabled = node_data->selected_packet_enabled(fd, edt);
+ node_data->enabled = node_data->selected_packet_enabled(fd, edt, node_data->callback_data);
} else {
/*
* It's an interior node; call
@@ -2418,7 +2480,7 @@ set_menus_for_selected_packet(capture_file *cf)
set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/UDP",
cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/PN-CBA Server",
- cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0) : FALSE);
+ cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0 && cf->edt->pi.profinet_type < 10) : FALSE);
set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
cf->current_frame != NULL && decode_as_ok());
set_menu_sensitivity(packet_list_menu_factory, "/Decode As...",
@@ -2467,7 +2529,7 @@ walk_menu_tree_for_selected_tree_row(GList *node, field_info *fi)
* based on its return value.
*/
if (node_data->selected_tree_row_enabled != NULL)
- node_data->enabled = node_data->selected_tree_row_enabled(fi);
+ node_data->enabled = node_data->selected_tree_row_enabled(fi, node_data->callback_data);
} else {
/*
* It's an interior node; call
diff --git a/gtk/tcp_graph.c b/gtk/tcp_graph.c
index 114a8d91c0..b423671aa4 100644
--- a/gtk/tcp_graph.c
+++ b/gtk/tcp_graph.c
@@ -4007,7 +4007,7 @@ static int rint (double x)
#endif
-static gboolean tcp_graph_selected_packet_enabled(frame_data *current_frame, epan_dissect_t *edt)
+static gboolean tcp_graph_selected_packet_enabled(frame_data *current_frame, epan_dissect_t *edt, gpointer callback_data _U_)
{
return current_frame != NULL ? (edt->pi.ipproto == IP_PROTO_TCP) : FALSE;
}
diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c
index a4ad213d42..0eee3afd15 100644
--- a/plugins/profinet/packet-dcerpc-pn-io.c
+++ b/plugins/profinet/packet-dcerpc-pn-io.c
@@ -61,6 +61,7 @@
#include <epan/emem.h>
#include <epan/dissectors/packet-dcerpc.h>
#include <epan/expert.h>
+#include <epan/dissector_filters.h>
#include "packet-pn.h"
@@ -5921,6 +5922,59 @@ dissect_PNIO_heur(tvbuff_t *tvb,
}
+
+gboolean
+pn_io_ar_conv_valid(packet_info *pinfo)
+{
+ return (pinfo->profinet_type == 10);
+}
+
+char *
+pn_io_ar_conv_filter(packet_info *pinfo)
+{
+ pnio_ar_t *ar = pinfo->profinet_conv;
+ char* buf;
+
+ if(pinfo->profinet_type != 10) {
+ return NULL;
+ }
+
+ buf = g_strdup_printf(
+ "pn_io.ar_uuid == %s || " /* ARUUID */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s) || " /* Alarm CR (contr -> dev) */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s)", /* Alarm CR (dev -> contr) */
+ guid_to_str((const e_guid_t*) &ar->aruuid),
+ ar->controlleralarmref, ether_to_str((const guint8 *)ar->controllermac),
+ ar->devicealarmref, ether_to_str((const guint8 *)ar->devicemac));
+ return buf;
+}
+
+char *
+pn_io_ar_conv_data_filter(packet_info *pinfo)
+{
+ pnio_ar_t *ar = pinfo->profinet_conv;
+ char* buf;
+
+ if(pinfo->profinet_type != 10) {
+ return NULL;
+ }
+
+ buf = g_strdup_printf(
+ "pn_io.ar_uuid == %s || " /* ARUUID */
+ "(pn_rt.frame_id == 0x%x && eth.src == %s && eth.dst == %s) || " /* Input CR && dev MAC -> contr MAC */
+ "(pn_rt.frame_id == 0x%x && eth.src == %s && eth.dst == %s) || " /* Output CR && contr MAC -> dev MAC */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s) || " /* Alarm CR (contr -> dev) */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s)", /* Alarm CR (dev -> contr) */
+ guid_to_str((const e_guid_t*) &ar->aruuid),
+ ar->inputframeid, ether_to_str((const guint8 *)ar->devicemac), ether_to_str((const guint8 *)ar->controllermac),
+ ar->outputframeid, ether_to_str((const guint8 *)ar->controllermac), ether_to_str((const guint8 *)ar->devicemac),
+ ar->controlleralarmref, ether_to_str((const guint8 *)ar->controllermac),
+ ar->devicealarmref, ether_to_str((const guint8 *)ar->devicemac));
+ return buf;
+}
+
+
+
/* the PNIO dcerpc interface table */
static dcerpc_sub_dissector pn_io_dissectors[] = {
{ 0, "Connect", dissect_IPNIO_rqst, dissect_IPNIO_resp },
@@ -6636,6 +6690,9 @@ proto_register_pn_io (void)
proto_register_subtree_array (ett, array_length (ett));
register_init_routine(pnio_reinit);
+
+ register_dissector_filter("PN-IO AR", pn_io_ar_conv_valid, pn_io_ar_conv_filter);
+ register_dissector_filter("PN-IO AR (with data)", pn_io_ar_conv_valid, pn_io_ar_conv_data_filter);
}
void
diff --git a/stat_menu.h b/stat_menu.h
index 142cc5b47e..d52b4c9353 100644
--- a/stat_menu.h
+++ b/stat_menu.h
@@ -50,7 +50,8 @@ typedef enum {
REGISTER_STAT_GROUP_RESPONSE_TIME,
REGISTER_STAT_GROUP_TELEPHONY,
/* XXX - split into telephony and VoIP? */
- REGISTER_ANALYZE_GROUP_NONE
+ REGISTER_ANALYZE_GROUP_NONE,
+ REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER
#ifdef HAVE_LUA_5_1
,REGISTER_TOOLS_GROUP_NONE
#endif