aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-04-12 15:26:34 -0700
committerGuy Harris <guy@alum.mit.edu>2014-04-12 22:27:22 +0000
commitcb16dff992c3844936bf5829f19e5a5247458503 (patch)
tree901b7be3379f5b94f150de71d1c0f3e2fa2d12e4 /epan
parentef8a0a2ce172810d48371eb65c73b1bd4a6303ca (diff)
Get rid of more tvb_get_nstringz* calls.
Add an FT_STRINGZPAD type, for null-padded strings (typically fixed-length fields, where the string can be up to the length of the field, and is null-padded if it's shorter than that), and use it. Use IS_FT_STRING() in more cases, so that less code needs to know what types are string types. Add a tvb_get_stringzpad() routine, which gets null-padded strings. Currently, it does the same thing that tvb_get_string_enc() does, but that might change if we don't store string values as null-terminated strings. Change-Id: I46f56e130de8f419a19b56ded914e24cc7518a66 Reviewed-on: https://code.wireshark.org/review/1082 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan')
-rw-r--r--epan/dfilter/dfunctions.c53
-rw-r--r--epan/dfilter/semcheck.c4
-rw-r--r--epan/dissectors/packet-fw1.c3
-rw-r--r--epan/dissectors/packet-hartip.c52
-rw-r--r--epan/dissectors/packet-ospf.c4
-rw-r--r--epan/dissectors/packet-quake3.c18
-rw-r--r--epan/dissectors/packet-quakeworld.c20
-rw-r--r--epan/dissectors/packet-rsync.c8
-rw-r--r--epan/dissectors/packet-smb-browse.c28
-rw-r--r--epan/dissectors/packet-tacacs.c11
-rw-r--r--epan/dissectors/packet-who.c17
-rw-r--r--epan/ftypes/ftype-string.c43
-rw-r--r--epan/ftypes/ftypes.h3
-rw-r--r--epan/packet.c3
-rw-r--r--epan/proto.c66
-rw-r--r--epan/proto.h13
-rw-r--r--epan/tvbuff.c18
-rw-r--r--epan/tvbuff.h23
18 files changed, 232 insertions, 155 deletions
diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c
index 81e446b500..cb59184775 100644
--- a/epan/dfilter/dfunctions.c
+++ b/epan/dfilter/dfunctions.c
@@ -61,26 +61,18 @@ string_walk(GList* arg1list, GList **retval, gchar(*conv_func)(gchar))
arg1 = arg1list;
while (arg1) {
arg_fvalue = (fvalue_t *)arg1->data;
- switch (fvalue_type_ftenum(arg_fvalue)) {
- case FT_STRING:
- case FT_STRINGZ:
- case FT_UINT_STRING:
- s = (char *)ep_strdup((gchar *)fvalue_get(arg_fvalue));
- for (c = s; *c; c++) {
- /**c = string_ascii_to_lower(*c);*/
- *c = conv_func(*c);
- }
-
- new_ft_string = fvalue_new(FT_STRING);
- fvalue_set_string(new_ft_string, s);
- *retval = g_list_append(*retval, new_ft_string);
- break;
-
- /* XXX - it would be nice to handle FT_TVBUFF, too */
-
- default:
- break;
- }
+ /* XXX - it would be nice to handle FT_TVBUFF, too */
+ if (IS_FT_STRING(fvalue_type_ftenum(arg_fvalue))) {
+ s = (char *)ep_strdup((gchar *)fvalue_get(arg_fvalue));
+ for (c = s; *c; c++) {
+ /**c = string_ascii_to_lower(*c);*/
+ *c = conv_func(*c);
+ }
+
+ new_ft_string = fvalue_new(FT_STRING);
+ fvalue_set_string(new_ft_string, s);
+ *retval = g_list_append(*retval, new_ft_string);
+ }
arg1 = arg1->next;
}
@@ -112,19 +104,11 @@ df_func_len(GList* arg1list, GList *arg2junk _U_, GList **retval)
arg1 = arg1list;
while (arg1) {
arg_fvalue = (fvalue_t *)arg1->data;
- switch (fvalue_type_ftenum(arg_fvalue)) {
- case FT_STRING:
- case FT_STRINGZ:
- case FT_UINT_STRING:
- ft_len = fvalue_new(FT_UINT32);
- fvalue_set_uinteger(ft_len, (guint) strlen((char *)fvalue_get(arg_fvalue)));
- *retval = g_list_append(*retval, ft_len);
- break;
-
- /* XXX - it would be nice to handle other types */
-
- default:
- break;
+ /* XXX - it would be nice to handle other types */
+ if (IS_FT_STRING(fvalue_type_ftenum(arg_fvalue))) {
+ ft_len = fvalue_new(FT_UINT32);
+ fvalue_set_uinteger(ft_len, (guint) strlen((char *)fvalue_get(arg_fvalue)));
+ *retval = g_list_append(*retval, ft_len);
}
arg1 = arg1->next;
}
@@ -187,8 +171,7 @@ ul_semcheck_params(int param_num, stnode_t *st_node)
case STTYPE_FIELD:
hfinfo = (header_field_info *)stnode_data(st_node);
ftype = hfinfo->type;
- if (ftype != FT_STRING && ftype != FT_STRINGZ
- && ftype != FT_UINT_STRING) {
+ if (IS_FT_STRING(ftype)) {
dfilter_fail("Only strings can be used in upper() or lower() or len()");
THROW(TypeError);
}
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index 501dce4e3e..c76859dc28 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -116,10 +116,12 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
switch (b) {
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
return TRUE;
default:
return FALSE;
@@ -186,6 +188,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
case FT_EUI64:
case FT_PCRE:
case FT_GUID:
@@ -314,6 +317,7 @@ is_bytes_type(enum ftenum type)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
case FT_BOOLEAN:
case FT_FRAMENUM:
case FT_UINT8:
diff --git a/epan/dissectors/packet-fw1.c b/epan/dissectors/packet-fw1.c
index 51ed2942a0..e4ff9e3a7d 100644
--- a/epan/dissectors/packet-fw1.c
+++ b/epan/dissectors/packet-fw1.c
@@ -160,8 +160,7 @@ dissect_fw1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (fw1_with_uuid)
iface_len = 6;
- interface_name=(char *)wmem_alloc(wmem_packet_scope(), iface_len+1);
- tvb_get_nstringz0(tvb, 2, iface_len+1, interface_name);
+ interface_name=tvb_get_stringzpad(wmem_packet_scope(), tvb, 2, iface_len, ENC_ASCII|ENC_NA);
/* Known interface name - if not, remember it */
found=FALSE;
diff --git a/epan/dissectors/packet-hartip.c b/epan/dissectors/packet-hartip.c
index c8edad2b94..6d6b0d71d3 100644
--- a/epan/dissectors/packet-hartip.c
+++ b/epan/dissectors/packet-hartip.c
@@ -384,26 +384,7 @@ dissect_float(proto_tree *tree, int hf, tvbuff_t *tvb, gint offset)
}
static gint
-dissect_string(proto_tree *tree, int hf, const char *name, int len,
- tvbuff_t *tvb, gint offset)
-{
- proto_item *ti;
- char *str;
-
- str = (char *)wmem_alloc(wmem_packet_scope(), 256);
-
- ti = proto_tree_add_item(tree, hf, tvb, offset, len, ENC_NA);
- if (len < 256) {
- (void) tvb_get_nstringz0(tvb, offset, len + 1, str);
- proto_item_set_text(ti, "%s: %s", name, str);
- }
-
- return len;
-}
-
-static gint
-dissect_packAscii(proto_tree *tree, int hf, const char *name, int len,
- tvbuff_t *tvb, gint offset)
+dissect_packAscii(proto_tree *tree, int hf, tvbuff_t *tvb, gint offset, int len)
{
gushort usIdx;
gushort usGroupCnt;
@@ -411,19 +392,16 @@ dissect_packAscii(proto_tree *tree, int hf, const char *name, int len,
gushort usMask;
gint iIndex;
gint i = 0;
- proto_item *ti;
gushort buf[4];
guint8 *tmp;
char *str = NULL;
- str = (char *)wmem_alloc(wmem_packet_scope(), 256+1);
-
- ti = proto_tree_add_item(tree, hf, tvb, offset, len, ENC_NA);
-
- DISSECTOR_ASSERT(len < 3 * (256/4));
tmp = (guint8 *)wmem_alloc0(wmem_packet_scope(), len);
tvb_memcpy(tvb, tmp, offset, len);
+ /* Maximum possible unpacked length = (len / 3) * 4 */
+ str = (char *)wmem_alloc(wmem_packet_scope(), ((len / 3) * 4)+1);
+
iIndex = 0;
usMaxGroups = (gushort)(len / 3);
for (usGroupCnt = 0; usGroupCnt < usMaxGroups; usGroupCnt++) {
@@ -446,7 +424,8 @@ dissect_packAscii(proto_tree *tree, int hf, const char *name, int len,
}
}
str[i] = '\0';
- proto_item_set_text(ti, "%s: %s", name, str);
+
+ proto_tree_add_string(tree, hf, tvb, offset, len, str);
return len;
}
@@ -630,8 +609,8 @@ static gint
dissect_cmd13(proto_tree *body_tree, tvbuff_t *tvb, gint offset, gint bodylen)
{
if (bodylen >= 21) {
- offset += dissect_packAscii(body_tree, hf_hartip_pt_rsp_tag, "Tag", 6, tvb, offset);
- offset += dissect_packAscii(body_tree, hf_hartip_pt_rsp_packed_descriptor, "descriptor", 12, tvb, offset);
+ offset += dissect_packAscii(body_tree, hf_hartip_pt_rsp_tag, tvb, offset, 6);
+ offset += dissect_packAscii(body_tree, hf_hartip_pt_rsp_packed_descriptor, tvb, offset, 12);
offset += dissect_byte(body_tree, hf_hartip_pt_rsp_day, tvb, offset);
offset += dissect_byte(body_tree, hf_hartip_pt_rsp_month, tvb, offset);
/*offset += */dissect_byte(body_tree, hf_hartip_pt_rsp_year, tvb, offset);
@@ -688,13 +667,16 @@ dissect_parse_hart_cmds(proto_tree *body_tree, tvbuff_t *tvb, guint8 cmd,
return dissect_cmd9(body_tree, tvb, offset, bodylen);
case 12:
if (bodylen >= 24)
- return dissect_packAscii(body_tree, hf_hartip_pt_rsp_message, "Message", 24, tvb, offset);
+ return dissect_packAscii(body_tree, hf_hartip_pt_rsp_message, tvb, offset, 24);
break;
case 13:
return dissect_cmd13(body_tree, tvb, offset, bodylen);
case 20:
- if (bodylen >= 32)
- return dissect_string(body_tree, hf_hartip_pt_rsp_tag, "Tag", 32, tvb, offset);
+ if (bodylen >= 32) {
+ proto_tree_add_item(body_tree, hf_hartip_pt_rsp_tag, tvb, offset, 32,
+ ENC_ASCII|ENC_NA);
+ return 32;
+ }
break;
case 48:
return dissect_cmd48(body_tree, tvb, offset, bodylen);
@@ -1438,7 +1420,7 @@ proto_register_hartip(void)
/* command 13 */
{ &hf_hartip_pt_rsp_packed_descriptor,
{ "Descriptor", "hart_ip.pt.rsp.descriptor",
- FT_BYTES, BASE_NONE, NULL, 0x0,
+ FT_STRINGZPAD, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_hartip_pt_rsp_day,
@@ -1460,14 +1442,14 @@ proto_register_hartip(void)
/* Tag */
{ &hf_hartip_pt_rsp_tag,
{ "Tag", "hart_ip.pt.rsp.tag",
- FT_BYTES, BASE_NONE, NULL, 0x0,
+ FT_STRINGZPAD, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
/* Message */
{ &hf_hartip_pt_rsp_message,
{ "Message", "hart_ip.pt.rsp.message",
- FT_BYTES, BASE_NONE, NULL, 0x0,
+ FT_STRINGZPAD, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
diff --git a/epan/dissectors/packet-ospf.c b/epan/dissectors/packet-ospf.c
index 281ba265b6..6d1a0a3b20 100644
--- a/epan/dissectors/packet-ospf.c
+++ b/epan/dissectors/packet-ospf.c
@@ -1042,7 +1042,7 @@ dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint16 cksum, computed_cksum;
guint length, reported_length;
guint16 auth_type;
- char auth_data[8+1];
+ guint8 *auth_data;
int crypto_len = 0;
unsigned int ospf_header_length;
guint8 instance_ID;
@@ -1210,7 +1210,7 @@ dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
case OSPF_AUTH_SIMPLE:
- tvb_get_nstringz0(tvb, 16, 8+1, auth_data);
+ auth_data = tvb_get_string_enc(wmem_packet_scope(), tvb, 16, 8, ENC_ASCII|ENC_NA);
proto_tree_add_text(ospf_header_tree, tvb, 16, 8, "Auth Data: %s", auth_data);
break;
diff --git a/epan/dissectors/packet-quake3.c b/epan/dissectors/packet-quake3.c
index c9d5fad22d..3b8bfc328f 100644
--- a/epan/dissectors/packet-quake3.c
+++ b/epan/dissectors/packet-quake3.c
@@ -144,7 +144,7 @@ dissect_quake3_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *cl_tree = NULL;
proto_item *text_item = NULL;
proto_tree *text_tree = NULL;
- guint8 text[2048];
+ guint8 *text;
int len;
int offset;
guint32 marker;
@@ -165,11 +165,21 @@ dissect_quake3_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
/* all the rest of the packet is just text */
offset = 4;
- len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
+ /*
+ * XXX - is there ever more than one null-terminated string in
+ * the packet?
+ *
+ * XXX - is the string guaranteed to be null-terminated (so
+ * that if there's no NUL at the end, it's an error)?
+ *
+ * XXX - are non-ASCII characters supported and, if so, what
+ * encoding is used for them?
+ */
+ text = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII|ENC_NA);
if (cl_tree) {
text_item = proto_tree_add_string(cl_tree,
hf_quake3_connectionless_text,
- tvb, offset, len + 1, text);
+ tvb, offset, len, text);
text_tree = proto_item_add_subtree(text_item, ett_quake3_connectionless_text);
}
@@ -321,7 +331,7 @@ dissect_quake3_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
val_to_str_const(command, names_command, "Unknown"));
}
- /*offset += len + 1;*/
+ /*offset += len;*/
}
diff --git a/epan/dissectors/packet-quakeworld.c b/epan/dissectors/packet-quakeworld.c
index 16ac74a911..4ceb8a4fad 100644
--- a/epan/dissectors/packet-quakeworld.c
+++ b/epan/dissectors/packet-quakeworld.c
@@ -90,8 +90,8 @@ static char com_token[MAX_TEXT_SIZE+1];
static int com_token_start;
static int com_token_length;
-static char *
-COM_Parse (char *data)
+static const char *
+COM_Parse (const char *data)
{
int c;
int len;
@@ -198,7 +198,7 @@ Cmd_Argv_length(int arg)
static void
-Cmd_TokenizeString(char* text)
+Cmd_TokenizeString(const char* text)
{
int start;
@@ -349,7 +349,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
{
proto_tree *cl_tree = NULL;
proto_tree *text_tree = NULL;
- guint8 text[MAX_TEXT_SIZE+1];
+ guint8 *text;
int len;
int offset;
guint32 marker;
@@ -370,13 +370,13 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
/* all the rest of the packet is just text */
offset = 4;
- len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
+ text = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII|ENC_NA);
/* actually, we should look for a eol char and stop already there */
if (cl_tree) {
proto_item *text_item;
text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text,
- tvb, offset, len + 1, text);
+ tvb, offset, len, text);
text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text);
}
@@ -469,7 +469,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
tvb, offset, command_len, command);
argument_item = proto_tree_add_string(text_tree,
hf_quakeworld_connectionless_arguments,
- tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1),
+ tvb, offset + Cmd_Argv_start(1), len - Cmd_Argv_start(1),
text + Cmd_Argv_start(1));
argument_tree = proto_item_add_subtree(argument_item,
ett_quakeworld_connectionless_arguments);
@@ -504,7 +504,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
command_len = 1;
} else {
command = "Unknown";
- command_len = len;
+ command_len = len - 1;
}
}
else {
@@ -529,7 +529,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
/* string, atoi */
} else {
command = "Unknown";
- command_len = len;
+ command_len = len - 1;
}
}
@@ -539,7 +539,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
tvb, offset, command_len, command);
}
- /*offset += len + 1;*/
+ /*offset += len;*/
}
diff --git a/epan/dissectors/packet-rsync.c b/epan/dissectors/packet-rsync.c
index 95eb7f36c1..9448d70f7e 100644
--- a/epan/dissectors/packet-rsync.c
+++ b/epan/dissectors/packet-rsync.c
@@ -123,17 +123,19 @@ static dissector_handle_t rsync_handle;
static guint glb_rsync_tcp_port = TCP_PORT_RSYNC;
+#define VERSION_LEN 4 /* 2 digits for main version; '.'; 1 digit for sub version */
+
static void
dissect_rsync_version_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rsync_tree, enum rsync_who me)
{
int offset = 0;
- gchar version[5]; /* 2 digits for main version; '.'; 1 digit for sub version; NULL */
+ guint8 *version;
proto_tree_add_item(rsync_tree, &hfi_rsync_hdr_magic, tvb, offset, RSYNCD_MAGIC_HEADER_LEN, ENC_ASCII|ENC_NA);
offset += RSYNCD_MAGIC_HEADER_LEN;
offset += 1; /* skip the space */
- proto_tree_add_item(rsync_tree, &hfi_rsync_hdr_version, tvb, offset, sizeof(version)-1, ENC_ASCII|ENC_NA);
- tvb_get_nstringz0(tvb, offset, sizeof(version), version);
+ proto_tree_add_item(rsync_tree, &hfi_rsync_hdr_version, tvb, offset, VERSION_LEN, ENC_ASCII|ENC_NA);
+ version = tvb_get_string_enc(wmem_packet_scope(),tvb, offset, VERSION_LEN, ENC_ASCII|ENC_NA);
col_add_fstr(pinfo->cinfo, COL_INFO, "%s Initialisation (Version %s)", (me == SERVER ? "Server" : "Client"), version);
}
diff --git a/epan/dissectors/packet-smb-browse.c b/epan/dissectors/packet-smb-browse.c
index 3c55bd1250..4c556ed0af 100644
--- a/epan/dissectors/packet-smb-browse.c
+++ b/epan/dissectors/packet-smb-browse.c
@@ -570,6 +570,7 @@ dissect_smb_server_type_flags(tvbuff_t *tvb, int offset, packet_info *pinfo,
return offset;
}
+#define HOST_NAME_LEN 16
static void
dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
@@ -579,8 +580,7 @@ dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
proto_tree *tree = NULL;
proto_item *item = NULL;
guint32 periodicity;
- gchar host_name[17];
- gchar *utf8_host_name;
+ guint8 *host_name;
gint namelen;
guint8 server_count, reset_cmd;
guint8 os_major_ver, os_minor_ver;
@@ -621,22 +621,16 @@ dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
offset += 4;
/* server name */
- tvb_get_nstringz0(tvb, offset, sizeof(host_name), host_name);
- utf8_host_name = g_convert(host_name, strlen(host_name),
- "UTF-8", "CP437", NULL, NULL, NULL);
- if (utf8_host_name == NULL)
- utf8_host_name = host_name;
- col_append_fstr(pinfo->cinfo, COL_INFO, " %s", utf8_host_name);
+ host_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, HOST_NAME_LEN, ENC_CP437|ENC_NA);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
proto_tree_add_string_format(tree, hf_server_name,
- tvb, offset, 16,
- utf8_host_name,
+ tvb, offset, HOST_NAME_LEN,
+ host_name,
(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
"Domain/Workgroup: %s":
"Host Name: %s",
- utf8_host_name);
- if (utf8_host_name != host_name)
- g_free(utf8_host_name);
- offset += 16;
+ host_name);
+ offset += HOST_NAME_LEN;
/* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
os_major_ver = tvb_get_guint8(tvb, offset);
@@ -838,7 +832,6 @@ dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
/* Put in something, and replace it later */
col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
-
if (parent_tree) {
item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
@@ -853,7 +846,6 @@ dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
case BROWSE_DOMAIN_ANNOUNCEMENT:
case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
case BROWSE_HOST_ANNOUNCE:
-
/* update count */
proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -888,7 +880,7 @@ dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
offset += 2;
/* server name */
- host_name = tvb_get_const_stringz(tvb, offset, &namelen);
+ host_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &namelen, ENC_CP437|ENC_NA);
col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
proto_tree_add_item(tree, hf_server_name,
@@ -900,7 +892,7 @@ dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
proto_tree_add_item(tree,
(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
hf_mb_server_name : hf_server_comment,
- tvb, offset, namelen, ENC_ASCII|ENC_NA);
+ tvb, offset, namelen, ENC_CP437|ENC_NA);
break;
}
}
diff --git a/epan/dissectors/packet-tacacs.c b/epan/dissectors/packet-tacacs.c
index 29339e7f6e..2ea2c8105b 100644
--- a/epan/dissectors/packet-tacacs.c
+++ b/epan/dissectors/packet-tacacs.c
@@ -396,14 +396,15 @@ static void
dissect_tacplus_args_list( tvbuff_t *tvb, proto_tree *tree, int data_off, int len_off, int arg_cnt )
{
int i;
- guint8 buff[257];
+ int len;
+ guint8 *value;
for(i=0;i<arg_cnt;i++){
- int len=tvb_get_guint8(tvb,len_off+i);
+ len=tvb_get_guint8(tvb,len_off+i);
proto_tree_add_uint_format(tree, hf_tacplus_arg_length, tvb, len_off+i, 1, len,
"Arg[%d] length: %d", i, len);
- tvb_get_nstringz0(tvb, data_off, len+1, buff);
- proto_tree_add_string_format(tree, hf_tacplus_arg_value, tvb, data_off, len, buff,
- "Arg[%d] value: %s", i, buff);
+ value=tvb_get_string_enc(wmem_packet_scope(), tvb, data_off, len, ENC_ASCII|ENC_NA);
+ proto_tree_add_string_format(tree, hf_tacplus_arg_value, tvb, data_off, len, value,
+ "Arg[%d] value: %s", i, value);
data_off+=len;
}
}
diff --git a/epan/dissectors/packet-who.c b/epan/dissectors/packet-who.c
index 05afd84cce..d1c604bb5e 100644
--- a/epan/dissectors/packet-who.c
+++ b/epan/dissectors/packet-who.c
@@ -56,12 +56,9 @@ RWHOD(8) UNIX System Manager's Manual RWHOD(8)
(20 each) int we_idle;
} wd_we[1024 / sizeof (struct whoent)];
};
-
- Linux 2.0 May 13, 1997 2
-
*
*/
-
+
void proto_register_who(void);
void proto_reg_handoff_who(void);
@@ -94,7 +91,7 @@ dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
int offset = 0;
proto_tree *who_tree = NULL;
proto_item *who_ti = NULL;
- gchar server_name[33];
+ guint8 *server_name;
double loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0;
nstime_t ts;
@@ -135,7 +132,7 @@ dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
offset += 4;
- tvb_get_nstringz0(tvb, offset, sizeof(server_name), (guint8*)server_name);
+ server_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, 32, ENC_ASCII|ENC_NA);
if (tree)
proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset,
32, server_name);
@@ -184,8 +181,8 @@ dissect_whoent(tvbuff_t *tvb, int offset, proto_tree *tree)
proto_tree *whoent_tree = NULL;
proto_item *whoent_ti = NULL;
int line_offset = offset;
- gchar out_line[9];
- gchar out_name[9];
+ guint8 *out_line;
+ guint8 *out_name;
nstime_t ts;
int whoent_num = 0;
guint32 idle_secs; /* say that out loud... */
@@ -198,12 +195,12 @@ dissect_whoent(tvbuff_t *tvb, int offset, proto_tree *tree)
line_offset, SIZE_OF_WHOENT, ENC_NA);
whoent_tree = proto_item_add_subtree(whoent_ti, ett_whoent);
- tvb_get_nstringz0(tvb, line_offset, sizeof(out_line), (guint8*)out_line);
+ out_line = tvb_get_stringzpad(wmem_packet_scope(), tvb, line_offset, 8, ENC_ASCII|ENC_NA);
proto_tree_add_string(whoent_tree, hf_who_tty, tvb, line_offset,
8, out_line);
line_offset += 8;
- tvb_get_nstringz0(tvb, line_offset, sizeof(out_name), (guint8*)out_name);
+ out_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, line_offset, 8, ENC_ASCII|ENC_NA);
proto_tree_add_string(whoent_tree, hf_who_uid, tvb, line_offset,
8, out_name);
line_offset += 8;
diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c
index b2e0c63ef0..3893823b28 100644
--- a/epan/ftypes/ftype-string.c
+++ b/epan/ftypes/ftype-string.c
@@ -356,8 +356,51 @@ ftype_register_string(void)
len,
slice,
};
+ static ftype_t stringzpad_type = {
+ FT_STRINGZPAD, /* ftype */
+ "FT_STRINGZPAD", /* name */
+ "Character string", /* pretty name */
+ 0, /* wire_size */
+ string_fvalue_new, /* new_value */
+ string_fvalue_free, /* free_value */
+ val_from_unparsed, /* val_from_unparsed */
+ val_from_string, /* val_from_string */
+ string_to_repr, /* val_to_string_repr */
+ string_repr_len, /* len_string_repr */
+
+ NULL, /* set_value_byte_array */
+ NULL, /* set_value_bytes */
+ NULL, /* set_value_guid */
+ NULL, /* set_value_time */
+ string_fvalue_set_string, /* set_value_string */
+ NULL, /* set_value_tvbuff */
+ NULL, /* set_value_uinteger */
+ NULL, /* set_value_sinteger */
+ NULL, /* set_value_integer64 */
+ NULL, /* set_value_floating */
+
+ value_get, /* get_value */
+ NULL, /* get_value_uinteger */
+ NULL, /* get_value_sinteger */
+ NULL, /* get_value_integer64 */
+ NULL, /* get_value_floating */
+
+ cmp_eq,
+ cmp_ne,
+ cmp_gt,
+ cmp_ge,
+ cmp_lt,
+ cmp_le,
+ NULL, /* cmp_bitwise_and */
+ cmp_contains, /* cmp_contains */
+ CMP_MATCHES,
+
+ len,
+ slice,
+ };
ftype_register(FT_STRING, &string_type);
ftype_register(FT_STRINGZ, &stringz_type);
ftype_register(FT_UINT_STRING, &uint_string_type);
+ ftype_register(FT_STRINGZPAD, &stringzpad_type);
}
diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h
index 1e238838b2..53042778f2 100644
--- a/epan/ftypes/ftypes.h
+++ b/epan/ftypes/ftypes.h
@@ -68,13 +68,14 @@ enum ftenum {
FT_VINES,
FT_REL_OID, /* RELATIVE-OID */
FT_SYSTEM_ID,
+ FT_STRINGZPAD, /* for use with proto_tree_add_item() */
FT_NUM_TYPES /* last item number plus one */
};
#define IS_FT_INT(ft) ((ft)==FT_INT8||(ft)==FT_INT16||(ft)==FT_INT24||(ft)==FT_INT32||(ft)==FT_INT64)
#define IS_FT_UINT(ft) ((ft)==FT_UINT8||(ft)==FT_UINT16||(ft)==FT_UINT24||(ft)==FT_UINT32||(ft)==FT_UINT64||(ft)==FT_FRAMENUM)
#define IS_FT_TIME(ft) ((ft)==FT_ABSOLUTE_TIME||(ft)==FT_RELATIVE_TIME)
-#define IS_FT_STRING(ft) ((ft)==FT_STRING||(ft)==FT_STRINGZ)
+#define IS_FT_STRING(ft) ((ft)==FT_STRING||(ft)==FT_STRINGZ||(ft)==FT_STRINGZPAD)
/* field types lengths */
#define FT_ETHER_LEN 6
diff --git a/epan/packet.c b/epan/packet.c
index 9ec656cb30..8bed533b7e 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1174,6 +1174,7 @@ find_string_dtbl_entry(dissector_table_t const sub_dissectors, const gchar *patt
case FT_STRING:
case FT_STRINGZ:
+ case FT_STRINGZPAD:
/*
* You can do a string lookup in these tables.
*/
@@ -1220,6 +1221,7 @@ dissector_add_string(const char *name, const gchar *pattern,
case FT_STRING:
case FT_STRINGZ:
+ case FT_STRINGZPAD:
/*
* You can do a string lookup in these tables.
*/
@@ -1780,6 +1782,7 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t
case FT_STRING:
case FT_STRINGZ:
+ case FT_STRINGZPAD:
sub_dissectors->hash_table = g_hash_table_new_full( g_str_hash,
g_str_equal,
&g_free,
diff --git a/epan/proto.c b/epan/proto.c
index f3dd81d922..5adc0497fa 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1641,6 +1641,19 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
new_fi->length = n + length;
break;
+ case FT_STRINGZPAD:
+ /*
+ * XXX - currently, string values are null-
+ * terminated, so a "zero-padded" string
+ * isn't special. If we represent string
+ * values as something that includes a counted
+ * array of bytes, we'll need to strip
+ * trailing NULs.
+ */
+ proto_tree_set_string_tvb(new_fi, tvb, start, length,
+ encoding);
+ break;
+
case FT_ABSOLUTE_TIME:
/*
* Absolute times can be in any of a number of
@@ -2665,8 +2678,8 @@ proto_tree_set_int64_tvb(field_info *fi, tvbuff_t *tvb, gint start,
proto_tree_set_uint64(fi, value);
}
-/* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
- * and frees it when the proto_tree is destroyed. */
+/* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
+ * own copy of string, and frees it when the proto_tree is destroyed. */
proto_item *
proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const char* value)
@@ -2676,7 +2689,7 @@ proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
+ DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ || hfinfo->type == FT_STRINGZPAD);
if (hfinfo->display == STR_UNICODE) {
DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
@@ -2728,9 +2741,9 @@ proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
return pi;
}
-/* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
- * field info update instead of only updating the representation as does
- * proto_item_append_text()
+/* Appends string data to a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD,
+ * allowing progressive field info update instead of only updating the
+ * representation as does proto_item_append_text()
*/
/* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
* speed optimization.
@@ -2764,7 +2777,7 @@ proto_item_append_string(proto_item *pi, const char *str)
/* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
return;
}
- DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
+ DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ || hfinfo->type == FT_STRINGZPAD);
old_str = (guint8 *)fvalue_get(&fi->value);
if (old_str && old_str[0])
new_str = ep_strconcat(old_str, str, NULL);
@@ -3541,9 +3554,9 @@ get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint
*/
if (*length == -1) {
/*
- * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
- * a length of -1 means "set the length to what remains in
- * the tvbuff".
+ * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
+ * FT_STRINGZPAD fields, a length of -1 means "set the
+ * length to what remains in the tvbuff".
*
* The assumption is either that
*
@@ -3605,6 +3618,7 @@ get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint
case FT_NONE:
case FT_BYTES:
case FT_STRING:
+ case FT_STRINGZPAD:
*length = tvb_ensure_captured_length_remaining(tvb, start);
DISSECTOR_ASSERT(*length >= 0);
break;
@@ -4076,6 +4090,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
bytes = (guint8 *)fvalue_get(&finfo->value);
offset_r += protoo_strlcpy(result+offset_r,
hfinfo_format_text(hfinfo, bytes),
@@ -4987,22 +5002,23 @@ static const value_string hf_types[] = {
{ FT_DOUBLE, "FT_DOUBLE" },
{ FT_ABSOLUTE_TIME, "FT_ABSOLUTE_TIME" },
{ FT_RELATIVE_TIME, "FT_RELATIVE_TIME" },
- { FT_STRING, "FT_STRING" },
- { FT_STRINGZ, "FT_STRINGZ" },
+ { FT_STRING, "FT_STRING" },
+ { FT_STRINGZ, "FT_STRINGZ" },
{ FT_UINT_STRING, "FT_UINT_STRING" },
- { FT_ETHER, "FT_ETHER" },
- { FT_BYTES, "FT_BYTES" },
+ { FT_ETHER, "FT_ETHER" },
+ { FT_BYTES, "FT_BYTES" },
{ FT_UINT_BYTES, "FT_UINT_BYTES" },
- { FT_IPv4, "FT_IPv4" },
- { FT_IPv6, "FT_IPv6" },
- { FT_IPXNET, "FT_IPXNET" },
- { FT_FRAMENUM, "FT_FRAMENUM" },
- { FT_PCRE, "FT_PCR" },
- { FT_GUID, "FT_GUID" },
- { FT_OID, "FT_OID" },
- { FT_REL_OID, "FT_REL_OID" },
- { FT_SYSTEM_ID, "FT_SYSTEM_ID" },
- { 0, NULL } };
+ { FT_IPv4, "FT_IPv4" },
+ { FT_IPv6, "FT_IPv6" },
+ { FT_IPXNET, "FT_IPXNET" },
+ { FT_FRAMENUM, "FT_FRAMENUM" },
+ { FT_PCRE, "FT_PCRE" },
+ { FT_GUID, "FT_GUID" },
+ { FT_OID, "FT_OID" },
+ { FT_REL_OID, "FT_REL_OID" },
+ { FT_SYSTEM_ID, "FT_SYSTEM_ID" },
+ { FT_STRINGZPAD, "FT_STRINGZPAD" },
+ { 0, NULL } };
static const value_string hf_display[] = {
{ BASE_NONE, "BASE_NONE" },
@@ -5213,6 +5229,7 @@ tmp_fld_check_assert(header_field_info *hfinfo)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
switch (hfinfo->display) {
case STR_ASCII:
case STR_UNICODE:
@@ -5671,6 +5688,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
+ case FT_STRINGZPAD:
bytes = (guint8 *)fvalue_get(&fi->value);
label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
break;
diff --git a/epan/proto.h b/epan/proto.h
index b34443a2c7..fdb4aaee00 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -1231,7 +1231,7 @@ extern proto_item *
proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const guint8* value_ptr, const char *format, ...) G_GNUC_PRINTF(7,8);
-/** Add a FT_STRING to a proto_tree.
+/** Add a FT_STRING or FT_STRINGZPAD to a proto_tree.
@param tree the tree to append this item to
@param hfindex field index
@param tvb the tv buffer of the current data
@@ -1243,9 +1243,9 @@ WS_DLL_PUBLIC proto_item *
proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const char* value);
-/** Add a formatted FT_STRING to a proto_tree, with the format generating
- the string for the value and with the field name being included
- automatically.
+/** Add a formatted FT_STRING or FT_STRINGZPAD to a proto_tree, with the
+ format generating the string for the value and with the field name
+ being included automatically.
@param tree the tree to append this item to
@param hfindex field index
@param tvb the tv buffer of the current data
@@ -1260,8 +1260,9 @@ proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
gint start, gint length, const char* value, const char *format, ...)
G_GNUC_PRINTF(7,8);
-/** Add a formatted FT_STRING to a proto_tree, with the format generating
- the entire string for the entry, including any field name.
+/** Add a formatted FT_STRING or FT_STRINGZPAD to a proto_tree, with the
+ format generating the entire string for the entry, including any field
+ name.
@param tree the tree to append this item to
@param hfindex field index
@param tvb the tv buffer of the current data
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 91e2202be2..fcdb0e22c9 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -2533,6 +2533,24 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
}
/*
+ * This is like tvb_get_string_enc(), except that it handles null-padded
+ * strings.
+ *
+ * Currently, string values are stored as UTF-8 null-terminated strings,
+ * so nothing needs to be done differently for null-padded strings; we
+ * could save a little memory by not storing the null padding.
+ *
+ * If we ever store string values differently, in a fashion that doesn't
+ * involve null termination, that might change.
+ */
+guint8 *
+tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
+ const gint length, const guint encoding)
+{
+ return tvb_get_string_enc(scope, tvb, offset, length, encoding);
+}
+
+/*
* These routines are like the above routines, except that they handle
* null-terminated strings. They find the length of that string (and
* throw an exception if the tvbuff ends before we find the null), and
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index 7d51a6ac0c..896a13587f 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -557,6 +557,29 @@ WS_DLL_PUBLIC gchar *tvb_get_ts_23_038_7bits_string(wmem_allocator_t *scope,
tvbuff_t *tvb, const gint bit_offset, gint no_of_chars);
/**
+ * Given an allocator scope, a tvbuff, a byte offset, a byte length, and
+ * a string encoding, with the specified offset and length referring to
+ * a null-padded string in the specified encoding:
+ *
+ * allocate a buffer using the specified scope;
+ *
+ * convert the string from the specified encoding to UTF-8, possibly
+ * mapping some characters or invalid octet sequences to the Unicode
+ * REPLACEMENT CHARACTER, and put the resulting UTF-8 string, plus a
+ * trailing '\0', into that buffer;
+ *
+ * and return a pointer to the buffer.
+ *
+ * Throws an exception if the tvbuff ends before the string does.
+ *
+ * If scope is set to NULL it is the user's responsibility to wmem_free()
+ * the memory allocated. Otherwise memory is automatically freed when the
+ * scope lifetime is reached.
+ */
+WS_DLL_PUBLIC guint8 *tvb_get_stringzpad(wmem_allocator_t *scope,
+ tvbuff_t *tvb, const gint offset, const gint length, const guint encoding);
+
+/**
* Given an allocator scope, a tvbuff, a byte offset, a pointer to a
* gint, and a string encoding, with the specified offset referring to
* a null-terminated string in the specified encoding: