sensitivity of packet range options fine tuning:
[obnox/wireshark/wip.git] / packet-vrrp.c
index f9382c991c6cf2e04e5b5829bfe38a75e3e66fa9..fbf485c488d249d6ccfc0976790cb5a934df81b6 100644 (file)
@@ -4,22 +4,22 @@
  *
  * Heikki Vatiainen <hessu@cs.tut.fi>
  *
- * $Id: packet-vrrp.c,v 1.21 2002/01/24 09:20:52 guy Exp $
+ * $Id: packet-vrrp.c,v 1.27 2003/06/12 06:58:38 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * 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.
 # include "config.h"
 #endif
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
 #include <string.h>
 #include <glib.h>
 #include <epan/packet.h>
@@ -56,6 +48,7 @@ static gint hf_vrrp_count_ip = -1;
 static gint hf_vrrp_auth_type = -1;
 static gint hf_vrrp_adver_int = -1;
 static gint hf_vrrp_ip = -1;
+static gint hf_vrrp_ip6 = -1;
 
 #define VRRP_VERSION_MASK 0xf0
 #define VRRP_TYPE_MASK 0x0f
@@ -95,13 +88,14 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         int offset = 0;
         gint vrrp_len;
         guint8  ver_type;
-       vec_t cksum_vec[1];
+       vec_t cksum_vec[4];
+       guint32 phdr[2];
 
         if (check_col(pinfo->cinfo, COL_PROTOCOL))
                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VRRP");
         if (check_col(pinfo->cinfo, COL_INFO))
                 col_clear(pinfo->cinfo, COL_INFO);
-        
+
        ver_type = tvb_get_guint8(tvb, 0);
         if (check_col(pinfo->cinfo, COL_INFO)) {
                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%u)",
@@ -111,9 +105,9 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         if (tree) {
                 proto_item *ti, *tv;
                 proto_tree *vrrp_tree, *ver_type_tree;
-                guint8 priority, ip_count, auth_type;
+                guint8 priority, ip_count = 0, auth_type;
                 guint16 cksum, computed_cksum;
-                guint8 auth_buf[VRRP_AUTH_DATA_LEN+1];
+                guint8 auth_buf[VRRP_AUTH_DATA_LEN + 1];
 
                 ti = proto_tree_add_item(tree, proto_vrrp, tvb, 0, -1, FALSE);
                 vrrp_tree = proto_item_add_subtree(ti, ett_vrrp);
@@ -129,7 +123,7 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 proto_tree_add_uint(ver_type_tree, hf_vrrp_type, tvb, offset, 1,
                                     ver_type);
                 offset++;
-                
+
                 proto_tree_add_item(vrrp_tree, hf_vrrp_virt_rtr_id, tvb, offset, 1, FALSE);
                 offset++;
 
@@ -139,9 +133,19 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                            val_to_str(priority, vrrp_prio_vals, "Non-default backup priority"));
                 offset++;
 
-                ip_count = tvb_get_guint8(tvb, offset);
-                proto_tree_add_uint(vrrp_tree, hf_vrrp_count_ip, tvb, offset, 1, ip_count);
-                offset++;
+               switch(hi_nibble(ver_type)) {
+               case 3:
+                       /* Skip reserve field */
+                       offset++;
+                       break;
+               case 2:
+               default:
+                       ip_count = tvb_get_guint8(tvb, offset);
+                       proto_tree_add_uint(vrrp_tree, hf_vrrp_count_ip, tvb,
+                           offset, 1, ip_count);
+                       offset++;
+                       break;
+               }
 
                 auth_type = tvb_get_guint8(tvb, offset);
                 proto_tree_add_item(vrrp_tree, hf_vrrp_auth_type, tvb, offset, 1, FALSE);
@@ -155,9 +159,28 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 if (!pinfo->fragmented && (gint)tvb_length(tvb) >= vrrp_len) {
                         /* The packet isn't part of a fragmented datagram
                            and isn't truncated, so we can checksum it. */
-                        cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, vrrp_len);
-                        cksum_vec[0].len = vrrp_len;
-                        computed_cksum = in_cksum(&cksum_vec[0], 1);
+                       switch(hi_nibble(ver_type)) {
+                       case 3:
+                               /* Set up the fields of the pseudo-header. */
+                               cksum_vec[0].ptr = pinfo->src.data;
+                               cksum_vec[0].len = pinfo->src.len;
+                               cksum_vec[1].ptr = pinfo->dst.data;
+                               cksum_vec[1].len = pinfo->dst.len;
+                               cksum_vec[2].ptr = (const guint8 *)&phdr;
+                               phdr[0] = g_htonl(vrrp_len);
+                               phdr[1] = g_htonl(IP_PROTO_VRRP);
+                               cksum_vec[2].len = 8;
+                               cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, vrrp_len);
+                               cksum_vec[3].len = vrrp_len;
+                               computed_cksum = in_cksum(cksum_vec, 4);
+                               break;
+                       case 2:
+                       default:
+                               cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, vrrp_len);
+                               cksum_vec[0].len = vrrp_len;
+                               computed_cksum = in_cksum(&cksum_vec[0], 1);
+                               break;
+                       }
                         if (computed_cksum == 0) {
                                 proto_tree_add_text(vrrp_tree, tvb, offset, 2,
                                                     "Checksum: 0x%04x (correct)",
@@ -174,16 +197,25 @@ dissect_vrrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 }
                 offset+=2;
 
-                while (ip_count > 0) {
-                        proto_tree_add_item(vrrp_tree, hf_vrrp_ip, tvb, offset, 4, FALSE);
-                        offset+=4;
-                        ip_count--;
-                }
-
+               switch(hi_nibble(ver_type)) {
+               case 3:
+                       proto_tree_add_item(vrrp_tree, hf_vrrp_ip6, tvb, offset, 16, FALSE);
+                       offset+=16;
+                       break;
+               case 2:
+               default:
+                       while (ip_count > 0) {
+                               proto_tree_add_item(vrrp_tree, hf_vrrp_ip, tvb,
+                                   offset, 4, FALSE);
+                               offset+=4;
+                               ip_count--;
+                       }
+                       break;
+               }
                 if (auth_type != VRRP_AUTH_TYPE_SIMPLE_TEXT)
                         return; /* Contents of the authentication data is undefined */
 
-                tvb_get_nstringz0(tvb, offset, VRRP_AUTH_DATA_LEN, auth_buf);
+                tvb_get_nstringz0(tvb, offset, sizeof auth_buf, auth_buf);
                 if (auth_buf[0] != '\0')
                         proto_tree_add_text(vrrp_tree, tvb, offset,
                                             VRRP_AUTH_DATA_LEN,
@@ -241,6 +273,10 @@ void proto_register_vrrp(void)
                    FT_IPv4, 0, NULL, 0x0,
                    "IP address associated with the virtual router", HFILL }},
 
+                { &hf_vrrp_ip6,
+                  {"IPv6 Address", "vrrp.ipv6_addr",
+                   FT_IPv6, 0, NULL, 0x0,
+                   "IPv6 address associated with the virtual router", HFILL }},
         };
 
         static gint *ett[] = {