Change match_selected() to produce a display filter using the selected
authorgram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 19 Nov 1999 22:32:00 +0000 (22:32 +0000)
committergram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 19 Nov 1999 22:32:00 +0000 (22:32 +0000)
field's name, if possible. (If the selected field is not a registered field,
then of course, we still have to use the frame[x:y] syntax).

tree_selected_start and tree_selected_len are on longer globals variables;
finfo_selected has replaced them.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@1070 f5534014-38df-0310-8fa8-9805f1628bb7

file.c
globals.h
gtk/main.c
ipv4.c
ipv4.h

diff --git a/file.c b/file.c
index 08ddbcb32c5d6a4511e9a415ba19f94f975b73dc..e4928de5eec5beb50fd23eebf08ccdc4cae1aec5 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.120 1999/11/17 21:58:33 guy Exp $
+ * $Id: file.c,v 1.121 1999/11/19 22:31:48 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -84,6 +84,7 @@
 #include "dfilter.h"
 #include "timestamp.h"
 #include "conversation.h"
+#include "globals.h"
 
 #ifndef __RESOLV_H__
 #include "resolv.h"
@@ -1140,6 +1141,7 @@ colorize_packets(capture_file *cf)
       /* It was selected, so re-select it. */
       gtk_clist_select_row(GTK_CLIST(packet_list), cf->current_row, -1);
     }
+    finfo_selected = NULL;
   } else {
     /* The current frame didn't pass the filter; make the first frame
        the current frame, and leave it unselected. */
@@ -1576,6 +1578,8 @@ unselect_packet(capture_file *cf)
     cf->protocol_tree = NULL;
   }
 
+  finfo_selected = NULL;
+
   /* Clear out the display of that packet. */
   clear_tree_and_hex_views();
 
index 5385407651a534952e3597c7b699ed5273589a3d..21774c82023e9ba9bec38b288fe0da9787465e37 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -1,7 +1,7 @@
 /* globals.h
  * Global defines, etc.
  *
- * $Id: globals.h,v 1.11 1999/10/20 22:35:57 gram Exp $
+ * $Id: globals.h,v 1.12 1999/11/19 22:31:50 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -92,6 +92,7 @@ extern gchar       *bold_font;
 extern gchar       *last_open_dir;
 extern gboolean     auto_scroll_live;
 extern int          g_resolving_actif;
+extern field_info  *finfo_selected;
 
 extern ts_type timestamp_type;
 
index 3961eacfe98889b4700de607f2ea82c28226a565..dcb28f911de4d8a01a32df913cc2406f1b708a80 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.38 1999/11/17 02:17:18 guy Exp $
+ * $Id: main.c,v 1.39 1999/11/19 22:32:00 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -112,13 +112,14 @@ ts_type timestamp_type = RELATIVE;
 
 GtkStyle *item_style;
 
-/* Specifies byte offsets for object selected in tree */
-static gint tree_selected_start=-1, tree_selected_len=-1; 
+/* Specifies the field currently selected in the GUI protocol tree */
+field_info *finfo_selected = NULL;
 
 static void follow_destroy_cb(GtkWidget *win, gpointer data);
 static void follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w);
 static void follow_load_text(GtkWidget *text, char *filename, gboolean show_ascii);
 static void follow_print_stream(GtkWidget *w, gpointer parent_w);
+static char* hfinfo_numeric_format(header_field_info *hfinfo);
 
 /* About Ethereal window */
 void
@@ -469,15 +470,16 @@ follow_load_text(GtkWidget *text, char *filename, gboolean show_ascii)
 void
 match_selected_cb(GtkWidget *w, gpointer data)
 {
-    char *buf;
-    GtkWidget *filter_te = NULL;
-    char *ptr;
-    int i;
-    guint8 *c;
+    char               *buf;
+    GtkWidget          *filter_te = NULL;
+    char               *ptr, *format, *stringified;
+    int                        i, dfilter_len, abbrev_len;
+    guint8             *c;
+    header_field_info  *hfinfo;
 
     filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
 
-    if (tree_selected_start<0) {
+    if (!finfo_selected) {
        simple_dialog(ESD_TYPE_WARN, NULL,
                      "Error determining selected bytes.  Please make\n"
                      "sure you have selected a field within the tree\n"
@@ -485,27 +487,118 @@ match_selected_cb(GtkWidget *w, gpointer data)
        return;
     }
 
-    c = cf.pd + tree_selected_start;
-    buf = g_malloc(32 + tree_selected_len * 3);
-    ptr = buf;
-
-    sprintf(ptr, "frame[%d : %d] == ", tree_selected_start, tree_selected_len);
-    ptr = buf+strlen(buf);
-
-    if (tree_selected_len == 1) {
-        sprintf(ptr, "0x%02x", *c++);
-    }
-    else {
-           for (i=0;i<tree_selected_len; i++) {
-               if (i == 0 ) {
-                       sprintf(ptr, "%02x", *c++);
-               }
-               else {
-                       sprintf(ptr, ":%02x", *c++);
-               }
-               ptr = buf+strlen(buf);
-           }
-    }
+    hfinfo = finfo_selected->hfinfo;
+    g_assert(hfinfo);
+    abbrev_len = strlen(hfinfo->abbrev);
+
+       switch(hfinfo->type) {
+
+               case FT_BOOLEAN:
+                       dfilter_len = abbrev_len + 2;
+                       buf = g_malloc0(dfilter_len);
+                       snprintf(buf, dfilter_len, "%s%s", finfo_selected->value.numeric ? "" : "!",
+                                       hfinfo->abbrev);
+                       break;
+
+               case FT_UINT8:
+               case FT_UINT16:
+               case FT_UINT24:
+               case FT_UINT32:
+               case FT_INT8:
+               case FT_INT16:
+               case FT_INT24:
+               case FT_INT32:
+                       dfilter_len = abbrev_len + 20;
+                       buf = g_malloc0(dfilter_len);
+                       format = hfinfo_numeric_format(hfinfo);
+                       snprintf(buf, dfilter_len, format, hfinfo->abbrev, finfo_selected->value.numeric);
+                       break;
+
+               case FT_IPv4:
+                       dfilter_len = abbrev_len + 21;
+                       buf = g_malloc0(dfilter_len);
+                                             /* xxx.xxx.xxx.xxx */
+                       format = g_strdup("%s ==                ");
+                       ipv4_addr_sprintf(&(finfo_selected->value.ipv4), &format[6]),
+                       snprintf(buf, dfilter_len, format, hfinfo->abbrev);
+                       g_free(format);
+                       break;
+
+               case FT_IPXNET:
+                       dfilter_len = abbrev_len + 15;
+                       buf = g_malloc0(dfilter_len);
+                       snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
+                                       finfo_selected->value.numeric);
+                       break;
+
+               case FT_IPv6:
+                       stringified = ip6_to_str((struct e_in6_addr*) &(finfo_selected->value.ipv6));
+                       dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
+                       buf = g_malloc0(dfilter_len);
+                       snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
+                                       stringified);
+                       break;
+
+               case FT_DOUBLE:
+                       dfilter_len = abbrev_len + 30;
+                       buf = g_malloc0(dfilter_len);
+                       snprintf(buf, dfilter_len, "%s == %f", hfinfo->abbrev,
+                                       finfo_selected->value.floating);
+                       break;
+
+               case FT_ETHER:
+                       dfilter_len = abbrev_len + 22;
+                       buf = g_malloc0(dfilter_len);
+                       snprintf(buf, dfilter_len, "%s == %02x:%02x:%02x:%02x:%02x:%02x",
+                                       hfinfo->abbrev,
+                                       finfo_selected->value.ether[0],
+                                       finfo_selected->value.ether[1],
+                                       finfo_selected->value.ether[2],
+                                       finfo_selected->value.ether[3],
+                                       finfo_selected->value.ether[4],
+                                       finfo_selected->value.ether[5]);
+                       break;
+#if 0
+
+               case FT_ABSOLUTE_TIME:
+               case FT_RELATIVE_TIME:
+                       memcpy(&fi->value.time, va_arg(ap, struct timeval*),
+                               sizeof(struct timeval));
+                       break;
+
+               case FT_STRING:
+                       /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+                       fi->value.string = g_strdup(va_arg(ap, char*));
+                       break;
+
+               case FT_TEXT_ONLY:
+                       ; /* nothing */
+                       break;
+#endif
+               default:
+                   c = cf.pd + finfo_selected->start;
+                   buf = g_malloc0(32 + finfo_selected->length * 3);
+                   ptr = buf;
+
+                   sprintf(ptr, "frame[%d : %d] == ", finfo_selected->start, finfo_selected->length);
+                   ptr = buf+strlen(buf);
+
+                   if (finfo_selected->length == 1) {
+                       sprintf(ptr, "0x%02x", *c++);
+                   }
+                   else {
+                           for (i=0;i<finfo_selected->length; i++) {
+                               if (i == 0 ) {
+                                       sprintf(ptr, "%02x", *c++);
+                               }
+                               else {
+                                       sprintf(ptr, ":%02x", *c++);
+                               }
+                               ptr = buf+strlen(buf);
+                           }
+                   }
+                   break;
+       }
 
     /* create a new one and set the display filter entry accordingly */
     if (filter_te) {
@@ -513,8 +606,66 @@ match_selected_cb(GtkWidget *w, gpointer data)
     }
     /* Run the display filter so it goes in effect. */
     filter_packets(&cf, buf);
+
+    /* Don't g_free(buf) here. filter_packets() will do it the next time it's called */
+}
+
+static char*
+hfinfo_numeric_format(header_field_info *hfinfo)
+{
+       char *format = NULL;
+
+       /* Pick the proper format string */
+       switch(hfinfo->display) {
+               case BASE_DEC:
+               case BASE_NONE:
+               case BASE_OCT: /* I'm lazy */
+               case BASE_BIN: /* I'm lazy */
+                       switch(hfinfo->type) {
+                               case FT_UINT8:
+                               case FT_UINT16:
+                               case FT_UINT24:
+                               case FT_UINT32:
+                                       format = "%s == %u";
+                                       break;
+                               case FT_INT8:
+                               case FT_INT16:
+                               case FT_INT24:
+                               case FT_INT32:
+                                       format = "%s == %d";
+                                       break;
+                               default:
+                                       g_assert_not_reached();
+                                       ;
+                       }
+                       break;
+               case BASE_HEX:
+                       switch(hfinfo->type) {
+                               case FT_UINT8:
+                                       format = "%s == 0x%02x";
+                                       break;
+                               case FT_UINT16:
+                                       format = "%s == 0x%04x";
+                                       break;
+                               case FT_UINT24:
+                                       format = "%s == 0x%06x";
+                                       break;
+                               case FT_UINT32:
+                                       format = "%s == 0x%08x";
+                                       break;
+                               default:
+                                       g_assert_not_reached();
+                                       ;
+                       }
+                       break;
+               default:
+                       g_assert_not_reached();
+                       ;
+       }
+       return format;
 }
 
+
 /* Run the current display filter on the current packet set, and
    redisplay. */
 static void
@@ -550,14 +701,15 @@ void
 tree_view_cb(GtkWidget *w, gpointer data) {
 
   field_info   *finfo;
-  tree_selected_start = -1;
-  tree_selected_len = -1;
+  int          tree_selected_start = -1;
+  int          tree_selected_len = -1;
 
   if (GTK_TREE(w)->selection) {
     finfo = 
        gtk_object_get_data(GTK_OBJECT(GTK_TREE(w)->selection->data),
                                   E_TREEINFO_FIELD_INFO_KEY);
     g_assert(finfo);
+    finfo_selected = finfo;
     tree_selected_start = finfo->start;
     tree_selected_len   = finfo->length;
   }
diff --git a/ipv4.c b/ipv4.c
index f647b154ee4c539ef504c9c37e7fec63577afa73..8c45934e540b5910c47357ec75b6402603b77b06 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -5,7 +5,7 @@
  *
  * Gilbert Ramirez <gram@xiexie.org>
  *
- * $Id: ipv4.c,v 1.2 1999/11/15 07:25:31 guy Exp $
+ * $Id: ipv4.c,v 1.3 1999/11/19 22:31:50 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@unicom.net>
@@ -93,6 +93,20 @@ ipv4_get_host_order_addr(ipv4_addr *ipv4)
        return ipv4->addr;
 }
 
+#define OCTET_0(x)     ( ( x & 0xff000000 ) >> 24 )
+#define OCTET_1(x)     ( ( x & 0x00ff0000 ) >> 16 )
+#define OCTET_2(x)     ( ( x & 0x0000ff00 ) >>  8 )
+#define OCTET_3(x)       ( x & 0x000000ff )
+
+void
+ipv4_addr_sprintf(ipv4_addr *ipv4, char *target_string)
+{
+       sprintf(target_string, "%d.%d.%d.%d",
+                       OCTET_0(ipv4->addr),
+                       OCTET_1(ipv4->addr),
+                       OCTET_2(ipv4->addr),
+                       OCTET_3(ipv4->addr) );
+}
 
 static guint32
 create_nmask(gint net_bits)
diff --git a/ipv4.h b/ipv4.h
index c6f4da99fcc86e6e1feecbafd27d65ec10c89ac4..6ad0e1234d9a997e2fc93cf1cf65253799cf77c5 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
@@ -5,7 +5,7 @@
  *
  * Gilbert Ramirez <gramirez@tivoli.cm>
  *
- * $Id: ipv4.h,v 1.1 1999/11/15 06:32:14 gram Exp $
+ * $Id: ipv4.h,v 1.2 1999/11/19 22:31:50 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@unicom.net>
@@ -48,6 +48,9 @@ void ipv4_addr_set_netmask_bits(ipv4_addr *ipv4, guint new_nmask_bits);
 guint32 ipv4_get_net_order_addr(ipv4_addr *ipv4);
 guint32 ipv4_get_host_order_addr(ipv4_addr *ipv4);
 
+/* Print and IPv4 address in dotted decimal notation to an already-allocated string */
+void ipv4_addr_sprintf(ipv4_addr *ipv4, char *target_string);
+
 /* Compares two ipv4_addrs, taking into account the less restrictive of the
  * two netmasks, applying that netmask to both addrs.
  */