aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--Makefile.am3
-rw-r--r--dfilter-grammar.y251
-rw-r--r--dfilter-scanner.l353
-rw-r--r--dfilter.c216
-rw-r--r--dfilter.h12
-rwxr-xr-xdoc/dfilter2pod.in5
-rw-r--r--packet-eth.c12
-rw-r--r--packet-fddi.c14
-rw-r--r--packet-ipx.c90
-rw-r--r--packet-tr.c13
-rw-r--r--proto.c32
-rw-r--r--proto.h5
12 files changed, 630 insertions, 376 deletions
diff --git a/Makefile.am b/Makefile.am
index 990d54de17..4398c21e00 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,7 @@ ethereal_SOURCES = \
column.h \
config.h \
dfilter-grammar.y \
+ dfilter-scanner.l \
dfilter.c \
dfilter.h \
display.c \
@@ -110,6 +111,7 @@ ethereal_SOURCES = \
EXTRA_ethereal_SOURCES = \
dfilter-grammar.c \
dfilter-grammar.h \
+ dfilter-scanner.c \
packet-snmp.c \
snprintf.c \
snprintf.h \
@@ -149,7 +151,6 @@ EXTRA_DIST = \
README.tru64 \
README.win32 \
rdps.c \
- ylwrap \
VERSION
SUBDIRS = wiretap @SUBDIRS@
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;
diff --git a/dfilter-scanner.l b/dfilter-scanner.l
new file mode 100644
index 0000000000..dc6412be9e
--- /dev/null
+++ b/dfilter-scanner.l
@@ -0,0 +1,353 @@
+%{
+
+/* dfilter-scanner.l
+ * Scanner for display filters
+ *
+ * $Id: dfilter-scanner.l,v 1.1 1999/08/01 04:28:07 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifndef _STDIO_H
+#include <stdio.h>
+#endif
+
+#ifndef _STRING_H
+#include <string.h>
+#endif
+
+#ifndef __G_LIB_H__
+#include <glib.h>
+#endif
+
+#ifndef __PROTO_H__
+#include "proto.h"
+#endif
+
+#ifndef __DFILTER_H__
+#include "dfilter.h"
+#endif
+
+#include "dfilter-grammar.h"
+
+static int ether_str_to_guint8_array(const char *s, guint8 *mac);
+static GByteArray* byte_str_to_guint8_array(const char *s);
+
+/* in dfilter-grammar.y */
+extern GSList *dfilter_list_byte_arrays;
+
+/* Flex has a few routines which help us get the scanner to read
+ * from a string rather than from a file. POSIX lex only provides
+ * for reading from a file; any method of reading from a string
+ * is inherently non-portable. Besides reading from a string,
+ * we have to worry about resetting the scanner after a bad
+ * parse; this too is non-portable. Combine the reset with
+ * a string input, and you have major non-portability. I'll provide
+ * the routines for flex here. If you really want to modify the
+ * scanner and use a non-flex lex implementation, you may
+ * add more ifdef's below.
+ */
+#ifdef FLEX_SCANNER
+
+/* Flex has built-in support for using a string as an input source
+ * instead of using a file. Nice!
+ */
+YY_BUFFER_STATE string_input_buffer;
+
+#else
+
+static char *in_buffer;
+#undef getc
+#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
+
+#endif
+
+%}
+
+whitespace [\t ]
+hex [A-Fa-f0-9]{1,2}
+hexsep [-:.]
+
+%%
+
+[\t\n ]+ /* ignore whitespace */
+
+
+\&\& { yylval.operand = TOK_AND; return TOK_AND; }
+and { yylval.operand = TOK_AND; return TOK_AND; }
+
+\|\| { yylval.operand = TOK_OR; return TOK_OR; }
+or { yylval.operand = TOK_OR; return TOK_OR; }
+
+\! { yylval.operand = TOK_NOT; return TOK_NOT; }
+not { yylval.operand = TOK_NOT; return TOK_NOT; }
+
+\^\^ { yylval.operand = TOK_XOR; return TOK_XOR; }
+xor { yylval.operand = TOK_XOR; return TOK_XOR; }
+
+\=\= { yylval.operand = TOK_EQ; return TOK_EQ; }
+eq { yylval.operand = TOK_EQ; return TOK_EQ; }
+
+\!\= { yylval.operand = TOK_NE; return TOK_NE; }
+ne { yylval.operand = TOK_NE; return TOK_NE; }
+
+\> { yylval.operand = TOK_GT; return TOK_GT; }
+gt { yylval.operand = TOK_GT; return TOK_GT; }
+
+\>\= { yylval.operand = TOK_GE; return TOK_GE; }
+ge { yylval.operand = TOK_GE; return TOK_GE; }
+
+\< { yylval.operand = TOK_LT; return TOK_LT; }
+lt { yylval.operand = TOK_LT; return TOK_LT; }
+
+\<\= { yylval.operand = TOK_LE; return TOK_LE; }
+le { yylval.operand = TOK_LE; return TOK_LE; }
+
+exist { yylval.operand = TOK_EXIST; return TOK_EXIST; }
+exists { yylval.operand = TOK_EXIST; return TOK_EXIST; }
+true { yylval.operand = TOK_TRUE; return TOK_TRUE; }
+false { yylval.operand = TOK_FALSE; return TOK_FALSE; }
+
+\[{whitespace}*-?[0-9]+{whitespace}*:{whitespace}*[0-9]+{whitespace}*\] { /* range [ x : y ] */
+
+ char *byterange_string = g_strdup(yytext);
+ char *s = byterange_string + 1; /* I don't want the first '[' */
+ char *p;
+
+ /* Get the offset from the string */
+ if ((p = strtok(s, ":"))) {
+ yylval.byte_range.offset = strtol(p, NULL, 10);
+ }
+ else {
+ g_free(byterange_string);
+ return 0;
+ }
+
+ /* Get the Length from the string */
+ if ((p = strtok(NULL, "]"))) {
+ yylval.byte_range.length = strtoul(p, NULL, 10);
+ }
+ else {
+ g_free(byterange_string);
+ return 0;
+ }
+ g_free(byterange_string);
+ return T_VAL_BYTE_RANGE;
+}
+
+
+({hex}{hexsep}){1,4}{hex} { /* small byte array */
+
+ yylval.bytes = byte_str_to_guint8_array(yytext);
+ return T_VAL_BYTES;
+}
+
+({hex}{hexsep}){5}{hex} { /* Ether Hardware Address */
+
+ /* it's faster to copy six bytes to yylval than to create a GByteArray
+ * structure and append 6 bytes. That means I'll have to handle this
+ * overloaded meaning of 6 bytes == 1 ether in the parser (what happens
+ * when a T_VAL_ETHER is passed when an expression expects a T_VAL_BYTES?),
+ * but the speed of processing T_VAL_ETHER's makes up for the added
+ * complexity.
+ */
+ ether_str_to_guint8_array(yytext, yylval.ether);
+ return T_VAL_ETHER;
+}
+
+({hex}{hexsep}){6,}{hex} { /* large byte array */
+
+ yylval.bytes = byte_str_to_guint8_array(yytext);
+ return T_VAL_BYTES;
+}
+
+[A-Za-z][A-Za-z0-9\.\_]+ { /* looks like a protocol or field name */
+
+ int retval = 0;
+ enum ftenum ftype;
+ yylval.variable = dfilter_lookup_token(yytext);
+ if (yylval.variable == 0) {
+ return 0;
+ }
+
+ ftype = proto_registrar_get_ftype(yylval.variable);
+ switch (ftype) {
+ case FT_UINT8:
+ case FT_VALS_UINT8:
+ retval = T_FT_UINT8;
+ break;
+ case FT_UINT16:
+ case FT_VALS_UINT16:
+ retval = T_FT_UINT16;
+ break;
+ case FT_UINT32:
+ case FT_VALS_UINT32:
+ case FT_VALS_UINT24:
+ retval = T_FT_UINT32;
+ break;
+ case FT_ETHER:
+ retval = T_FT_ETHER;
+ break;
+ case FT_IPv4:
+ retval = T_FT_IPv4;
+ break;
+ case FT_NONE:
+ retval = T_FT_NONE;
+ break;
+ case FT_BYTES:
+ retval = T_FT_BYTES;
+ break;
+ case FT_BOOLEAN:
+ retval = T_FT_BOOLEAN;
+ break;
+ case FT_IPXNET:
+ retval = T_FT_IPXNET;
+ break;
+ default:
+ g_assert_not_reached();
+ retval = 0;
+ break;
+ }
+ return retval;
+}
+
+[0-9]+ { /* decimal or octal values */
+ yylval.id = g_strdup(yytext);
+ return T_VAL_ID;
+}
+
+
+0[xX][A-Fa-f0-9]+ { /* hex values */
+ yylval.id = g_strdup(yytext);
+ return T_VAL_ID;
+}
+
+[0-9\:\.]+ {
+ yylval.id = g_strdup(yytext);
+ return T_VAL_ID;
+}
+
+%%
+
+/* Resets scanner and assigns the char* argument
+ * as the text to scan
+ */
+void
+dfilter_scanner_text(char *text)
+{
+#ifdef FLEX_SCANNER
+ string_input_buffer = yy_scan_string(text);
+#else
+ in_buffer = text;
+#endif
+}
+
+void
+dfilter_scanner_cleanup(void)
+{
+#ifdef FLEX_SCANNER
+ yy_delete_buffer(string_input_buffer);
+#else
+ /* There is no standard way to reset a lex scanner.
+ * This is necessary after a failed parse on a syntactically
+ * incorrect display filter. You have to reset the scanner
+ * so that yy_lex() doesn't start scanning from the middle
+ * of the previous input string.
+ */
+#endif
+}
+
+/* Flex has an option '%option noyywrap' so that I don't have to
+ * provide this yywrap function, but in order to maintain portability,
+ * I'll just use this yywrap() function.
+ */
+int
+yywrap()
+{
+ return 1; /* stop at EOF, instead of looking for next file */
+}
+
+/* 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, "-:."))) {
+ mac[i] = (guint8) strtoul(p, NULL, 16);
+ i++;
+ /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
+ if (i > 6) {
+ break;
+ }
+ /* subsequent calls to strtok() require NULL as arg 1 */
+ str = NULL;
+ }
+ return 0;
+}
+
+/* converts a string representing a byte array
+ * to a guint8 array.
+ *
+ * Returns a non-null GByteArray pointer on success, NULL on failure.
+ */
+static GByteArray*
+byte_str_to_guint8_array(const char *s)
+{
+ GByteArray *barray;
+ guint8 val;
+ char *byte_str = g_strdup(s); /* local copy of string */
+ char *p, *str;
+
+ barray = g_byte_array_new();
+ dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray);
+
+ byte_str = g_strdup(s);
+ str = byte_str;
+ while ((p = strtok(str, "-:."))) {
+ val = (guint8) strtoul(p, NULL, 16);
+ g_byte_array_append(barray, &val, 1);
+
+ /* subsequent calls to strtok() require NULL as arg 1 */
+ str = NULL;
+ }
+
+ g_free(byte_str);
+ return barray;
+}
diff --git a/dfilter.c b/dfilter.c
index b3807757f5..b5a79e5099 100644
--- a/dfilter.c
+++ b/dfilter.c
@@ -1,7 +1,7 @@
/* dfilter.c
* Routines for display filters
*
- * $Id: dfilter.c,v 1.4 1999/07/11 08:40:51 guy Exp $
+ * $Id: dfilter.c,v 1.5 1999/08/01 04:28:07 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -54,23 +54,29 @@
int yyparse(void); /* yacc entry-point */
-#define DFILTER_LEX_SYMBOL_OFFSET 1000
#define DFILTER_LEX_ABBREV_OFFSET 2000
-#define DFILTER_LEX_SCOPE_ANY 0
-
-GScanner *scanner;
+/* Balanced tree of abbreviations and IDs */
+GTree *dfilter_tokens = NULL;
+
+/* Comparision function for tree insertion. A wrapper around strcmp() */
+static int g_strcmp(gconstpointer a, gconstpointer b);
/* Silly global variables used to pass parameter to check_relation_bytes() */
int bytes_offset = 0;
int bytes_length = 0;
YYSTYPE yylval;
+
/* in dfilter-grammar.y */
extern GMemChunk *gmc_dfilter_nodes;
extern GNode *dfilter_tree;
extern GSList *dfilter_list_byte_arrays;
+/* in dfilter-scanner.l */
+void dfilter_scanner_text(char*);
+void dfilter_scanner_cleanup(void);
+
static gboolean dfilter_apply_node(GNode *gnode, proto_tree *ptree, const guint8 *pd);
static gboolean check_relation(gint operand, GNode *a, GNode *b, proto_tree *ptree, const guint8 *pd);
static gboolean check_logical(gint operand, GNode *a, GNode *b, proto_tree *ptree, const guint8 *pd);
@@ -86,86 +92,13 @@ static void clear_byte_array(gpointer data, gpointer user_data);
*/
#define g_array_index_ptr(a,s,i) (((guint8*) (a)->data) + (i*s))
-static GScannerConfig dfilter_scanner_config =
-{
- (
- " \t\n"
- ) /* cset_skip_characters */,
-
- /* I wish I didn't have to start strings with numeric
- digits, but if I don't, strings like MAC and IPv4
- addresses get really hard to handle */
- (
- G_CSET_a_2_z
- "_0123456789"
- G_CSET_A_2_Z
- ) /* cset_identifier_first */,
- (
- G_CSET_a_2_z
- ".-_0123456789"
- G_CSET_A_2_Z
- ) /* cset_identifier_nth */,
- ( "#\n" ) /* cpair_comment_single */,
-
- FALSE /* case_sensitive */,
-
- FALSE /* skip_comment_multi */,
- FALSE /* skip_comment_single */,
- TRUE /* scan_comment_multi */,
- TRUE /* scan_identifier */,
- TRUE /* scan_identifier_1char */,
- FALSE /* scan_identifier_NULL */,
- TRUE /* scan_symbols */,
- TRUE /* scan_binary */,
- TRUE /* scan_octal */,
- TRUE /* scan_float */,
- TRUE /* scan_hex */,
- TRUE /* scan_hex_dollar */,
- TRUE /* scan_string_sq */,
- FALSE /* scan_string_dq */,
- TRUE /* numbers_2_int */,
- FALSE /* int_2_float */,
- FALSE /* identifier_2_string */,
- TRUE /* char_2_token */,
- TRUE /* symbol_2_token */,
- FALSE /* scope_0_fallback */,
-};
-
-typedef struct symtab_record {
- int id;
- char *token;
-} symtab_record;
-
-symtab_record operator_symtab[] = {
- { TOK_AND, "and" },
- { TOK_OR, "or" },
- { TOK_NOT, "not" },
- { TOK_XOR, "xor" },
- { TOK_EQ, "eq" },
- { TOK_NE, "ne" },
- { TOK_GT, "gt" },
- { TOK_GE, "ge" },
- { TOK_LT, "lt" },
- { TOK_LE, "le" },
- { TOK_EXIST, "exist" },
- { TOK_EXISTS, "exists" },
- { TOK_TRUE, "true" },
- { TOK_FALSE, "false" },
- { 0, NULL }
-};
-
-
void
dfilter_init(void)
{
- int num_symbols, i, symbol;
+ int i, num_symbols, symbol;
char *s;
- symtab_record *symrec;
-
- scanner = g_scanner_new(&dfilter_scanner_config);
- scanner->input_name = "Ethereal Display Filter";
- g_scanner_freeze_symbol_table(scanner);
+ dfilter_tokens = g_tree_new(g_strcmp);
/* Add the header field and protocol abbrevs to the symbol table */
num_symbols = proto_registrar_n();
@@ -173,35 +106,31 @@ dfilter_init(void)
s = proto_registrar_get_abbrev(i);
if (s) {
symbol = DFILTER_LEX_ABBREV_OFFSET + i;
- g_scanner_scope_add_symbol(scanner,
- DFILTER_LEX_SCOPE_ANY, s, GINT_TO_POINTER(symbol));
+ g_tree_insert(dfilter_tokens, s, GINT_TO_POINTER(symbol));
}
}
-
- /* Add the operators to the symbol table */
- for (symrec=operator_symtab; symrec->token != NULL; symrec++) {
- symbol = DFILTER_LEX_SYMBOL_OFFSET + symrec->id;
- g_scanner_scope_add_symbol(scanner, DFILTER_LEX_SCOPE_ANY,
- symrec->token, GINT_TO_POINTER(symbol));
- }
- g_scanner_thaw_symbol_table(scanner);
}
+/* I should eventually g_tree_destroy(dfilter_tokens), when ethereal shuts down */
+/* Compiles the textual representation of the display filter into a tree
+ * of operations to perform.
+ */
int
dfilter_compile(char *dfilter_text, GNode **p_dfcode)
{
int retval;
g_assert(dfilter_text != NULL);
- g_scanner_input_text(scanner, dfilter_text, strlen(dfilter_text));
+ dfilter_scanner_text(dfilter_text);
if (dfilter_tree) {
/* clear tree */
dfilter_tree = NULL;
}
-
+ /* clear the memory that the tree was using for nodes */
g_mem_chunk_reset(gmc_dfilter_nodes);
+ /* clear the memory that the tree was using for byte arrays */
if (dfilter_list_byte_arrays) {
g_slist_foreach(dfilter_list_byte_arrays, clear_byte_array, NULL);
g_slist_free(dfilter_list_byte_arrays);
@@ -212,7 +141,9 @@ dfilter_compile(char *dfilter_text, GNode **p_dfcode)
g_node_destroy(*p_dfcode);
retval = yyparse();
+ dfilter_scanner_cleanup();
*p_dfcode = dfilter_tree;
+
return retval;
}
@@ -224,70 +155,6 @@ clear_byte_array(gpointer data, gpointer user_data)
g_byte_array_free(barray, TRUE);
}
-int
-yylex(void)
-{
- guint token;
-
- if (g_scanner_peek_next_token(scanner) == G_TOKEN_EOF) {
- return 0;
- }
- else {
- token = g_scanner_get_next_token(scanner);
- }
-
- /* Set the yacc-defined tokens back to their yacc-defined values */
- if (token >= DFILTER_LEX_SYMBOL_OFFSET && token <= DFILTER_LEX_ABBREV_OFFSET) {
- token -= DFILTER_LEX_SYMBOL_OFFSET;
- yylval.operand = token;
- }
- /* Handle our dynamically-created list of header field abbrevs */
- else if (token >= DFILTER_LEX_ABBREV_OFFSET) {
- yylval.variable = token;
- switch (proto_registrar_get_ftype(token - DFILTER_LEX_ABBREV_OFFSET)) {
- case FT_UINT8:
- case FT_VALS_UINT8:
- token = T_FT_UINT8;
- break;
- case FT_UINT16:
- case FT_VALS_UINT16:
- token = T_FT_UINT16;
- break;
- case FT_UINT32:
- case FT_VALS_UINT32:
- case FT_VALS_UINT24:
- token = T_FT_UINT32;
- break;
- case FT_ETHER:
- token = T_FT_ETHER;
- break;
- case FT_IPv4:
- token = T_FT_IPv4;
- break;
- case FT_NONE:
- token = T_FT_NONE;
- break;
- case FT_BYTES:
- token = T_FT_BYTES;
- break;
- case FT_BOOLEAN:
- token = T_FT_BOOLEAN;
- break;
- default:
- token = 0;
- break;
- }
- }
- /* unidentified strings. that's how I make numbers come in! */
- else if (token == G_TOKEN_IDENTIFIER || token == G_TOKEN_IDENTIFIER_NULL) {
- token = T_VAL_ID;
- yylval.id = g_strdup(scanner->value.v_identifier);
- }
- /* else it's punctuation */
-
- return token;
-}
-
void
yyerror(char *s)
{
@@ -301,6 +168,28 @@ dfilter_yyerror(char *fmt, ...)
yyerror(fmt);
}
+/* lookup an abbreviation in our token tree, returing the ID #
+ * If the abbreviation doesn't exit, returns 0 */
+int dfilter_lookup_token(char *abbrev)
+{
+ int value;
+
+ g_assert(abbrev != NULL);
+ value = GPOINTER_TO_INT(g_tree_lookup(dfilter_tokens, abbrev));
+
+ if (value < DFILTER_LEX_ABBREV_OFFSET) {
+ return 0;
+ }
+ return value - DFILTER_LEX_ABBREV_OFFSET;
+}
+
+static int
+g_strcmp(gconstpointer a, gconstpointer b)
+{
+ return strcmp((const char*)a, (const char*)b);
+}
+
+
gboolean
dfilter_apply(GNode *dfcode, proto_tree *ptree, const guint8* pd)
{
@@ -348,6 +237,7 @@ dfilter_apply_node(GNode *gnode, proto_tree *ptree, const guint8* pd)
case string:
case abs_time:
case bytes:
+ case ipxnet:
/* the only time we'll see these at this point is if the display filter
* is really wacky. Just return TRUE */
g_assert(!gnode_a && !gnode_b);
@@ -447,8 +337,7 @@ check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree)
int target_field;
proto_tree *subtree;
- target_field = dnode->value.variable - DFILTER_LEX_ABBREV_OFFSET;
- /*subtree = proto_find_protocol(ptree, target_field);*/
+ target_field = dnode->value.variable;
subtree = proto_find_field(ptree, target_field);
if (subtree)
@@ -469,7 +358,7 @@ get_values_from_ptree(dfilter_node *dnode, proto_tree *ptree, const guint8 *pd)
g_assert(dnode->elem_size > 0);
array = g_array_new(FALSE, FALSE, dnode->elem_size);
- target_field = dnode->value.variable - DFILTER_LEX_ABBREV_OFFSET;
+ target_field = dnode->value.variable;
/* Find the proto_tree subtree where we should start searching.*/
if (proto_registrar_is_protocol(target_field)) {
@@ -681,7 +570,7 @@ gboolean check_relation_numeric(gint operand, GArray *a, GArray *b)
gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
{
int i, j, len_a, len_b;
- guint8* ptr_a;
+ guint8 *ptr_a, *ptr_b;
len_a = a->len;
len_b = b->len;
@@ -692,7 +581,8 @@ gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
for(i = 0; i < len_a; i++) {
ptr_a = g_array_index_ptr(a, 6, i);
for (j = 0; j < len_b; j++) {
- if (memcmp(ptr_a, g_array_index_ptr(b, 6, j), 6) == 0)
+ ptr_b = g_array_index_ptr(b, 6, j);
+ if (memcmp(ptr_a, ptr_b, 6) == 0)
return TRUE;
}
}
@@ -702,7 +592,8 @@ gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
for(i = 0; i < len_a; i++) {
ptr_a = g_array_index_ptr(a, 6, i);
for (j = 0; j < len_b; j++) {
- if (memcmp(ptr_a, g_array_index_ptr(b, 6, j), 6) != 0)
+ ptr_b = g_array_index_ptr(b, 6, j);
+ if (memcmp(ptr_a, ptr_b, 6) != 0)
return TRUE;
}
}
@@ -809,3 +700,4 @@ gboolean check_relation_boolean(gint operand, GArray *a, GArray *b)
g_assert_not_reached();
return FALSE;
}
+
diff --git a/dfilter.h b/dfilter.h
index a325a1e51b..8fcf65bee7 100644
--- a/dfilter.h
+++ b/dfilter.h
@@ -1,7 +1,7 @@
/* dfilter.h
* Definitions for display filters
*
- * $Id: dfilter.h,v 1.3 1999/07/13 02:52:48 gram Exp $
+ * $Id: dfilter.h,v 1.4 1999/08/01 04:28:08 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -68,7 +68,8 @@ enum node_type {
ether,
ether_vendor,
bytes,
- ipv4
+ ipv4,
+ ipxnet
};
typedef gboolean(*CheckRelationFunc) (gint operand, GArray *a, GArray *b);
@@ -100,10 +101,11 @@ typedef struct dfilter_node {
} value;
/* used for byte-ranges */
- int offset;
- int length;
+ gint offset;
+ guint length;
} dfilter_node;
-
+/* lookup an abbreviation in our token hash, returing the ID # */
+int dfilter_lookup_token(char *abbrev);
#endif /* ! __DFILTER_H__ */
diff --git a/doc/dfilter2pod.in b/doc/dfilter2pod.in
index d75b22c8a1..1afde713bd 100755
--- a/doc/dfilter2pod.in
+++ b/doc/dfilter2pod.in
@@ -9,7 +9,7 @@
# will be replaced by the pod-formatted glossary
# STDOUT is the output
#
-# $Id: dfilter2pod.in,v 1.1 1999/07/20 08:02:24 guy Exp $
+# $Id: dfilter2pod.in,v 1.2 1999/08/01 04:28:20 gram Exp $
%ftenum_names = (
'FT_NONE', 'No value',
@@ -21,11 +21,10 @@
'FT_RELATIVE_TIME', 'Time duration',
'FT_STRING', 'String',
'FT_ETHER', '6-byte Hardware (MAC) Address',
- 'FT_ETHER_VENDOR', '3-byte MAC vendor',
'FT_BYTES', 'Byte array',
'FT_IPv4', 'IPv4 address',
'FT_IPv6', 'IPv6 address',
- 'FT_IPXSERVER', 'IPX network or server name',
+ 'FT_IPXNET', 'IPX network or server name',
'FT_VALS_UINT8', 'Unsigned 8-bit integer',
'FT_VALS_UINT16', 'Unsigned 16-bit integer',
'FT_VALS_UINT24', 'Unsigned 24-bit integer',
diff --git a/packet-eth.c b/packet-eth.c
index 3a06b413cc..34ff78081b 100644
--- a/packet-eth.c
+++ b/packet-eth.c
@@ -1,7 +1,7 @@
/* packet-eth.c
* Routines for ethernet packet disassembly
*
- * $Id: packet-eth.c,v 1.13 1999/07/29 05:46:54 gram Exp $
+ * $Id: packet-eth.c,v 1.14 1999/08/01 04:28:08 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -41,9 +41,7 @@ extern const value_string etype_vals[];
/* protocols and header fields */
static int proto_eth = -1;
static int hf_eth_dst = -1;
-static int hf_eth_dst_vendor = -1;
static int hf_eth_src = -1;
-static int hf_eth_src_vendor = -1;
static int hf_eth_len = -1;
static int hf_eth_type = -1;
@@ -153,9 +151,7 @@ dissect_eth(const u_char *pd, frame_data *fd, proto_tree *tree) {
fh_tree = proto_item_add_subtree(ti, ETT_IEEE8023);
proto_tree_add_item(fh_tree, hf_eth_dst, 0, 6, &pd[0]);
- proto_tree_add_item_hidden(fh_tree, hf_eth_dst_vendor, 0, 3, &pd[0]);
proto_tree_add_item(fh_tree, hf_eth_src, 6, 6, &pd[6]);
- proto_tree_add_item_hidden(fh_tree, hf_eth_src_vendor, 6, 3, &pd[6]);
proto_tree_add_item(fh_tree, hf_eth_len, 12, 2, length);
}
@@ -203,12 +199,6 @@ proto_register_eth(void)
{ &hf_eth_src,
{ "Source", "eth.src", FT_ETHER, NULL }},
- { &hf_eth_dst_vendor,
- { "Destination Hardware Vendor", "eth.dst_vendor", FT_ETHER, NULL }},
-
- { &hf_eth_src_vendor,
- { "Source Hardware Vendor", "eth.src_vendor", FT_ETHER, NULL }},
-
{ &hf_eth_len,
{ "Length", "eth.len", FT_UINT16, NULL }},
diff --git a/packet-fddi.c b/packet-fddi.c
index 159024dcf8..4545e90282 100644
--- a/packet-fddi.c
+++ b/packet-fddi.c
@@ -3,7 +3,7 @@
*
* Laurent Deniel <deniel@worldnet.fr>
*
- * $Id: packet-fddi.c,v 1.15 1999/07/29 05:46:54 gram Exp $
+ * $Id: packet-fddi.c,v 1.16 1999/08/01 04:28:08 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -40,9 +40,7 @@
static int proto_fddi = -1;
static int hf_fddi_fc = -1;
static int hf_fddi_dst = -1;
-static int hf_fddi_dst_vendor = -1;
static int hf_fddi_src = -1;
-static int hf_fddi_src_vendor = -1;
/* FDDI Frame Control values */
@@ -235,15 +233,11 @@ void dissect_fddi(const u_char *pd, frame_data *fd, proto_tree *tree)
fh_tree = proto_item_add_subtree(ti, ETT_FDDI);
proto_tree_add_item(fh_tree, hf_fddi_fc, FDDI_P_FC, 1, fc);
proto_tree_add_item(fh_tree, hf_fddi_dst, FDDI_P_DHOST, 6, dst);
- proto_tree_add_item_hidden(fh_tree, hf_fddi_dst_vendor, FDDI_P_DHOST, 3, dst);
proto_tree_add_item(fh_tree, hf_fddi_src, FDDI_P_SHOST, 6, src);
- proto_tree_add_item_hidden(fh_tree, hf_fddi_src_vendor, FDDI_P_SHOST, 3, src);
/* hide some bit-swapped mac address fields in the proto_tree, just in case */
proto_tree_add_item_hidden(fh_tree, hf_fddi_dst, FDDI_P_DHOST, 6, dst_swapped);
proto_tree_add_item_hidden(fh_tree, hf_fddi_dst, FDDI_P_SHOST, 6, src_swapped);
- proto_tree_add_item_hidden(fh_tree, hf_fddi_dst_vendor, FDDI_P_DHOST, 3, dst_swapped);
- proto_tree_add_item_hidden(fh_tree, hf_fddi_src_vendor, FDDI_P_SHOST, 3, src_swapped);
}
switch (fc) {
@@ -289,12 +283,6 @@ proto_register_fddi(void)
{ &hf_fddi_src,
{ "Source", "fddi.src", FT_ETHER, NULL }},
-
- { &hf_fddi_dst_vendor,
- { "Destination Hardware Vendor", "fddi.dst_vendor", FT_ETHER_VENDOR, NULL }},
-
- { &hf_fddi_src_vendor,
- { "Source Hardware Vendor", "fddi.src_vendor", FT_ETHER_VENDOR, NULL }}
};
proto_fddi = proto_register_protocol ("Fiber Distributed Data Interface", "fddi" );
diff --git a/packet-ipx.c b/packet-ipx.c
index 8490555de8..f71b693882 100644
--- a/packet-ipx.c
+++ b/packet-ipx.c
@@ -2,7 +2,7 @@
* Routines for NetWare's IPX
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
- * $Id: packet-ipx.c,v 1.24 1999/07/29 05:46:57 gram Exp $
+ * $Id: packet-ipx.c,v 1.25 1999/08/01 04:28:08 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
@@ -53,8 +53,13 @@ static int proto_ipx = -1;
static int hf_ipx_checksum = -1;
static int hf_ipx_len = -1;
static int hf_ipx_hops = -1;
+static int hf_ipx_packet_type = -1;
+static int hf_ipx_dnet = -1;
static int hf_ipx_dnode = -1;
+static int hf_ipx_dsocket = -1;
+static int hf_ipx_snet = -1;
static int hf_ipx_snode = -1;
+static int hf_ipx_ssocket = -1;
static int proto_spx = -1;
static int proto_ipxrip = -1;
@@ -130,28 +135,27 @@ port_func(guint16 port) {
return NULL;
}
-char *
-ipx_packet_type(u_char val)
-{
- if (val == 0) {
- return "IPX";
- }
- else if (val == 5) {
- return "SPX";
- }
- else if (val == 17) {
- return "NCP";
- }
- else if (val == 20) {
- return "NetBIOS Broadcast";
- }
- else if (val >= 16 && val <= 31) {
- return "Experimental Protocol";
- }
- else {
- return "Unknown";
- }
-}
+static const value_string ipx_packet_type_vals[] = {
+ { 0, "IPX" },
+ { 5, "SPX" },
+ { 16, "Experimental Protocol" },
+ { 17, "NCP" },
+ { 18, "Experimental Protocol" },
+ { 19, "Experimental Protocol" },
+ { 20, "NetBIOS Broadcast" },
+ { 21, "Experimental Protocol" },
+ { 22, "Experimental Protocol" },
+ { 23, "Experimental Protocol" },
+ { 24, "Experimental Protocol" },
+ { 25, "Experimental Protocol" },
+ { 26, "Experimental Protocol" },
+ { 27, "Experimental Protocol" },
+ { 28, "Experimental Protocol" },
+ { 29, "Experimental Protocol" },
+ { 30, "Experimental Protocol" },
+ { 31, "Experimental Protocol" },
+ { 0, NULL }
+};
gchar*
ipxnet_to_string(const guint8 *ad)
@@ -203,12 +207,15 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
guint16 ipx_dsocket, ipx_ssocket;
void (*dissect) (const u_char *, int, frame_data *, proto_tree *, int);
int max_data;
+ guint32 ipx_dnet_val, ipx_snet_val;
/* Calculate here for use in pinfo and in tree */
ipx_dnet = (guint8*)&pd[offset+6];
ipx_snet = (guint8*)&pd[offset+18];
str_dnet = ipxnet_to_string(ipx_dnet);
str_snet = ipxnet_to_string(ipx_snet);
+ ipx_dnet_val = pntohl(ipx_dnet);
+ ipx_snet_val = pntohl(ipx_snet);
ipx_dsocket = pntohs(&pd[offset+16]);
ipx_ssocket = pntohs(&pd[offset+28]);
ipx_dnode = (guint8*)&pd[offset+10];
@@ -242,19 +249,17 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
"Length: %d bytes", ipx_length);
proto_tree_add_item_format(ipx_tree, hf_ipx_hops, offset+4, 1, ipx_hops,
"Transport Control: %d hops", ipx_hops);
- proto_tree_add_text(ipx_tree, offset+5, 1, "Packet Type: %s",
- ipx_packet_type(ipx_type));
- proto_tree_add_text(ipx_tree, offset+6, 4, "Destination Network: %s",
- str_dnet);
+ proto_tree_add_item(ipx_tree, hf_ipx_packet_type, offset+5, 1, ipx_type);
+ proto_tree_add_item(ipx_tree, hf_ipx_dnet, offset+6, 4, ipx_dnet_val);
proto_tree_add_item(ipx_tree, hf_ipx_dnode, offset+10, 6, ipx_dnode);
- proto_tree_add_text(ipx_tree, offset+16, 2,
- "Destination Socket: %s (0x%04X)", port_text(ipx_dsocket),
- ipx_dsocket);
- proto_tree_add_text(ipx_tree, offset+18, 4, "Source Network: %s",
- str_snet);
+ proto_tree_add_item_format(ipx_tree, hf_ipx_dsocket, offset+16, 2,
+ ipx_dsocket, "Destination Socket: %s (0x%04X)",
+ port_text(ipx_dsocket), ipx_dsocket);
+ proto_tree_add_item(ipx_tree, hf_ipx_snet, offset+18, 4, ipx_snet_val);
proto_tree_add_item(ipx_tree, hf_ipx_snode, offset+22, 6, ipx_snode);
- proto_tree_add_text(ipx_tree, offset+28, 2,
- "Source Socket: %s (0x%04X)", port_text(ipx_ssocket), ipx_ssocket);
+ proto_tree_add_item_format(ipx_tree, hf_ipx_ssocket, offset+28, 2,
+ ipx_ssocket, "Source Socket: %s (0x%04X)", port_text(ipx_ssocket),
+ ipx_ssocket);
}
offset += 30;
@@ -594,11 +599,26 @@ proto_register_ipx(void)
{ &hf_ipx_hops,
{ "Transport Control (Hops)", "ipx.hops", FT_UINT8, NULL }},
+ { &hf_ipx_packet_type,
+ { "Packet Type", "ipx.packet_type", FT_VALS_UINT8, VALS(ipx_packet_type_vals) }},
+
+ { &hf_ipx_dnet,
+ { "Destination Network","ipx.dstnet", FT_IPXNET, NULL }},
+
{ &hf_ipx_dnode,
{ "Destination Node", "ipx.dstnode", FT_ETHER, NULL }},
+ { &hf_ipx_dsocket,
+ { "Destination Socket", "ipx.dstsocket", FT_UINT16, NULL }},
+
+ { &hf_ipx_snet,
+ { "Source Network","ipx.srcnet", FT_IPXNET, NULL }},
+
{ &hf_ipx_snode,
- { "Source Node", "ipx.srcnode", FT_ETHER, NULL }}
+ { "Source Node", "ipx.srcnode", FT_ETHER, NULL }},
+
+ { &hf_ipx_ssocket,
+ { "Source Socket", "ipx.srcsocket", FT_UINT16, NULL }},
};
proto_ipx = proto_register_protocol ("Internetwork Packet eXchange", "ipx");
diff --git a/packet-tr.c b/packet-tr.c
index 28051d30a1..147eab795b 100644
--- a/packet-tr.c
+++ b/packet-tr.c
@@ -2,7 +2,7 @@
* Routines for Token-Ring packet disassembly
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
- * $Id: packet-tr.c,v 1.17 1999/07/29 05:47:06 gram Exp $
+ * $Id: packet-tr.c,v 1.18 1999/08/01 04:28:09 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
@@ -40,8 +40,6 @@
static int proto_tr = -1;
static int hf_tr_dst = -1;
static int hf_tr_src = -1;
-static int hf_tr_dst_vendor = -1;
-static int hf_tr_src_vendor = -1;
static int hf_tr_sr = -1;
static int hf_tr_ac = -1;
static int hf_tr_priority = -1;
@@ -348,14 +346,11 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) {
decode_enumerated_bitfield(trn_fc, 0x0f, 8, pcf_vals, "%s"));
proto_tree_add_item(tr_tree, hf_tr_dst, 2, 6, trn_dhost);
- proto_tree_add_item_hidden(tr_tree, hf_tr_dst_vendor, 2, 3, trn_dhost);
proto_tree_add_item(tr_tree, hf_tr_src, 8, 6, trn_shost);
- proto_tree_add_item_hidden(tr_tree, hf_tr_src_vendor, 8, 3, trn_shost);
proto_tree_add_item_hidden(tr_tree, hf_tr_sr, 8, 1, source_routed);
/* non-source-routed version of src addr */
proto_tree_add_item_hidden(tr_tree, hf_tr_src, 8, 6, trn_shost_nonsr);
- proto_tree_add_item_hidden(tr_tree, hf_tr_src_vendor, 8, 3, trn_shost_nonsr);
if (source_routed) {
/* RCF Byte 1 */
@@ -470,12 +465,6 @@ proto_register_tr(void)
{ &hf_tr_src,
{ "Source", "tr.src", FT_ETHER, NULL }},
- { &hf_tr_dst_vendor,
- { "Destination Hardware Vendor", "tr.dst_vendor", FT_ETHER_VENDOR, NULL }},
-
- { &hf_tr_src_vendor,
- { "Source Hardware Vendor", "tr.src_vendor", FT_ETHER_VENDOR, NULL }},
-
{ &hf_tr_sr,
{ "Source Routed", "tr.sr", FT_BOOLEAN, NULL }},
diff --git a/proto.c b/proto.c
index 9c68451a14..1b7ac4b474 100644
--- a/proto.c
+++ b/proto.c
@@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
- * $Id: proto.c,v 1.6 1999/07/31 02:15:12 guy Exp $
+ * $Id: proto.c,v 1.7 1999/08/01 04:28:09 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -369,13 +369,11 @@ NOTES
case FT_VALS_UINT32:
case FT_RELATIVE_TIME:
case FT_IPv4:
- case FT_IPXSERVER:
- fi->value.numeric = va_arg(ap, guint32);
+ case FT_IPXNET:
+ fi->value.numeric = va_arg(ap, unsigned int);
break;
case FT_ETHER:
- case FT_ETHER_VENDOR:
-/* fi->value.ether = va_arg(ap, guint8*);*/
memcpy(fi->value.ether, va_arg(ap, guint8*), 6);
break;
@@ -385,7 +383,8 @@ NOTES
break;
case FT_STRING:
- fi->value.string = g_strdup(va_arg(ap, char*)); /* XXX */
+ /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+ fi->value.string = g_strdup(va_arg(ap, char*));
break;
case FT_TEXT_ONLY:
@@ -548,6 +547,11 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
(s ? s : "Unknown"), fi->value.numeric);
break;
+ case FT_IPXNET:
+ snprintf(label_str, ITEM_LABEL_LENGTH,
+ "%s: 0x%08X", fi->hfinfo->name, fi->value.numeric);
+ break;
+
case FT_ETHER:
snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", fi->hfinfo->name,
@@ -555,15 +559,6 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
get_ether_name(fi->value.ether));
break;
- case FT_ETHER_VENDOR:
- snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %02x:%02x:%02x (%s)", fi->hfinfo->name,
- fi->value.ether[0],
- fi->value.ether[1],
- fi->value.ether[2],
- get_manuf_name(fi->value.ether));
- break;
-
case FT_IPv4:
snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", fi->hfinfo->name,
@@ -777,9 +772,6 @@ proto_registrar_dump(void)
case FT_ETHER:
enum_name = "FT_ETHER";
break;
- case FT_ETHER_VENDOR:
- enum_name = "FT_ETHER_VENDOR";
- break;
case FT_BYTES:
enum_name = "FT_BYTES";
break;
@@ -789,8 +781,8 @@ proto_registrar_dump(void)
case FT_IPv6:
enum_name = "FT_IPv6";
break;
- case FT_IPXSERVER:
- enum_name = "FT_IPXSERVER";
+ case FT_IPXNET:
+ enum_name = "FT_IPXNET";
break;
case FT_VALS_UINT8:
enum_name = "FT_VALS_UINT8";
diff --git a/proto.h b/proto.h
index d4ce6d10bf..3d436c4fa1 100644
--- a/proto.h
+++ b/proto.h
@@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
- * $Id: proto.h,v 1.4 1999/07/15 15:32:44 gram Exp $
+ * $Id: proto.h,v 1.5 1999/08/01 04:28:09 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -60,11 +60,10 @@ enum ftenum {
FT_RELATIVE_TIME,
FT_STRING,
FT_ETHER,
- FT_ETHER_VENDOR,
FT_BYTES,
FT_IPv4,
FT_IPv6,
- FT_IPXSERVER,
+ FT_IPXNET,
FT_VALS_UINT8,
FT_VALS_UINT16,
FT_VALS_UINT24,