forked from osmocom/wireshark
Add a "tftp_strnlen()" routine that
1) checks to make sure that the terminating '\0' is found in the string, and throws a BoundsError exception if it isn't (TFTP packets should fit in a single frame, so if the '\0' isn't found, that's an error); 2) adds 1 to the length to include the trailing '\0'; and use it to find all string lengths, so that we properly handle short or malformed frames. svn path=/trunk/; revision=2778
This commit is contained in:
parent
60f9476740
commit
a184a9d612
|
@ -5,7 +5,7 @@
|
||||||
* Craig Newell <CraigN@cheque.uq.edu.au>
|
* Craig Newell <CraigN@cheque.uq.edu.au>
|
||||||
* RFC2347 TFTP Option Extension
|
* RFC2347 TFTP Option Extension
|
||||||
*
|
*
|
||||||
* $Id: packet-tftp.c,v 1.19 2000/12/02 08:41:08 guy Exp $
|
* $Id: packet-tftp.c,v 1.20 2000/12/24 20:33:04 guy Exp $
|
||||||
*
|
*
|
||||||
* Ethereal - Network traffic analyzer
|
* Ethereal - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@zing.org>
|
* By Gerald Combs <gerald@zing.org>
|
||||||
|
@ -87,6 +87,7 @@ static const value_string tftp_error_code_vals[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree);
|
static void tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree);
|
||||||
|
static gint tftp_strnlen(tvbuff_t *tvb, gint offset);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
@ -151,28 +152,28 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case RRQ:
|
case RRQ:
|
||||||
i1 = tvb_strnlen(tvb, offset, -1);
|
i1 = tftp_strnlen(tvb, offset);
|
||||||
proto_tree_add_item(tftp_tree, hf_tftp_source_file,
|
proto_tree_add_item(tftp_tree, hf_tftp_source_file,
|
||||||
tvb, offset, i1 + 1, FALSE);
|
tvb, offset, i1, FALSE);
|
||||||
offset += i1 + 1;
|
offset += i1;
|
||||||
|
|
||||||
i1 = tvb_strnlen(tvb, offset, -1);
|
i1 = tftp_strnlen(tvb, offset);
|
||||||
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
|
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
|
||||||
tvb, offset, i1 + 1, FALSE);
|
tvb, offset, i1, FALSE);
|
||||||
offset += i1 + 1;
|
offset += i1;
|
||||||
|
|
||||||
tftp_dissect_options(tvb, offset, tftp_tree);
|
tftp_dissect_options(tvb, offset, tftp_tree);
|
||||||
break;
|
break;
|
||||||
case WRQ:
|
case WRQ:
|
||||||
i1 = tvb_strnlen(tvb, offset, -1);
|
i1 = tftp_strnlen(tvb, offset);
|
||||||
proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
|
proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
|
||||||
tvb, offset, i1 + 1, FALSE);
|
tvb, offset, i1, FALSE);
|
||||||
offset += i1 + 1;
|
offset += i1;
|
||||||
|
|
||||||
i1 = tvb_strnlen(tvb, offset, -1);
|
i1 = tftp_strnlen(tvb, offset);
|
||||||
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
|
ti = proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
|
||||||
tvb, offset, i1 + 1, FALSE);
|
tvb, offset, i1, FALSE);
|
||||||
offset += i1 + 1;
|
offset += i1;
|
||||||
|
|
||||||
tftp_dissect_options(tvb, offset, tftp_tree);
|
tftp_dissect_options(tvb, offset, tftp_tree);
|
||||||
break;
|
break;
|
||||||
|
@ -193,9 +194,9 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
FALSE);
|
FALSE);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
i1 = tvb_strnlen(tvb, offset, -1);
|
i1 = tftp_strnlen(tvb, offset);
|
||||||
proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
|
proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
|
||||||
i1 + 1, FALSE);
|
i1, FALSE);
|
||||||
break;
|
break;
|
||||||
case OACK:
|
case OACK:
|
||||||
tftp_dissect_options(tvb, offset, tftp_tree);
|
tftp_dissect_options(tvb, offset, tftp_tree);
|
||||||
|
@ -212,19 +213,48 @@ dissect_tftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
static void
|
static void
|
||||||
tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree)
|
tftp_dissect_options(tvbuff_t *tvb, int offset, proto_tree *tree)
|
||||||
{
|
{
|
||||||
int i1, i2;
|
int option_len, value_len;
|
||||||
|
int value_offset;
|
||||||
|
|
||||||
while (tvb_offset_exists(tvb, offset)) {
|
while (tvb_offset_exists(tvb, offset)) {
|
||||||
i1 = tvb_strnlen(tvb, offset, -1); /* length of option */
|
option_len = tftp_strnlen(tvb, offset); /* length of option */
|
||||||
i2 = tvb_strnlen(tvb, offset+i1+1, -1); /* length of value */
|
value_offset = offset + option_len;
|
||||||
proto_tree_add_text(tree, tvb, offset, i1+i2+2,
|
value_len = tftp_strnlen(tvb, value_offset); /* length of value */
|
||||||
|
proto_tree_add_text(tree, tvb, offset, option_len+value_len,
|
||||||
"Option: %.*s = %.*s",
|
"Option: %.*s = %.*s",
|
||||||
i1, tvb_get_ptr(tvb, offset, i1),
|
option_len - 1, tvb_get_ptr(tvb, offset, option_len - 1),
|
||||||
i2, tvb_get_ptr(tvb, offset+i1+1, i2));
|
value_len - 1, tvb_get_ptr(tvb, value_offset, value_len - 1));
|
||||||
offset += i1 + i2 + 2;
|
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
|
void
|
||||||
proto_register_tftp(void)
|
proto_register_tftp(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue