diff --git a/AUTHORS b/AUTHORS index 45d6e1308c..8f0d480143 100644 --- a/AUTHORS +++ b/AUTHORS @@ -180,6 +180,8 @@ Greg Hankins { Heikki Vatiainen { SAP (Session Announcement Protocol) support + VRRP (Virtual Router Redundancy) + HSRP (Hot Standby Router Protocol) } Alain Magloire was kind enough to diff --git a/Makefile.am b/Makefile.am index fbbfce641f..86c668c6c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.114 1999/11/21 14:43:51 gram Exp $ +# $Id: Makefile.am,v 1.115 1999/11/21 20:02:29 gram Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs @@ -56,6 +56,7 @@ DISSECTOR_SOURCES = \ packet-ftp.c \ packet-giop.c \ packet-gre.c \ + packet-hsrp.c \ packet-http.c \ packet-icmpv6.c\ packet-icp.c \ diff --git a/packet-hsrp.c b/packet-hsrp.c new file mode 100644 index 0000000000..298841b650 --- /dev/null +++ b/packet-hsrp.c @@ -0,0 +1,162 @@ +/* packet-hsrp.c + * Routines for the Cisco Hot Standby Router Protocol (HSRP) + * RFC2281 + * + * Heikki Vatiainen + * + * $Id: packet-hsrp.c,v 1.1 1999/11/21 20:02:30 gram Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * Copied from packet-vrrp.c + * + * 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 +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#include +#include "packet.h" + +static gint proto_hsrp = -1; +static gint ett_hsrp = -1; + +struct hsrp_packet { /* Multicast to 224.0.0.2, TTL 1, UDP, port 1985 */ + guint8 version; /* RFC2281 describes version 0 */ + guint8 opcode; + guint8 state; +#define HSRP_DEFAULT_HELLOTIME 3 + guint8 hellotime; /* In seconds */ +#define HSRP_DEFAULT_HOLDTIME 10 + guint8 holdtime; /* In seconds */ + guint8 priority; /* Higher is stronger, highest IP address tie-breaker */ + guint8 group; /* Identifies the standby group */ + guint8 reserved; + guint8 auth_data[8]; /* Clear-text password, recommended default is `cisco' */ + guint32 virt_ip_addr; /* The virtual IP address used by this group */ +}; + + +#define HSRP_OPCODE_HELLO 0 +#define HSRP_OPCODE_COUP 1 +#define HSRP_OPCODE_RESIGN 2 +static const value_string hsrp_opcode_vals[] = { + {HSRP_OPCODE_HELLO, "Hello"}, + {HSRP_OPCODE_COUP, "Coup"}, + {HSRP_OPCODE_RESIGN, "Resign"} +}; + +#define HSRP_STATE_INITIAL 0 +#define HSRP_STATE_LEARN 1 +#define HSRP_STATE_LISTEN 2 +#define HSRP_STATE_SPEAK 4 +#define HSRP_STATE_STANDBY 8 +#define HSRP_STATE_ACTIVE 16 +static const value_string hsrp_state_vals[] = { + {HSRP_STATE_INITIAL, "Initial"}, + {HSRP_STATE_LEARN, "Learn"}, + {HSRP_STATE_LISTEN, "Listen"}, + {HSRP_STATE_SPEAK, "Speak"}, + {HSRP_STATE_STANDBY, "Standby"}, + {HSRP_STATE_ACTIVE, "Active"} +}; + +void dissect_hsrp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + struct hsrp_packet hsrp; + gboolean short_packet = FALSE; + + if (sizeof(struct hsrp_packet) > END_OF_FRAME) + short_packet = TRUE; + else + memcpy(&hsrp, pd + offset, sizeof(struct hsrp_packet)); + + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "HSRP"); + + if (check_col(fd, COL_INFO)) { + if (short_packet) + col_add_fstr(fd, COL_INFO, "Short packet, length %u", END_OF_FRAME); + else + col_add_fstr(fd, COL_INFO, "%s (state %s)", + val_to_str(hsrp.opcode, hsrp_opcode_vals, "Unknown"), + val_to_str(hsrp.state, hsrp_state_vals, "Unknown")); + } + + if (tree) { + proto_item *ti; + proto_tree *hsrp_tree; + guint8 auth_buf[sizeof(hsrp.auth_data) + 1]; + + if (short_packet) { + dissect_data(pd, offset, fd, tree); + return; + } + + ti = proto_tree_add_item(tree, proto_hsrp, offset, END_OF_FRAME, NULL); + hsrp_tree = proto_item_add_subtree(ti, ett_hsrp); + + proto_tree_add_text(hsrp_tree, offset++, 1, "Version: %u", hsrp.version); + proto_tree_add_text(hsrp_tree, offset++, 1, "Opcode: %u (%s)", hsrp.opcode, + val_to_str(hsrp.opcode, hsrp_opcode_vals, "Unknown")); + proto_tree_add_text(hsrp_tree, offset++, 1, "State: %u (%s)", hsrp.state, + val_to_str(hsrp.state, hsrp_state_vals, "Unknown")); + + proto_tree_add_text(hsrp_tree, offset++, 1, "Hellotime: %u second%s (%sdefault)", + hsrp.hellotime, plurality(hsrp.hellotime, "", "s"), + (hsrp.hellotime == HSRP_DEFAULT_HELLOTIME) ? "" : "non-"); + proto_tree_add_text(hsrp_tree, offset++, 1, "Holdtime: %u second%s (%sdefault)", + hsrp.holdtime, plurality(hsrp.holdtime, "", "s"), + (hsrp.holdtime == HSRP_DEFAULT_HOLDTIME) ? "" : "non-"); + proto_tree_add_text(hsrp_tree, offset++, 1, "Priority: %u", hsrp.priority); + proto_tree_add_text(hsrp_tree, offset++, 1, "Group: %u", hsrp.group); + proto_tree_add_text(hsrp_tree, offset++, 1, "Reserved: 0x%x", hsrp.reserved); + + memcpy(auth_buf, hsrp.auth_data, sizeof(hsrp.auth_data)); + auth_buf[sizeof(auth_buf)] = '\0'; + proto_tree_add_text(hsrp_tree, offset, 8, "Authentication Data: `%s'", auth_buf); + offset+=8; + + proto_tree_add_text(hsrp_tree, offset++, 4, "Virtual IP address: %s", + ip_to_str((guint8 *)&hsrp.virt_ip_addr)); + + } + + return; +} + +void proto_register_hsrp(void) +{ + static gint *ett[] = { + &ett_hsrp, + }; + + proto_hsrp = proto_register_protocol("Cisco Hot Standby Router Protocol", "hsrp"); + proto_register_subtree_array(ett, array_length(ett)); + + return; +} diff --git a/packet-udp.c b/packet-udp.c index 126a0a3eaf..92c8d2e6df 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,7 +1,7 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.36 1999/11/17 02:17:07 guy Exp $ + * $Id: packet-udp.c,v 1.37 1999/11/21 20:02:31 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -80,6 +80,7 @@ typedef struct _e_udphdr { #define UDP_PORT_RADIUS_NEW 1812 #define UDP_PORT_RADACCT 1646 #define UDP_PORT_RADACCT_NEW 1813 +#define UDP_PORT_HSRP 1985 #define UDP_PORT_ICP 3130 #define UDP_PORT_ICQ 4000 #define UDP_PORT_SAP 9875 @@ -173,6 +174,7 @@ void init_dissect_udp(void) { udp_hash_add(UDP_PORT_BOOTPS, dissect_bootp); udp_hash_add(UDP_PORT_TFTP, dissect_tftp); udp_hash_add(UDP_PORT_SAP, dissect_sap); + udp_hash_add(UDP_PORT_HSRP, dissect_hsrp); } diff --git a/packet.h b/packet.h index afba8aaee5..64fcd594a4 100644 --- a/packet.h +++ b/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.148 1999/11/21 14:43:53 gram Exp $ + * $Id: packet.h,v 1.149 1999/11/21 20:02:32 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -328,6 +328,7 @@ void dissect_eth(const u_char *, int, frame_data *, proto_tree *); void dissect_ftp(const u_char *, int, frame_data *, proto_tree *); void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *); void dissect_giop(const u_char *, int, frame_data *, proto_tree *); +void dissect_hsrp(const u_char *, int, frame_data *, proto_tree *); void dissect_http(const u_char *, int, frame_data *, proto_tree *); void dissect_icmp(const u_char *, int, frame_data *, proto_tree *); void dissect_icmpv6(const u_char *, int, frame_data *, proto_tree *);