Ethereal-dev: [Ethereal-dev] dfilter bytes cleanup

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Ed Warnicke <hagbard@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 22 Dec 2000 03:09:37 -0500 (EST)
Here's a patch which should clean up the way the dfilter code handles 
FT_BYTES.  I've fixed the FT_BYTES types so that one can filter on 
them without the range operators.  I've also added code to the 
gtk/main.c to allow "Match Selected" to work for FT_BYTES.  This entailed 
creating a bytes_to_str_punct in strutil.c ( in the spirit of the 
ether_to_str_punct in packet.c).  I also adjusted the bytes_to_str 
to call bytes_to_str in the same way that ether_to_str calls 
ether_str_punct (but with no changes in expected behavior).  

I'd appreciate it if someone would look over the patch changes and then 
check them in if they look ok.

Ed

P.S. Reduce/Reduce conflicts suck.
? cscope.out
? epan/y.output
? epan/cscope.out
Index: epan/dfilter-grammar.y
===================================================================
RCS file: /cvsroot/ethereal/epan/dfilter-grammar.y,v
retrieving revision 1.1
diff -u -r1.1 dfilter-grammar.y
--- dfilter-grammar.y	2000/09/27 04:54:47	1.1
+++ dfilter-grammar.y	2000/12/22 07:58:49
@@ -1,5 +1,4 @@
 %{
-
 /* dfilter-grammar.y
  * Parser for display filters
  *
@@ -92,7 +91,7 @@
 static GNode* dfilter_mknode_ipv6_variable(gint id);
 static GNode* dfilter_mknode_existence(gint id);
 static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
-static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
+static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length, gboolean to_the_end);
 static GNode* dfilter_mknode_string_value(char *s);
 static GNode* dfilter_mknode_string_variable(gint id);
 
@@ -549,11 +548,22 @@
 string_variable:	T_FT_STRING	{ $$ = dfilter_mknode_string_variable($1.id); }
 	;
 
+bytes_variable:		T_FT_BYTES T_VAL_BYTE_RANGE
+		{
+			$$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length, FALSE);
+		}
+
+        |               T_FT_BYTES      
+                {
+		        $$ = dfilter_mknode_bytes_variable($1.id, 0, 0, TRUE);
+		}
+
+	;
+
 variable_name:		any_variable_type
-	{
+                {
 		GNode	*variable;
 		GNode	*value;
-
 		if ($1.type == T_FT_BOOLEAN) {
 			/* Make "variable == TRUE" for BOOLEAN variable */
 			variable = dfilter_mknode_numeric_variable($1.id);
@@ -566,12 +576,6 @@
 	}
 	;
 
-bytes_variable:		any_variable_type T_VAL_BYTE_RANGE
-		{
-			$$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length);
-		}
-	;
-
 any_variable_type:	T_FT_UINT8	{ $$ = $1; }
 	|		T_FT_UINT16	{ $$ = $1; }
 	|		T_FT_UINT24	{ $$ = $1; }
@@ -788,7 +792,7 @@
 }
 
 static GNode*
-dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
+dfilter_mknode_bytes_variable(gint id, gint offset, guint length, gboolean to_the_end)
 {
 	dfilter_node	*node;
 	GNode		*gnode;
@@ -802,6 +806,7 @@
 	node->value.variable = id;
 	node->offset = offset;
 	node->length = length;
+	node->to_the_end = to_the_end;
 	gnode = g_node_new(node);
 
 	return gnode;
Index: epan/dfilter-int.h
===================================================================
RCS file: /cvsroot/ethereal/epan/dfilter-int.h,v
retrieving revision 1.1
diff -u -r1.1 dfilter-int.h
--- dfilter-int.h	2000/09/27 04:54:48	1.1
+++ dfilter-int.h	2000/12/22 07:58:49
@@ -137,6 +137,9 @@
 	/* used for byte-ranges */
 	gint				offset;
 	guint				length;
+
+        /* used to indicate range should go to end of sequence */
+        gboolean                        to_the_end;
 } dfilter_node;
 
 /* lookup an abbreviation in our token hash, returing the ID # */
Index: epan/dfilter.c
===================================================================
RCS file: /cvsroot/ethereal/epan/dfilter.c,v
retrieving revision 1.2
diff -u -r1.2 dfilter.c
--- dfilter.c	2000/09/28 03:16:15	1.2
+++ dfilter.c	2000/12/22 07:58:49
@@ -57,6 +57,7 @@
 /* Silly global variables used to pass parameter to check_relation_bytes() */
 int bytes_offset = 0;
 int bytes_length = 0;
+gboolean bytes_to_the_end = FALSE;
 
 YYSTYPE yylval;
 
@@ -431,8 +432,6 @@
 	gboolean	retval;
 
 
-	bytes_length = MIN(node_a->length, node_b->length);
-	bytes_offset = MIN(node_a->offset, node_b->offset);
 	if (node_a->ntype == variable)
 		vals_a = get_values_from_ptree(node_a, ptree, pd);
 	else
@@ -482,6 +481,14 @@
 	g_assert(dnode->elem_size > 0);
 	result_array = g_array_new(FALSE, FALSE, dnode->elem_size);
 
+	/* Set bytes_offset, bytes_length, and bytes_to_the_end 
+	 * for this dnode
+	 */
+
+	bytes_offset = dnode->offset;
+	bytes_length = dnode->length;
+	bytes_to_the_end = dnode->to_the_end;
+
 	/* Cull the finfos from the proto_tree */
 	finfo_array = proto_get_finfo_ptr_array(ptree, dnode->value.variable);
 	if (!finfo_array) {
@@ -544,7 +551,7 @@
 fill_array_bytes_variable(field_info *finfo, GArray *array, const guint8 *pd)
 {
 	GByteArray		*barray;
-	guint			read_start, pkt_end;
+	guint			read_start, pkt_end, read_len;
 
 	if (bytes_offset < 0) {
 		/* Handle negative byte offsets */
@@ -561,14 +568,19 @@
 
 	pkt_end = finfo->start + finfo->length;
 	read_start = finfo->start + bytes_offset;
-
+	if(bytes_to_the_end){
+	        read_len = pkt_end - read_start;;
+	}
+	else {
+	        read_len = bytes_length;
+	}
 	/* Check to make sure entire length requested is inside field */
-	if (pkt_end < read_start + bytes_length) {
+	if (pkt_end < read_start + read_len) {
 		return;
 	}
 
 	barray = g_byte_array_new();
-	g_byte_array_append(barray, pd + read_start, bytes_length);
+	g_byte_array_append(barray, pd + read_start, read_len);
 	g_array_append_val(array, barray);
 }
 
@@ -980,7 +992,8 @@
 			ptr_a = g_array_index(a, GByteArray*, i);
 			for (j = 0; j < len_b; j++) {
 				ptr_b = g_array_index(b, GByteArray*, j);
-				if (memcmp(ptr_a->data, ptr_b->data, bytes_length) == 0)
+				if(ptr_a->len != ptr_b->len)
+				        return FALSE;							       if (memcmp(ptr_a->data, ptr_b->data, ptr_a->len) == 0)
 					return TRUE;
 			}
 		}
@@ -991,7 +1004,9 @@
 			ptr_a = g_array_index(a, GByteArray*, i);
 			for (j = 0; j < len_b; j++) {
 				ptr_b = g_array_index(b, GByteArray*, j);
-				if (memcmp(ptr_a->data, ptr_b->data, bytes_length) != 0)
+				if(ptr_a->len != ptr_b->len)
+				        return TRUE;
+				if (memcmp(ptr_a->data, ptr_b->data, ptr_a->len) != 0)
 					return TRUE;
 			}
 		}
@@ -1002,7 +1017,11 @@
 			ptr_a = g_array_index(a, GByteArray*, i);
 			for (j = 0; j < len_b; j++) {
 				ptr_b = g_array_index(b, GByteArray*, j);
-				if (memcmp(ptr_a->data, ptr_b->data, bytes_length) > 0)
+				if(ptr_a->len > ptr_b->len)
+				        return TRUE;
+				if(ptr_a->len < ptr_b->len)
+				        return FALSE;
+				if (memcmp(ptr_a->data, ptr_b->data, ptr_a->len) > 0)
 					return TRUE;
 			}
 		}
@@ -1013,7 +1032,11 @@
 			ptr_a = g_array_index(a, GByteArray*, i);
 			for (j = 0; j < len_b; j++) {
 				ptr_b = g_array_index(b, GByteArray*, j);
-				if (memcmp(ptr_a->data, ptr_b->data, bytes_length) < 0)
+				if(ptr_a->len < ptr_b->len)
+				        return TRUE;
+				if(ptr_a->len > ptr_b->len)
+				        return FALSE;
+				if (memcmp(ptr_a->data, ptr_b->data, ptr_a->len) < 0)
 					return TRUE;
 			}
 		}
Index: epan/strutil.c
===================================================================
RCS file: /cvsroot/ethereal/epan/strutil.c,v
retrieving revision 1.6
diff -u -r1.6 strutil.c
--- strutil.c	2000/11/13 07:19:32	1.6
+++ strutil.c	2000/12/22 07:58:49
@@ -246,6 +246,14 @@
 #define	N_BYTES_TO_STR_STRINGS	6
 gchar *
 bytes_to_str(const guint8 *bd, int bd_len) {
+  return bytes_to_str_punct(bd,bd_len,'\0');
+}
+
+/* Turn an array of bytes into a string showing the bytes in hex with 
+ * punct as a bytes separator.
+ */
+gchar *
+bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct) {
   static gchar  str[N_BYTES_TO_STR_STRINGS][MAX_BYTE_STR_LEN+3+1];
   static int    cur_idx;
   gchar        *cur;
@@ -266,6 +274,10 @@
     len -= 2;
     bd++;
     bd_len--;
+    if(punct && bd_len > 0){
+      *p++ = punct;
+      len--;
+    }
   }
   if (bd_len != 0) {
     /* Note that we're not showing the full string.  */
Index: epan/strutil.h
===================================================================
RCS file: /cvsroot/ethereal/epan/strutil.h,v
retrieving revision 1.5
diff -u -r1.5 strutil.h
--- strutil.h	2000/11/13 07:19:33	1.5
+++ strutil.h	2000/12/22 07:58:49
@@ -42,5 +42,5 @@
     const u_char **next_token);
 gchar*     format_text(const u_char *line, int len);
 gchar*     bytes_to_str(const guint8 *, int);
-
+gchar*     bytes_to_str_punct(const guint8 *, int, gchar punct);
 #endif /* __STRUTIL_H__ */
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.168
diff -u -r1.168 main.c
--- main.c	2000/12/15 13:53:11	1.168
+++ main.c	2000/12/22 07:58:51
@@ -121,6 +121,7 @@
 #include "gtkglobals.h"
 #include "plugins.h"
 #include "colors.h"
+#include "strutil.h"
 
 packet_info  pi;
 capture_file cfile;
@@ -265,6 +266,15 @@
 				 finfo_selected->value.string);
 			break;
 
+	        case FT_BYTES:
+		        printf("hfinfo->abbrev %s\n", hfinfo->abbrev);
+		        dfilter_len = finfo_selected->length*3 - 1;
+		        dfilter_len += abbrev_len + 7;
+			buf = g_malloc0(dfilter_len);
+			snprintf(buf, dfilter_len, "%s == %s",
+				 hfinfo->abbrev,
+				 bytes_to_str_punct(finfo_selected->value.bytes, finfo_selected->length,':'));
+			break;                       
 		default:
 		    c = cfile.pd + finfo_selected->start;
 		    buf = g_malloc0(32 + finfo_selected->length * 3);