From b2f932c1dbb6180a3b4a86c7510ef4beff814bb0 Mon Sep 17 00:00:00 2001 From: Gilbert Ramirez Date: Sun, 1 Aug 1999 04:28:20 +0000 Subject: Changed the display filter scanner from GLIB's GScanner to lex. The code as it standed depends on your lex being flex, but that only matters if you're a developer. The distribution will include the dfilter-scanner.c file, so that if the user doesn't modify dfilter-scanner.l, he won't need flex to re-create the *.c file. The new lex scanner gives me better syntax checking for ether addresses. I thought I could get by using GScanner, but it simply wasn't powerful enough. All operands have English-like abbreviations and C-like syntax: and, && ; or, || ; eq, == ; ne, != ; , etc. I removed the ETHER_VENDOR type in favor of letting the user use the [x:y] notation: ether.src[0:3] == 0:6:29 instead of ether.srcvendor == 00:06:29 I implemented the IPXNET field type; it had been there before, but was not implemented. I chose to make it use integer values rather than byte ranges, since an IPX Network is 4 bytes. So a display filter looks like this: ipx.srcnet == 0xc0a82c00 rather than this: ipx.srcnet == c0:a8:2c:00 I can supposrt the byte-range type IPXNET in the future, very trivially. I still have more work to do on the parser though. It needs to check ranges when extracting byte ranges ([x:y]) from packets. And I need to get rid of those reduce/reduce errors from yacc! svn path=/trunk/; revision=414 --- dfilter-grammar.y | 251 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 140 insertions(+), 111 deletions(-) (limited to 'dfilter-grammar.y') diff --git a/dfilter-grammar.y b/dfilter-grammar.y index 06d479b891..0e1dd5f461 100644 --- a/dfilter-grammar.y +++ b/dfilter-grammar.y @@ -1,5 +1,30 @@ %{ +/* dfilter-grammar.y + * Parser for display filters + * + * $Id: dfilter-grammar.y,v 1.3 1999/08/01 04:28:06 gram Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -43,13 +68,15 @@ static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, static GNode* dfilter_mknode_unary(int operand, GNode *n2); static GNode* dfilter_mknode_numeric_variable(gint id); static GNode* dfilter_mknode_numeric_value(guint32 val); -static GNode* dfilter_mknode_ether_value(char *a, char *b, char *c, char *d, char *e, char *f); +static GNode* dfilter_mknode_ether_value(guint8*); static GNode* dfilter_mknode_ether_variable(gint id); +static GNode* dfilter_mknode_ipxnet_value(guint32); +static GNode* dfilter_mknode_ipxnet_variable(gint id); static GNode* dfilter_mknode_ipv4_value(char *host); static GNode* dfilter_mknode_ipv4_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, gint length); +static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length); static GNode* dfilter_mknode_boolean_value(gint truth_value); static GNode* dfilter_mknode_boolean_variable(gint id); @@ -73,11 +100,17 @@ GSList *dfilter_list_byte_arrays = NULL; GNode* node; gchar* id; GByteArray* bytes; + guint8 ether[6]; + struct { + gint offset; + guint length; + } byte_range; } %type statement expression relation %type numeric_value numeric_variable %type ether_value ether_variable +%type ipxnet_value ipxnet_variable %type ipv4_value ipv4_variable %type protocol_name %type bytes_value bytes_variable @@ -88,7 +121,6 @@ GSList *dfilter_list_byte_arrays = NULL; %type bytes_relation %type boolean_relation -%type byte_range %type any_variable_type %type exists_operand @@ -101,21 +133,18 @@ GSList *dfilter_list_byte_arrays = NULL; %token T_FT_BYTES %token T_FT_BOOLEAN %token T_FT_STRING +%token T_FT_IPXNET %token T_VAL_ID +%token T_VAL_ETHER +%token T_VAL_BYTES +%token T_VAL_BYTE_RANGE %token TOK_AND TOK_OR TOK_NOT TOK_XOR %token TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE -%token TOK_EXIST TOK_EXISTS +%token TOK_EXIST %token TOK_TRUE TOK_FALSE -%type type_eq -%type type_ne -%type type_gt -%type type_ge -%type type_lt -%type type_le - %left TOK_AND %left TOK_OR %left TOK_XOR @@ -164,6 +193,19 @@ relation: numeric_variable numeric_relation numeric_value $$ = dfilter_mknode_join($1, relation, $2, $3); } + | ipxnet_variable ether_relation ipxnet_value + { + $$ = dfilter_mknode_join($1, relation, $2, $3); + } + | ipxnet_value ether_relation ipxnet_variable + { + $$ = dfilter_mknode_join($1, relation, $2, $3); + } + | ipxnet_variable ether_relation ipxnet_variable + { + $$ = dfilter_mknode_join($1, relation, $2, $3); + } + | ipv4_variable numeric_relation ipv4_value { @@ -216,15 +258,15 @@ numeric_value: T_VAL_ID } ; -ether_value: T_VAL_ID ':' T_VAL_ID ':' T_VAL_ID ':' T_VAL_ID ':' T_VAL_ID ':' T_VAL_ID +ether_value: T_VAL_ETHER { - $$ = dfilter_mknode_ether_value($1, $3, $5, $7, $9, $11); - g_free($1); - g_free($3); - g_free($5); - g_free($7); - g_free($9); - g_free($11); + $$ = dfilter_mknode_ether_value($1); + } + ; + +ipxnet_value: T_VAL_ID + { + $$ = dfilter_mknode_ipxnet_value(string_to_value($1)); } ; @@ -235,47 +277,35 @@ ipv4_value: T_VAL_ID } ; -bytes_value: T_VAL_ID - { - GByteArray *barray = g_byte_array_new(); - guint8 val; - char *endptr; - - dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray); - val = (guint8) strtoul($1, &endptr, 16); - g_byte_array_append(barray, &val, 1); - $$ = dfilter_mknode_bytes_value(barray); - g_free($1); - } - | byte_range { $$ = dfilter_mknode_bytes_value($1); } - ; +bytes_value: T_VAL_BYTES + { /* 2 - 5, or > 6 bytes */ + $$ = dfilter_mknode_bytes_value($1); + } -byte_range: T_VAL_ID ':' T_VAL_ID - { - GByteArray *barray = g_byte_array_new(); - guint8 val; - char *endptr; - - dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray); - val = (guint8) strtoul($1, &endptr, 16); - g_byte_array_append(barray, &val, 1); - val = (guint8) strtoul($3, &endptr, 16); - $$ = g_byte_array_append(barray, &val, 1); - g_free($1); - g_free($3); - } + | T_VAL_ID + { /* one byte */ + GByteArray *barray = g_byte_array_new(); + guint8 val; + char *endptr; - | byte_range ':' T_VAL_ID - { - guint8 val; - char *endptr; + dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray); + val = (guint8) strtoul($1, &endptr, 16); + g_byte_array_append(barray, &val, 1); + $$ = dfilter_mknode_bytes_value(barray); + g_free($1); + } - val = (guint8) strtoul($3, &endptr, 16); - $$ = g_byte_array_append($1, &val, 1); - g_free($3); - } + | T_VAL_ETHER + { /* 6 bytes */ + GByteArray *barray = g_byte_array_new(); + + dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray); + g_byte_array_append(barray, $1, 6); + $$ = dfilter_mknode_bytes_value(barray); + } ; + boolean_value: TOK_TRUE { $$ = dfilter_mknode_boolean_value($1); } | TOK_FALSE { $$ = dfilter_mknode_boolean_value($1); } ; @@ -289,22 +319,18 @@ numeric_variable: T_FT_UINT8 { $$ = dfilter_mknode_numeric_variable($1); } ether_variable: T_FT_ETHER { $$ = dfilter_mknode_ether_variable($1); } ; +ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1); } + ; + ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1); } ; protocol_name: T_FT_NONE { $$ = dfilter_mknode_existence($1); } ; -bytes_variable: any_variable_type '[' T_VAL_ID ':' T_VAL_ID ']' - { - $$ = dfilter_mknode_bytes_variable($1, string_to_value($3), string_to_value($5)); - g_free($3); - g_free($5); - } - | any_variable_type '[' T_VAL_ID ']' +bytes_variable: any_variable_type T_VAL_BYTE_RANGE { - $$ = dfilter_mknode_bytes_variable($1, string_to_value($3), 1); - g_free($3); + $$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length); } ; @@ -322,54 +348,32 @@ any_variable_type: T_FT_UINT8 { $$ = $1; } | T_FT_STRING { $$ = $1; } ; -numeric_relation: type_eq { $$ = $1; } - | type_ne { $$ = $1; } - | type_gt { $$ = $1; } - | type_ge { $$ = $1; } - | type_lt { $$ = $1; } - | type_le { $$ = $1; } +numeric_relation: TOK_EQ { $$ = $1; } + | TOK_NE { $$ = $1; } + | TOK_GT { $$ = $1; } + | TOK_GE { $$ = $1; } + | TOK_LT { $$ = $1; } + | TOK_LE { $$ = $1; } ; -ether_relation: type_eq { $$ = $1; } - | type_ne { $$ = $1; } +ether_relation: TOK_EQ { $$ = $1; } + | TOK_NE { $$ = $1; } ; -bytes_relation: type_eq { $$ = $1; } - | type_ne { $$ = $1; } - | type_gt { $$ = $1; } - | type_lt { $$ = $1; } +bytes_relation: TOK_EQ { $$ = $1; } + | TOK_NE { $$ = $1; } + | TOK_GT { $$ = $1; } + | TOK_LT { $$ = $1; } ; -boolean_relation: type_eq { $$ = $1; } - | type_ne { $$ = $1; } +boolean_relation: TOK_EQ { $$ = $1; } + | TOK_NE { $$ = $1; } ; exists_operand: TOK_EXIST { $$ = $1; } - | TOK_EXISTS { $$ = $1; } | '?' { $$ = TOK_EXIST; } ; -type_eq: TOK_EQ { $$ = $1; } - | '=' '=' { $$ = TOK_EQ; } - ; - -type_ne: TOK_NE { $$ = $1; } - | '!' '=' { $$ = TOK_NE; } - ; - -type_gt: TOK_GT { $$ = $1; } - ; - -type_ge: TOK_GE { $$ = $1; } - ; - -type_lt: TOK_LT { $$ = $1; } - ; - -type_le: TOK_LE { $$ = $1; } - ; - - %% void @@ -479,6 +483,23 @@ dfilter_mknode_ether_variable(gint id) return gnode; } +static GNode* +dfilter_mknode_ipxnet_variable(gint id) +{ + dfilter_node *node; + GNode *gnode; + + node = g_mem_chunk_alloc(gmc_dfilter_nodes); + node->ntype = variable; + node->elem_size = sizeof(guint8) * 4; + node->fill_array_func = fill_array_numeric_variable; /* cheating ! */ + node->check_relation_func = check_relation_numeric; /* cheating ! */ + node->value.variable = id; + gnode = g_node_new(node); + + return gnode; +} + static GNode* dfilter_mknode_ipv4_variable(gint id) { @@ -497,14 +518,13 @@ dfilter_mknode_ipv4_variable(gint id) } static GNode* -dfilter_mknode_bytes_variable(gint id, gint offset, gint length) +dfilter_mknode_bytes_variable(gint id, gint offset, guint length) { dfilter_node *node; GNode *gnode; node = g_mem_chunk_alloc(gmc_dfilter_nodes); node->ntype = variable; - /*node->elem_size = length * sizeof(guint8);*/ node->elem_size = sizeof(GByteArray*); node->fill_array_func = fill_array_bytes_variable; node->check_relation_func = check_relation_bytes; @@ -551,11 +571,10 @@ dfilter_mknode_numeric_value(guint32 val) } static GNode* -dfilter_mknode_ether_value(char *a, char *b, char *c, char *d, char *e, char *f) +dfilter_mknode_ether_value(guint8 *ether_bytes) { dfilter_node *node; GNode *gnode; - char *endptr; node = g_mem_chunk_alloc(gmc_dfilter_nodes); node->ntype = ether; @@ -563,13 +582,24 @@ dfilter_mknode_ether_value(char *a, char *b, char *c, char *d, char *e, char *f) node->fill_array_func = fill_array_ether_value; node->check_relation_func = check_relation_ether; - node->value.ether[0] = (guint8) strtoul(a, &endptr, 16); - node->value.ether[1] = (guint8) strtoul(b, &endptr, 16); - node->value.ether[2] = (guint8) strtoul(c, &endptr, 16); - node->value.ether[3] = (guint8) strtoul(d, &endptr, 16); - node->value.ether[4] = (guint8) strtoul(e, &endptr, 16); - node->value.ether[5] = (guint8) strtoul(f, &endptr, 16); + memcpy(&node->value.ether, ether_bytes, 6); + + gnode = g_node_new(node); + return gnode; +} + +static GNode* +dfilter_mknode_ipxnet_value(guint32 ipx_net_val) +{ + dfilter_node *node; + GNode *gnode; + node = g_mem_chunk_alloc(gmc_dfilter_nodes); + node->ntype = ipxnet; + node->elem_size = sizeof(guint8) * 4; + node->fill_array_func = fill_array_numeric_value; /* cheating ! */ + node->check_relation_func = check_relation_numeric; /* cheating ! */ + node->value.numeric = ipx_net_val; gnode = g_node_new(node); return gnode; @@ -601,7 +631,6 @@ dfilter_mknode_bytes_value(GByteArray *barray) node = g_mem_chunk_alloc(gmc_dfilter_nodes); node->ntype = bytes; - /*node->elem_size = barray->len * sizeof(guint8);*/ node->elem_size = sizeof(GByteArray*); node->fill_array_func = fill_array_bytes_value; node->check_relation_func = check_relation_bytes; -- cgit v1.2.3