aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2000-08-30 02:50:18 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2000-08-30 02:50:18 +0000
commit0e3cb70212e3be65cca036b9e89e6366f8a8a5ef (patch)
treed443ba6ccbe2a38e65d07311896e4db887bfad28
parent1a06c6a7eae14624d1e1a766fe2221c49a306537 (diff)
downloadwireshark-0e3cb70212e3be65cca036b9e89e6366f8a8a5ef.tar.gz
wireshark-0e3cb70212e3be65cca036b9e89e6366f8a8a5ef.tar.bz2
wireshark-0e3cb70212e3be65cca036b9e89e6366f8a8a5ef.zip
Add FT_STRINGZ type. NCP dissector is only one that uses it right now.
Remove tvb_get_stringz from quake dissector and add tvb_get_nstringz, tvb_get_nstringz0, and tvb_strnlen to tvbuff.c. Remove multiple definitions of pntohl and friends from various places (except for wiretap) and put into pint.h Consolidate duplicate code for turning FT_* enums into strings (ala the glossary). svn path=/trunk/; revision=2382
-rw-r--r--dfilter-scanner.l3
-rw-r--r--gtk/help_dlg.c73
-rwxr-xr-xncp2222.py24
-rw-r--r--packet-quake.c51
-rw-r--r--packet.h52
-rw-r--r--pint.h89
-rw-r--r--proto.c210
-rw-r--r--proto.h8
-rw-r--r--tvbtest.c75
-rw-r--r--tvbuff.c216
-rw-r--r--tvbuff.h25
11 files changed, 473 insertions, 353 deletions
diff --git a/dfilter-scanner.l b/dfilter-scanner.l
index 2cc2b429e9..12a301768b 100644
--- a/dfilter-scanner.l
+++ b/dfilter-scanner.l
@@ -3,7 +3,7 @@
/* dfilter-scanner.l
* Scanner for display filters
*
- * $Id: dfilter-scanner.l,v 1.32 2000/08/22 06:38:16 gram Exp $
+ * $Id: dfilter-scanner.l,v 1.33 2000/08/30 02:49:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -231,6 +231,7 @@ le|\<\= { dfilter_lval.operand = TOK_LE; return TOK_LE; }
retval = 0;
break;
case FT_STRING:
+ case FT_STRINGZ:
case FT_UINT_STRING:
retval = T_FT_STRING;
break;
diff --git a/gtk/help_dlg.c b/gtk/help_dlg.c
index de7ef1be6f..6fe37795a3 100644
--- a/gtk/help_dlg.c
+++ b/gtk/help_dlg.c
@@ -1,6 +1,6 @@
/* help_dlg.c
*
- * $Id: help_dlg.c,v 1.6 2000/08/22 06:38:32 gram Exp $
+ * $Id: help_dlg.c,v 1.7 2000/08/30 02:50:18 gram Exp $
*
* Laurent Deniel <deniel@worldnet.fr>
*
@@ -48,6 +48,7 @@
#include "main.h"
#include "util.h"
#include "ui_util.h"
+#include "proto.h"
typedef enum {
OVERVIEW_HELP,
@@ -365,75 +366,7 @@ static void set_help_text(GtkWidget *w, help_type_t type)
nb_lines += 2;
} else {
- /* XXX should convert this ? */
- switch(hfinfo->type) {
- case FT_NONE:
- type_name = "FT_NONE";
- break;
- case FT_BOOLEAN:
- type_name = "FT_BOOLEAN";
- break;
- case FT_UINT8:
- type_name = "FT_UINT8";
- break;
- case FT_UINT16:
- type_name = "FT_UINT16";
- break;
- case FT_UINT24:
- type_name = "FT_UINT24";
- break;
- case FT_UINT32:
- type_name = "FT_UINT32";
- break;
- case FT_INT8:
- type_name = "FT_INT8";
- break;
- case FT_INT16:
- type_name = "FT_INT16";
- break;
- case FT_INT24:
- type_name = "FT_INT24";
- break;
- case FT_INT32:
- type_name = "FT_INT32";
- break;
- case FT_DOUBLE:
- type_name = "FT_DOUBLE";
- break;
- case FT_ABSOLUTE_TIME:
- type_name = "FT_ABSOLUTE_TIME";
- break;
- case FT_RELATIVE_TIME:
- type_name = "FT_RELATIVE_TIME";
- break;
- case FT_UINT_STRING:
- type_name = "FT_UINT_STRING";
- break;
- case FT_STRING:
- type_name = "FT_STRING";
- break;
- case FT_ETHER:
- type_name = "FT_ETHER";
- break;
- case FT_BYTES:
- type_name = "FT_BYTES";
- break;
- case FT_IPv4:
- type_name = "FT_IPv4";
- break;
- case FT_IPv6:
- type_name = "FT_IPv6";
- break;
- case FT_IPXNET:
- type_name = "FT_IPXNET";
- break;
- case FT_TEXT_ONLY:
- type_name = "FT_TEXT_ONLY";
- break;
- default:
- g_assert_not_reached();
- type_name = NULL;
- }
+ type_name = proto_registrar_ftype_name(hfinfo->type);
snprintf(buffer, BUFF_LEN, "%s%s%s%s(%s)\n",
hfinfo->abbrev,
&blanks[B_LEN - (maxlen - strlen(hfinfo->abbrev)) - 2],
diff --git a/ncp2222.py b/ncp2222.py
index 70760bf213..6916e06a7d 100755
--- a/ncp2222.py
+++ b/ncp2222.py
@@ -9,7 +9,7 @@ part of the 0x2222 "family")
Data comes from "Programmer's Guide to the NetWare Core Protocol"
by Steve Conner and Dianne Conner.
-$Id: ncp2222.py,v 1.4 2000/08/22 06:38:17 gram Exp $
+$Id: ncp2222.py,v 1.5 2000/08/30 02:50:00 gram Exp $
Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
@@ -137,7 +137,7 @@ class PTVC(NamedList):
ptvc_rec = PTVCRecord(record)
# We can't make a PTVC list from a variable-length
- # packet. XXX - unless it's FT_NSTRING
+ # packet. XXX - unless it's FT_UINT_STRING
# if type(ptvc_rec.Length()) == type(()):
# if ptvc_rec.Field() == nstring8:
# pass
@@ -496,11 +496,21 @@ class nstring8(Type):
def __init__(self, abbrev, descr):
Type.__init__(self, abbrev, descr, 1)
+class fw_string(Type):
+ """A fixed-width string of n bytes."""
+
+ type = "fw_string"
+ ftype = "FT_STRING"
+
+ def __init__(self, abbrev, descr, bytes):
+ Type.__init__(self, abbrev, descr, bytes)
+
+
class stringz(Type):
- "NUL-terminated string."
+ "NUL-terminated string, with a maximum length"
type = "stringz"
- ftype = "FT_STRING"
+ ftype = "FT_STRINGZ"
def __init__(self, abbrev, descr):
Type.__init__(self, abbrev, descr, -1)
@@ -611,7 +621,7 @@ ObjectID = uint32("object_id", "Object ID")
ObjectID.Display('BASE_HEX')
ObjectName = nstring8("object_name", "Object Name")
-ObjectNameZ = stringz("object_nameZ", "Object Name")
+ObjectName1 = fw_string("object_name1", "Object Name", 48)
ObjectSecurity = val_string8("object_security", "Object Security", [
[ 0x00, "Anyone can read or modify the object" ],
@@ -1057,7 +1067,7 @@ pkt.Request((13,60), [
pkt.Reply(62, [
[ 8, 4, ObjectID ],
[ 12, 2, ObjectType ],
- [ 14, 48, ObjectName ], # XXX
+ [ 14, 48, ObjectName1 ],
])
pkt.CompletionCodes([0x0000, 0x9600, 0xef01, 0xf000, 0xfc02,
0xfe01, 0xff00])
@@ -1072,7 +1082,7 @@ pkt.Request((17,64), [
pkt.Reply(65, [
[ 8, 4, ObjectID ],
[ 12, 2, ObjectType ],
- [ 14, 48, ObjectNameZ ], # XXX
+ [ 14, 48, ObjectName1 ],
[ 62, 1, ObjectFlags ],
[ 63, 1, ObjectSecurity ],
[ 64, 1, ObjectHasProperties ],
diff --git a/packet-quake.c b/packet-quake.c
index f32d6c7d1a..4bacc020a1 100644
--- a/packet-quake.c
+++ b/packet-quake.c
@@ -4,7 +4,7 @@
* Uwe Girlich <uwe@planetquake.com>
* http://www.idsoftware.com/q1source/q1source.zip
*
- * $Id: packet-quake.c,v 1.5 2000/08/21 18:36:34 guy Exp $
+ * $Id: packet-quake.c,v 1.6 2000/08/30 02:50:01 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -154,33 +154,6 @@ static const value_string names_colors[] = {
static void dissect_quake(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static gint
-tvb_get_stringz(tvbuff_t *tvb, gint offset, gint maxlength, guint8* buffer)
-{
- int i;
- char* zeropos = NULL;
- gint stringlen = 0;
-
- if (maxlength == 0) {
- buffer[0] = 0;
- return 0;
- }
-
- tvb_memcpy(tvb, buffer, offset, maxlength);
- for (i=0 ; i<maxlength ; i++) {
- if (buffer[i] == 0) {
- stringlen = i;
- zeropos = buffer+i;
- break;
- }
- }
- if (zeropos == NULL) {
- buffer[maxlength-1] = 0;
- return maxlength-1;
- }
- return stringlen;
-}
-
static void
dissect_quake_CCREQ_CONNECT
@@ -192,7 +165,7 @@ dissect_quake_CCREQ_CONNECT
gint len;
maxbufsize = MIN(sizeof(game), tvb_length(tvb));
- len = tvb_get_stringz(tvb, 0, maxbufsize, game);
+ len = tvb_get_nstringz0(tvb, 0, maxbufsize, game);
version = tvb_get_guint8(tvb, len + 1);
if (tree) {
@@ -214,7 +187,7 @@ dissect_quake_CCREQ_SERVER_INFO
gint len;
maxbufsize = MIN(sizeof(game), tvb_length(tvb));
- len = tvb_get_stringz(tvb, 0, maxbufsize, game);
+ len = tvb_get_nstringz0(tvb, 0, maxbufsize, game);
version = tvb_get_guint8(tvb, len + 1);
if (tree) {
@@ -249,7 +222,7 @@ dissect_quake_CCREQ_RULE_INFO
gint len;
maxbufsize = MIN(sizeof(rule), tvb_length(tvb));
- len = tvb_get_stringz(tvb, 0, maxbufsize, rule);
+ len = tvb_get_nstringz0(tvb, 0, maxbufsize, rule);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREQ_RULE_INFO_lastrule,
tvb, 0, len + 1, rule);
@@ -285,7 +258,7 @@ dissect_quake_CCREP_REJECT
gint len;
maxbufsize = MIN(sizeof(reason), tvb_length(tvb));
- len = tvb_get_stringz(tvb, 0, maxbufsize, reason);
+ len = tvb_get_nstringz0(tvb, 0, maxbufsize, reason);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_REJECT_reason,
@@ -312,7 +285,7 @@ dissect_quake_CCREP_SERVER_INFO
offset = 0;
maxbufsize = MIN(sizeof(address), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, address);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, address);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_address,
tvb, offset, len + 1, address);
@@ -320,7 +293,7 @@ dissect_quake_CCREP_SERVER_INFO
offset += len + 1;
maxbufsize = MIN(sizeof(server), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, server);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, server);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_server,
tvb, offset, len + 1, server);
@@ -328,7 +301,7 @@ dissect_quake_CCREP_SERVER_INFO
offset += len + 1;
maxbufsize = MIN(sizeof(map), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, map);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, map);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_map,
tvb, offset, len + 1, map);
@@ -376,7 +349,7 @@ dissect_quake_CCREP_PLAYER_INFO
offset += 1;
maxbufsize = MIN(sizeof(name), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, name);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, name);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_PLAYER_INFO_name,
tvb, offset, len + 1, name);
@@ -413,7 +386,7 @@ dissect_quake_CCREP_PLAYER_INFO
offset += 3*4;
maxbufsize = MIN(sizeof(address), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, address);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, address);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_PLAYER_INFO_address,
tvb, offset, len + 1, address);
@@ -437,7 +410,7 @@ dissect_quake_CCREP_RULE_INFO
offset = 0;
maxbufsize = MIN(sizeof(rule), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, rule);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, rule);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_RULE_INFO_rule,
tvb, offset, len + 1, rule);
@@ -445,7 +418,7 @@ dissect_quake_CCREP_RULE_INFO
offset += len + 1;
maxbufsize = MIN(sizeof(value), tvb_length_remaining(tvb, offset));
- len = tvb_get_stringz(tvb, offset, maxbufsize, value);
+ len = tvb_get_nstringz0(tvb, offset, maxbufsize, value);
if (tree) {
proto_tree_add_string(tree, hf_quake_CCREP_RULE_INFO_value,
tvb, offset, len + 1, value);
diff --git a/packet.h b/packet.h
index b5a2bb8175..43581883e0 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.198 2000/08/22 08:19:40 itojun Exp $
+ * $Id: packet.h,v 1.199 2000/08/30 02:50:01 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -30,55 +30,7 @@
#include "wiretap/wtap.h"
#include "proto.h"
#include "tvbuff.h"
-
-/* Pointer versions of ntohs and ntohl. Given a pointer to a member of a
- * byte array, returns the value of the two or four bytes at the pointer.
- * The pletoh[sl] versions return the little-endian representation.
- *
- * If G_HAVE_GINT64 is defined, so we can use "gint64" and "guint64" to
- * refer to 64-bit integral quantities, we also provide pntohll and
- * phtolell, which extract 64-bit integral quantities.
- */
-
-#define pntohs(p) ((guint16) \
- ((guint16)*((guint8 *)(p)+0)<<8| \
- (guint16)*((guint8 *)(p)+1)<<0))
-
-#define pntohl(p) ((guint32)*((guint8 *)(p)+0)<<24| \
- (guint32)*((guint8 *)(p)+1)<<16| \
- (guint32)*((guint8 *)(p)+2)<<8| \
- (guint32)*((guint8 *)(p)+3)<<0)
-
-#ifdef G_HAVE_GINT64
-#define pntohll(p) ((guint64)*((guint8 *)(p)+0)<<56| \
- (guint64)*((guint8 *)(p)+1)<<48| \
- (guint64)*((guint8 *)(p)+2)<<40| \
- (guint64)*((guint8 *)(p)+3)<<32| \
- (guint64)*((guint8 *)(p)+4)<<24| \
- (guint64)*((guint8 *)(p)+5)<<16| \
- (guint64)*((guint8 *)(p)+6)<<8| \
- (guint64)*((guint8 *)(p)+7)<<0)
-#endif
-
-#define pletohs(p) ((guint16) \
- ((guint16)*((guint8 *)(p)+1)<<8| \
- (guint16)*((guint8 *)(p)+0)<<0))
-
-#define pletohl(p) ((guint32)*((guint8 *)(p)+3)<<24| \
- (guint32)*((guint8 *)(p)+2)<<16| \
- (guint32)*((guint8 *)(p)+1)<<8| \
- (guint32)*((guint8 *)(p)+0)<<0)
-
-#ifdef G_HAVE_GINT64
-#define pletohll(p) ((guint64)*((guint8 *)(p)+7)<<56| \
- (guint64)*((guint8 *)(p)+6)<<48| \
- (guint64)*((guint8 *)(p)+5)<<40| \
- (guint64)*((guint8 *)(p)+4)<<32| \
- (guint64)*((guint8 *)(p)+3)<<24| \
- (guint64)*((guint8 *)(p)+2)<<16| \
- (guint64)*((guint8 *)(p)+1)<<8| \
- (guint64)*((guint8 *)(p)+0)<<0)
-#endif
+#include "pint.h"
#define hi_nibble(b) (((b) & 0xf0) >> 4)
#define lo_nibble(b) ((b) & 0x0f)
diff --git a/pint.h b/pint.h
new file mode 100644
index 0000000000..b8f034ea75
--- /dev/null
+++ b/pint.h
@@ -0,0 +1,89 @@
+/* pint.h
+ * Definitions for extracting and translating integers safely and portably
+ * via pointers.
+ *
+ * $Id: pint.h,v 1.1 2000/08/30 02:50:02 gram Exp $
+ *
+ * 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 __PINT_H__
+#define __PINT_H__
+
+#include <glib.h>
+
+/* Pointer versions of ntohs and ntohl. Given a pointer to a member of a
+ * byte array, returns the value of the two or four bytes at the pointer.
+ * The pletoh[sl] versions return the little-endian representation.
+ *
+ * If G_HAVE_GINT64 is defined, so we can use "gint64" and "guint64" to
+ * refer to 64-bit integral quantities, we also provide pntohll and
+ * phtolell, which extract 64-bit integral quantities.
+ */
+
+#define pntohs(p) ((guint16) \
+ ((guint16)*((guint8 *)(p)+0)<<8| \
+ (guint16)*((guint8 *)(p)+1)<<0))
+
+#define pntoh24(p) ((guint32)*((guint8 *)(p)+0)<<16| \
+ (guint32)*((guint8 *)(p)+1)<<8| \
+ (guint32)*((guint8 *)(p)+2)<<0)
+
+#define pntohl(p) ((guint32)*((guint8 *)(p)+0)<<24| \
+ (guint32)*((guint8 *)(p)+1)<<16| \
+ (guint32)*((guint8 *)(p)+2)<<8| \
+ (guint32)*((guint8 *)(p)+3)<<0)
+
+#ifdef G_HAVE_GINT64
+#define pntohll(p) ((guint64)*((guint8 *)(p)+0)<<56| \
+ (guint64)*((guint8 *)(p)+1)<<48| \
+ (guint64)*((guint8 *)(p)+2)<<40| \
+ (guint64)*((guint8 *)(p)+3)<<32| \
+ (guint64)*((guint8 *)(p)+4)<<24| \
+ (guint64)*((guint8 *)(p)+5)<<16| \
+ (guint64)*((guint8 *)(p)+6)<<8| \
+ (guint64)*((guint8 *)(p)+7)<<0)
+#endif
+
+#define pletohs(p) ((guint16) \
+ ((guint16)*((guint8 *)(p)+1)<<8| \
+ (guint16)*((guint8 *)(p)+0)<<0))
+
+#define pletoh24(p) ((guint32)*((guint8 *)(p)+2)<<16| \
+ (guint32)*((guint8 *)(p)+1)<<8| \
+ (guint32)*((guint8 *)(p)+0)<<0)
+
+#define pletohl(p) ((guint32)*((guint8 *)(p)+3)<<24| \
+ (guint32)*((guint8 *)(p)+2)<<16| \
+ (guint32)*((guint8 *)(p)+1)<<8| \
+ (guint32)*((guint8 *)(p)+0)<<0)
+
+#ifdef G_HAVE_GINT64
+#define pletohll(p) ((guint64)*((guint8 *)(p)+7)<<56| \
+ (guint64)*((guint8 *)(p)+6)<<48| \
+ (guint64)*((guint8 *)(p)+5)<<40| \
+ (guint64)*((guint8 *)(p)+4)<<32| \
+ (guint64)*((guint8 *)(p)+3)<<24| \
+ (guint64)*((guint8 *)(p)+2)<<16| \
+ (guint64)*((guint8 *)(p)+1)<<8| \
+ (guint64)*((guint8 *)(p)+0)<<0)
+#endif
+
+#endif /* PINT_H */
diff --git a/proto.c b/proto.c
index 028a11ea0c..e1d4958e84 100644
--- a/proto.c
+++ b/proto.c
@@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
- * $Id: proto.c,v 1.79 2000/08/24 02:55:36 gram Exp $
+ * $Id: proto.c,v 1.80 2000/08/30 02:50:02 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -239,6 +239,8 @@ proto_tree_free_node(GNode *node, gpointer data)
g_mem_chunk_free(gmc_item_labels, fi->representation);
if (fi->hfinfo->type == FT_STRING)
g_free(fi->value.string);
+ else if (fi->hfinfo->type == FT_STRINGZ)
+ g_free(fi->value.string);
else if (fi->hfinfo->type == FT_UINT_STRING)
g_free(fi->value.string);
else if (fi->hfinfo->type == FT_BYTES)
@@ -409,6 +411,8 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
field_info *new_fi;
proto_item *pi;
guint32 value, n;
+ char *string;
+ int found_length;
new_fi = alloc_field_info(hfindex, tvb, start, length);
@@ -478,6 +482,24 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
proto_tree_set_string_tvb(new_fi, tvb, start, length);
break;
+ case FT_STRINGZ:
+ /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+ string = g_malloc(length);
+
+ CLEANUP_PUSH(g_free, string);
+
+ found_length = tvb_get_nstringz(tvb, start, length, string);
+ if (found_length < 1) {
+ found_length = tvb_get_nstringz0(tvb, start, length, string);
+ }
+
+ CLEANUP_POP;
+
+ proto_tree_set_string(new_fi, string);
+ new_fi->length = found_length + 1;
+
+ break;
+
case FT_UINT_STRING:
/* This g_strdup'ed memory is freed in proto_tree_free_node() */
n = get_uint_value(tvb, start, length, little_endian);
@@ -487,11 +509,13 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
* have a proto_item, we set the field_info's length ourselves. */
new_fi->length = n + 1;
break;
-
default:
- g_error("new_fi->hfinfo->type %d not handled\n", new_fi->hfinfo->type);
- g_assert_not_reached();
- break;
+ g_error("new_fi->hfinfo->type %d (%s) not handled\n",
+ new_fi->hfinfo->type,
+ proto_registrar_ftype_name(new_fi->hfinfo->type));
+ g_assert_not_reached();
+ break;
+
}
CLEANUP_POP;
@@ -1635,31 +1659,31 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
case FT_DOUBLE:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %g", fi->hfinfo->name,
+ "%s: %g", hfinfo->name,
fi->value.floating);
break;
case FT_ABSOLUTE_TIME:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s", fi->hfinfo->name,
+ "%s: %s", hfinfo->name,
abs_time_to_str(&fi->value.time));
break;
case FT_RELATIVE_TIME:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s seconds", fi->hfinfo->name,
+ "%s: %s seconds", hfinfo->name,
rel_time_to_str(&fi->value.time));
break;
case FT_IPXNET:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: 0x%08X (%s)", fi->hfinfo->name,
+ "%s: 0x%08X (%s)", hfinfo->name,
fi->value.numeric, get_ipxnet_name(fi->value.numeric));
break;
case FT_ETHER:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s (%s)", fi->hfinfo->name,
+ "%s: %s (%s)", hfinfo->name,
ether_to_str(fi->value.ether),
get_ether_name(fi->value.ether));
break;
@@ -1667,27 +1691,31 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
case FT_IPv4:
n_addr = ipv4_get_net_order_addr(&fi->value.ipv4);
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s (%s)", fi->hfinfo->name,
+ "%s: %s (%s)", hfinfo->name,
get_hostname(n_addr),
ip_to_str((guint8*)&n_addr));
break;
case FT_IPv6:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s (%s)", fi->hfinfo->name,
+ "%s: %s (%s)", hfinfo->name,
get_hostname6((struct e_in6_addr *)fi->value.ipv6),
ip6_to_str((struct e_in6_addr*)fi->value.ipv6));
break;
case FT_STRING:
+ case FT_STRINGZ:
case FT_UINT_STRING:
snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s", fi->hfinfo->name, fi->value.string);
+ "%s: %s", hfinfo->name, fi->value.string);
break;
default:
- g_error("hfinfo->type %d not handled\n", fi->hfinfo->type);
- break;
+ g_error("hfinfo->type %d (%s) not handled\n",
+ hfinfo->type,
+ proto_registrar_ftype_name(hfinfo->type));
+ g_assert_not_reached();
+ break;
}
}
@@ -2129,6 +2157,7 @@ proto_registrar_get_length(int n)
case FT_BYTES:
case FT_BOOLEAN:
case FT_STRING:
+ case FT_STRINGZ:
case FT_UINT_STRING:
case FT_DOUBLE:
case FT_ABSOLUTE_TIME:
@@ -2361,76 +2390,91 @@ proto_registrar_dump(void)
parent_hfinfo = proto_registrar_get_nth(hfinfo->parent);
g_assert(parent_hfinfo);
- switch(hfinfo->type) {
- case FT_NONE:
- enum_name = "FT_NONE";
- break;
- case FT_BOOLEAN:
- enum_name = "FT_BOOLEAN";
- break;
- case FT_UINT8:
- enum_name = "FT_UINT8";
- break;
- case FT_UINT16:
- enum_name = "FT_UINT16";
- break;
- case FT_UINT24:
- enum_name = "FT_UINT24";
- break;
- case FT_UINT32:
- enum_name = "FT_UINT32";
- break;
- case FT_INT8:
- enum_name = "FT_INT8";
- break;
- case FT_INT16:
- enum_name = "FT_INT16";
- break;
- case FT_INT24:
- enum_name = "FT_INT24";
- break;
- case FT_INT32:
- enum_name = "FT_INT32";
- break;
- case FT_DOUBLE:
- enum_name = "FT_DOUBLE";
- break;
- case FT_ABSOLUTE_TIME:
- enum_name = "FT_ABSOLUTE_TIME";
- break;
- case FT_RELATIVE_TIME:
- enum_name = "FT_RELATIVE_TIME";
- break;
- case FT_UINT_STRING:
- enum_name = "FT_UINT_STRING";
- break;
- case FT_STRING:
- enum_name = "FT_STRING";
- break;
- case FT_ETHER:
- enum_name = "FT_ETHER";
- break;
- case FT_BYTES:
- enum_name = "FT_BYTES";
- break;
- case FT_IPv4:
- enum_name = "FT_IPv4";
- break;
- case FT_IPv6:
- enum_name = "FT_IPv6";
- break;
- case FT_IPXNET:
- enum_name = "FT_IPXNET";
- break;
- case FT_TEXT_ONLY:
- enum_name = "FT_TEXT_ONLY";
- break;
- default:
- g_assert_not_reached();
- enum_name = NULL;
- }
+ enum_name = proto_registrar_ftype_name(hfinfo->type);
printf("F\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
enum_name,parent_hfinfo->abbrev);
}
}
}
+
+
+/* Returns a string representing the field type */
+const char*
+proto_registrar_ftype_name(enum ftenum ftype)
+{
+ const char *enum_name = NULL;
+
+ switch(ftype) {
+ case FT_NONE:
+ enum_name = "FT_NONE";
+ break;
+ case FT_BOOLEAN:
+ enum_name = "FT_BOOLEAN";
+ break;
+ case FT_UINT8:
+ enum_name = "FT_UINT8";
+ break;
+ case FT_UINT16:
+ enum_name = "FT_UINT16";
+ break;
+ case FT_UINT24:
+ enum_name = "FT_UINT24";
+ break;
+ case FT_UINT32:
+ enum_name = "FT_UINT32";
+ break;
+ case FT_INT8:
+ enum_name = "FT_INT8";
+ break;
+ case FT_INT16:
+ enum_name = "FT_INT16";
+ break;
+ case FT_INT24:
+ enum_name = "FT_INT24";
+ break;
+ case FT_INT32:
+ enum_name = "FT_INT32";
+ break;
+ case FT_DOUBLE:
+ enum_name = "FT_DOUBLE";
+ break;
+ case FT_ABSOLUTE_TIME:
+ enum_name = "FT_ABSOLUTE_TIME";
+ break;
+ case FT_RELATIVE_TIME:
+ enum_name = "FT_RELATIVE_TIME";
+ break;
+ case FT_UINT_STRING:
+ enum_name = "FT_UINT_STRING";
+ break;
+ case FT_STRING:
+ enum_name = "FT_STRING";
+ break;
+ case FT_STRINGZ:
+ enum_name = "FT_STRINGZ";
+ break;
+ case FT_ETHER:
+ enum_name = "FT_ETHER";
+ break;
+ case FT_BYTES:
+ enum_name = "FT_BYTES";
+ break;
+ case FT_IPv4:
+ enum_name = "FT_IPv4";
+ break;
+ case FT_IPv6:
+ enum_name = "FT_IPv6";
+ break;
+ case FT_IPXNET:
+ enum_name = "FT_IPXNET";
+ break;
+ case FT_TEXT_ONLY:
+ enum_name = "FT_TEXT_ONLY";
+ break;
+ case NUM_FIELD_TYPES:
+ g_assert_not_reached();
+ break;
+ }
+ g_assert(enum_name);
+ return enum_name;
+}
diff --git a/proto.h b/proto.h
index 957e3417ed..f0087b6477 100644
--- a/proto.h
+++ b/proto.h
@@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
- * $Id: proto.h,v 1.41 2000/08/22 06:38:20 gram Exp $
+ * $Id: proto.h,v 1.42 2000/08/30 02:50:03 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -89,7 +89,8 @@ enum ftenum {
FT_ABSOLUTE_TIME,
FT_RELATIVE_TIME,
FT_STRING,
- FT_UINT_STRING,
+ FT_STRINGZ, /* for use with proto_tree_add_item() */
+ FT_UINT_STRING, /* for use with proto_tree_add_item() */
FT_ETHER,
FT_BYTES,
FT_IPv4,
@@ -546,4 +547,7 @@ extern int num_tree_types;
#define g_ptr_array_len(a) ((a)->len)
#endif
+/* Returns a string representing the field type */
+const char* proto_registrar_ftype_name(enum ftenum ftype);
+
#endif /* proto.h */
diff --git a/tvbtest.c b/tvbtest.c
index c4d07bfd66..172aea76d9 100644
--- a/tvbtest.c
+++ b/tvbtest.c
@@ -2,7 +2,7 @@
*
* tvbtest : tvbtest.o tvbuff.o except.o
*
- * $Id: tvbtest.c,v 1.2 2000/06/22 06:36:45 guy Exp $
+ * $Id: tvbtest.c,v 1.3 2000/08/30 02:50:04 gram Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@@ -27,24 +27,7 @@
#include <string.h>
#include "tvbuff.h"
-
-#define pntohs(p) ((guint16) \
- ((guint16)*((guint8 *)p+0)<<8| \
- (guint16)*((guint8 *)p+1)<<0))
-
-#define pntohl(p) ((guint32)*((guint8 *)p+0)<<24| \
- (guint32)*((guint8 *)p+1)<<16| \
- (guint32)*((guint8 *)p+2)<<8| \
- (guint32)*((guint8 *)p+3)<<0)
-
-#define pletohs(p) ((guint16) \
- ((guint16)*((guint8 *)p+1)<<8| \
- (guint16)*((guint8 *)p+0)<<0))
-
-#define pletohl(p) ((guint32)*((guint8 *)p+3)<<24| \
- (guint32)*((guint8 *)p+2)<<16| \
- (guint32)*((guint8 *)p+1)<<8| \
- (guint32)*((guint8 *)p+0)<<0)
+#include "pint.h"
/* Tests a tvbuff against the expected pattern/length.
* Returns TRUE if all tests succeeed, FALSE if any test fails */
@@ -52,16 +35,17 @@ gboolean
test(tvbuff_t *tvb, gchar* name,
guint8* expected_data, guint expected_length)
{
- guint length;
- guint8 *ptr;
- gboolean ex_thrown;
- guint32 val32, expected32;
- int incr, i;
+ guint length;
+ guint8 *ptr;
+ volatile gboolean ex_thrown;
+ volatile guint32 val32;
+ guint32 expected32;
+ int incr, i;
length = tvb_length(tvb);
if (length != expected_length) {
- printf("Failed TVB=%s Length of tvb=%u while expected length=%u\n",
+ printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
name, length, expected_length);
return FALSE;
}
@@ -74,10 +58,13 @@ test(tvbuff_t *tvb, gchar* name,
CATCH(BoundsError) {
ex_thrown = TRUE;
}
+ CATCH(ReportedBoundsError) {
+ printf("02: Caught wrong exception: ReportedBoundsError\n");
+ }
ENDTRY;
if (!ex_thrown) {
- printf("Failed TVB=%s No BoundsError when retrieving %u bytes\n",
+ printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
name, length + 1);
return FALSE;
}
@@ -88,13 +75,16 @@ test(tvbuff_t *tvb, gchar* name,
TRY {
ptr = tvb_get_ptr(tvb, 0, length + 2);
}
+ CATCH(BoundsError) {
+ printf("03: Caught wrong exception: BoundsError\n");
+ }
CATCH(ReportedBoundsError) {
ex_thrown = TRUE;
}
ENDTRY;
if (!ex_thrown) {
- printf("Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
+ printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
name, length + 2);
return FALSE;
}
@@ -107,10 +97,13 @@ test(tvbuff_t *tvb, gchar* name,
CATCH(BoundsError) {
ex_thrown = TRUE;
}
+ CATCH(ReportedBoundsError) {
+ printf("04: Caught wrong exception: ReportedBoundsError\n");
+ }
ENDTRY;
if (!ex_thrown) {
- printf("Failed TVB=%s No BoundsError when retrieving 2 bytes from"
+ printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
" offset -1\n", name);
return FALSE;
}
@@ -123,10 +116,13 @@ test(tvbuff_t *tvb, gchar* name,
CATCH(BoundsError) {
ex_thrown = TRUE;
}
+ CATCH(ReportedBoundsError) {
+ printf("05: Caught wrong exception: ReportedBoundsError\n");
+ }
ENDTRY;
if (ex_thrown) {
- printf("Failed TVB=%s BoundsError when retrieving 1 bytes from"
+ printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
" offset 0\n", name);
return FALSE;
}
@@ -139,10 +135,13 @@ test(tvbuff_t *tvb, gchar* name,
CATCH(BoundsError) {
ex_thrown = TRUE;
}
+ CATCH(ReportedBoundsError) {
+ printf("06: Caught wrong exception: ReportedBoundsError\n");
+ }
ENDTRY;
if (ex_thrown) {
- printf("Failed TVB=%s BoundsError when retrieving 1 bytes from"
+ printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
" offset -1\n", name);
return FALSE;
}
@@ -154,20 +153,20 @@ test(tvbuff_t *tvb, gchar* name,
TRY {
val32 = tvb_get_ntohl(tvb, 0);
}
- CATCH(BoundsError) {
+ CATCH_ALL {
ex_thrown = TRUE;
}
ENDTRY;
if (ex_thrown) {
- printf("Failed TVB=%s BoundsError when retrieving "
+ printf("07: Failed TVB=%s Exception when retrieving "
"guint32 from offset 0\n", name);
return FALSE;
}
expected32 = pntohl(expected_data);
if (val32 != expected32) {
- printf("Failed TVB=%s guint32 @ 0 %u != expected %u\n",
+ printf("08: Failed TVB=%s guint32 @ 0 %u != expected %u\n",
name, val32, expected32);
return FALSE;
}
@@ -179,20 +178,20 @@ test(tvbuff_t *tvb, gchar* name,
TRY {
val32 = tvb_get_ntohl(tvb, -4);
}
- CATCH(BoundsError) {
+ CATCH_ALL {
ex_thrown = TRUE;
}
ENDTRY;
if (ex_thrown) {
- printf("Failed TVB=%s BoundsError when retrieving "
+ printf("09: Failed TVB=%s Exception when retrieving "
"guint32 from offset 0\n", name);
return FALSE;
}
expected32 = pntohl(&expected_data[length-4]);
if (val32 != expected32) {
- printf("Failed TVB=%s guint32 @ -4 %u != expected %u\n",
+ printf("10: Failed TVB=%s guint32 @ -4 %u != expected %u\n",
name, val32, expected32);
return FALSE;
}
@@ -204,7 +203,7 @@ test(tvbuff_t *tvb, gchar* name,
for (i = 0; i < length - incr; i += incr) {
ptr = tvb_memdup(tvb, i, incr);
if (memcmp(ptr, &expected_data[i], incr) != 0) {
- printf("Failed TVB=%s Offset=%d Length=%d "
+ printf("11: Failed TVB=%s Offset=%d Length=%d "
"Bad memdup\n",
name, i, incr);
g_free(ptr);
@@ -217,7 +216,7 @@ test(tvbuff_t *tvb, gchar* name,
/* One big memdup */
ptr = tvb_memdup(tvb, 0, -1);
if (memcmp(ptr, expected_data, length) != 0) {
- printf("Failed TVB=%s Offset=0 Length=-1 "
+ printf("12: Failed TVB=%s Offset=0 Length=-1 "
"Bad memdup\n", name);
g_free(ptr);
return FALSE;
diff --git a/tvbuff.c b/tvbuff.c
index 0d723c5cf6..191964253f 100644
--- a/tvbuff.c
+++ b/tvbuff.c
@@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
- * $Id: tvbuff.c,v 1.7 2000/08/11 13:34:31 deniel Exp $
+ * $Id: tvbuff.c,v 1.8 2000/08/30 02:50:04 gram Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@@ -33,69 +33,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include "tvbuff.h"
-
#include <string.h>
-/* Pointer versions of ntohs and ntohl. Given a pointer to a member of a
- * byte array, returns the value of the two or four bytes at the pointer.
- * The pletoh[sl] versions return the little-endian representation.
- *
- * We also provide "pntoh24()" and "pletoh24()", to extract 24-bit
- * quantities.
- *
- * If G_HAVE_GINT64 is defined, so we can use "gint64" and "guint64" to
- * refer to 64-bit integral quantities, we also provide pntohll and
- * phtolell, which extract 64-bit integral quantities.
- */
-
-#define pntohs(p) ((guint16) \
- ((guint16)*((guint8 *)p+0)<<8| \
- (guint16)*((guint8 *)p+1)<<0))
-
-#define pntoh24(p) ((guint32)*((guint8 *)p+0)<<16| \
- (guint32)*((guint8 *)p+1)<<8| \
- (guint32)*((guint8 *)p+2)<<0)
-
-#define pntohl(p) ((guint32)*((guint8 *)p+0)<<24| \
- (guint32)*((guint8 *)p+1)<<16| \
- (guint32)*((guint8 *)p+2)<<8| \
- (guint32)*((guint8 *)p+3)<<0)
-
-#ifdef G_HAVE_GINT64
-#define pntohll(p) ((guint64)*((guint8 *)p+0)<<56| \
- (guint64)*((guint8 *)p+1)<<48| \
- (guint64)*((guint8 *)p+2)<<40| \
- (guint64)*((guint8 *)p+3)<<32| \
- (guint64)*((guint8 *)p+4)<<24| \
- (guint64)*((guint8 *)p+5)<<16| \
- (guint64)*((guint8 *)p+6)<<8| \
- (guint64)*((guint8 *)p+7)<<0)
-#endif
-
-#define pletohs(p) ((guint16) \
- ((guint16)*((guint8 *)p+1)<<8| \
- (guint16)*((guint8 *)p+0)<<0))
-
-#define pletoh24(p) ((guint32)*((guint8 *)p+2)<<16| \
- (guint32)*((guint8 *)p+1)<<8| \
- (guint32)*((guint8 *)p+0)<<0)
-
-#define pletohl(p) ((guint32)*((guint8 *)p+3)<<24| \
- (guint32)*((guint8 *)p+2)<<16| \
- (guint32)*((guint8 *)p+1)<<8| \
- (guint32)*((guint8 *)p+0)<<0)
+#include "pint.h"
+#include "tvbuff.h"
-#ifdef G_HAVE_GINT64
-#define pletohll(p) ((guint64)*((guint8 *)p+7)<<56| \
- (guint64)*((guint8 *)p+6)<<48| \
- (guint64)*((guint8 *)p+5)<<40| \
- (guint64)*((guint8 *)p+4)<<32| \
- (guint64)*((guint8 *)p+3)<<24| \
- (guint64)*((guint8 *)p+2)<<16| \
- (guint64)*((guint8 *)p+1)<<8| \
- (guint64)*((guint8 *)p+0)<<0)
-#endif
typedef struct {
/* The backing tvbuff_t */
@@ -772,6 +714,22 @@ ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
return NULL;
}
+static const guint8*
+guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
+{
+ const guint8 *b;
+ int i;
+
+ for (b = haystack, i = 0; i < haystacklen; i++, b++) {
+ if (*b == needle) {
+ return b;
+ }
+ }
+
+ return NULL;
+}
+
+
/************** ACCESSORS **************/
@@ -838,6 +796,7 @@ tvb_memcpy(tvbuff_t *tvb, guint8* target, gint offset, gint length)
{
guint abs_offset, abs_length;
+ g_assert(length >= -1);
check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
if (tvb->real_data) {
@@ -966,3 +925,138 @@ tvb_get_letohll(tvbuff_t *tvb, gint offset)
return pletohll(ptr);
}
#endif
+
+
+/* Find first occurence of needle in tvbuff, starting at offset. Searches
+ * at most maxlength number of bytes. Returns the offset of the found needle,
+ * or -1 if not found. Will not throw an exception, even if maxlength exceeds
+ * boundary of tvbuff; in that case, -1 will be returned if the boundary is
+ * reached before finding needle. */
+gint
+tvb_find_guint8(tvbuff_t *tvb, gint offset, guint maxlength, guint8 needle)
+{
+ guint abs_offset, junk_length;
+ const guint8 *result;
+ guint limit;
+
+ check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
+
+ /* Only search to end of tvbuff, w/o throwing exception. */
+ if (tvb_length_remaining(tvb, abs_offset) < maxlength) {
+ limit = maxlength - (tvb_length(tvb) - abs_offset);
+ }
+ else {
+ limit = maxlength;
+ }
+
+ /* If we have real data, perform our search now. */
+ if (tvb->real_data) {
+ result = guint8_find(tvb->real_data + abs_offset, limit, needle);
+ if (result == NULL) {
+ return -1;
+ }
+ else {
+ return result - tvb->real_data;
+ }
+ }
+
+ switch(tvb->type) {
+ case TVBUFF_REAL_DATA:
+ g_assert_not_reached();
+
+ case TVBUFF_SUBSET:
+ return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
+ abs_offset - tvb->tvbuffs.subset.offset,
+ limit, needle);
+
+ case TVBUFF_COMPOSITE:
+ g_assert_not_reached();
+ /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
+ }
+
+ g_assert_not_reached();
+ return -1;
+}
+
+/* Find length of string by looking for end of string ('\0'), up to
+ * 'max_length' characters'. Returns -1 if 'max_length' reached
+ * before finding EOS. */
+gint tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
+{
+ gint result_offset;
+ guint abs_offset, junk_length;
+
+ check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
+
+ result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
+
+ if (result_offset == -1) {
+ return -1;
+ }
+ else {
+ return result_offset;
+ }
+}
+
+
+/* Looks for a stringz (NUL-terminated string) in tvbuff and copies
+ * no more than maxlength number of bytes, including terminating NUL, to buffer.
+ * Returns length of string (not including terminating NUL), or -1 if the string was
+ * truncated in the buffer due to not having reached the terminating NUL.
+ * In this way, it acts like snprintf().
+ */
+gint
+tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer)
+{
+ gint stringlen, NUL_offset;
+ guint abs_offset, junk_length;
+ gint limit;
+
+ check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
+
+ if (maxlength == 0) {
+ buffer[0] = 0;
+ return 0;
+ }
+
+ /* Only copy to end of tvbuff, w/o throwing exception. */
+ if (tvb_length_remaining(tvb, abs_offset) < maxlength) {
+ limit = maxlength - (tvb_length(tvb) - abs_offset);
+ }
+ else {
+ limit = maxlength;
+ }
+
+ NUL_offset = tvb_strnlen(tvb, abs_offset, limit);
+
+ /* If NUL wasn't found, copy the data and return -1 */
+ if (NUL_offset == -1) {
+ tvb_memcpy(tvb, buffer, abs_offset, limit);
+ return -1;
+ }
+
+ /* Copy the string to buffer */
+ stringlen = NUL_offset - abs_offset;
+ tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
+ return stringlen;
+}
+
+/* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
+ * have a terminating NUL. If the string was truncated when copied into buffer,
+ * a NUL is placed at the end of buffer to terminate it.
+ */
+gint
+tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer)
+{
+ gint len;
+
+ len = tvb_get_nstringz(tvb, offset, maxlength, buffer);
+
+ if (len == -1) {
+ buffer[maxlength] = 0;
+ return maxlength - 1;
+ }
+ else {
+ return len;
+ }
+}
diff --git a/tvbuff.h b/tvbuff.h
index ee2f444abe..2735b1c2d6 100644
--- a/tvbuff.h
+++ b/tvbuff.h
@@ -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/08/17 17:16:02 gram Exp $
+ * $Id: tvbuff.h,v 1.9 2000/08/30 02:50:05 gram Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@@ -243,10 +243,31 @@ guint8* tvb_memdup(tvbuff_t*, gint offset, gint length);
* tvbuff_free_cb_t() is called, if any. */
guint8* tvb_get_ptr(tvbuff_t*, gint offset, gint length);
+/* Find first occurence of needle in tvbuff, starting at offset. Searches
+ * at most maxlength number of bytes. Returns the offset of the found needle,
+ * or -1 if not found. Will not throw an exception, even if maxlength exceeds
+ * boundary of tvbuff; in that case, -1 will be returned if the boundary is
+ * reached before finding needle. */
+gint tvb_find_guint8(tvbuff_t*, gint offset, guint maxlength, guint8 needle);
+
/* Find length of string by looking for end of string ('\0'), up to
* 'max_length' characters'. Returns -1 if 'max_length' reached
* before finding EOS. */
-/*gint tvb_strnlen(tvbuff_t*, gint offset, gint max_length);*/
+gint tvb_strnlen(tvbuff_t*, gint offset, guint maxlength);
+
+/* Looks for a stringz (NUL-terminated string) in tvbuff and copies
+ * no more than maxlength number of bytes, including terminating NUL, to buffer.
+ * Returns length of string (not including terminating NUL), or -1 if the string was
+ * truncated in the buffer due to not having reached the terminating NUL.
+ * In this way, it acts like snprintf().
+ */
+gint tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer);
+
+/* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
+ * have a terminating NUL. If the string was truncated when copied into buffer,
+ * a NUL is placed at the end of buffer to terminate it.
+ */
+gint tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer);
/************** END OF ACCESSORS ****************/