Introduce, and start using, tvb_get_const_stringz(). This function returns a

pointer to a NULL-terminated string in the TVB.  It is no safer than dissectors
which call tvb_get_strsize() and then tvb_get_ptr() but it makes it clear that
this usage of tvb_get_ptr() is safe.

This function is slightly more efficient than tvb_get_ephemeral_stringz()--but
only as long as we're not using composite TVBs.

svn path=/trunk/; revision=35493
This commit is contained in:
Jeff Morriss 2011-01-12 02:25:08 +00:00
parent 1c5d75288c
commit 0c4e881911
5 changed files with 81 additions and 49 deletions

View File

@ -1277,20 +1277,26 @@ free() this buffer, it will happen automatically once the a new capture or
file is opened.
guint8 *tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
const guint8 *tvb_get_const stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding);
guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
Returns a null-terminated buffer, allocated with "g_malloc()",
containing data from the specified tvbuff, starting at the
specified offset, and containing all characters from the tvbuff up to
and including a terminating null character in the tvbuff. "*lengthp"
will be set to the length of the string, including the terminating null.
Returns a null-terminated buffer containing data from the specified tvbuff,
starting at the specified offset, and containing all characters from the
tvbuff up to and including a terminating null character in the tvbuff.
"*lengthp" will be set to the length of the string, including the terminating
null.
tvb_get_stringz() returns a buffer allocated by g_malloc() so you must
g_free() it when you are finished with the string. Failure to g_free() this
buffer will lead to memory leaks.
tvb_get_const_stringz() returns a pointer to the (const) string in the tvbuff.
You do not need to free() this buffer, it will happen automatically once the
next packet is dissected. This function is slightly more efficient than the
others because it does not allocate memory and copy the string.
tvb_get_ephemeral_stringz() returns a buffer allocated from a special heap
with a lifetime until the next packet is dissected. You do not need to
free() this buffer, it will happen automatically once the next packet is

View File

@ -206,7 +206,7 @@ static dissector_handle_t pdcp_lte_handle;
void proto_register_catapult_dct2000(void);
static dissector_handle_t look_for_dissector(char *protocol_name);
static dissector_handle_t look_for_dissector(const char *protocol_name);
static void parse_outhdr_string(const guchar *outhdr_string);
static void attach_fp_info(packet_info *pinfo, gboolean received,
const char *protocol_name, int variant);
@ -1082,7 +1082,7 @@ static void dissect_pdcp_lte(tvbuff_t *tvb, gint offset,
/* Look up dissector by protocol name. Fix up known name mis-matches.
This includes exact matches and prefixes (e.g. "diameter_rx" -> "diameter") */
static dissector_handle_t look_for_dissector(char *protocol_name)
static dissector_handle_t look_for_dissector(const char *protocol_name)
{
/* Use known aliases and protocol name prefixes */
if (strcmp(protocol_name, "tbcp") == 0) {
@ -1714,22 +1714,22 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item *ti = NULL;
gint offset = 0;
gint context_length;
const char *context_name;
guint8 port_number;
gint protocol_start;
gint protocol_length;
gint timestamp_start;
gint timestamp_length;
gint variant_start;
const char *timestamp_string;
gint variant_length;
gint outhdr_start;
const char *variant_string;
gint outhdr_length;
const char *outhdr_string;
guint8 direction;
tvbuff_t *next_tvb;
int encap;
dissector_handle_t protocol_handle = 0;
dissector_handle_t heur_protocol_handle = 0;
int sub_dissector_result = 0;
char *protocol_name;
const char *protocol_name;
gboolean is_comment;
/* Set Protocol */
@ -1749,7 +1749,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* by the wiretap module */
/* Context Name */
context_length = tvb_strsize(tvb, offset);
context_name = tvb_get_const_stringz(tvb, offset, &context_length);
if (dct2000_tree) {
proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_context, tvb,
offset, context_length, FALSE);
@ -1765,33 +1765,29 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset++;
/* Timestamp in file */
timestamp_start = offset;
timestamp_length = tvb_strsize(tvb, offset);
timestamp_string = tvb_get_const_stringz(tvb, offset, &timestamp_length);
if (dct2000_tree) {
/* TODO: this is *very* slow, but float version adds trailing digits when
displayed as a custom column... */
proto_tree_add_double(dct2000_tree, hf_catapult_dct2000_timestamp, tvb,
offset, timestamp_length,
atof(tvb_get_ptr(tvb, offset, timestamp_length)));
atof(timestamp_string));
}
offset += timestamp_length;
/* DCT2000 protocol name */
protocol_start = offset;
protocol_length = tvb_strsize(tvb, offset);
protocol_name = tvb_get_const_stringz(tvb, offset, &protocol_length);
if (dct2000_tree) {
proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_protocol, tvb,
offset, protocol_length, FALSE);
}
protocol_name = (char*)tvb_get_ptr(tvb, protocol_start, protocol_length);
is_comment = (strcmp(protocol_name, "comment") == 0);
offset += protocol_length;
/* Protocol Variant */
variant_start = offset;
variant_length = tvb_strsize(tvb, offset);
variant_string = tvb_get_const_stringz(tvb, offset, &variant_length);
if (!is_comment) {
proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_variant, tvb,
offset, variant_length, FALSE);
@ -1799,8 +1795,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += variant_length;
/* Outhdr (shown as string) */
outhdr_start = offset;
outhdr_length = tvb_strsize(tvb, offset);
outhdr_string = tvb_get_const_stringz(tvb, offset, &outhdr_length);
if (!is_comment && (outhdr_length > 1)) {
proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_outhdr, tvb,
offset, outhdr_length, FALSE);
@ -1825,12 +1820,12 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Add useful details to protocol tree label */
proto_item_append_text(ti, " context=%s.%u t=%s %c prot=%s (v=%s)",
tvb_get_ptr(tvb, 0, context_length),
context_name,
port_number,
tvb_get_ptr(tvb, timestamp_start, timestamp_length),
timestamp_string,
(direction == 0) ? 'S' : 'R',
protocol_name,
tvb_get_ptr(tvb, variant_start, variant_length));
variant_string);
@ -1843,26 +1838,25 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
(strcmp(protocol_name, "fp_r8") == 0) ||
(strcmp(protocol_name, "fpiur_r5") == 0)) {
parse_outhdr_string(tvb_get_ptr(tvb, outhdr_start, outhdr_length));
attach_fp_info(pinfo, direction, protocol_name,
atoi((char*)tvb_get_ptr(tvb, variant_start, variant_length)));
parse_outhdr_string(outhdr_string);
attach_fp_info(pinfo, direction, protocol_name, atoi(variant_string));
}
/* LTE MAC needs info attached */
else if (strcmp(protocol_name, "mac_r8_lte") == 0) {
parse_outhdr_string(tvb_get_ptr(tvb, outhdr_start, outhdr_length));
parse_outhdr_string(outhdr_string);
attach_mac_lte_info(pinfo);
}
/* LTE RLC needs info attached */
else if (strcmp(protocol_name, "rlc_r8_lte") == 0) {
parse_outhdr_string(tvb_get_ptr(tvb, outhdr_start, outhdr_length));
parse_outhdr_string(outhdr_string);
attach_rlc_lte_info(pinfo);
}
/* LTE PDCP needs info attached */
else if (strcmp(protocol_name, "pdcp_r8_lte") == 0) {
parse_outhdr_string(tvb_get_ptr(tvb, outhdr_start, outhdr_length));
parse_outhdr_string(outhdr_string);
attach_pdcp_lte_info(pinfo);
}
@ -1922,14 +1916,14 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (direction == 0) {
col_add_fstr(pinfo->cinfo, COL_DEF_SRC,
"%s.%u",
tvb_get_ptr(tvb, 0, context_length),
context_name,
port_number);
}
else
if (direction == 1) {
col_add_fstr(pinfo->cinfo, COL_DEF_DST,
"%s.%u",
tvb_get_ptr(tvb, 0, context_length),
context_name,
port_number);
}
@ -2336,12 +2330,12 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_add_fstr(pinfo->cinfo, COL_INFO,
"Not dissected (context=%s.%u t=%s %c prot=%s (v=%s))",
tvb_get_ptr(tvb, 0, context_length),
context_name,
port_number,
tvb_get_ptr(tvb, timestamp_start, timestamp_length),
timestamp_string,
(direction == 0) ? 'S' : 'R',
tvb_get_ptr(tvb, protocol_start, protocol_length),
tvb_get_ptr(tvb, variant_start, variant_length));
protocol_name,
variant_string);
}
else {
/* Show number of dissected bytes */

View File

@ -1041,6 +1041,7 @@ tvb_get_bits8
tvb_get_bits16
tvb_get_bits32
tvb_get_bits64
tvb_get_const_stringz
tvb_get_ephemeral_faked_unicode
tvb_get_ephemeral_string
tvb_get_ephemeral_stringz

View File

@ -2257,11 +2257,11 @@ tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length)
/*
* Unicode (UTF-16) version of tvb_get_string()
*
*
* Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
*
* Specify length in bytes
*
*
* Returns an UTF-8 string that must be freed by the caller
*/
gchar *
@ -2336,11 +2336,11 @@ tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length)
/*
* Unicode (UTF-16) version of tvb_get_ephemeral_string()
*
*
* Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
*
* Specify length in bytes
*
*
* Returns an ep_ allocated UTF-8 string
*/
gchar *
@ -2432,6 +2432,31 @@ tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
*lengthp = size;
return strptr;
}
/*
* Given a tvbuff and an offset, with the offset assumed to refer to
* a null-terminated string, find the length of that string (and throw
* an exception if the tvbuff ends before we find the null), ensure that
* the TVB is flat, and return a pointer to the string (in the TVB).
* Also return the length of the string (including the terminating null)
* through a pointer.
*
* As long as we aren't using composite TVBs, this saves the cycles used
* (often unnecessariliy) in allocating a buffer and copying the string into
* it. (If we do start using composite TVBs, we may want to replace this
* function with the _ephemeral versoin.)
*/
const guint8 *
tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
{
guint size;
const guint8 *strptr;
size = tvb_strsize(tvb, offset);
strptr = tvb_get_ptr(tvb, offset, size);
if (lengthp)
*lengthp = size;
return strptr;
}
/*
* Given a tvbuff and an offset, with the offset assumed to refer to
* a null-terminated string, find the length of that string (and throw
@ -2462,7 +2487,7 @@ tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
/*
* Unicode (UTF-16) version of tvb_get_ephemeral_stringz()
*
*
* Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
*
* Returns an ep_ allocated UTF-8 string and updates lengthp pointer with length of string (in bytes)
@ -3002,8 +3027,8 @@ tvb_bytes_to_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const g
/*
* Given a tvbuff, an offset into the tvbuff, and a length that starts
* at that offset (which may be -1 for "all the way to the end of the
* tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
* the low or high half byte, formating the digits according to an input digit set,
* tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
* the low or high half byte, formating the digits according to an input digit set,
* if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
* A pointer to the EP allocated string will be returned.
* Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
@ -3040,7 +3065,7 @@ tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_
octet = tvb_get_guint8(tvb,t_offset);
if (!skip_first){
digit_str[i] = dgt->out[octet & 0x0f];
digit_str[i] = dgt->out[octet & 0x0f];
i++;
}
skip_first = FALSE;
@ -3053,7 +3078,7 @@ tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_
if (octet == 0x0f) /* odd number bytes - hit filler */
break;
digit_str[i] = dgt->out[octet & 0x0f];
digit_str[i] = dgt->out[octet & 0x0f];
i++;
t_offset++;

View File

@ -517,6 +517,11 @@ extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const g
* MUST be g_free() by the caller in order not to leak
* memory.
*
* tvb_get_const_stringz() returns a constant (unmodifiable) string that does
* not need to be freed, instead it will automatically be
* freed once the next packet is dissected. It is slightly
* more efficient than the other routines.
*
* tvb_get_ephemeral_stringz() returns a string that does not need to be freed,
* instead it will automatically be freed once the next
* packet is dissected.
@ -528,6 +533,7 @@ extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const g
* or file is opened.
*/
extern guint8 *tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
extern const guint8 *tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
extern guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
extern gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding);
extern guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
@ -659,8 +665,8 @@ extern gchar *tvb_bytes_to_str(tvbuff_t *tvb, const gint offset, const gint len)
/**
* Given a tvbuff, an offset into the tvbuff, and a length that starts
* at that offset (which may be -1 for "all the way to the end of the
* tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
* the low or high half byte, formating the digits according to an input digit set,
* tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
* the low or high half byte, formating the digits according to an input digit set,
* if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
* A pointer to the EP allocated string will be returned.
* Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.