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>
This commit is contained in:
Guy Harris 2014-04-12 15:26:34 -07:00
parent ef8a0a2ce1
commit cb16dff992
27 changed files with 260 additions and 161 deletions

View File

@ -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);
}
/* 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);
break;
/* XXX - it would be nice to handle FT_TVBUFF, too */
default:
break;
}
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);
}

View File

@ -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:

View File

@ -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;

View File

@ -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 }
},

View File

@ -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;

View File

@ -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;*/
}

View File

@ -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;*/
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -2532,6 +2532,24 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
return strbuf;
}
/*
* 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

View File

@ -556,6 +556,29 @@ WS_DLL_PUBLIC guint8 *tvb_get_string_enc(wmem_allocator_t *scope,
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

View File

@ -1256,6 +1256,8 @@ static const char* ftenum_to_string(header_field_info *hfi)
return "FT_REL_OID";
case FT_SYSTEM_ID:
return "FT_SYSTEM_ID";
case FT_STRINGZPAD:
return "FT_STRIGZPAD";
case FT_NUM_TYPES:
return "FT_NUM_TYPES";
default:
@ -1343,7 +1345,7 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
fs_buf);
/* String types are quoted. Remove them. */
if ((finfo->value.ftype->ftype == FT_STRING || finfo->value.ftype->ftype == FT_STRINGZ) && fs_len > 2) {
if (IS_FT_STRING(finfo->value.ftype->ftype) && fs_len > 2) {
fs_buf[fs_len - 1] = '\0';
fs_ptr++;
}

View File

@ -574,6 +574,8 @@ add_decode_as(const gchar *cl_param)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
/* The selector for this table is a string. */
break;
@ -680,6 +682,8 @@ add_decode_as(const gchar *cl_param)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
/* The selector for this table is a string. */
dissector_change_string(table_name, selector_str, dissector_matching);
break;

View File

@ -706,6 +706,8 @@ add_decode_as(const gchar *cl_param)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
/* The selector for this table is a string. */
break;
@ -812,6 +814,8 @@ add_decode_as(const gchar *cl_param)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
/* The selector for this table is a string. */
dissector_change_string(table_name, selector_str, dissector_matching);
break;

View File

@ -130,7 +130,7 @@ read_set_decode_as_entries(gchar *key, const gchar *value,
}
if (is_valid) {
if (selector_type == FT_STRING || selector_type == FT_STRINGZ) {
if (IS_FT_STRING(selector_type)) {
dissector_change_string(values[0], values[1], lookup.handle);
} else {
dissector_change_uint(values[0], atoi(values[1]), lookup.handle);
@ -191,6 +191,8 @@ decode_build_reset_list (const gchar *table_name, ftenum_t selector_type,
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
item->ddi_selector.sel_string = (char *)key;
break;
@ -223,6 +225,8 @@ decode_clear_all(void)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
dissector_reset_string(item->ddi_table_name,
item->ddi_selector.sel_string);
break;

View File

@ -336,6 +336,8 @@ decode_build_show_list (const gchar *table_name, ftenum_t selector_type,
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
selector_name = (gchar *)key;
break;

View File

@ -145,6 +145,8 @@ decode_proto_add_to_list (const gchar *table_name _U_, ftenum_t selector_type,
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
str = (gchar*) key;
proto_add_to_list(tree_info, store, str, proto_name);
break;
@ -230,6 +232,8 @@ display_dissector_table_names(const char *table_name, const char *ui_name, gpoin
break;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
table_name_add_to_list(tree_info, dis_tbl_trees->str_tree_wgt, table_name, ui_name);
break;
default:

View File

@ -612,7 +612,7 @@ get_filter_from_packet_list_row_and_column(gpointer data)
if (hfi && hfi->parent == -1) {
/* Protocol only */
buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
} else if (hfi && hfi->type == FT_STRING) {
} else if (hfi && IS_FT_STRING(hfi->type)) {
/* Custom string, add quotes */
buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
cfile.cinfo.col_expr.col_expr_val[column]);

View File

@ -605,7 +605,7 @@ new_finfo_window(GtkWidget *w, struct FieldinfoWinData *DataPtr)
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(fvalue_edit), TRUE);
g_signal_connect(fvalue_edit, "value-changed", G_CALLBACK(finfo_integer_changed), DataPtr);
} else if (finfo_type == FT_STRING || finfo_type == FT_STRINGZ) {
} else if (finfo_type == FT_STRING || finfo_type == FT_STRINGZ || finfo_type == FT_STRINGZPAD) {
fvalue_edit = gtk_entry_new();
gtk_entry_set_max_length(GTK_ENTRY(fvalue_edit), finfo->length);
gtk_entry_set_text(GTK_ENTRY(fvalue_edit), (const gchar*) fvalue_get(&finfo->value));

View File

@ -138,6 +138,8 @@ QString DecodeAsDialog::entryString(const gchar *table_name, gpointer value)
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
entry_str = (char *)value;
break;
@ -341,7 +343,7 @@ void DecodeAsDialog::fillTypeColumn(QTreeWidgetItem *item)
ftenum_t selector_type = get_dissector_table_selector_type(table_name);
if (selector_type == FT_STRING || selector_type == FT_STRINGZ) {
if (IS_FT_STRING(selector_type)) {
item->setText(type_col_, tr("String"));
} else {
QString type_desc = tr("Integer, base ");
@ -430,7 +432,7 @@ void DecodeAsDialog::tableNamesCurrentIndexChanged(const QString &text)
selector_combo_box_->setCurrentIndex(0);
} else {
ftenum_t selector_type = get_dissector_table_selector_type(ui_name_to_name_[text]);
if (selector_type == FT_STRING || selector_type == FT_STRINGZ) {
if (IS_FT_STRING(selector_type)) {
selector_combo_box_->setEditText(default_str_selector_);
} else {
selector_combo_box_->setEditText(default_int_selector_);
@ -463,7 +465,7 @@ void DecodeAsDialog::selectorEditTextChanged(const QString &text)
ftenum_t selector_type = get_dissector_table_selector_type(table_name);
dissector_handle_t dissector;
if (selector_type == FT_STRING || selector_type == FT_STRINGZ) {
if (IS_FT_STRING(selector_type)) {
dissector = dissector_get_default_string_handle(table_name, text.toUtf8().constData());
} else {
dissector = dissector_get_default_uint_handle(table_name, text.toInt(NULL, 0));