static expert_field ei_dcerpc_nt_badsid = EI_INIT;
+static int cb_array_hdr_size(dcerpc_info *di,
+ gboolean is_conformant, gboolean is_varying,
+ int start_offset, int end_offset);
+static void cb_str_postprocess_options(packet_info *pinfo,
+ proto_item *item,
+ dcerpc_info *di,
+ gint options,
+ const char *s);
/* This is used to safely walk the decode tree up, one item at a time safely.
This is used by dcerpc dissectors that want to push the display of a string
void *callback_args)
{
gint options = GPOINTER_TO_INT(callback_args);
- gint levels = CB_STR_ITEM_LEVELS(options);
char *s;
- int conformance_size = 4;
int hdr_size;
- if (di->call_data->flags & DCERPC_IS_NDR64) {
- conformance_size = 8;
- }
-
- /* Align start_offset on 4-byte boundary. */
-
- if (start_offset % conformance_size)
- start_offset += conformance_size - (start_offset % conformance_size);
-
- /* Get byte array value */
- hdr_size = 3 * conformance_size;
-
- if ((end_offset - start_offset) <= hdr_size)
+ hdr_size = cb_array_hdr_size(di,
+ TRUE, /* is_conformant */
+ TRUE, /* is_varying */
+ start_offset,
+ end_offset);
+ if (hdr_size < 0) {
return;
-
- s = tvb_bytes_to_str(pinfo->pool, tvb, start_offset + hdr_size, (end_offset - start_offset - hdr_size) );
-
- /* Append string to COL_INFO */
-
- if (options & CB_STR_COL_INFO) {
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", s);
}
- /* Append string to upper-level proto_items */
+ start_offset += hdr_size;
- if (levels > 0 && item && s && s[0]) {
- proto_item_append_text(item, ": %s", s);
- item = GET_ITEM_PARENT(item);
- levels--;
- if (levels > 0) {
- proto_item_append_text(item, ": %s", s);
- item = GET_ITEM_PARENT(item);
- levels--;
- while (levels > 0) {
- proto_item_append_text(item, " %s", s);
- item = GET_ITEM_PARENT(item);
- levels--;
- }
- }
- }
+ s = tvb_bytes_to_str(pinfo->pool, tvb, start_offset, end_offset - start_offset);
+
+ cb_str_postprocess_options(pinfo, item, di, options, s);
}
int
tree, drep, hfindex, length);
}
+static int cb_array_hdr_size(dcerpc_info *di,
+ gboolean is_conformant, gboolean is_varying,
+ int start_offset, int end_offset)
+{
+ int orig_offset = start_offset;
+ gint8 conformance_size = 4;
+ int hdr_size = 0;
+
+ DISSECTOR_ASSERT(is_conformant || is_varying);
+
+ if (di->call_data->flags & DCERPC_IS_NDR64) {
+ conformance_size = 8;
+ }
+
+ /* Align start_offset on 4-byte boundary. */
+
+ if (start_offset % conformance_size)
+ start_offset += conformance_size - (start_offset % conformance_size);
+
+ /* Get byte array value */
+ if (is_conformant)
+ hdr_size += conformance_size;
+ if (is_varying)
+ hdr_size += (2*conformance_size);
+
+ if ((end_offset - start_offset) <= hdr_size)
+ return -1;
+
+ return start_offset - orig_offset;
+}
+
static void cb_str_postprocess_options(packet_info *pinfo,
proto_item *item,
dcerpc_info *di,
void *callback_args)
{
gint options = GPOINTER_TO_INT(callback_args);
- char *s;
-
- /* Align start_offset on 4-byte boundary. */
-
- if (start_offset % 4)
- start_offset += 4 - (start_offset % 4);
+ guint8 *s;
+ int hdr_size;
- /* Get string value */
+ hdr_size = cb_array_hdr_size(di,
+ TRUE, /* is_conformant */
+ TRUE, /* is_varying */
+ start_offset,
+ end_offset);
+ if (hdr_size < 0) {
+ return;
+ }
- if ((end_offset - start_offset) <= 12)
- return; /* XXX: Use unistr2 dissector instead? */
+ start_offset += hdr_size;
/*
* XXX - need to handle non-printable characters here.
* efforts of that routine?
*/
s = tvb_get_string_enc(pinfo->pool,
- tvb, start_offset + 12, end_offset - start_offset - 12,
+ tvb, start_offset, end_offset - start_offset,
ENC_UTF_16|ENC_LITTLE_ENDIAN);
- cb_str_postprocess_options(pinfo, item, di, options, s);
+ cb_str_postprocess_options(pinfo, item, di, options, (char *)s);
}
void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
{
gint options = GPOINTER_TO_INT(callback_args);
guint8 *s;
+ int hdr_size;
- /* Align start_offset on 4-byte boundary. */
-
- if (start_offset % 4)
- start_offset += 4 - (start_offset % 4);
-
- /* Get string value */
+ hdr_size = cb_array_hdr_size(di,
+ TRUE, /* is_conformant */
+ TRUE, /* is_varying */
+ start_offset,
+ end_offset);
+ if (hdr_size < 0) {
+ return;
+ }
- if ((end_offset - start_offset) <= 12)
- return; /* XXX: Use unistr2 dissector instead? */
+ start_offset += hdr_size;
/*
* XXX - need to handle non-printable characters here.
* efforts of that routine?
*/
s = tvb_get_string_enc(pinfo->pool,
- tvb, start_offset + 12, (end_offset - start_offset - 12), ENC_ASCII);
+ tvb, start_offset, end_offset - start_offset, ENC_ASCII);
- cb_str_postprocess_options(pinfo, item, di, options, s);
+ cb_str_postprocess_options(pinfo, item, di, options, (char *)s);
}
/* Dissect a pointer to a NDR string and append the string value to the