Add a new "tvb_strsize()" routine, which finds the size of a

NUL-terminated string, starting at a given offset.  The size includes
the terminating NUL.  If it doesn't find the terminating NUL, it throws
the appropriate exception, as either there's no terminating NUL in the
packet or there is but it's past the end of the captured data in the
packet.

Use that routine in the TFTP dissector.  As it throws an exception if
the string isn't NUL-terminated, we can just use "%s" to print option
strings; we don't need to use "%.*s" with a string length.

svn path=/trunk/; revision=2783
This commit is contained in:
Guy Harris 2000-12-25 23:48:16 +00:00
parent cac14407f4
commit d46aa3d576
3 changed files with 53 additions and 41 deletions

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.12 2000/11/30 06:11:32 guy Exp $
* $Id: tvbuff.c,v 1.13 2000/12/25 23:48:15 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -1136,6 +1136,39 @@ tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, guint maxlength, guint8 *needles)
return -1;
}
/* Find size of stringz (NUL-terminated string) by looking for terminating
* NUL. The size of the string includes the terminating NUL.
*
* If the NUL isn't found, it throws the appropriate exception.
*/
guint
tvb_strsize(tvbuff_t *tvb, gint offset)
{
guint abs_offset, junk_length;
gint nul_offset;
check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
if (nul_offset == -1) {
/*
* OK, we hit the end of the tvbuff, so we should throw
* an exception.
*
* Did we hit the end of the captured data, or the end
* of the actual data? If there's less captured data
* than actual data, we presumably hit the end of the
* captured data, otherwise we hit the end of the actual
* data.
*/
if (tvb_length(tvb) < tvb_reported_length(tvb)) {
THROW(BoundsError);
} else {
THROW(ReportedBoundsError);
}
}
return (nul_offset - abs_offset) + 1;
}
/* Find length of string by looking for end of string ('\0'), up to
* 'maxlength' characters'; if 'maxlength' is -1, searches to end
* of tvbuff.

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.8 2000/11/18 10:38:33 guy Exp $
* $Id: tvbuff.h,v 1.9 2000/12/25 23:48:16 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -280,6 +280,13 @@ gint tvb_find_guint8(tvbuff_t*, gint offset, guint maxlength, guint8 needle);
* the boundary is reached before finding needle. */
gint tvb_pbrk_guint8(tvbuff_t *, gint offset, guint maxlength, guint8 *needles);
/* Find size of stringz (NUL-terminated string) by looking for terminating
* NUL. The size of the string includes the terminating NUL.
*
* If the NUL isn't found, it throws the appropriate exception.
*/
guint tvb_strsize(tvbuff_t *tvb, gint offset);
/* Find length of string by looking for end of string ('\0'), up to
* 'maxlength' characters'; if 'maxlength' is -1, searches to end
* of tvbuff.

View File

@ -5,7 +5,7 @@
* Craig Newell <CraigN@cheque.uq.edu.au>
* RFC2347 TFTP Option Extension
*
* $Id: packet-tftp.c,v 1.20 2000/12/24 20:33:04 guy Exp $
* $Id: packet-tftp.c,v 1.21 2000/12/25 23:48:14 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -87,7 +87,6 @@ static const value_string tftp_error_code_vals[] = {
};
static void tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree);
static gint tftp_strnlen(tvbuff_t *tvb, gint offset);
static void
dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@ -152,12 +151,12 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
switch (opcode) {
case RRQ:
i1 = tftp_strnlen(tvb, offset);
i1 = tvb_strsize(tvb, offset);
proto_tree_add_item(tftp_tree, hf_tftp_source_file,
tvb, offset, i1, FALSE);
offset += i1;
i1 = tftp_strnlen(tvb, offset);
i1 = tvb_strsize(tvb, offset);
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
tvb, offset, i1, FALSE);
offset += i1;
@ -165,12 +164,12 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tftp_dissect_options(tvb, offset, tftp_tree);
break;
case WRQ:
i1 = tftp_strnlen(tvb, offset);
i1 = tvb_strsize(tvb, offset);
proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
tvb, offset, i1, FALSE);
offset += i1;
i1 = tftp_strnlen(tvb, offset);
i1 = tvb_strsize(tvb, offset);
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
tvb, offset, i1, FALSE);
offset += i1;
@ -194,7 +193,7 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
FALSE);
offset += 2;
i1 = tftp_strnlen(tvb, offset);
i1 = tvb_strsize(tvb, offset);
proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
i1, FALSE);
break;
@ -217,44 +216,17 @@ tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree)
int value_offset;
while (tvb_offset_exists(tvb, offset)) {
option_len = tftp_strnlen(tvb, offset); /* length of option */
option_len = tvb_strsize(tvb, offset); /* length of option */
value_offset = offset + option_len;
value_len = tftp_strnlen(tvb, value_offset); /* length of value */
value_len = tvb_strsize(tvb, value_offset); /* length of value */
proto_tree_add_text(tree, tvb, offset, option_len+value_len,
"Option: %.*s = %.*s",
option_len - 1, tvb_get_ptr(tvb, offset, option_len - 1),
value_len - 1, tvb_get_ptr(tvb, value_offset, value_len - 1));
"Option: %s = %s",
tvb_get_ptr(tvb, offset, option_len),
tvb_get_ptr(tvb, value_offset, value_len));
offset += option_len + value_len;
}
}
/*
* Find the length of a null-terminated string in a TFTP packet; if we
* don't find the '\0', throw an exception, as it means that either
* we didn't capture enough of the frame, or the frame is malformed.
*
* XXX - we'd like to know *which* exception to throw....
*
* XXX - this should probably be a standard tvbuff accessor.
*
* Add 1 to the resulting length, so that it includes the '\0'.
*/
static gint
tftp_strnlen(tvbuff_t *tvb, gint offset)
{
gint len;
len = tvb_strnlen(tvb, offset, -1);
if (len == -1) {
/*
* No '\0' found before the end of the tvbuff; throw an
* exception.
*/
THROW(BoundsError);
}
return len + 1;
}
void
proto_register_tftp(void)
{