Wireshark-dev: [Wireshark-dev] RFC: Filterable addresses

From: Joerg Mayer <jmayer@xxxxxxxxx>
Date: Sat, 14 Jan 2012 04:53:19 +0100
Hello List,

some while ago I sent a proposal to this list to enable filtering on
IP-addresses in arp requests. Guy asked whether generalizing that would
make more sense. IMO, it does. So, as a prove of concept I tried to
make everything of type FT_IPv4 filterable - and failed. My problem
is, that I don't know how/where to add the hf_ip_addr element in proto.c.
Putting it behind hf_text_only isn't the right place, I just fail to
find the right place/way to add it.
Hints (and general comments on the rest of the implementation) are
welcome!

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 40490)
+++ 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 */
+static int hf_ip_addr = -1;
+
 /* 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 */
+gboolean adding_pseudo = FALSE;
+
 /* List of all protocols */
 static GList *protocols = NULL;
 
@@ -350,6 +356,11 @@
 		{ &hf_text_only,
 		{ "Text item",	"text", FT_NONE, BASE_NONE, NULL, 0x0,
 		  NULL, HFILL }},
+
+		{ &hf_ip_addr,
+		{ "IP Address",       "ip.addr",
+		  FT_IPv4,        BASE_NONE,      NULL,   0x0,
+		  NULL, HFILL }},
 	};
 
 	proto_cleanup();
@@ -1203,6 +1214,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 +1700,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, FALSE);
+			PROTO_ITEM_SET_HIDDEN(item);
+		default:
+			break;
+	}
 	return pi;
 }
 
@@ -2088,7 +2113,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 +2124,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, FALSE);
+	PROTO_ITEM_SET_HIDDEN(item);
+
 	return pi;
 }
 
Index: epan/dissectors/packet-ip.c
===================================================================
--- epan/dissectors/packet-ip.c	(revision 40490)
+++ 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);