diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-08-30 02:50:18 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-08-30 02:50:18 +0000 |
commit | 0e3cb70212e3be65cca036b9e89e6366f8a8a5ef (patch) | |
tree | d443ba6ccbe2a38e65d07311896e4db887bfad28 | |
parent | 1a06c6a7eae14624d1e1a766fe2221c49a306537 (diff) | |
download | wireshark-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.l | 3 | ||||
-rw-r--r-- | gtk/help_dlg.c | 73 | ||||
-rwxr-xr-x | ncp2222.py | 24 | ||||
-rw-r--r-- | packet-quake.c | 51 | ||||
-rw-r--r-- | packet.h | 52 | ||||
-rw-r--r-- | pint.h | 89 | ||||
-rw-r--r-- | proto.c | 210 | ||||
-rw-r--r-- | proto.h | 8 | ||||
-rw-r--r-- | tvbtest.c | 75 | ||||
-rw-r--r-- | tvbuff.c | 216 | ||||
-rw-r--r-- | tvbuff.h | 25 |
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); @@ -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 */ @@ -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; +} @@ -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 */ @@ -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; @@ -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; + } +} @@ -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 ****************/ |