aboutsummaryrefslogtreecommitdiffstats
path: root/dfilter-grammar.y
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>1999-08-01 04:28:20 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>1999-08-01 04:28:20 +0000
commitb2f932c1dbb6180a3b4a86c7510ef4beff814bb0 (patch)
tree4b9c007a4f6bbfa27c0c7f9cad2a1e7800c30863 /dfilter-grammar.y
parentc31abd81fa1fa78b0ac19d0b1de3d492a016768c (diff)
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
Diffstat (limited to 'dfilter-grammar.y')
-rw-r--r--dfilter-grammar.y251
1 files changed, 140 insertions, 111 deletions
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 <gerald@zing.org>
+ * 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 <node> statement expression relation
%type <node> numeric_value numeric_variable
%type <node> ether_value ether_variable
+%type <node> ipxnet_value ipxnet_variable
%type <node> ipv4_value ipv4_variable
%type <node> protocol_name
%type <node> bytes_value bytes_variable
@@ -88,7 +121,6 @@ GSList *dfilter_list_byte_arrays = NULL;
%type <operand> bytes_relation
%type <operand> boolean_relation
-%type <bytes> byte_range
%type <variable> any_variable_type
%type <operand> exists_operand
@@ -101,21 +133,18 @@ GSList *dfilter_list_byte_arrays = NULL;
%token <variable> T_FT_BYTES
%token <variable> T_FT_BOOLEAN
%token <variable> T_FT_STRING
+%token <variable> T_FT_IPXNET
%token <id> T_VAL_ID
+%token <ether> T_VAL_ETHER
+%token <bytes> T_VAL_BYTES
+%token <byte_range> T_VAL_BYTE_RANGE
%token <operand> TOK_AND TOK_OR TOK_NOT TOK_XOR
%token <operand> TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
-%token <operand> TOK_EXIST TOK_EXISTS
+%token <operand> TOK_EXIST
%token <operand> TOK_TRUE TOK_FALSE
-%type <operand> type_eq
-%type <operand> type_ne
-%type <operand> type_gt
-%type <operand> type_ge
-%type <operand> type_lt
-%type <operand> 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
@@ -480,6 +484,23 @@ dfilter_mknode_ether_variable(gint id)
}
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)
{
dfilter_node *node;
@@ -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;