- add handling of FT_IPv6 variables
authordeniel <deniel@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 11 Oct 1999 17:05:49 +0000 (17:05 +0000)
committerdeniel <deniel@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 11 Oct 1999 17:05:49 +0000 (17:05 +0000)
  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)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@808 f5534014-38df-0310-8fa8-9805f1628bb7

dfilter-grammar.y
dfilter-int.h
dfilter-scanner.l
dfilter.c
packet-ipv6.c
proto.c
proto.h

index 722a74bf99b1d2c207fdfdccc815723efe8d6cb6..2d9daf1156fc64557a540f524ea02ee3aef4f1db 100644 (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 */
+}
+
index e447701d2e3e1072c58abc92a54d39e19f6ba2e0..45a90006488e8a63469bc135ad8f18b4a226bffb 100644 (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;
 
index 80e030501cac51c0d3e0b6aeeccf1a1d956a6493..b6bab0d9e2cbc693390a31f6f2d4ffa4d5919526 100644 (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;
index 00b832219a173b51f362e8df84d2a7fdba6604ef..56ac93d336c616a129026067320a43c3a4e4bcf9 100644 (file)
--- a/dfilter.c
+++ b/dfilter.c
@@ -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)
 {
index 22a3e439572de8e09cebc99c210e46431332d039..41a69221680ee06d11948da297538fa2b9e83de4 100644 (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 }},
-        };*/
-
-        proto_ipv6 = proto_register_protocol("Internet Protocol Version 6", "ipv6");
- /*       proto_register_field_array(proto_ipv6, hf, array_length(hf));*/
+  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));
 }
diff --git a/proto.c b/proto.c
index 2f7e1c9bb5320b9720d4b462f8f92aeac5fce4a6..cefed2863f0485f0773dbe8b117e18e3b9430af4 100644 (file)
--- a/proto.c
+++ b/proto.c
@@ -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,
diff --git a/proto.h b/proto.h
index 4fdad5f9c99d01da814a49917081e20f4b24bef6..f60466a9e45cd1da031b8103dc01f4504565cca2 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -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;