diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 1999-08-01 04:28:20 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 1999-08-01 04:28:20 +0000 |
commit | b2f932c1dbb6180a3b4a86c7510ef4beff814bb0 (patch) | |
tree | 4b9c007a4f6bbfa27c0c7f9cad2a1e7800c30863 | |
parent | c31abd81fa1fa78b0ac19d0b1de3d492a016768c (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.am | 3 | ||||
-rw-r--r-- | dfilter-grammar.y | 251 | ||||
-rw-r--r-- | dfilter-scanner.l | 353 | ||||
-rw-r--r-- | dfilter.c | 216 | ||||
-rw-r--r-- | dfilter.h | 12 | ||||
-rwxr-xr-x | doc/dfilter2pod.in | 5 | ||||
-rw-r--r-- | packet-eth.c | 12 | ||||
-rw-r--r-- | packet-fddi.c | 14 | ||||
-rw-r--r-- | packet-ipx.c | 90 | ||||
-rw-r--r-- | packet-tr.c | 13 | ||||
-rw-r--r-- | proto.c | 32 | ||||
-rw-r--r-- | proto.h | 5 |
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; +} @@ -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; } + @@ -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 }}, @@ -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"; @@ -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, |