Tvbuffify the RIP and OSPF dissectors.

Change them to use facilities in Ethereal that were probably not present
when they were originally written, e.g. routines to fetch 24-bit
integers and to dump a bunch of raw bytes in hex.

Redo them to extract data from the packet as they dissect it, rather
than extracting an entire data structure at once; that way, it may be
able to dissect a structure not all of which is in the packet.

Dissect a bit more of the type-of-service metrics etc. in OSPF packets.

Make "tvb_length_remaining()" return a "gint", not a "guint"; it returns
-1 if the offset is past the end of the tvbuff.

Add a "tvb_reported_length_remaining()" routine, similar to
"tvb_length_remaining()".  Use it instead of just subtracting an offset
from "tvb_reported_length()".

svn path=/trunk/; revision=2787
This commit is contained in:
Guy Harris 2000-12-27 12:48:27 +00:00
parent 7e8b1d3a10
commit 11b24c6094
8 changed files with 885 additions and 990 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.262 2000/12/24 09:10:11 guy Exp $
# $Id: Makefile.am,v 1.263 2000/12/27 12:48:25 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -227,13 +227,11 @@ noinst_HEADERS = \
packet-null.h \
packet-osi.h \
packet-osi-options.h \
packet-ospf.h \
packet-portmap.h \
packet-ppp.h \
packet-q2931.h \
packet-q931.h \
packet-raw.h \
packet-rip.h \
packet-ripng.h \
packet-rpc.h \
packet-rtcp.h \

View File

@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
* $Id: tvbuff.c,v 1.13 2000/12/25 23:48:15 guy Exp $
* $Id: tvbuff.c,v 1.14 2000/12/27 12:48:27 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -570,7 +570,7 @@ tvb_length(tvbuff_t* tvb)
return tvb->length;
}
guint
gint
tvb_length_remaining(tvbuff_t *tvb, gint offset)
{
guint abs_offset, abs_length;
@ -632,6 +632,24 @@ tvb_reported_length(tvbuff_t* tvb)
return tvb->reported_length;
}
gint
tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
{
guint abs_offset, abs_length;
g_assert(tvb->initialized);
if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
if (tvb->reported_length >= abs_offset)
return tvb->reported_length - abs_offset;
else
return -1;
}
else {
return -1;
}
}
/* Set the reported length of a tvbuff to a given value; used for protocols
whose headers contain an explicit length and where the calling
dissector's payload may include padding as well as the packet for

View File

@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
* $Id: tvbuff.h,v 1.9 2000/12/25 23:48:16 guy Exp $
* $Id: tvbuff.h,v 1.10 2000/12/27 12:48:27 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -189,7 +189,7 @@ guint tvb_length(tvbuff_t*);
/* Computes bytes to end of buffer, from offset (which can be negative,
* to indicate bytes from end of buffer). Function returns -1 to
* indicate that offset is out of bounds. No exception is thrown. */
guint tvb_length_remaining(tvbuff_t*, gint offset);
gint tvb_length_remaining(tvbuff_t*, gint offset);
/* Checks (w/o throwing exception) that the bytes referred to by 'offset'/'length'
* actualy exist in the buffer */
@ -201,6 +201,12 @@ gboolean tvb_offset_exists(tvbuff_t*, gint offset);
/* Get reported length of buffer */
guint tvb_reported_length(tvbuff_t*);
/* Computes bytes of reported packet data to end of buffer, from offset
* (which can be negative, to indicate bytes from end of buffer). Function
* returns -1 to indicate that offset is out of bounds. No exception is
* thrown. */
gint tvb_reported_length_remaining(tvbuff_t *tvb, gint offset);
/* Set the reported length of a tvbuff to a given value; used for protocols
whose headers contain an explicit length and where the calling
dissector's payload may include padding as well as the packet for

File diff suppressed because it is too large Load Diff

View File

@ -1,167 +0,0 @@
/* packet-ospf.h
*
* $Id: packet-ospf.h,v 1.10 2000/09/13 07:47:10 guy Exp $
*
* (c) 1998 Hannes Boehm
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* 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.
*/
#ifndef __PACKET_OSPF_H__
#define __PACKET_OSPF_H__
#define OSPF_HEADER_LENGTH 24
#define OSPF_HELLO 1
#define OSPF_DB_DESC 2
#define OSPF_LS_REQ 3
#define OSPF_LS_UPD 4
#define OSPF_LS_ACK 5
#define OSPF_AUTH_NONE 0
#define OSPF_AUTH_SIMPLE 1
#define OSPF_AUTH_CRYPT 2
#define OSPF_OPTIONS_E 2
#define OSPF_OPTIONS_MC 4
#define OSPF_OPTIONS_NP 8
#define OSPF_OPTIONS_EA 16
#define OSPF_OPTIONS_DC 32
#define OSPF_DBD_FLAG_MS 1
#define OSPF_DBD_FLAG_M 2
#define OSPF_DBD_FLAG_I 4
#define OSPF_LS_REQ_LENGTH 12
#define OSPF_LSTYPE_ROUTER 1
#define OSPF_LSTYPE_NETWORK 2
#define OSPF_LSTYPE_SUMMERY 3
#define OSPF_LSTYPE_ASBR 4
#define OSPF_LSTYPE_ASEXT 5
#define OSPF_LSTYPE_ASEXT7 7
/* Opaque LSA types */
#define OSPF_LSTYPE_OP_LINKLOCAL 9
#define OSPF_LSTYPE_OP_AREALOCAL 10
#define OSPF_LSTYPE_OP_ASWIDE 11
#define OSPF_LINK_PTP 1
#define OSPF_LINK_TRANSIT 2
#define OSPF_LINK_STUB 3
#define OSPF_LINK_VIRTUAL 4
#define OSPF_LSA_HEADER_LENGTH 20
/* Known opaque LSAs */
#define OSPF_LSA_MPLS_TE 1
typedef struct _e_ospfhdr {
guint8 version;
guint8 packet_type;
guint16 length;
guint32 routerid;
guint32 area;
guint16 checksum;
guint16 auth_type;
char auth_data[8];
} e_ospfhdr;
typedef struct _e_ospf_hello {
guint32 network_mask;
guint16 hellointervall;
guint8 options;
guint8 priority;
guint32 dead_interval;
guint32 drouter;
guint32 bdrouter;
} e_ospf_hello ;
typedef struct _e_ospf_dbd {
guint16 interface_mtu;
guint8 options;
guint8 flags;
guint32 dd_sequence;
} e_ospf_dbd;
typedef struct _e_ospf_ls_req {
guint32 ls_type;
guint32 ls_id;
guint32 adv_router;
} e_ospf_ls_req;
typedef struct _e_ospf_lsa_hdr {
guint16 ls_age;
guint8 options;
guint8 ls_type;
guint32 ls_id;
guint32 adv_router;
guint32 ls_seq;
guint16 ls_checksum;
guint16 length;
} e_ospf_lsa_hdr;
typedef struct _e_ospf_router_lsa {
guint8 flags;
guint8 empfty;
guint16 nr_links;
} e_ospf_router_lsa;
typedef struct _e_ospf_router_data {
guint32 link_id;
guint32 link_data;
guint8 link_type;
guint8 nr_tos;
guint16 tos0_metric;
} e_ospf_router_data;
typedef struct _e_ospf_router_metric {
guint8 tos;
guint8 empty;
guint16 metric;
} e_ospf_router_metric;
typedef struct _e_ospf_network_lsa {
guint32 network_mask;
} e_ospf_network_lsa;
typedef struct _e_ospf_lsa_upd_hdr {
guint32 lsa_nr;
} e_ospf_lsa_upd_hdr;
typedef struct _e_ospf_summary_lsa {
guint32 network_mask;
} e_ospf_summary_lsa;
typedef struct _e_ospf_asexternal_lsa {
guint8 options;
guint8 metric[3];
guint32 gateway;
guint32 external_tag;
} e_ospf_asexternal_lsa;
typedef struct _e_ospf_crypto {
guint16 mbz;
guint8 key_id;
guint8 length;
guint32 sequence_num;
} e_ospf_crypto;
#endif

View File

@ -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;
guint8 *ip;
guint32 metric;
rip_vektor_tree = proto_item_add_subtree(tree, ett_rip_vec);
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;
char authentication[16];
rip_authentication_tree = proto_item_add_subtree(tree, ett_rip_vec);
ti = proto_tree_add_text(tree, tvb, offset, RIP_ENTRY_LENGTH,
"Authentication");
rip_authentication_tree = proto_item_add_subtree(ti, 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);
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);
}

View File

@ -1,62 +0,0 @@
/* packet-rip.h
*
* $Id: packet-rip.h,v 1.6 2000/08/11 13:34:02 deniel Exp $
*
* (c) 1998 Hannes Boehm
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* 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.
*/
#ifndef __PACKET_RIP_H__
#define __PACKET_RIP_H__
#define RIPv1 1
#define RIPv2 2
#define RIP_HEADER_LENGTH 4
#define RIP_ENTRY_LENGTH 20
typedef struct _e_riphdr {
guint8 command;
guint8 version;
guint16 domain;
} e_riphdr;
typedef struct _e_rip_vektor {
guint16 family;
guint16 tag;
guint32 ip;
guint32 mask;
guint32 next_hop;
guint32 metric;
} e_rip_vektor;
typedef struct _e_rip_authentication {
guint16 family;
guint16 authtype;
guint8 authentication[16];
} e_rip_authentication;
typedef union _e_rip_entry {
e_rip_vektor vektor;
e_rip_authentication authentication;
} e_rip_entry;
#endif

View File

@ -4,7 +4,7 @@
* Jason Lango <jal@netapp.com>
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
*
* $Id: packet-rtsp.c,v 1.29 2000/12/02 06:05:29 guy Exp $
* $Id: packet-rtsp.c,v 1.30 2000/12/27 12:48:25 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -446,7 +446,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
* boundaries, we'll need to remember the actual
* content length.
*/
reported_datalen = tvb_reported_length(tvb) - offset;
reported_datalen = tvb_reported_length_remaining(tvb, offset);
if (content_length > reported_datalen)
content_length = reported_datalen;
}