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
This commit is contained in:
Gilbert Ramirez 1999-08-01 04:28:20 +00:00
parent c31abd81fa
commit b2f932c1db
12 changed files with 631 additions and 377 deletions

View File

@ -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@

View File

@ -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,46 +277,34 @@ ipv4_value: T_VAL_ID
}
;
bytes_value: T_VAL_ID
{
GByteArray *barray = g_byte_array_new();
guint8 val;
char *endptr;
bytes_value: T_VAL_BYTES
{ /* 2 - 5, or > 6 bytes */
$$ = dfilter_mknode_bytes_value($1);
}
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); }
| T_VAL_ID
{ /* one byte */
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);
}
| 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);
}
;
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);
}
| byte_range ':' T_VAL_ID
{
guint8 val;
char *endptr;
val = (guint8) strtoul($3, &endptr, 16);
$$ = g_byte_array_append($1, &val, 1);
g_free($3);
}
;
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 ']'
bytes_variable: any_variable_type T_VAL_BYTE_RANGE
{
$$ = 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 ']'
{
$$ = dfilter_mknode_bytes_variable($1, string_to_value($3), 1);
g_free($3);
$$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length);
}
;
@ -322,54 +348,32 @@ any_variable_type: T_FT_UINT8 { $$ = $1; }
| T_FT_STRING { $$ = $1; }
;
numeric_relation: type_eq { $$ = $1; }
| type_ne { $$ = $1; }
| type_gt { $$ = $1; }
| type_ge { $$ = $1; }
| type_lt { $$ = $1; }
| type_le { $$ = $1; }
numeric_relation: TOK_EQ { $$ = $1; }
| TOK_NE { $$ = $1; }
| TOK_GT { $$ = $1; }
| TOK_GE { $$ = $1; }
| TOK_LT { $$ = $1; }
| TOK_LE { $$ = $1; }
;
ether_relation: type_eq { $$ = $1; }
| type_ne { $$ = $1; }
ether_relation: TOK_EQ { $$ = $1; }
| TOK_NE { $$ = $1; }
;
bytes_relation: type_eq { $$ = $1; }
| type_ne { $$ = $1; }
| type_gt { $$ = $1; }
| type_lt { $$ = $1; }
bytes_relation: TOK_EQ { $$ = $1; }
| TOK_NE { $$ = $1; }
| TOK_GT { $$ = $1; }
| TOK_LT { $$ = $1; }
;
boolean_relation: type_eq { $$ = $1; }
| type_ne { $$ = $1; }
boolean_relation: TOK_EQ { $$ = $1; }
| TOK_NE { $$ = $1; }
;
exists_operand: TOK_EXIST { $$ = $1; }
| TOK_EXISTS { $$ = $1; }
| '?' { $$ = TOK_EXIST; }
;
type_eq: TOK_EQ { $$ = $1; }
| '=' '=' { $$ = TOK_EQ; }
;
type_ne: TOK_NE { $$ = $1; }
| '!' '=' { $$ = TOK_NE; }
;
type_gt: TOK_GT { $$ = $1; }
;
type_ge: TOK_GE { $$ = $1; }
;
type_lt: TOK_LT { $$ = $1; }
;
type_le: TOK_LE { $$ = $1; }
;
%%
void
@ -479,6 +483,23 @@ dfilter_mknode_ether_variable(gint id)
return gnode;
}
static GNode*
dfilter_mknode_ipxnet_variable(gint id)
{
dfilter_node *node;
GNode *gnode;
node = g_mem_chunk_alloc(gmc_dfilter_nodes);
node->ntype = variable;
node->elem_size = sizeof(guint8) * 4;
node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
node->check_relation_func = check_relation_numeric; /* cheating ! */
node->value.variable = id;
gnode = g_node_new(node);
return gnode;
}
static GNode*
dfilter_mknode_ipv4_variable(gint id)
{
@ -497,14 +518,13 @@ dfilter_mknode_ipv4_variable(gint id)
}
static GNode*
dfilter_mknode_bytes_variable(gint id, gint offset, gint length)
dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
{
dfilter_node *node;
GNode *gnode;
node = g_mem_chunk_alloc(gmc_dfilter_nodes);
node->ntype = variable;
/*node->elem_size = length * sizeof(guint8);*/
node->elem_size = sizeof(GByteArray*);
node->fill_array_func = fill_array_bytes_variable;
node->check_relation_func = check_relation_bytes;
@ -551,11 +571,10 @@ dfilter_mknode_numeric_value(guint32 val)
}
static GNode*
dfilter_mknode_ether_value(char *a, char *b, char *c, char *d, char *e, char *f)
dfilter_mknode_ether_value(guint8 *ether_bytes)
{
dfilter_node *node;
GNode *gnode;
char *endptr;
node = g_mem_chunk_alloc(gmc_dfilter_nodes);
node->ntype = ether;
@ -563,13 +582,24 @@ dfilter_mknode_ether_value(char *a, char *b, char *c, char *d, char *e, char *f)
node->fill_array_func = fill_array_ether_value;
node->check_relation_func = check_relation_ether;
node->value.ether[0] = (guint8) strtoul(a, &endptr, 16);
node->value.ether[1] = (guint8) strtoul(b, &endptr, 16);
node->value.ether[2] = (guint8) strtoul(c, &endptr, 16);
node->value.ether[3] = (guint8) strtoul(d, &endptr, 16);
node->value.ether[4] = (guint8) strtoul(e, &endptr, 16);
node->value.ether[5] = (guint8) strtoul(f, &endptr, 16);
memcpy(&node->value.ether, ether_bytes, 6);
gnode = g_node_new(node);
return gnode;
}
static GNode*
dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
{
dfilter_node *node;
GNode *gnode;
node = g_mem_chunk_alloc(gmc_dfilter_nodes);
node->ntype = ipxnet;
node->elem_size = sizeof(guint8) * 4;
node->fill_array_func = fill_array_numeric_value; /* cheating ! */
node->check_relation_func = check_relation_numeric; /* cheating ! */
node->value.numeric = ipx_net_val;
gnode = g_node_new(node);
return gnode;
@ -601,7 +631,6 @@ dfilter_mknode_bytes_value(GByteArray *barray)
node = g_mem_chunk_alloc(gmc_dfilter_nodes);
node->ntype = bytes;
/*node->elem_size = barray->len * sizeof(guint8);*/
node->elem_size = sizeof(GByteArray*);
node->fill_array_func = fill_array_bytes_value;
node->check_relation_func = check_relation_bytes;

353
dfilter-scanner.l Normal file
View File

@ -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;
}

216
dfilter.c
View File

@ -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;
}

View File

@ -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__ */

View File

@ -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',

View File

@ -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 }},

View File

@ -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" );

View File

@ -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");

View File

@ -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 }},

32
proto.c
View File

@ -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";

View File

@ -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,