- add handling of FT_IPv6 variables

there is still some work to do in resolv.c (get_host_ipaddr6)

- add display filters of this kind in packet-ipv6.c just
  for testing (display filtering is incomplete)

svn path=/trunk/; revision=808
This commit is contained in:
Laurent Deniel 1999-10-11 17:05:49 +00:00
parent c6d6deee3c
commit 2e08b800b4
7 changed files with 207 additions and 18 deletions

View File

@ -3,7 +3,7 @@
/* dfilter-grammar.y
* Parser for display filters
*
* $Id: dfilter-grammar.y,v 1.23 1999/10/11 07:06:43 guy Exp $
* $Id: dfilter-grammar.y,v 1.24 1999/10/11 17:04:31 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -84,12 +84,15 @@ 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_ipv6_value(char *host);
static GNode* dfilter_mknode_ipv6_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, guint length);
static guint32 string_to_value(char *s);
static int ether_str_to_guint8_array(const char *s, guint8 *mac);
static int ipv6_str_to_guint8_array(const char *s, guint8 *ipv6);
/* This is the dfilter we're currently processing. It's how
* dfilter_compile communicates with us.
@ -117,6 +120,7 @@ dfilter *global_df = NULL;
%type <node> ether_value ether_variable
%type <node> ipxnet_value ipxnet_variable
%type <node> ipv4_value ipv4_variable
%type <node> ipv6_value ipv6_variable
%type <node> variable_name
%type <node> bytes_value bytes_variable
@ -131,6 +135,7 @@ dfilter *global_df = NULL;
%token <variable> T_FT_UINT32
%token <variable> T_FT_ETHER
%token <variable> T_FT_IPv4
%token <variable> T_FT_IPv6
%token <variable> T_FT_NONE
%token <variable> T_FT_BYTES
%token <variable> T_FT_BOOLEAN
@ -207,6 +212,15 @@ relation: numeric_variable numeric_relation numeric_value
$$ = dfilter_mknode_join($1, relation, $2, $3);
}
| ipv6_variable equality_relation ipv6_value
{
$$ = dfilter_mknode_join($1, relation, $2, $3);
}
| ipv6_variable equality_relation ipv6_variable
{
$$ = dfilter_mknode_join($1, relation, $2, $3);
}
| bytes_variable bytes_relation bytes_value
{
$$ = dfilter_mknode_join($1, relation, $2, $3);
@ -256,6 +270,19 @@ ipv4_value: T_VAL_UNQUOTED_STRING
}
;
ipv6_value: T_VAL_UNQUOTED_STRING
{
$$ = dfilter_mknode_ipv6_value($1);
g_free($1);
}
| T_VAL_BYTE_STRING
{
$$ = dfilter_mknode_ipv6_value($1);
g_free($1);
}
;
bytes_value: T_VAL_BYTE_STRING
{
GByteArray *barray;
@ -282,6 +309,9 @@ ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1.id); }
ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1.id); }
;
ipv6_variable: T_FT_IPv6 { $$ = dfilter_mknode_ipv6_variable($1.id); }
;
variable_name: any_variable_type
{
GNode *variable;
@ -310,6 +340,7 @@ any_variable_type: T_FT_UINT8 { $$ = $1; }
| T_FT_UINT32 { $$ = $1; }
| T_FT_ETHER { $$ = $1; }
| T_FT_IPv4 { $$ = $1; }
| T_FT_IPv6 { $$ = $1; }
| T_FT_IPXNET { $$ = $1; }
| T_FT_NONE { $$ = $1; }
| T_FT_BYTES { $$ = $1; }
@ -453,6 +484,23 @@ dfilter_mknode_ipv4_variable(gint id)
return gnode;
}
static GNode*
dfilter_mknode_ipv6_variable(gint id)
{
dfilter_node *node;
GNode *gnode;
node = g_mem_chunk_alloc(global_df->node_memchunk);
node->ntype = variable;
node->elem_size = 128;
node->fill_array_func = fill_array_ipv6_variable;
node->check_relation_func = check_relation_ipv6;
node->value.variable = id;
gnode = g_node_new(node);
return gnode;
}
static GNode*
dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
{
@ -559,6 +607,28 @@ dfilter_mknode_ipv4_value(char *host)
return gnode;
}
static GNode*
dfilter_mknode_ipv6_value(char *host)
{
dfilter_node *node;
GNode *gnode;
node = g_mem_chunk_alloc(global_df->node_memchunk);
node->ntype = ipv6;
node->elem_size = 128;
node->fill_array_func = fill_array_ipv6_value;
node->check_relation_func = check_relation_ipv6;
/* XXX should use get_host_ipaddr6 */
if (!ipv6_str_to_guint8_array(host, &node->value.ipv6[0])) {
dfilter_fail("\"%s\" isn't a valid IPv6 address.",
host);
}
gnode = g_node_new(node);
return gnode;
}
static GNode*
dfilter_mknode_bytes_value(GByteArray *barray)
{
@ -641,3 +711,40 @@ ether_str_to_guint8_array(const char *s, guint8 *mac)
return 1; /* read exactly 6 hex pairs */
}
/* converts a string representing an IPV6 address
* to a guint8 array.
*
* Returns 0 on failure, 1 on success.
*/
static int
ipv6_str_to_guint8_array(const char *s, guint8 *ipv6)
{
/* XXX should be deleted as soon as get_host_ipaddr6
is implemented in resolv.c */
char ipv6_str[48];
char *p, *str;
int i = 0;
if (strlen(s) > 47) {
return 0;
}
strcpy(ipv6_str, s); /* local copy of string */
str = ipv6_str;
while ((p = strtok(str, "-:."))) {
/* catch short strings with too many hex bytes */
if (i > 15) {
return 0;
}
ipv6[i] = (guint8) strtoul(p, NULL, 16);
i++;
/* subsequent calls to strtok() require NULL as arg 1 */
str = NULL;
}
if (i != 16)
return 0; /* failed to read 16 hex pairs */
else
return 1; /* read exactly 16 hex pairs */
}

View File

@ -2,7 +2,7 @@
* Definitions for routines common to multiple modules in the display
* filter code, but not used outside that code.
*
* $Id: dfilter-int.h,v 1.8 1999/10/11 06:39:04 guy Exp $
* $Id: dfilter-int.h,v 1.9 1999/10/11 17:04:32 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -54,12 +54,15 @@ void dfilter_fail(char *fmt, ...);
/* functions that dfilter-grammar.y needs during parsing*/
gboolean check_relation_numeric(gint operand, GArray *a, GArray *b);
gboolean check_relation_ether(gint operand, GArray *a, GArray *b);
gboolean check_relation_ipv6(gint operand, GArray *a, GArray *b);
gboolean check_relation_bytes(gint operand, GArray *a, GArray *b);
gboolean fill_array_numeric_value(GNode *gnode, gpointer data);
gboolean fill_array_numeric_variable(GNode *gnode, gpointer data);
gboolean fill_array_ether_value(GNode *gnode, gpointer data);
gboolean fill_array_ether_variable(GNode *gnode, gpointer data);
gboolean fill_array_ipv6_value(GNode *gnode, gpointer data);
gboolean fill_array_ipv6_variable(GNode *gnode, gpointer data);
gboolean fill_array_bytes_value(GNode *gnode, gpointer data);
gboolean fill_array_bytes_variable(GNode *gnode, gpointer data);
@ -80,6 +83,7 @@ enum node_type {
ether,
bytes,
ipv4,
ipv6,
ipxnet
};
@ -107,6 +111,7 @@ typedef struct dfilter_node {
struct timeval abs_time; /* the whole struct, not a pointer */
gchar *string;
guint8 ether[6];
guint8 ipv6[16];
GByteArray *bytes;
} value;

View File

@ -3,7 +3,7 @@
/* dfilter-scanner.l
* Scanner for display filters
*
* $Id: dfilter-scanner.l,v 1.17 1999/10/11 03:03:10 guy Exp $
* $Id: dfilter-scanner.l,v 1.18 1999/10/11 17:04:33 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -200,9 +200,7 @@ le|\<\= { dfilter_lval.operand = TOK_LE; return TOK_LE; }
retval = T_FT_IPv4;
break;
case FT_IPv6:
dfilter_fail("Sorry, you can't filter on field \"%s\", as we don't yet support filtering on IPv6 addresses.",
yytext);
retval = 0;
retval = T_FT_IPv6;
break;
case FT_IPXNET:
retval = T_FT_IPXNET;

View File

@ -1,7 +1,7 @@
/* dfilter.c
* Routines for display filters
*
* $Id: dfilter.c,v 1.27 1999/10/11 14:58:00 gram Exp $
* $Id: dfilter.c,v 1.28 1999/10/11 17:04:34 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -333,6 +333,7 @@ dfilter_apply_node(GNode *gnode, proto_tree *ptree, const guint8* pd, guint len)
case numeric:
case ipv4:
case ipv6:
case boolean:
case ether:
case string:
@ -493,6 +494,18 @@ gboolean fill_array_ether_variable(GNode *gnode, gpointer data)
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
gboolean fill_array_ipv6_variable(GNode *gnode, gpointer data)
{
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
field_info *fi = (field_info*) (gnode->data);
if (fi->hfinfo->id == sinfo->target) {
g_array_append_val(sinfo->result.array, fi->value.ipv6);
}
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
gboolean fill_array_bytes_variable(GNode *gnode, gpointer data)
{
proto_tree_search_info *sinfo = (proto_tree_search_info*)data;
@ -530,6 +543,16 @@ gboolean fill_array_ether_value(GNode *gnode, gpointer data)
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
gboolean fill_array_ipv6_value(GNode *gnode, gpointer data)
{
GArray *array = (GArray*)data;
dfilter_node *dnode = (dfilter_node*) (gnode->data);
g_array_append_val(array, dnode->value.ipv6);
return FALSE; /* FALSE = do not end traversal of GNode tree */
}
gboolean fill_array_bytes_value(GNode *gnode, gpointer data)
{
GArray *array = (GArray*)data;
@ -619,6 +642,42 @@ gboolean check_relation_numeric(gint operand, GArray *a, GArray *b)
return FALSE;
}
gboolean check_relation_ipv6(gint operand, GArray *a, GArray *b)
{
int i, j, len_a, len_b;
guint8 *ptr_a, *ptr_b;
len_a = a->len;
len_b = b->len;
switch(operand) {
case TOK_EQ:
for(i = 0; i < len_a; i++) {
ptr_a = g_array_index_ptr(a, 16, i);
for (j = 0; j < len_b; j++) {
ptr_b = g_array_index_ptr(b, 16, j);
if (memcmp(ptr_a, ptr_b, 16) == 0)
return TRUE;
}
}
return FALSE;
case TOK_NE:
for(i = 0; i < len_a; i++) {
ptr_a = g_array_index_ptr(a, 16, i);
for (j = 0; j < len_b; j++) {
ptr_b = g_array_index_ptr(b, 16, j);
if (memcmp(ptr_a, ptr_b, 16) != 0)
return TRUE;
}
}
return FALSE;
}
g_assert_not_reached();
return FALSE;
}
gboolean check_relation_ether(gint operand, GArray *a, GArray *b)
{

View File

@ -1,7 +1,7 @@
/* packet-ipv6.c
* Routines for IPv6 packet disassembly
*
* $Id: packet-ipv6.c,v 1.13 1999/08/24 17:26:12 gram Exp $
* $Id: packet-ipv6.c,v 1.14 1999/10/11 17:05:49 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -48,6 +48,8 @@
#include "resolv.h"
static int proto_ipv6 = -1;
static int hf_ipv6_src = -1;
static int hf_ipv6_dst = -1;
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
@ -160,8 +162,9 @@ dissect_ipv6(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
offset + offsetof(struct ip6_hdr, ip6_hlim), 1,
"Hop limit: %d", ipv6.ip6_hlim);
proto_tree_add_text(ipv6_tree,
proto_tree_add_item_format(ipv6_tree, hf_ipv6_src,
offset + offsetof(struct ip6_hdr, ip6_src), 16,
&ipv6.ip6_src,
#ifdef INET6
"Source address: %s (%s)",
get_hostname6(&ipv6.ip6_src),
@ -170,8 +173,9 @@ dissect_ipv6(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
#endif
ip6_to_str(&ipv6.ip6_src));
proto_tree_add_text(ipv6_tree,
proto_tree_add_item_format(ipv6_tree, hf_ipv6_dst,
offset + offsetof(struct ip6_hdr, ip6_dst), 16,
&ipv6.ip6_dst,
#ifdef INET6
"Destination address: %s (%s)",
get_hostname6(&ipv6.ip6_dst),
@ -408,11 +412,13 @@ inet_ntop6(src, dst, size)
void
proto_register_ipv6(void)
{
/* static hf_register_info hf[] = {
{ &variable,
{ "Name", "ipv6.abbreviation", TYPE, VALS_POINTER }},
};*/
static hf_register_info hf[] = {
{ &hf_ipv6_src,
{ "Source", "ipv6.src", FT_IPv6, NULL }},
{ &hf_ipv6_dst,
{ "Destination", "ipv6.dst", FT_IPv6, NULL }}
};
proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "ipv6");
/* proto_register_field_array(proto_ipv6, hf, array_length(hf));*/
proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "ipv6");
proto_register_field_array(proto_ipv6, hf, array_length(hf));
}

15
proto.c
View File

@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
* $Id: proto.c,v 1.32 1999/10/08 20:50:37 guy Exp $
* $Id: proto.c,v 1.33 1999/10/11 17:02:06 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -61,6 +61,8 @@
#include "resolv.h"
#endif
#include "packet-ipv6.h"
#define cVALS(x) (const value_string*)(x)
#if defined(HAVE_UCD_SNMP_SNMP_H)
@ -432,6 +434,10 @@ NOTES
fi->value.numeric = va_arg(ap, unsigned int);
break;
case FT_IPv6:
memcpy(fi->value.ipv6, va_arg(ap, guint8*), 16);
break;
case FT_DOUBLE:
fi->value.floating = va_arg(ap, double);
break;
@ -646,6 +652,13 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
get_hostname(fi->value.numeric),
ip_to_str((guint8*)&fi->value.numeric));
break;
case FT_IPv6:
snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", fi->hfinfo->name,
get_hostname6((struct e_in6_addr *)fi->value.ipv6),
ip6_to_str((struct e_in6_addr*)fi->value.ipv6));
break;
case FT_STRING:
snprintf(label_str, ITEM_LABEL_LENGTH,

View File

@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
* $Id: proto.h,v 1.14 1999/10/11 14:58:04 gram Exp $
* $Id: proto.h,v 1.15 1999/10/11 17:02:08 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -110,6 +110,7 @@ typedef struct field_info {
gchar *string;
guint8 *bytes;
guint8 ether[6];
guint8 ipv6[16];
} value;
} field_info;