1999-07-07 22:52:57 +00:00
|
|
|
%{
|
|
|
|
|
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
1999-08-01 04:28:20 +00:00
|
|
|
/* dfilter-grammar.y
|
|
|
|
* Parser for display filters
|
|
|
|
*
|
1999-11-15 06:32:38 +00:00
|
|
|
* $Id: dfilter-grammar.y,v 1.37 1999/11/15 06:32:11 gram Exp $
|
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
1999-08-01 04:28:20 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
1999-08-20 20:45:14 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# ifdef HAVE_STDARG_H
|
|
|
|
# include <stdarg.h>
|
|
|
|
# else
|
|
|
|
# include <varargs.h>
|
|
|
|
# endif
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
#ifndef __GLIB_H__
|
|
|
|
#include <glib.h>
|
|
|
|
#endif
|
|
|
|
|
1999-08-14 06:24:27 +00:00
|
|
|
#include <string.h>
|
1999-10-19 05:31:14 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <math.h>
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
#ifndef _STDLIB_H
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __PROTO_H__
|
|
|
|
#include "proto.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __PACKET_H__
|
|
|
|
#include "packet.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __DFILTER_H__
|
|
|
|
#include "dfilter.h"
|
|
|
|
#endif
|
|
|
|
|
1999-08-12 21:16:32 +00:00
|
|
|
#include "dfilter-int.h"
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
#ifndef __RESOLV_H__
|
|
|
|
#include "resolv.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2);
|
|
|
|
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);
|
1999-10-19 05:31:14 +00:00
|
|
|
static GNode* dfilter_mknode_floating_variable(gint id);
|
|
|
|
static GNode* dfilter_mknode_floating_value(double val);
|
1999-08-20 06:01:07 +00:00
|
|
|
static GNode* dfilter_mknode_ether_value(gchar*);
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode* dfilter_mknode_ether_variable(gint id);
|
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
1999-08-01 04:28:20 +00:00
|
|
|
static GNode* dfilter_mknode_ipxnet_value(guint32);
|
|
|
|
static GNode* dfilter_mknode_ipxnet_variable(gint id);
|
1999-11-15 06:32:38 +00:00
|
|
|
static GNode* dfilter_mknode_ipv4_value(char *host, int nmask_bits);
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode* dfilter_mknode_ipv4_variable(gint id);
|
1999-10-11 17:05:49 +00:00
|
|
|
static GNode* dfilter_mknode_ipv6_value(char *host);
|
|
|
|
static GNode* dfilter_mknode_ipv6_variable(gint id);
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode* dfilter_mknode_existence(gint id);
|
|
|
|
static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
|
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
1999-08-01 04:28:20 +00:00
|
|
|
static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
static guint32 string_to_guint32(char *s, gboolean *success);
|
|
|
|
static double string_to_double(char *s, gboolean *success);
|
1999-08-20 06:01:07 +00:00
|
|
|
static int ether_str_to_guint8_array(const char *s, guint8 *mac);
|
1999-10-12 04:21:13 +00:00
|
|
|
static guint dfilter_get_bytes_variable_offset(GNode *gnode);
|
|
|
|
static guint dfilter_get_bytes_value_length(GNode* gnode);
|
|
|
|
static void dfilter_set_bytes_variable_length(GNode *gnode, guint length);
|
|
|
|
static guint dfilter_get_bytes_variable_length(GNode *gnode);
|
|
|
|
static gint dfilter_get_bytes_variable_field_registered_length(GNode *gnode);
|
|
|
|
static char* dfilter_get_variable_abbrev(GNode *gnode);
|
|
|
|
static int check_bytes_variable_sanity(GNode *gnode);
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
/* This is the dfilter we're currently processing. It's how
|
|
|
|
* dfilter_compile communicates with us.
|
|
|
|
*/
|
1999-10-11 06:39:26 +00:00
|
|
|
dfilter *global_df = NULL;
|
1999-08-26 06:20:50 +00:00
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
%}
|
|
|
|
|
|
|
|
%union {
|
|
|
|
gint operand; /* logical, relation, alternation */
|
1999-09-15 06:13:21 +00:00
|
|
|
struct {
|
|
|
|
gint id;
|
|
|
|
gint type; /* using macros defined below, in this yacc grammar */
|
|
|
|
} variable;
|
1999-07-07 22:52:57 +00:00
|
|
|
GNode* node;
|
1999-08-20 06:01:07 +00:00
|
|
|
gchar* string;
|
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
1999-08-01 04:28:20 +00:00
|
|
|
struct {
|
|
|
|
gint offset;
|
|
|
|
guint length;
|
|
|
|
} byte_range;
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
%type <node> statement expression relation
|
|
|
|
%type <node> numeric_value numeric_variable
|
1999-10-19 05:31:14 +00:00
|
|
|
%type <node> floating_value floating_variable
|
1999-07-07 22:52:57 +00:00
|
|
|
%type <node> ether_value ether_variable
|
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
1999-08-01 04:28:20 +00:00
|
|
|
%type <node> ipxnet_value ipxnet_variable
|
1999-07-07 22:52:57 +00:00
|
|
|
%type <node> ipv4_value ipv4_variable
|
1999-10-11 17:05:49 +00:00
|
|
|
%type <node> ipv6_value ipv6_variable
|
1999-08-03 15:04:33 +00:00
|
|
|
%type <node> variable_name
|
1999-07-07 22:52:57 +00:00
|
|
|
%type <node> bytes_value bytes_variable
|
|
|
|
|
|
|
|
%type <operand> numeric_relation
|
1999-08-02 06:34:23 +00:00
|
|
|
%type <operand> equality_relation
|
1999-07-07 22:52:57 +00:00
|
|
|
%type <operand> bytes_relation
|
|
|
|
|
|
|
|
%type <variable> any_variable_type
|
|
|
|
|
|
|
|
%token <variable> T_FT_UINT8
|
|
|
|
%token <variable> T_FT_UINT16
|
|
|
|
%token <variable> T_FT_UINT32
|
1999-10-12 06:21:15 +00:00
|
|
|
%token <variable> T_FT_INT8
|
|
|
|
%token <variable> T_FT_INT16
|
|
|
|
%token <variable> T_FT_INT32
|
1999-07-07 22:52:57 +00:00
|
|
|
%token <variable> T_FT_ETHER
|
|
|
|
%token <variable> T_FT_IPv4
|
1999-10-11 17:05:49 +00:00
|
|
|
%token <variable> T_FT_IPv6
|
1999-07-07 22:52:57 +00:00
|
|
|
%token <variable> T_FT_NONE
|
|
|
|
%token <variable> T_FT_BYTES
|
|
|
|
%token <variable> T_FT_BOOLEAN
|
|
|
|
%token <variable> T_FT_STRING
|
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
1999-08-01 04:28:20 +00:00
|
|
|
%token <variable> T_FT_IPXNET
|
1999-10-19 05:31:14 +00:00
|
|
|
%token <variable> T_FT_DOUBLE
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
%token <string> T_VAL_UNQUOTED_STRING
|
|
|
|
%token <string> T_VAL_BYTE_STRING
|
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
1999-08-01 04:28:20 +00:00
|
|
|
%token <byte_range> T_VAL_BYTE_RANGE
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
%token <operand> TOK_AND TOK_OR TOK_NOT TOK_XOR
|
|
|
|
%token <operand> TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
|
|
|
|
|
1999-10-14 08:05:51 +00:00
|
|
|
%expect 4
|
1999-07-07 22:52:57 +00:00
|
|
|
%left TOK_AND
|
1999-10-12 05:21:07 +00:00
|
|
|
%left TOK_OR TOK_XOR
|
1999-07-07 22:52:57 +00:00
|
|
|
%nonassoc TOK_NOT
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
statement: expression
|
|
|
|
{
|
1999-08-13 23:47:43 +00:00
|
|
|
global_df->dftree = $1;
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
Make "dfilter_error()" available to the lexical analyzer.
Get rid of the declaration of the non-existent "dfilter_yyerror()", and
put in some #defines to work around the fact that the #defines to
replace "yy" with "dfilter_" in the names of Flex-generated and
Yacc-generated routines aren't put into a header file, they're put into
".c" files.
Have it remember the error message it was handed (unless it's Yacc's
boring "parse error" message).
When generating the message to be shown to the user on a parse error,
make it be the "Unable to parse filter string" message, and, if a
non-boring error message was supplied to "dfilter_error()", take that
error message onto the end.
Don't panic if a field type we don't yet support in the parser is seen;
generate an error, telling the user we don't support filter on that type
yet.
Don't assume that "global_df" has been set if we see an empty statement
(if the first token was the end-marker, because, say, the first token
the lexical analyzer found was a field of a type not yet supported in
filter expressions, "global_df" won't have been set).
svn path=/trunk/; revision=783
1999-10-07 21:47:20 +00:00
|
|
|
| /* NULL */ { if (global_df != NULL) global_df->dftree = NULL; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
expression: '(' expression ')' { $$ = $2; }
|
|
|
|
| expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
|
|
|
|
| expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
|
1999-08-03 15:04:33 +00:00
|
|
|
| expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
|
1999-07-07 22:52:57 +00:00
|
|
|
| TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
|
|
|
|
| relation { $$ = $1; }
|
1999-08-03 15:04:33 +00:00
|
|
|
| variable_name { $$ = $1; }
|
1999-09-29 22:11:51 +00:00
|
|
|
| expression error { YYABORT; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
relation: numeric_variable numeric_relation numeric_value
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
| numeric_variable numeric_relation numeric_variable
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
| floating_variable numeric_relation floating_value
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
| floating_variable numeric_relation floating_variable
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-08-02 06:34:23 +00:00
|
|
|
| ether_variable equality_relation ether_value
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
1999-08-02 06:34:23 +00:00
|
|
|
| ether_variable equality_relation ether_variable
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-08-02 06:34:23 +00:00
|
|
|
| ipxnet_variable equality_relation ipxnet_value
|
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
1999-08-01 04:28:20 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
1999-08-02 06:34:23 +00:00
|
|
|
| ipxnet_variable equality_relation ipxnet_variable
|
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
1999-08-01 04:28:20 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
| ipv4_variable numeric_relation ipv4_value
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
| ipv4_variable numeric_relation ipv4_variable
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-10-11 17:05:49 +00:00
|
|
|
| ipv6_variable equality_relation ipv6_value
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
| ipv6_variable equality_relation ipv6_variable
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
| bytes_variable bytes_relation bytes_value
|
|
|
|
{
|
1999-10-12 04:21:13 +00:00
|
|
|
int a_len, b_len;
|
|
|
|
|
|
|
|
a_len = dfilter_get_bytes_variable_length($1);
|
|
|
|
b_len = dfilter_get_bytes_value_length($3);
|
|
|
|
|
|
|
|
if (a_len == 0) {
|
|
|
|
dfilter_set_bytes_variable_length($1, b_len);
|
|
|
|
a_len = b_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!check_bytes_variable_sanity($1)) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (a_len != b_len) {
|
|
|
|
dfilter_fail("Field \"%s\" has %u byte%s being compared, but %u byte%s "
|
1999-10-13 06:01:04 +00:00
|
|
|
"%s supplied.",
|
1999-10-12 04:21:13 +00:00
|
|
|
dfilter_get_variable_abbrev($1),
|
|
|
|
a_len, plurality(a_len, "", "s"),
|
1999-10-13 06:01:04 +00:00
|
|
|
b_len, plurality(b_len, "", "s"),
|
|
|
|
plurality(b_len, "was", "were"));
|
1999-10-12 04:21:13 +00:00
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
| bytes_variable bytes_relation bytes_variable
|
|
|
|
{
|
1999-10-12 04:21:13 +00:00
|
|
|
int a_len, b_len;
|
|
|
|
|
|
|
|
a_len = dfilter_get_bytes_variable_length($1);
|
|
|
|
b_len = dfilter_get_bytes_variable_length($3);
|
|
|
|
|
|
|
|
if (!check_bytes_variable_sanity($1)) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!check_bytes_variable_sanity($3)) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (a_len != b_len) {
|
|
|
|
dfilter_fail("Fields \"%s\" and \"%s\" are being compared with "
|
|
|
|
"disparate lengths of %u byte%s and %u byte%s.",
|
|
|
|
dfilter_get_variable_abbrev($1),
|
|
|
|
dfilter_get_variable_abbrev($3),
|
|
|
|
a_len, plurality(a_len, "", "s"),
|
|
|
|
b_len, plurality(b_len, "", "s"));
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
$$ = dfilter_mknode_join($1, relation, $2, $3);
|
|
|
|
}
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
1999-10-17 20:54:56 +00:00
|
|
|
numeric_value: T_VAL_UNQUOTED_STRING
|
1999-07-08 03:05:55 +00:00
|
|
|
{
|
1999-10-19 05:31:14 +00:00
|
|
|
gboolean success;
|
|
|
|
$$ = dfilter_mknode_numeric_value(string_to_guint32($1, &success));
|
1999-07-08 03:05:55 +00:00
|
|
|
g_free($1);
|
1999-10-19 05:31:14 +00:00
|
|
|
if (!success) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
1999-07-08 03:05:55 +00:00
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
ether_value: T_VAL_BYTE_STRING
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_ether_value($1);
|
|
|
|
g_free($1);
|
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
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
1999-08-01 04:28:20 +00:00
|
|
|
}
|
1999-08-20 06:01:07 +00:00
|
|
|
}
|
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
1999-08-01 04:28:20 +00:00
|
|
|
;
|
|
|
|
|
1999-10-17 20:54:56 +00:00
|
|
|
ipxnet_value: T_VAL_UNQUOTED_STRING
|
1999-07-08 03:05:55 +00:00
|
|
|
{
|
1999-10-19 05:31:14 +00:00
|
|
|
gboolean success;
|
|
|
|
$$ = dfilter_mknode_ipxnet_value(string_to_guint32($1, &success));
|
|
|
|
g_free($1);
|
|
|
|
if (!success) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
floating_value: T_VAL_UNQUOTED_STRING
|
|
|
|
{
|
|
|
|
gboolean success;
|
|
|
|
$$ = dfilter_mknode_floating_value(string_to_double($1, &success));
|
|
|
|
g_free($1);
|
|
|
|
if (!success) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
| T_VAL_BYTE_STRING
|
|
|
|
{
|
|
|
|
/* e.g., 0.0, 0.1, 0.01 ... */
|
|
|
|
gboolean success;
|
|
|
|
$$ = dfilter_mknode_floating_value(string_to_double($1, &success));
|
1999-07-08 03:05:55 +00:00
|
|
|
g_free($1);
|
1999-10-19 05:31:14 +00:00
|
|
|
if (!success) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
1999-07-08 03:05:55 +00:00
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
ipv4_value: T_VAL_UNQUOTED_STRING
|
1999-11-15 06:32:38 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_ipv4_value($1, 32);
|
|
|
|
g_free($1);
|
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
1999-08-20 06:01:07 +00:00
|
|
|
}
|
1999-11-15 06:32:38 +00:00
|
|
|
}
|
1999-08-20 06:01:07 +00:00
|
|
|
|
|
|
|
| T_VAL_BYTE_STRING
|
1999-11-15 06:32:38 +00:00
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_ipv4_value($1, 32);
|
|
|
|
g_free($1);
|
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
| T_VAL_UNQUOTED_STRING '/' T_VAL_UNQUOTED_STRING
|
|
|
|
{
|
|
|
|
gboolean success;
|
|
|
|
guint32 nmask_bits;
|
|
|
|
|
|
|
|
nmask_bits = string_to_guint32($3, &success);
|
|
|
|
if (!success) {
|
1999-08-20 06:01:07 +00:00
|
|
|
g_free($1);
|
1999-11-15 06:32:38 +00:00
|
|
|
g_free($3);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nmask_bits > 32) {
|
|
|
|
dfilter_fail("The number of netmask bits in \"%s/%s\" should "
|
|
|
|
"be between 0 and 32.", $1, $3);
|
|
|
|
g_free($1);
|
|
|
|
g_free($3);
|
|
|
|
YYERROR;
|
1999-08-20 06:01:07 +00:00
|
|
|
}
|
1999-11-15 06:32:38 +00:00
|
|
|
|
|
|
|
$$ = dfilter_mknode_ipv4_value($1, nmask_bits);
|
|
|
|
g_free($1);
|
|
|
|
g_free($3);
|
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
| T_VAL_BYTE_STRING '/' T_VAL_UNQUOTED_STRING
|
|
|
|
{
|
|
|
|
gboolean success;
|
|
|
|
guint32 nmask_bits;
|
|
|
|
|
|
|
|
nmask_bits = string_to_guint32($3, &success);
|
|
|
|
if (!success) {
|
|
|
|
g_free($1);
|
|
|
|
g_free($3);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nmask_bits > 32) {
|
|
|
|
dfilter_fail("The number of netmask bits in \"%s/%s\" should "
|
|
|
|
"be between 0 and 32.", $1, $3);
|
|
|
|
g_free($1);
|
|
|
|
g_free($3);
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
$$ = dfilter_mknode_ipv4_value($1, nmask_bits);
|
|
|
|
g_free($1);
|
|
|
|
g_free($3);
|
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
}
|
1999-08-20 06:01:07 +00:00
|
|
|
;
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-10-11 17:05:49 +00:00
|
|
|
ipv6_value: T_VAL_UNQUOTED_STRING
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_ipv6_value($1);
|
|
|
|
g_free($1);
|
1999-10-11 19:39:29 +00:00
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
1999-10-11 17:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
| T_VAL_BYTE_STRING
|
|
|
|
{
|
|
|
|
$$ = dfilter_mknode_ipv6_value($1);
|
|
|
|
g_free($1);
|
1999-10-11 19:39:29 +00:00
|
|
|
if ($$ == NULL) {
|
|
|
|
YYERROR;
|
|
|
|
}
|
1999-10-11 17:05:49 +00:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
bytes_value: T_VAL_BYTE_STRING
|
|
|
|
{
|
1999-08-12 15:10:48 +00:00
|
|
|
GByteArray *barray;
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
/* the next function appends to list_of_byte_arrays for me */
|
1999-08-12 15:10:48 +00:00
|
|
|
barray = byte_str_to_guint8_array($1);
|
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
1999-08-01 04:28:20 +00:00
|
|
|
$$ = dfilter_mknode_bytes_value(barray);
|
|
|
|
g_free($1);
|
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-10-17 20:54:56 +00:00
|
|
|
| T_VAL_UNQUOTED_STRING
|
1999-10-12 04:21:13 +00:00
|
|
|
{
|
1999-10-19 05:31:14 +00:00
|
|
|
gboolean success;
|
|
|
|
guint32 val32;
|
1999-10-12 04:21:13 +00:00
|
|
|
guint8 val8;
|
|
|
|
GByteArray *barray;
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
val32 = string_to_guint32($1, &success);
|
|
|
|
if (!success) {
|
|
|
|
g_free($1);
|
|
|
|
YYERROR;
|
|
|
|
}
|
1999-10-12 04:21:13 +00:00
|
|
|
if (val32 > 0xff) {
|
|
|
|
dfilter_fail("The value \"%s\" cannot be stored in a single-byte byte-string. "
|
|
|
|
"Use the multi-byte \"xx:yy\" representation.", $1);
|
1999-10-19 05:31:14 +00:00
|
|
|
g_free($1);
|
1999-10-12 04:21:13 +00:00
|
|
|
YYERROR;
|
|
|
|
}
|
|
|
|
val8 = (guint8) val32;
|
|
|
|
barray = g_byte_array_new();
|
|
|
|
global_df->list_of_byte_arrays = g_slist_append(global_df->list_of_byte_arrays, barray);
|
|
|
|
g_byte_array_append(barray, &val8, 1);
|
|
|
|
|
|
|
|
$$ = dfilter_mknode_bytes_value(barray);
|
|
|
|
g_free($1);
|
|
|
|
}
|
|
|
|
;
|
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
1999-08-01 04:28:20 +00:00
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
numeric_variable: T_FT_UINT8 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
|
|
|
| T_FT_UINT16 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
|
|
|
| T_FT_UINT32 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
1999-10-12 06:21:15 +00:00
|
|
|
| T_FT_INT8 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
|
|
|
| T_FT_INT16 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
|
|
|
| T_FT_INT32 { $$ = dfilter_mknode_numeric_variable($1.id); }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
ether_variable: T_FT_ETHER { $$ = dfilter_mknode_ether_variable($1.id); }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
floating_variable: T_FT_DOUBLE { $$ = dfilter_mknode_floating_variable($1.id); }
|
|
|
|
;
|
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1.id); }
|
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
1999-08-01 04:28:20 +00:00
|
|
|
;
|
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1.id); }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-10-11 17:05:49 +00:00
|
|
|
ipv6_variable: T_FT_IPv6 { $$ = dfilter_mknode_ipv6_variable($1.id); }
|
|
|
|
;
|
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
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);
|
|
|
|
value = dfilter_mknode_numeric_value(TRUE);
|
|
|
|
$$ = dfilter_mknode_join(variable, relation, TOK_EQ, value);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$$ = dfilter_mknode_existence($1.id);
|
|
|
|
}
|
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
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
1999-08-01 04:28:20 +00:00
|
|
|
bytes_variable: any_variable_type T_VAL_BYTE_RANGE
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
1999-09-15 06:13:21 +00:00
|
|
|
$$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length);
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
any_variable_type: T_FT_UINT8 { $$ = $1; }
|
|
|
|
| T_FT_UINT16 { $$ = $1; }
|
|
|
|
| T_FT_UINT32 { $$ = $1; }
|
|
|
|
| T_FT_INT8 { $$ = $1; }
|
|
|
|
| T_FT_INT16 { $$ = $1; }
|
|
|
|
| T_FT_INT32 { $$ = $1; }
|
|
|
|
| T_FT_DOUBLE { $$ = $1; }
|
|
|
|
| T_FT_ETHER { $$ = $1; }
|
|
|
|
| T_FT_IPv4 { $$ = $1; }
|
|
|
|
| T_FT_IPv6 { $$ = $1; }
|
|
|
|
| T_FT_IPXNET { $$ = $1; }
|
|
|
|
| T_FT_NONE { $$ = $1; }
|
|
|
|
| T_FT_BYTES { $$ = $1; }
|
|
|
|
| T_FT_BOOLEAN { $$ = $1; }
|
|
|
|
| T_FT_STRING { $$ = $1; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-08-03 15:04:33 +00:00
|
|
|
numeric_relation: TOK_EQ { $$ = TOK_EQ; }
|
|
|
|
| TOK_NE { $$ = TOK_NE; }
|
|
|
|
| TOK_GT { $$ = TOK_GT; }
|
|
|
|
| TOK_GE { $$ = TOK_GE; }
|
|
|
|
| TOK_LT { $$ = TOK_LT; }
|
|
|
|
| TOK_LE { $$ = TOK_LE; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-08-03 15:04:33 +00:00
|
|
|
equality_relation: TOK_EQ { $$ = TOK_EQ; }
|
|
|
|
| TOK_NE { $$ = TOK_NE; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
1999-08-03 15:04:33 +00:00
|
|
|
bytes_relation: TOK_EQ { $$ = TOK_EQ; }
|
|
|
|
| TOK_NE { $$ = TOK_NE; }
|
|
|
|
| TOK_GT { $$ = TOK_GT; }
|
|
|
|
| TOK_LT { $$ = TOK_LT; }
|
1999-07-07 22:52:57 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
|
|
|
|
{
|
|
|
|
dfilter_node *node_root;
|
|
|
|
GNode *gnode_root;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node_root = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node_root->ntype = ntype;
|
|
|
|
node_root->elem_size = 0;
|
|
|
|
node_root->fill_array_func = NULL;
|
|
|
|
node_root->check_relation_func = NULL;
|
|
|
|
if (ntype == relation) {
|
|
|
|
node_root->value.relation = operand;
|
|
|
|
}
|
|
|
|
else if (ntype == logical) {
|
|
|
|
node_root->value.logical = operand;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
gnode_root = g_node_new(node_root);
|
|
|
|
g_node_append(gnode_root, n1);
|
|
|
|
g_node_append(gnode_root, n2);
|
|
|
|
|
|
|
|
return gnode_root;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_unary(int operand, GNode *n2)
|
|
|
|
{
|
|
|
|
dfilter_node *node_root;
|
|
|
|
GNode *gnode_root;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node_root = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node_root->ntype = logical;
|
|
|
|
node_root->value.logical = operand;
|
|
|
|
node_root->elem_size = 0;
|
|
|
|
node_root->fill_array_func = NULL;
|
|
|
|
node_root->check_relation_func = NULL;
|
|
|
|
|
|
|
|
gnode_root = g_node_new(node_root);
|
|
|
|
g_node_append(gnode_root, n2);
|
|
|
|
|
|
|
|
return gnode_root;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_numeric_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = variable;
|
|
|
|
node->elem_size = sizeof(guint32);
|
|
|
|
node->fill_array_func = fill_array_numeric_variable;
|
|
|
|
node->check_relation_func = check_relation_numeric;
|
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ether_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = variable;
|
|
|
|
node->elem_size = sizeof(guint8) * 6;
|
|
|
|
node->fill_array_func = fill_array_ether_variable;
|
|
|
|
node->check_relation_func = check_relation_ether;
|
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_floating_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
|
|
|
node->ntype = variable;
|
|
|
|
node->elem_size = sizeof(double);
|
|
|
|
node->fill_array_func = fill_array_floating_variable;
|
|
|
|
node->check_relation_func = check_relation_floating;
|
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
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
1999-08-01 04:28:20 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ipxnet_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
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
1999-08-01 04:28:20 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ipv4_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = variable;
|
1999-11-15 06:32:38 +00:00
|
|
|
node->elem_size = sizeof(ipv4_addr);
|
|
|
|
node->fill_array_func = fill_array_ipv4_variable;
|
|
|
|
node->check_relation_func = check_relation_ipv4;
|
1999-07-07 22:52:57 +00:00
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-11 17:05:49 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ipv6_variable(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
|
|
|
node->ntype = variable;
|
1999-10-15 20:46:02 +00:00
|
|
|
node->elem_size = 16;
|
1999-10-11 17:05:49 +00:00
|
|
|
node->fill_array_func = fill_array_ipv6_variable;
|
|
|
|
node->check_relation_func = check_relation_ipv6;
|
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
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
1999-08-01 04:28:20 +00:00
|
|
|
dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = variable;
|
|
|
|
node->elem_size = sizeof(GByteArray*);
|
|
|
|
node->fill_array_func = fill_array_bytes_variable;
|
|
|
|
node->check_relation_func = check_relation_bytes;
|
|
|
|
node->value.variable = id;
|
|
|
|
node->offset = offset;
|
|
|
|
node->length = length;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-12 04:21:13 +00:00
|
|
|
/* Gets length of variable represented by node from proto_register */
|
|
|
|
static gint
|
|
|
|
dfilter_get_bytes_variable_field_registered_length(GNode *gnode)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
/* Is this really a bytes_variable? */
|
|
|
|
g_assert(node->fill_array_func = fill_array_bytes_variable);
|
|
|
|
|
|
|
|
return proto_registrar_get_length(node->value.variable);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sets the length of a bytes_variable node */
|
|
|
|
static void
|
|
|
|
dfilter_set_bytes_variable_length(GNode *gnode, guint length)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
/* Is this really a bytes_variable? */
|
|
|
|
g_assert(node->fill_array_func = fill_array_bytes_variable);
|
|
|
|
|
|
|
|
node->length = length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Gets the length of a bytes_variable node */
|
|
|
|
static guint
|
|
|
|
dfilter_get_bytes_variable_length(GNode *gnode)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
/* Is this really a bytes_variable? */
|
|
|
|
g_assert(node->fill_array_func = fill_array_bytes_variable);
|
|
|
|
|
|
|
|
return node->length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Gets the offset of a bytes_variable node */
|
|
|
|
static guint
|
|
|
|
dfilter_get_bytes_variable_offset(GNode *gnode)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
/* Is this really a bytes_variable? */
|
|
|
|
g_assert(node->fill_array_func = fill_array_bytes_variable);
|
|
|
|
|
|
|
|
return node->offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
dfilter_get_variable_abbrev(GNode *gnode)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
return proto_registrar_get_abbrev(node->value.variable);
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_numeric_value(guint32 val)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = numeric;
|
|
|
|
node->elem_size = sizeof(guint32);
|
|
|
|
node->fill_array_func = fill_array_numeric_value;
|
|
|
|
node->check_relation_func = check_relation_numeric;
|
|
|
|
node->value.numeric = val;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-19 05:31:14 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_floating_value(double val)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
|
|
|
node->ntype = floating;
|
|
|
|
node->elem_size = sizeof(double);
|
|
|
|
node->fill_array_func = fill_array_floating_value;
|
|
|
|
node->check_relation_func = check_relation_floating;
|
|
|
|
node->value.floating = val;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
/* Returns NULL on bad parse of ETHER value */
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
1999-08-20 06:01:07 +00:00
|
|
|
dfilter_mknode_ether_value(gchar *byte_string)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = ether;
|
|
|
|
node->elem_size = sizeof(guint8) * 6;
|
|
|
|
node->fill_array_func = fill_array_ether_value;
|
|
|
|
node->check_relation_func = check_relation_ether;
|
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
|
|
|
|
/* Rather than free the mem_chunk allocation, let it
|
1999-10-11 19:39:29 +00:00
|
|
|
* stay. It will be cleaned up when "dfilter_compile()"
|
|
|
|
* calls "dfilter_destroy()". */
|
|
|
|
dfilter_fail("\"%s\" is not a valid hardware address.",
|
|
|
|
byte_string);
|
1999-08-20 06:01:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
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
1999-08-01 04:28:20 +00:00
|
|
|
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
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
1999-08-01 04:28:20 +00:00
|
|
|
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;
|
1999-07-07 22:52:57 +00:00
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-11 19:39:29 +00:00
|
|
|
/* Returns NULL on bad parse of IP value */
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
1999-11-15 06:32:38 +00:00
|
|
|
dfilter_mknode_ipv4_value(char *host, int nmask_bits)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
1999-11-15 06:32:38 +00:00
|
|
|
guint32 addr;
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = numeric;
|
1999-11-15 06:32:38 +00:00
|
|
|
node->elem_size = sizeof(ipv4_addr);
|
|
|
|
node->fill_array_func = fill_array_ipv4_value;
|
|
|
|
node->check_relation_func = check_relation_ipv4;
|
|
|
|
if (!get_host_ipaddr(host, &addr)) {
|
1999-10-11 19:39:29 +00:00
|
|
|
/* Rather than free the mem_chunk allocation, let it
|
|
|
|
* stay. It will be cleaned up when "dfilter_compile()"
|
|
|
|
* calls "dfilter_destroy()". */
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
dfilter_fail("\"%s\" isn't a valid host name or IP address.",
|
|
|
|
host);
|
1999-10-11 19:39:29 +00:00
|
|
|
return NULL;
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
}
|
1999-11-15 06:32:38 +00:00
|
|
|
ipv4_addr_set_host_order_addr(&node->value.ipv4, addr);
|
|
|
|
ipv4_addr_set_netmask_bits(&node->value.ipv4, nmask_bits);
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-10-11 19:39:29 +00:00
|
|
|
gnode = g_node_new(node);
|
1999-07-07 22:52:57 +00:00
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-11 19:39:29 +00:00
|
|
|
/* Returns NULL on bad parse of IPv6 value */
|
1999-10-11 17:05:49 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_ipv6_value(char *host)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
|
|
|
node->ntype = ipv6;
|
1999-10-15 20:46:02 +00:00
|
|
|
node->elem_size = 16;
|
1999-10-11 17:05:49 +00:00
|
|
|
node->fill_array_func = fill_array_ipv6_value;
|
|
|
|
node->check_relation_func = check_relation_ipv6;
|
|
|
|
|
1999-10-15 20:46:02 +00:00
|
|
|
if (!get_host_ipaddr6(host, (struct e_in6_addr*)&node->value.ipv6[0])) {
|
1999-10-11 19:39:29 +00:00
|
|
|
/* Rather than free the mem_chunk allocation, let it
|
|
|
|
* stay. It will be cleaned up when "dfilter_compile()"
|
|
|
|
* calls "dfilter_destroy()". */
|
|
|
|
dfilter_fail("\"%s\" isn't a valid IPv6 address.",
|
|
|
|
host);
|
|
|
|
return NULL;
|
1999-10-11 17:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_bytes_value(GByteArray *barray)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = bytes;
|
|
|
|
node->elem_size = sizeof(GByteArray*);
|
|
|
|
node->fill_array_func = fill_array_bytes_value;
|
|
|
|
node->check_relation_func = check_relation_bytes;
|
|
|
|
node->value.bytes = barray;
|
|
|
|
node->offset = G_MAXINT;
|
|
|
|
node->length = barray->len;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
|
|
|
|
1999-10-12 04:21:13 +00:00
|
|
|
/* Given a node representing a bytes_value, returns
|
|
|
|
* the length of the byte array */
|
|
|
|
static guint
|
|
|
|
dfilter_get_bytes_value_length(GNode* gnode)
|
|
|
|
{
|
|
|
|
dfilter_node *node = gnode->data;
|
|
|
|
|
|
|
|
g_assert(node->ntype == bytes);
|
|
|
|
return node->length;
|
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static guint32
|
1999-10-19 05:31:14 +00:00
|
|
|
string_to_guint32(char *s, gboolean *success)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
|
|
|
char *endptr;
|
|
|
|
guint32 val;
|
|
|
|
|
|
|
|
val = strtoul(s, &endptr, 0);
|
1999-10-19 05:31:14 +00:00
|
|
|
*success = TRUE;
|
1999-10-12 05:13:32 +00:00
|
|
|
if (endptr == s || *endptr != '\0') {
|
|
|
|
/* This isn't a valid number. */
|
|
|
|
dfilter_fail("\"%s\" is not a valid number.", s);
|
1999-10-19 05:31:14 +00:00
|
|
|
*success = FALSE;
|
|
|
|
}
|
|
|
|
if (errno == ERANGE) {
|
|
|
|
*success = FALSE;
|
|
|
|
if (val == ULONG_MAX) {
|
|
|
|
dfilter_fail("\"%s\" causes an integer overflow.", s);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dfilter_fail("\"%s\" is not an integer.", s);
|
|
|
|
}
|
1999-10-12 05:13:32 +00:00
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
return (guint32)val;
|
|
|
|
}
|
1999-10-19 05:31:14 +00:00
|
|
|
|
|
|
|
static double
|
|
|
|
string_to_double(char *s, gboolean *success)
|
|
|
|
{
|
|
|
|
char *endptr = NULL;
|
|
|
|
double retval;
|
|
|
|
|
|
|
|
retval = strtod(s, &endptr);
|
|
|
|
*success = TRUE;
|
|
|
|
|
|
|
|
if (endptr == s) {
|
|
|
|
dfilter_fail("\"%s\" is not a valid floating-point number.", s);
|
|
|
|
*success = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (errno == ERANGE) {
|
|
|
|
*success = FALSE;
|
|
|
|
if (retval == 0) {
|
|
|
|
dfilter_fail("\"%s\" causes a floating-point underflow.", s);
|
|
|
|
}
|
|
|
|
else if (retval == HUGE_VAL) {
|
|
|
|
dfilter_fail("\"%s\" causes a floating-point overflow.", s);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dfilter_fail("\"%s\" is not a valid floating-point.", s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
static GNode*
|
|
|
|
dfilter_mknode_existence(gint id)
|
|
|
|
{
|
|
|
|
dfilter_node *node;
|
|
|
|
GNode *gnode;
|
|
|
|
|
1999-08-13 23:47:43 +00:00
|
|
|
node = g_mem_chunk_alloc(global_df->node_memchunk);
|
1999-07-07 22:52:57 +00:00
|
|
|
node->ntype = existence;
|
|
|
|
node->elem_size = sizeof(guint32);
|
|
|
|
node->fill_array_func = NULL;
|
|
|
|
node->check_relation_func = NULL;
|
|
|
|
node->value.variable = id;
|
|
|
|
gnode = g_node_new(node);
|
|
|
|
|
|
|
|
return gnode;
|
|
|
|
}
|
1999-08-20 06:01:07 +00:00
|
|
|
|
1999-09-15 06:13:21 +00:00
|
|
|
|
1999-08-20 06:01:07 +00:00
|
|
|
/* converts a string representing an ether HW address
|
|
|
|
* to a guint8 array.
|
|
|
|
*
|
|
|
|
* Returns 0 on failure, 1 on success.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ether_str_to_guint8_array(const char *s, guint8 *mac)
|
|
|
|
{
|
|
|
|
char ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
|
|
|
|
char *p, *str;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (strlen(s) > 17) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
strcpy(ether_str, s); /* local copy of string */
|
|
|
|
str = ether_str;
|
|
|
|
while ((p = strtok(str, "-:."))) {
|
|
|
|
/* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
|
|
|
|
if (i > 5) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
mac[i] = (guint8) strtoul(p, NULL, 16);
|
|
|
|
i++;
|
|
|
|
/* subsequent calls to strtok() require NULL as arg 1 */
|
|
|
|
str = NULL;
|
|
|
|
}
|
|
|
|
if (i != 6)
|
|
|
|
return 0; /* failed to read 6 hex pairs */
|
|
|
|
else
|
|
|
|
return 1; /* read exactly 6 hex pairs */
|
|
|
|
}
|
|
|
|
|
1999-10-12 04:21:13 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
check_bytes_variable_sanity(GNode *gnode)
|
|
|
|
{
|
|
|
|
int a_off, a_len, reg_len, t_off;
|
|
|
|
|
|
|
|
a_off = dfilter_get_bytes_variable_offset(gnode);
|
|
|
|
a_len = dfilter_get_bytes_variable_length(gnode);
|
|
|
|
reg_len = dfilter_get_bytes_variable_field_registered_length(gnode);
|
|
|
|
|
|
|
|
if (reg_len > 0) {
|
|
|
|
t_off = a_off >= 0 ? a_off : reg_len + a_off;
|
|
|
|
if (t_off + a_len > reg_len) {
|
|
|
|
dfilter_fail("The \"%s\" field is only %u byte%s wide, but "
|
1999-10-13 06:01:04 +00:00
|
|
|
"%u byte%s %s supplied.",
|
1999-10-12 04:21:13 +00:00
|
|
|
dfilter_get_variable_abbrev(gnode),
|
|
|
|
reg_len, plurality(reg_len, "", "s"),
|
1999-10-13 06:01:04 +00:00
|
|
|
a_len, plurality(a_len, "", "s"),
|
|
|
|
plurality(a_len, "was", "were"));
|
1999-10-12 04:21:13 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|