Wireshark-dev: [Wireshark-dev] How do display filters work internally?

From: Joerg Mayer <jmayer@xxxxxxxxx>
Date: Thu, 19 Jan 2012 23:41:11 +0100
Hello List,

I fail to understand how display filters work internally. I'm still trying
to get my generic ip.addr filter working, but I seem to lack some understanding
on how display filters work.

It looks like putting an "alien" protocol filter into the hf array will work,
as ip.version inside packet-ipv6.c shows: The field is shown and filterable.
Putting the ip.addr field vom packet-ip.c into all uses of ipv4 addresses
(everything of type FT_IPv4) will show it, but it won't be filterable (neither
existence nor value).

Can someone please fill in some info how display filtering works?

Thanks
   Joerg
-- 
Joerg Mayer                                           <jmayer@xxxxxxxxx>
We are stuck with technology when what we really want is just stuff that
works. Some say that should read Microsoft instead of technology.
Index: epan/proto.c
===================================================================
--- epan/proto.c	(revision 40592)
+++ epan/proto.c	(working copy)
@@ -244,6 +244,9 @@
 /* special-case header field used within proto.c */
 int hf_text_only = -1;
 
+/* Handle pseudo fields */
+extern int hf_ip_addr;
+
 /* Structure for information about a protocol */
 struct _protocol {
 	const char *name;		/* long description */
@@ -257,6 +260,9 @@
 	gboolean is_private;		/* TRUE is protocol is private */
 };
 
+/* Prevent recursion adding pseudo elements */
+static gboolean adding_pseudo = FALSE;
+
 /* List of all protocols */
 static GList *protocols = NULL;
 
@@ -1203,6 +1209,7 @@
 	const char	*string;
 	nstime_t	time_stamp;
 	GPtrArray	*ptrs;
+	proto_item	*item;
 
 	/* there is a possibility here that we might raise an exception
 	 * and thus would lose track of the field_info.
@@ -1688,6 +1695,19 @@
 	if (ptrs)
 		g_ptr_array_add(ptrs, new_fi);
 
+	/* Add pseudo elements for some types */
+	if (adding_pseudo == TRUE) {
+		adding_pseudo = FALSE;
+		return pi;
+	}
+	switch(new_fi->hfinfo->type) {
+		case FT_IPv4:
+			adding_pseudo = TRUE;
+			item = proto_tree_add_item(tree, hf_ip_addr, tvb, start, length, ENC_BIG_ENDIAN);
+			PROTO_ITEM_SET_HIDDEN(item);
+		default:
+			break;
+	}
 	return pi;
 }
 
@@ -2088,7 +2108,7 @@
 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
 		    gint length, guint32 value)
 {
-	proto_item		*pi;
+	proto_item		*pi, *item;
 	field_info		*new_fi;
 	header_field_info	*hfinfo;
 
@@ -2099,6 +2119,14 @@
 	pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
 	proto_tree_set_ipv4(new_fi, value);
 
+	if ( adding_pseudo == TRUE ) {
+		adding_pseudo = FALSE;
+		return pi;
+	}
+	adding_pseudo = TRUE;
+	item = proto_tree_add_item(tree, hf_ip_addr, tvb, start, length, ENC_BIG_ENDIAN);
+	PROTO_ITEM_SET_HIDDEN(item);
+
 	return pi;
 }
 
Index: epan/dissectors/packet-ip.c
===================================================================
--- epan/dissectors/packet-ip.c	(revision 40592)
+++ epan/dissectors/packet-ip.c	(working copy)
@@ -104,7 +104,7 @@
 static int hf_ip_dst_host = -1;
 static int hf_ip_src = -1;
 static int hf_ip_src_host = -1;
-static int hf_ip_addr = -1;
+int hf_ip_addr = -1;
 static int hf_ip_host = -1;
 static int hf_ip_flags = -1;
 static int hf_ip_flags_sf = -1;
@@ -1035,9 +1035,6 @@
       dst_host = get_hostname(addr);
       proto_tree_add_ipv4(field_tree, hf_ip_dst, tvb,
                           offset + optoffset, 4, addr);
-      item = proto_tree_add_ipv4(field_tree, hf_ip_addr, tvb,
-                                 offset + optoffset, 4, addr);
-      PROTO_ITEM_SET_HIDDEN(item);
       item = proto_tree_add_string(field_tree, hf_ip_dst_host, tvb,
                                    offset + optoffset, 4, dst_host);
       PROTO_ITEM_SET_GENERATED(item);
@@ -1960,8 +1957,6 @@
                              ip_to_str(iph->ip_src.data));
     }
     proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, addr);
-    item = proto_tree_add_ipv4(ip_tree, hf_ip_addr, tvb, offset + 12, 4, addr);
-    PROTO_ITEM_SET_HIDDEN(item);
     item = proto_tree_add_string(ip_tree, hf_ip_src_host, tvb, offset + 12, 4,
                                  src_host);
     PROTO_ITEM_SET_GENERATED(item);
@@ -2042,9 +2037,6 @@
     }
     else {
       proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, addr);
-      item = proto_tree_add_ipv4(ip_tree, hf_ip_addr, tvb, offset + 16, 4,
-                                 addr);
-      PROTO_ITEM_SET_HIDDEN(item);
       item = proto_tree_add_string(ip_tree, hf_ip_dst_host, tvb, offset + 16,
                                    4, dst_host);
       PROTO_ITEM_SET_GENERATED(item);
@@ -2251,7 +2243,7 @@
         NULL, 0x0, NULL, HFILL }},
 
     { &hf_ip_addr,
-      { "Source or Destination Address", "ip.addr", FT_IPv4, BASE_NONE,
+      { "IP Address", "ip.addr", FT_IPv4, BASE_NONE,
         NULL, 0x0, NULL, HFILL }},
 
     { &hf_ip_host,