diff options
Diffstat (limited to 'packet-rip.c')
-rw-r--r-- | packet-rip.c | 201 |
1 files changed, 103 insertions, 98 deletions
diff --git a/packet-rip.c b/packet-rip.c index 345869d910..e688ac57f8 100644 --- a/packet-rip.c +++ b/packet-rip.c @@ -2,7 +2,7 @@ * Routines for RIPv1 and RIPv2 packet disassembly * (c) Copyright Hannes R. Boehm <hannes@boehm.org> * - * $Id: packet-rip.c,v 1.19 2000/11/17 21:00:36 gram Exp $ + * $Id: packet-rip.c,v 1.20 2000/12/27 12:48:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -37,102 +37,92 @@ #include <string.h> #include <glib.h> #include "packet.h" -#include "packet-rip.h" #define UDP_PORT_RIP 520 +#define RIPv1 1 +#define RIPv2 2 + +static const value_string version_vals[] = { + { RIPv1, "RIPv1" }, + { RIPv2, "RIPv2" }, + { 0, NULL } +}; + +static const value_string command_vals[] = { + { 1, "Request" }, + { 2, "Response" }, + { 3, "Traceon" }, + { 4, "Traceoff" }, + { 5, "Vendor specific (Sun)" }, + { 0, NULL } +}; + +#define RIP_HEADER_LENGTH 4 +#define RIP_ENTRY_LENGTH 20 + static int proto_rip = -1; static gint ett_rip = -1; static gint ett_rip_vec = -1; -static void dissect_ip_rip_vektor(guint8 version, - const e_rip_vektor *rip_vektor, int offset, proto_tree *tree); -static void dissect_rip_authentication(const e_rip_authentication *rip_authentication, - int offset, proto_tree *tree); +static void dissect_ip_rip_vektor(tvbuff_t *tvb, int offset, guint8 version, + proto_tree *tree); +static void dissect_rip_authentication(tvbuff_t *tvb, int offset, + proto_tree *tree); static void -dissect_rip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { - e_riphdr rip_header; - e_rip_entry rip_entry; - guint16 family; +dissect_rip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; proto_tree *rip_tree = NULL; - proto_item *ti; + proto_item *ti; + guint8 command; + guint8 version; + guint16 family; + guint reported_length; - /* we do the range checking of the index when checking wether or not this is a RIP packet */ - static char *packet_type[8] = { "never used", "Request", "Response", - "Traceon", "Traceoff", "Vendor specific (Sun)" }; - static char *version[3] = { "RIP", "RIPv1", "RIPv2" }; + CHECK_DISPLAY_AS_DATA(proto_rip, tvb, pinfo, tree); - OLD_CHECK_DISPLAY_AS_DATA(proto_rip, pd, offset, fd, tree); + pinfo->current_proto = "RIP"; - /* avoid alignment problem */ - memcpy(&rip_header, &pd[offset], sizeof(rip_header)); + command = tvb_get_guint8(tvb, 0); + version = tvb_get_guint8(tvb, 1); - /* Check if we 've realy got a RIP packet */ - - switch(rip_header.version) { - case RIPv1: - /* the domain field has to be set to zero for RIPv1 */ - if(!(rip_header.domain == 0)){ - old_dissect_data(pd, offset, fd, tree); - return; - } - /* the RIPv2 checks are also made for v1 packets */ - case RIPv2: - /* check wether or not command nr. is between 1-7 - * (range checking for index of char* packet_type is done at the same time) - */ - if( !( (rip_header.command > 0) && (rip_header.command <= 7) )){ - old_dissect_data(pd, offset, fd, tree); - return; - } - break; - default: - /* we only know RIPv1 and RIPv2 */ - old_dissect_data(pd, offset, fd, tree); - return; - } - - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, version[rip_header.version] ); - if (check_col(fd, COL_INFO)) - col_add_str(fd, COL_INFO, packet_type[rip_header.command]); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, + val_to_str(version, version_vals, "RIP")); + if (check_col(pinfo->fd, COL_INFO)) + col_add_str(pinfo->fd, COL_INFO, + val_to_str(command, command_vals, "Unknown command (%u)")); if (tree) { - ti = proto_tree_add_item(tree, proto_rip, NullTVB, offset, END_OF_FRAME, FALSE); + ti = proto_tree_add_item(tree, proto_rip, tvb, 0, tvb_length(tvb), FALSE); rip_tree = proto_item_add_subtree(ti, ett_rip); - proto_tree_add_text(rip_tree, NullTVB, offset, 1, "Command: %d (%s)", rip_header.command, packet_type[rip_header.command]); - proto_tree_add_text(rip_tree, NullTVB, offset + 1, 1, "Version: %d", rip_header.version); - if(rip_header.version == RIPv2) - proto_tree_add_text(rip_tree, NullTVB, offset + 2 , 2, "Routing Domain: %d", ntohs(rip_header.domain)); + proto_tree_add_text(rip_tree, tvb, 0, 1, "Command: %u (%s)", command, + val_to_str(command, command_vals, "Unknown")); + proto_tree_add_text(rip_tree, tvb, 1, 1, "Version: %u", version); + if (version == RIPv2) + proto_tree_add_text(rip_tree, tvb, 2, 2, "Routing Domain: %u", + tvb_get_ntohs(tvb, 2)); /* skip header */ - offset += RIP_HEADER_LENGTH; + offset = RIP_HEADER_LENGTH; /* zero or more entries */ - - while((pi.captured_len - offset) >= RIP_ENTRY_LENGTH){ - memcpy(&rip_entry, &pd[offset], sizeof(rip_entry)); /* avoid alignment problem */ - family = ntohs(rip_entry.vektor.family); + reported_length = tvb_reported_length(tvb); + while (offset < reported_length) { + family = tvb_get_ntohs(tvb, offset); switch (family) { case 2: /* IP */ - ti = proto_tree_add_text(rip_tree, NullTVB, offset, - RIP_ENTRY_LENGTH, "IP Address: %s, Metric: %ld", - ip_to_str((guint8 *) &(rip_entry.vektor.ip)), - (long)ntohl(rip_entry.vektor.metric)); - dissect_ip_rip_vektor(rip_header.version, &rip_entry.vektor, - offset, ti); + dissect_ip_rip_vektor(tvb, offset, version, rip_tree); break; case 0xFFFF: - proto_tree_add_text(rip_tree, NullTVB, offset, - RIP_ENTRY_LENGTH, "Authentication"); - dissect_rip_authentication(&rip_entry.authentication, - offset, ti); + dissect_rip_authentication(tvb, offset, rip_tree); break; default: - proto_tree_add_text(rip_tree, NullTVB, offset, + proto_tree_add_text(rip_tree, tvb, offset, RIP_ENTRY_LENGTH, "Unknown address family %u", family); break; @@ -144,45 +134,60 @@ dissect_rip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { } static void -dissect_ip_rip_vektor(guint8 version, const e_rip_vektor *rip_vektor, - int offset, proto_tree *tree) +dissect_ip_rip_vektor(tvbuff_t *tvb, int offset, guint8 version, + proto_tree *tree) { + proto_item *ti; proto_tree *rip_vektor_tree; - - rip_vektor_tree = proto_item_add_subtree(tree, ett_rip_vec); + guint8 *ip; + guint32 metric; + + ip = tvb_get_ptr(tvb, offset+4, 4); + metric = tvb_get_ntohl(tvb, offset+16); + ti = proto_tree_add_text(tree, tvb, offset, + RIP_ENTRY_LENGTH, "IP Address: %s, Metric: %u", + ip_to_str(ip), metric); + rip_vektor_tree = proto_item_add_subtree(ti, ett_rip_vec); - proto_tree_add_text(rip_vektor_tree, NullTVB, offset, 2, "Address Family ID: IP"); - if(version == RIPv2) - proto_tree_add_text(rip_vektor_tree, NullTVB, offset + 2 , 2, "Route Tag: %d", - ntohs(rip_vektor->tag)); - proto_tree_add_text(rip_vektor_tree, NullTVB, offset + 4, 4, "IP Address: %s", - ip_to_str((guint8 *) &(rip_vektor->ip))); - if(version == RIPv2) { - proto_tree_add_text(rip_vektor_tree, NullTVB, offset + 8 , 4, "Netmask: %s", - ip_to_str((guint8 *) &(rip_vektor->mask))); - proto_tree_add_text(rip_vektor_tree, NullTVB, offset + 12, 4, "Next Hop: %s", - ip_to_str((guint8 *) &(rip_vektor->next_hop))); + proto_tree_add_text(rip_vektor_tree, tvb, offset, 2, + "Address Family ID: IP"); + if (version == RIPv2) + proto_tree_add_text(rip_vektor_tree, tvb, offset + 2, 2, + "Route Tag: %u", tvb_get_ntohs(tvb, offset+2)); + proto_tree_add_text(rip_vektor_tree, tvb, offset + 4, 4, "IP Address: %s", + ip_to_str(ip)); + if (version == RIPv2) { + proto_tree_add_text(rip_vektor_tree, tvb, offset + 8, 4, + "Netmask: %s", + ip_to_str(tvb_get_ptr(tvb, offset + 8, 4))); + proto_tree_add_text(rip_vektor_tree, tvb, offset + 12, 4, + "Next Hop: %s", + ip_to_str(tvb_get_ptr(tvb, offset+12, 4))); } - proto_tree_add_text(rip_vektor_tree, NullTVB, offset + 16, 4, "Metric: %ld", - (long)ntohl(rip_vektor->metric)); + proto_tree_add_text(rip_vektor_tree, tvb, offset + 16, 4, "Metric: %u", + metric); } static void -dissect_rip_authentication(const e_rip_authentication *rip_authentication, - int offset, proto_tree *tree) +dissect_rip_authentication(tvbuff_t *tvb, int offset, proto_tree *tree) { + proto_item *ti; proto_tree *rip_authentication_tree; guint16 authtype; - - rip_authentication_tree = proto_item_add_subtree(tree, ett_rip_vec); - - authtype = ntohs(rip_authentication->authtype); - proto_tree_add_text(rip_authentication_tree, NullTVB, offset + 2, 2, - "Authentication type: %u", authtype); - if (authtype == 2) - proto_tree_add_text(rip_authentication_tree, NullTVB, offset + 4 , 16, - "Password: %.16s", - rip_authentication->authentication); + char authentication[16]; + + ti = proto_tree_add_text(tree, tvb, offset, RIP_ENTRY_LENGTH, + "Authentication"); + rip_authentication_tree = proto_item_add_subtree(ti, ett_rip_vec); + + authtype = tvb_get_ntohs(tvb, offset + 2); + proto_tree_add_text(rip_authentication_tree, tvb, offset + 2, 2, + "Authentication type: %u", authtype); + if (authtype == 2) { + tvb_get_nstringz0(tvb, offset + 4, 16, authentication); + proto_tree_add_text(rip_authentication_tree, tvb, offset + 4, 16, + "Password: %s", authentication); + } } void @@ -205,5 +210,5 @@ proto_register_rip(void) void proto_reg_handoff_rip(void) { - old_dissector_add("udp.port", UDP_PORT_RIP, dissect_rip); + dissector_add("udp.port", UDP_PORT_RIP, dissect_rip); } |