/* dfilter.c
* Routines for display filters
*
- * $Id: dfilter.c,v 1.7 1999/08/12 15:10:48 gram Exp $
+ * $Id: dfilter.c,v 1.32 1999/11/15 06:32:13 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#include <string.h>
#endif
+#ifdef NEED_SNPRINTF_H
+# ifdef HAVE_STDARG_H
+# include <stdarg.h>
+# else
+# include <varargs.h>
+# endif
+# include "snprintf.h"
+#endif
+
#ifndef __G_LIB_H__
#include <glib.h>
#endif
#ifndef __DFILTER_H__
#include "dfilter.h"
#endif
+
+#ifndef __UTIL_H__
+#include "util.h"
+#endif
+
+#include "dfilter-int.h"
#include "dfilter-grammar.h"
-int yyparse(void); /* yacc entry-point */
+int dfilter_parse(void); /* yacc entry-point */
#define DFILTER_LEX_ABBREV_OFFSET 2000
YYSTYPE yylval;
-/* in dfilter-grammar.y */
-extern GMemChunk *gmc_dfilter_nodes;
-extern GNode *dfilter_tree;
-extern GSList *dfilter_list_byte_arrays;
-
-/* in dfilter-scanner.l */
-void dfilter_scanner_text(char*);
-void dfilter_scanner_cleanup(void);
+/* Global error message space for dfilter_compile errors */
+gchar dfilter_error_msg_buf[1024];
+gchar *dfilter_error_msg; /* NULL when no error resulted */
static gboolean dfilter_apply_node(GNode *gnode, proto_tree *ptree, const guint8 *pd);
static gboolean check_relation(gint operand, GNode *a, GNode *b, proto_tree *ptree, const guint8 *pd);
}
}
}
-/* I should eventually g_tree_destroy(dfilter_tokens), when ethereal shuts down */
+
+void
+dfilter_cleanup(void)
+{
+ if (dfilter_tokens)
+ g_tree_destroy(dfilter_tokens);
+}
/* Compiles the textual representation of the display filter into a tree
- * of operations to perform.
+ * of operations to perform. Can be called multiple times, compiling a new
+ * display filter each time, without having to clear any memory used, since
+ * dfilter_compile will take care of that automatically.
+ *
+ * Returns 0 on success, non-zero on failure.
+ *
+ * On success, sets the "dfilter *" pointed to by its second argument
+ * either to a null pointer (if the filter is a null filter, as
+ * generated by an all-blank string) or to a pointer to a newly-allocated
+ * dfilter structure (if the filter isn't null).
+ *
+ * On failure, "dfilter_error_msg" points to an appropriate error message.
+ * This error message is a global string, so another invocation of
+ * dfilter_compile will clear it. If the caller needs is stored, he
+ * needs to g_strdup it himself.
*/
int
-dfilter_compile(char *dfilter_text, GNode **p_dfcode)
+dfilter_compile(gchar *dfilter_text, dfilter **dfp)
{
+ dfilter *df;
int retval;
g_assert(dfilter_text != NULL);
+
+ df = dfilter_new();
+
+ /* tell the scanner to use the filter string as input */
dfilter_scanner_text(dfilter_text);
- if (dfilter_tree) {
- /* clear tree */
- dfilter_tree = NULL;
+ /* Assign global variable so dfilter_parse knows which dfilter we're
+ * talking about. Reset the global error message.
+ */
+ global_df = df;
+ dfilter_error_msg = NULL;
+
+ /* The magic happens right here. */
+ retval = dfilter_parse();
+
+ /* clean up lex */
+ dfilter_scanner_cleanup();
+
+ /* Errors not found by the parser may not cause the parse to
+ * fail; if "dfilter_error_msg" is set, it means somebody
+ * else called "dfilter_fail()", e.g. the lexical analyzer,
+ * so treat that as a parse error. */
+ if (dfilter_error_msg != NULL)
+ retval = 1;
+
+ if (retval != 0) {
+ if (dfilter_error_msg == NULL) {
+ snprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),
+ "Unable to parse filter string \"%s\".",
+ dfilter_text);
+ dfilter_error_msg = &dfilter_error_msg_buf[0];
+ }
+ }
+
+ /* Set global_df to NULL just to be tidy. */
+ global_df = NULL;
+
+ if (retval == 0) {
+ /* Success. Check if the filter is empty; if so, discard
+ * it and set "*dfp" to NULL, otherwise set "*dfp" to
+ * point to the filter. */
+ if (df->dftree == NULL) {
+ /* The filter is empty. */
+ dfilter_destroy(df);
+ df = NULL;
+ }
+ *dfp = df;
+ } else {
+ /* Failure. Destroy the filter. */
+ dfilter_destroy(df);
+ df = NULL;
}
+ return retval;
+}
+
+/* Allocates new dfilter, initializes values, and returns pointer to dfilter */
+dfilter*
+dfilter_new(void)
+{
+ dfilter *df;
+
+ df = g_malloc(sizeof(dfilter));
+
+ df->dftree = NULL;
+ df->node_memchunk = g_mem_chunk_new("df->node_memchunk",
+ sizeof(dfilter_node), 20 * sizeof(dfilter_node), G_ALLOC_ONLY);
+ df->list_of_byte_arrays = NULL;
+
+ return df;
+}
+
+/* Frees all memory used by dfilter, and frees dfilter itself */
+void
+dfilter_destroy(dfilter *df)
+{
+ if (!df)
+ return;
+
+ if (df->dftree != NULL)
+ g_node_destroy(df->dftree);
+
/* clear the memory that the tree was using for nodes */
- g_mem_chunk_reset(gmc_dfilter_nodes);
+ if (df->node_memchunk)
+ g_mem_chunk_reset(df->node_memchunk);
/* clear the memory that the tree was using for byte arrays */
- if (dfilter_list_byte_arrays) {
- g_slist_foreach(dfilter_list_byte_arrays, clear_byte_array, NULL);
- g_slist_free(dfilter_list_byte_arrays);
- dfilter_list_byte_arrays = NULL;
+ if (df->list_of_byte_arrays) {
+ g_slist_foreach(df->list_of_byte_arrays, clear_byte_array, NULL);
+ g_slist_free(df->list_of_byte_arrays);
}
- if (*p_dfcode != NULL)
- g_node_destroy(*p_dfcode);
+ df->dftree = NULL;
+ df->list_of_byte_arrays = NULL;
- retval = yyparse();
- dfilter_scanner_cleanup();
- *p_dfcode = dfilter_tree;
+ /* Git rid of memchunk */
+ if (df->node_memchunk)
+ g_mem_chunk_destroy(df->node_memchunk);
- return retval;
+ g_free(df);
}
+
static void
clear_byte_array(gpointer data, gpointer user_data)
{
g_byte_array_free(barray, TRUE);
}
+/* Called when the yacc grammar finds a parsing error */
void
-yyerror(char *s)
+dfilter_error(char *s)
{
-/* fprintf(stderr, "%s\n", s);
- Do not report the error, just let yyparse() return 1 */
}
+/* Called when an error other than a parsing error occurs. */
void
-dfilter_yyerror(char *fmt, ...)
+dfilter_fail(char *format, ...)
{
- dfilter_tree = NULL;
- yyerror(fmt);
+ va_list ap;
+
+ /* If we've already reported one error, don't overwrite it with this
+ * one. */
+ if (dfilter_error_msg != NULL)
+ return;
+
+ va_start(ap, format);
+ vsnprintf(dfilter_error_msg_buf, sizeof dfilter_error_msg_buf, format, ap);
+ dfilter_error_msg = dfilter_error_msg_buf;
+ va_end(ap);
}
/* lookup an abbreviation in our token tree, returing the ID #
- * If the abbreviation doesn't exit, returns 0 */
+ * If the abbreviation doesn't exit, returns -1 */
int dfilter_lookup_token(char *abbrev)
{
int value;
value = GPOINTER_TO_INT(g_tree_lookup(dfilter_tokens, abbrev));
if (value < DFILTER_LEX_ABBREV_OFFSET) {
- return 0;
+ return -1;
}
return value - DFILTER_LEX_ABBREV_OFFSET;
}
gboolean
-dfilter_apply(GNode *dfcode, proto_tree *ptree, const guint8* pd)
+dfilter_apply(dfilter *dfcode, proto_tree *ptree, const guint8* pd)
{
gboolean retval;
- retval = dfilter_apply_node(dfcode, ptree, pd);
+ if (dfcode == NULL)
+ return FALSE;
+ retval = dfilter_apply_node(dfcode->dftree, ptree, pd);
return retval;
}
g_assert_not_reached();
case logical:
+ g_assert(gnode_a);
return check_logical(dnode->value.logical, gnode_a, gnode_b, ptree, pd);
case relation:
/* not coded yet */
case numeric:
+ case floating:
case ipv4:
+ case ipv6:
case boolean:
case ether:
case string:
switch(operand) {
case TOK_AND:
+ g_assert(b);
return (val_a && dfilter_apply_node(b, ptree, pd));
case TOK_OR:
+ g_assert(b);
return (val_a || dfilter_apply_node(b, ptree, pd));
case TOK_XOR:
+ g_assert(b);
val_b = dfilter_apply_node(b, ptree, pd);
return ( ( val_a || val_b ) && ! ( val_a && val_b ) );
case TOK_NOT:
static gboolean
check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree)
{
- int target_field;
- proto_tree *subtree;
+ int target;
- target_field = dnode->value.variable;
- subtree = proto_find_field(ptree, target_field);
-
- if (subtree)
- return TRUE;
- else
- return FALSE;
+ target = dnode->value.variable;
+ return proto_check_for_protocol_or_field(ptree, target);
}
static GArray*
{
GArray *array;
int parent_protocol;
- int target_field;
- proto_tree *subtree = NULL; /* where the parent protocol's sub-tree starts */
proto_tree_search_info sinfo;
g_assert(dnode->elem_size > 0);
array = g_array_new(FALSE, FALSE, dnode->elem_size);
- target_field = dnode->value.variable;
+ sinfo.target = dnode->value.variable;
+ sinfo.result.array = array;
+ sinfo.packet_data = pd;
+ sinfo.traverse_func = dnode->fill_array_func;
/* Find the proto_tree subtree where we should start searching.*/
- if (proto_registrar_is_protocol(target_field)) {
- subtree = proto_find_protocol(ptree, target_field);
+ if (proto_registrar_is_protocol(sinfo.target)) {
+ proto_find_protocol_multi(ptree, sinfo.target,
+ (GNodeTraverseFunc)proto_get_field_values, &sinfo);
}
else {
- parent_protocol = proto_registrar_get_parent(target_field);
+ parent_protocol = proto_registrar_get_parent(sinfo.target);
if (parent_protocol >= 0) {
- subtree = proto_find_protocol(ptree, parent_protocol);
+ proto_find_protocol_multi(ptree, parent_protocol,
+ (GNodeTraverseFunc)proto_get_field_values, &sinfo);
}
}
- if (subtree) {
- sinfo.target_field = target_field;
- sinfo.result_array = array;
- sinfo.packet_data = pd;
- proto_get_field_values(subtree, dnode->fill_array_func, &sinfo);
- }
-
return array;
}
array = g_array_new(FALSE, FALSE, dnode->elem_size);
g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, dnode->fill_array_func, array);
-/* dnode->fill_array_func(gnode, array);*/
return array;
}
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
field_info *fi = (field_info*) (gnode->data);
- if (fi->hfinfo->id == sinfo->target_field) {
- g_array_append_val(sinfo->result_array, fi->value.numeric);
+ if (fi->hfinfo->id == sinfo->target) {
+ g_array_append_val(sinfo->result.array, fi->value.numeric);
+ }
+
+ return FALSE; /* FALSE = do not end traversal of GNode tree */
+}
+
+gboolean fill_array_floating_variable(GNode *gnode, gpointer data)
+{
+ proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
+ field_info *fi = (field_info*) (gnode->data);
+
+ if (fi->hfinfo->id == sinfo->target) {
+ g_array_append_val(sinfo->result.array, fi->value.floating);
}
return FALSE; /* FALSE = do not end traversal of GNode tree */
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
field_info *fi = (field_info*) (gnode->data);
- if (fi->hfinfo->id == sinfo->target_field) {
- g_array_append_val(sinfo->result_array, fi->value.ether);
+ if (fi->hfinfo->id == sinfo->target) {
+ g_array_append_val(sinfo->result.array, fi->value.ether);
}
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
-gboolean fill_array_bytes_variable(GNode *gnode, gpointer data)
+gboolean fill_array_ipv4_variable(GNode *gnode, gpointer data)
{
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
field_info *fi = (field_info*) (gnode->data);
- GByteArray *barray;
- if (fi->hfinfo->id == sinfo->target_field) {
- barray = g_byte_array_new();
- /*dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray);*/
- g_byte_array_append(barray, sinfo->packet_data + fi->start + bytes_offset, bytes_length);
- g_array_append_val(sinfo->result_array, barray);
+ if (fi->hfinfo->id == sinfo->target) {
+ g_array_append_val(sinfo->result.array, fi->value.ipv4);
}
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
+gboolean fill_array_ipv6_variable(GNode *gnode, gpointer data)
+{
+ proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
+ field_info *fi = (field_info*) (gnode->data);
+
+ if (fi->hfinfo->id == sinfo->target) {
+ g_array_append_val(sinfo->result.array, fi->value.ipv6);
+ }
-gboolean fill_array_boolean_variable(GNode *gnode, gpointer data)
+ return FALSE; /* FALSE = do not end traversal of GNode tree */
+}
+
+gboolean fill_array_bytes_variable(GNode *gnode, gpointer data)
{
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
field_info *fi = (field_info*) (gnode->data);
+ GByteArray *barray;
+ guint read_start, pkt_end;
+
+ if (fi->hfinfo->id == sinfo->target) {
+ if (bytes_offset < 0) {
+ /* Handle negative byte offsets */
+ bytes_offset = fi->length + bytes_offset;
+ if (bytes_offset < 0) {
+ goto FAIL;
+ }
+ }
+
+ /* Check to make sure offset exists for this field */
+ if (bytes_offset >= fi->length) {
+ goto FAIL;
+ }
- if (fi->hfinfo->id == sinfo->target_field) {
- g_array_append_val(sinfo->result_array, fi->value.boolean);
+ pkt_end = fi->start + fi->length;
+ read_start = fi->start + bytes_offset;
+
+ /* Check to make sure entire length requested is inside field */
+ if (pkt_end < read_start + bytes_length) {
+ goto FAIL;
+ }
+
+ barray = g_byte_array_new();
+ g_byte_array_append(barray, sinfo->packet_data + read_start, bytes_length);
+ g_array_append_val(sinfo->result.array, barray);
}
+ FAIL:
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
dfilter_node *dnode = (dfilter_node*) (gnode->data);
g_array_append_val(array, dnode->value.numeric);
+ return FALSE; /* FALSE = do not end traversal of GNode tree */
+}
+
+gboolean fill_array_floating_value(GNode *gnode, gpointer data)
+{
+ GArray *array = (GArray*)data;
+ dfilter_node *dnode = (dfilter_node*) (gnode->data);
+ g_array_append_val(array, dnode->value.floating);
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
-gboolean fill_array_bytes_value(GNode *gnode, gpointer data)
+gboolean fill_array_ipv4_value(GNode *gnode, gpointer data)
{
GArray *array = (GArray*)data;
dfilter_node *dnode = (dfilter_node*) (gnode->data);
- GByteArray *barray = dnode->value.bytes;
- g_array_append_val(array, barray);
+ g_array_append_val(array, dnode->value.ipv4);
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
-gboolean fill_array_boolean_value(GNode *gnode, gpointer data)
+gboolean fill_array_ipv6_value(GNode *gnode, gpointer data)
{
GArray *array = (GArray*)data;
dfilter_node *dnode = (dfilter_node*) (gnode->data);
- g_array_append_val(array, dnode->value.boolean);
+ g_array_append_val(array, dnode->value.ipv6);
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
+gboolean fill_array_bytes_value(GNode *gnode, gpointer data)
+{
+ GArray *array = (GArray*)data;
+ dfilter_node *dnode = (dfilter_node*) (gnode->data);
+ GByteArray *barray = dnode->value.bytes;
+
+ g_array_append_val(array, barray);
+
+ return FALSE; /* FALSE = do not end traversal of GNode tree */
+}
gboolean check_relation_numeric(gint operand, GArray *a, GArray *b)
{
return FALSE;
}
-
-gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
+gboolean check_relation_floating(gint operand, GArray *a, GArray *b)
{
int i, j, len_a, len_b;
- guint8 *ptr_a, *ptr_b;
+ double val_a;
len_a = a->len;
len_b = b->len;
switch(operand) {
case TOK_EQ:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index_ptr(a, 6, i);
+ val_a = g_array_index(a, double, i);
for (j = 0; j < len_b; j++) {
- ptr_b = g_array_index_ptr(b, 6, j);
- if (memcmp(ptr_a, ptr_b, 6) == 0)
+ if (val_a == g_array_index(b, double, j))
return TRUE;
}
}
case TOK_NE:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index_ptr(a, 6, i);
+ val_a = g_array_index(a, double, i);
for (j = 0; j < len_b; j++) {
- ptr_b = g_array_index_ptr(b, 6, j);
- if (memcmp(ptr_a, ptr_b, 6) != 0)
+ if (val_a != g_array_index(b, double, j))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_GT:
+ for(i = 0; i < len_a; i++) {
+ val_a = g_array_index(a, double, i);
+ for (j = 0; j < len_b; j++) {
+ if (val_a > g_array_index(b, double, j))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_GE:
+ for(i = 0; i < len_a; i++) {
+ val_a = g_array_index(a, double, i);
+ for (j = 0; j < len_b; j++) {
+ if (val_a >= g_array_index(b, double, j))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_LT:
+ for(i = 0; i < len_a; i++) {
+ val_a = g_array_index(a, double, i);
+ for (j = 0; j < len_b; j++) {
+ if (val_a < g_array_index(b, double, j))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_LE:
+ for(i = 0; i < len_a; i++) {
+ val_a = g_array_index(a, double, i);
+ for (j = 0; j < len_b; j++) {
+ if (val_a <= g_array_index(b, double, j))
return TRUE;
}
}
return FALSE;
+
+ default:
+ g_assert_not_reached();
}
g_assert_not_reached();
return FALSE;
}
-gboolean check_relation_bytes(gint operand, GArray *a, GArray *b)
+gboolean check_relation_ipv4(gint operand, GArray *a, GArray *b)
{
- int i, j, len_a, len_b;
- GByteArray *ptr_a,*ptr_b;
+ int i, j, len_a, len_b;
+ ipv4_addr *ptr_a, *ptr_b;
len_a = a->len;
len_b = b->len;
switch(operand) {
case TOK_EQ:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index(a, GByteArray*, i);
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), 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)
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (ipv4_addr_eq(ptr_a, ptr_b))
return TRUE;
}
}
case TOK_NE:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index(a, GByteArray*, i);
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), 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)
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (!ipv4_addr_eq(ptr_a, ptr_b))
return TRUE;
}
}
case TOK_GT:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index(a, GByteArray*, i);
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), 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)
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (ipv4_addr_gt(ptr_a, ptr_b))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_GE:
+ for(i = 0; i < len_a; i++) {
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), i);
+ for (j = 0; j < len_b; j++) {
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (ipv4_addr_ge(ptr_a, ptr_b))
return TRUE;
}
}
case TOK_LT:
for(i = 0; i < len_a; i++) {
- ptr_a = g_array_index(a, GByteArray*, i);
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), 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)
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (ipv4_addr_lt(ptr_a, ptr_b))
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_LE:
+ for(i = 0; i < len_a; i++) {
+ ptr_a = (ipv4_addr*) g_array_index_ptr(a, sizeof(ipv4_addr), i);
+ for (j = 0; j < len_b; j++) {
+ ptr_b = (ipv4_addr*) g_array_index_ptr(b, sizeof(ipv4_addr), j);
+ if (ipv4_addr_le(ptr_a, ptr_b))
return TRUE;
}
}
return FALSE;
}
-gboolean check_relation_boolean(gint operand, GArray *a, GArray *b)
+gboolean check_relation_ipv6(gint operand, GArray *a, GArray *b)
{
int i, j, len_a, len_b;
- guint32 val_a;
+ guint8 *ptr_a, *ptr_b;
len_a = a->len;
len_b = b->len;
switch(operand) {
case TOK_EQ:
for(i = 0; i < len_a; i++) {
- val_a = g_array_index(a, guint32, i);
+ ptr_a = g_array_index_ptr(a, 16, i);
for (j = 0; j < len_b; j++) {
- if (val_a == g_array_index(b, guint32, j))
+ ptr_b = g_array_index_ptr(b, 16, j);
+ if (memcmp(ptr_a, ptr_b, 16) == 0)
return TRUE;
}
}
case TOK_NE:
for(i = 0; i < len_a; i++) {
- val_a = g_array_index(a, guint32, i);
+ ptr_a = g_array_index_ptr(a, 16, i);
for (j = 0; j < len_b; j++) {
- if (val_a != g_array_index(b, guint32, j))
+ ptr_b = g_array_index_ptr(b, 16, j);
+ if (memcmp(ptr_a, ptr_b, 16) != 0)
return TRUE;
}
}
return FALSE;
+ }
- default:
- g_assert_not_reached();
+ g_assert_not_reached();
+ return FALSE;
+}
+
+gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
+{
+ int i, j, len_a, len_b;
+ guint8 *ptr_a, *ptr_b;
+
+ len_a = a->len;
+ len_b = b->len;
+
+
+ switch(operand) {
+ case TOK_EQ:
+ for(i = 0; i < len_a; i++) {
+ ptr_a = g_array_index_ptr(a, 6, i);
+ for (j = 0; j < len_b; j++) {
+ ptr_b = g_array_index_ptr(b, 6, j);
+ if (memcmp(ptr_a, ptr_b, 6) == 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_NE:
+ for(i = 0; i < len_a; i++) {
+ ptr_a = g_array_index_ptr(a, 6, i);
+ for (j = 0; j < len_b; j++) {
+ ptr_b = g_array_index_ptr(b, 6, j);
+ if (memcmp(ptr_a, ptr_b, 6) != 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
}
g_assert_not_reached();
return FALSE;
}
+gboolean check_relation_bytes(gint operand, GArray *a, GArray *b)
+{
+ int i, j, len_a, len_b;
+ GByteArray *ptr_a,*ptr_b;
+
+ len_a = a->len;
+ len_b = b->len;
+
+
+ switch(operand) {
+ case TOK_EQ:
+ for(i = 0; i < len_a; i++) {
+ 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)
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_NE:
+ for(i = 0; i < len_a; i++) {
+ 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)
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_GT:
+ for(i = 0; i < len_a; i++) {
+ 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)
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case TOK_LT:
+ for(i = 0; i < len_a; i++) {
+ 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)
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ g_assert_not_reached();
+ return FALSE;
+}