aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2003-02-03 02:00:54 +0000
committerTim Potter <tpot@samba.org>2003-02-03 02:00:54 +0000
commit91c6b0c70b698c3a41cf9d4f9e5e38064bb3d387 (patch)
treeaa98d5ba6835ec09c675ee52823b26d018a2dee4
parent48c7ab1f05343741dd0ed5eb237b98b7f45acf07 (diff)
Replace the confusing collection of Windows DCERPC string handling
functions with something a little less confusing. We now have two sets of functions to dissect strings: - dissect_ndr_wchar_array() which dissects NDR arrays of wide characters (uint32, uint32, uint32, buffer) - dissect_ndr_counted_string() which dissects a "counted string" (uint16, uint16, pointer to array of wchar) There are three contexts for dissecting counted strings: 1. "in-line" using dissect_ndr_counted_string() 2. as a callback to dissect_ndr_pointer() 3. as a callback to dissect_ndr_pointer_cb() Context 2 is used when you have a pointer to a counted string. Context 3 is when you wish to perform some special processing with the returned string. svn path=/trunk/; revision=7068
-rw-r--r--packet-dcerpc-nt.c360
-rw-r--r--packet-dcerpc-nt.h47
2 files changed, 188 insertions, 219 deletions
diff --git a/packet-dcerpc-nt.c b/packet-dcerpc-nt.c
index 56ba3d7527..707b3c3fdc 100644
--- a/packet-dcerpc-nt.c
+++ b/packet-dcerpc-nt.c
@@ -2,7 +2,7 @@
* Routines for DCERPC over SMB packet disassembly
* Copyright 2001-2003, Tim Potter <tpot@samba.org>
*
- * $Id: packet-dcerpc-nt.c,v 1.61 2003/01/31 06:47:55 guy Exp $
+ * $Id: packet-dcerpc-nt.c,v 1.62 2003/02/03 02:00:54 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -70,243 +70,178 @@ char *fake_unicode(tvbuff_t *tvb, int offset, int len)
return buffer;
}
-/* following are a few functions for dissecting common structures used by NT
- services. These might need to be cleaned up at a later time but at least we get
- them out of the real service dissectors.
-*/
-
-
-/* UNICODE_STRING BEGIN */
-/* functions to dissect a UNICODE_STRING structure, common to many
- NT services
- struct {
- short len;
- short size;
- [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
- } UNICODE_STRING;
+/* Dissect an NDR array of elements. The length of each element is
+ given by the 'size_is' parameter. */
- these variables can be found in packet-dcerpc-samr.c
-*/
-extern int hf_nt_str_len;
-extern int hf_nt_str_off;
-extern int hf_nt_str_max_len;
-extern int hf_nt_string_length;
-extern int hf_nt_string_size;
-
-gint ett_nt_unicode_string = -1;
-static gint ett_nt_policy_hnd = -1;
+int hf_nt_str_len = -1; /* FIXME: make static */
+int hf_nt_str_off = -1;
+int hf_nt_str_max_len = -1;
+static int hf_nt_str_buffer = -1;
-/* this function will dissect the
- [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
- part of the unicode string
+static int hf_nt_string_length = -1;
+static int hf_nt_string_size = -1;
- struct {
- short len;
- short size;
- [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
- } UNICODE_STRING;
- structure used by NT to transmit unicode string values.
+gint ett_nt_unicode_string = -1; /* FIXME: make static */
-*/
-int
-dissect_ndr_nt_UNICODE_STRING_str(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- char *drep)
+static int
+dissect_ndr_element_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep, int size_is)
{
- guint32 len;
- dcerpc_info *di;
- char *text;
+ guint32 len, buffer_len;
- di=pinfo->private_data;
- if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
- return offset;
- }
+ /* NDR array header */
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_max_len, NULL);
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_off, NULL);
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_len, &len);
- if (offset % 2)
- offset++;
+ buffer_len = size_is * len;
- if (tree) {
- text = fake_unicode(tvb, offset, len);
- proto_tree_add_string (tree, di->hf_index, tvb, offset, len * 2, text);
- g_free(text);
- }
+ /* Adjust offset */
+
+ if (offset % size_is)
+ offset += size_is - (offset % size_is);
- offset += len * 2;
+ if (tree && buffer_len)
+ proto_tree_add_item(
+ tree, hf_nt_str_buffer, tvb, offset, buffer_len,
+ drep[0] & 0x10);
- return offset;
+ offset += buffer_len;
+
+ return offset;
}
-/* this function will dissect the
- struct {
- short len;
- short size;
- [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
- } UNICODE_STRING;
- structure used by NT to transmit unicode string values.
-*/
+/* Dissect an array of wchars (wide characters). This corresponds to
+ IDL of the form '[string] wchar *foo' */
+
int
-dissect_ndr_nt_UNICODE_STRING_cb(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index,
- dcerpc_callback_fnct_t *callback,
- void *callback_args)
+dissect_ndr_wchar_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
{
- proto_item *item=NULL;
- proto_tree *tree=NULL;
- int old_offset=offset;
- dcerpc_info *di;
- char *name;
+ dcerpc_info *di = pinfo->private_data;
- ALIGN_TO_4_BYTES; /* strcture starts with short, but is aligned for longs */
-
- di=pinfo->private_data;
- if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
+ if (di->conformant_run)
return offset;
- }
- name = proto_registrar_get_name(hf_index);
- if(parent_tree){
- item = proto_tree_add_text(parent_tree, tvb, offset, -1,
- "%s", name);
- tree = proto_item_add_subtree(item, ett_nt_unicode_string);
- }
-
- offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
- hf_nt_string_length, NULL);
- offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
- hf_nt_string_size, NULL);
- offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
- dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
- name, hf_index, callback, callback_args);
-
- proto_item_set_len(item, offset-old_offset);
- return offset;
+ return dissect_ndr_element_array(
+ tvb, offset, pinfo, tree, drep, sizeof(guint16));
}
-/* UNICODE_STRING END */
+
+/* Dissect an array of wchars (wide characters). This corresponds to
+ IDL of the form '[string] wchar *foo' */
int
-dissect_ndr_nt_UNICODE_STRING(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index, int levels)
+dissect_ndr_char_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
{
- return dissect_ndr_nt_UNICODE_STRING_cb(
- tvb, offset, pinfo, parent_tree, drep, hf_index,
- cb_str_postprocess, GINT_TO_POINTER(2 + levels));
+ dcerpc_info *di = pinfo->private_data;
+
+ if (di->conformant_run)
+ return offset;
+
+ return dissect_ndr_element_array(
+ tvb, offset, pinfo, tree, drep, sizeof(guint8));
}
-/* functions to dissect a STRING structure, common to many
- NT services
- struct {
- short len;
- short size;
- [size_is(size), length_is(len), ptr] char *string;
- } STRING;
-*/
+/* Dissect a counted string as a callback to dissect_ndr_pointer_cb() */
+
+static int hf_nt_cs_len = -1;
+static int hf_nt_cs_size = -1;
+
int
-dissect_ndr_nt_STRING_string(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- char *drep)
+dissect_ndr_counted_string_cb(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep, int hf_index,
+ dcerpc_callback_fnct_t *callback,
+ void *callback_args)
{
- guint32 len, off, max_len;
- const guint8 *text;
- header_field_info *hfi;
- dcerpc_info *di;
+ dcerpc_info *di = pinfo->private_data;
+ guint16 len, size;
- di=pinfo->private_data;
- if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
+ /* Structure starts with short, but is aligned for longs */
+
+ ALIGN_TO_4_BYTES;
+
+ if (di->conformant_run)
return offset;
- }
+
+ /*
+ struct {
+ short len;
+ short size;
+ [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
+ } UNICODE_STRING;
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
- hf_nt_str_max_len, &max_len);
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
- hf_nt_str_off, &off);
- offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
- hf_nt_str_len, &len);
-
- hfi = proto_registrar_get_nth(di->hf_index);
-
- switch(hfi->type){
- case FT_STRING:
- text = tvb_get_ptr(tvb, offset, len);
- break;
- case FT_BYTES:
- text = NULL;
- break;
- default:
- text = NULL;
- g_assert_not_reached();
- }
- proto_tree_add_item(tree, di->hf_index, tvb, offset, len, FALSE);
- offset += len;
+ */
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_nt_cs_len, &len);
- return offset;
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_nt_cs_size, &size);
+
+ offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
+ dissect_ndr_wchar_array, NDR_POINTER_UNIQUE,
+ "Character Array", hf_index, callback, callback_args);
+
+ return offset;
}
-int
-dissect_ndr_nt_STRING_cb(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index,
- dcerpc_callback_fnct_t *callback,
- void *callback_args)
+static gint ett_nt_counted_string = -1;
+
+static int
+dissect_ndr_counted_string_helper(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep, int hf_index, int levels,
+ gboolean add_subtree)
{
- proto_item *item=NULL;
- proto_tree *tree=NULL;
- int old_offset=offset;
- dcerpc_info *di;
- char *name;
+ proto_item *item;
+ proto_tree *subtree = tree;
- ALIGN_TO_4_BYTES; /* strcture starts with short, but is aligned for longs */
+ if (add_subtree) {
- di=pinfo->private_data;
- if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
- return offset;
- }
+ item = proto_tree_add_text(
+ tree, tvb, offset, 0,
+ proto_registrar_get_name(hf_index));
- name = proto_registrar_get_name(hf_index);
- if(parent_tree){
- item = proto_tree_add_text(parent_tree, tvb, offset, -1,
- "%s", name);
- tree = proto_item_add_subtree(item, ett_nt_unicode_string);
+ subtree = proto_item_add_subtree(item, ett_nt_counted_string);
}
- offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
- hf_nt_string_length, NULL);
- offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
- hf_nt_string_size, NULL);
- offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
- dissect_ndr_nt_STRING_string, NDR_POINTER_UNIQUE,
- name, hf_index, callback, callback_args);
-
- proto_item_set_len(item, offset-old_offset);
- return offset;
+ return dissect_ndr_counted_string_cb(
+ tvb, offset, pinfo, subtree, drep, hf_index,
+ cb_str_postprocess, GINT_TO_POINTER(1 + levels));
}
+/* Dissect a counted string in-line. */
+
int
-dissect_ndr_nt_STRING(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index)
+dissect_ndr_counted_string(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep, int hf_index, int levels)
{
- header_field_info *hfi;
+ return dissect_ndr_counted_string_helper(
+ tvb, offset, pinfo, tree, drep, hf_index, levels, TRUE);
+}
- hfi = proto_registrar_get_nth(hf_index);
+/* Dissect a counted string as a callback to dissect_ndr_pointer().
+ This doesn't add a adds a proto item and subtreee for the string as
+ the pointer dissection already creates one. */
- return dissect_ndr_nt_STRING_cb(
- tvb, offset, pinfo, parent_tree, drep, hf_index,
- cb_str_postprocess,
- hfi->type == FT_STRING ? GINT_TO_POINTER(1):
- GINT_TO_POINTER(0));
+int
+dissect_ndr_counted_string_ptr(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ dcerpc_info *di = pinfo->private_data;
+
+ return dissect_ndr_counted_string_helper(
+ tvb, offset, pinfo, tree, drep, di->hf_index, 1, FALSE);
}
/* This function is used to dissect a DCERPC encoded 64 bit time value.
@@ -849,6 +784,8 @@ dissect_doserror(tvbuff_t *tvb, gint offset, packet_info *pinfo,
static int hf_nt_policy_open_frame = -1;
static int hf_nt_policy_close_frame = -1;
+static gint ett_nt_policy_hnd = -1;
+
int
dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep, int hfindex,
@@ -1046,7 +983,7 @@ int dissect_ndr_str_pointer_item(tvbuff_t *tvb, gint offset,
{
return dissect_ndr_pointer_cb(
tvb, offset, pinfo, tree, drep,
- dissect_ndr_nt_UNICODE_STRING_str, type, text, hf_index,
+ dissect_ndr_wchar_array, type, text, hf_index,
cb_str_postprocess, GINT_TO_POINTER(levels + 1));
}
@@ -1058,6 +995,44 @@ void dcerpc_smb_init(int proto_dcerpc)
{
static hf_register_info hf[] = {
+ /* String handling */
+
+ { &hf_nt_string_length,
+ { "Length", "nt.string.length", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "Length of string in bytes", HFILL }},
+
+ { &hf_nt_string_size,
+ { "Size", "nt.string.size", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "Size of string in bytes", HFILL }},
+
+ { &hf_nt_str_len,
+ { "Length", "nt.str.len", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "Length of string in short integers", HFILL }},
+
+ { &hf_nt_str_off,
+ { "Offset", "nt.str.offset", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "Offset into string in short integers",
+ HFILL }},
+
+ { &hf_nt_str_max_len,
+ { "Max Length", "nt.str.max_len", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "Max Length of string in short integers",
+ HFILL }},
+
+ { &hf_nt_str_buffer,
+ { "Buffer", "nt.str.buffer", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "Buffer", HFILL }},
+
+ { &hf_nt_cs_size,
+ { "Size", "nt.str.size", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "Size of string in short integers",
+ HFILL }},
+
+ { &hf_nt_cs_len,
+ { "Length", "nt.str.len", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "Length of string in short integers",
+ HFILL }},
+
/* Access mask */
{ &hf_access_generic_read,
@@ -1210,6 +1185,7 @@ void dcerpc_smb_init(int proto_dcerpc)
static gint *ett[] = {
&ett_nt_unicode_string,
+ &ett_nt_counted_string,
&ett_nt_policy_hnd,
&ett_nt_access_mask,
&ett_nt_access_mask_generic,
diff --git a/packet-dcerpc-nt.h b/packet-dcerpc-nt.h
index b3b8eb554b..e2a0650a65 100644
--- a/packet-dcerpc-nt.h
+++ b/packet-dcerpc-nt.h
@@ -2,7 +2,7 @@
* Routines for DCERPC over SMB packet disassembly
* Copyright 2001-2003 Tim Potter <tpot@samba.org>
*
- * $Id: packet-dcerpc-nt.h,v 1.37 2003/01/30 08:19:38 guy Exp $
+ * $Id: packet-dcerpc-nt.h,v 1.38 2003/02/03 02:00:54 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -48,36 +48,21 @@ char *fake_unicode(tvbuff_t *tvb, int offset, int len);
}
int
-dissect_ndr_nt_UNICODE_STRING_str(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- char *drep);
-int
-dissect_ndr_nt_UNICODE_STRING_cb(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index,
- dcerpc_callback_fnct_t *callback,
- void *callback_args);
+dissect_ndr_counted_string_cb(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep, int hf_index,
+ dcerpc_callback_fnct_t *callback,
+ void *callback_args);
int
-dissect_ndr_nt_UNICODE_STRING(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index, int levels);
+dissect_ndr_counted_string_ptr(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *parent_tree,
+ char *drep);
int
-dissect_ndr_nt_STRING_string(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- char *drep);
-int
-dissect_ndr_nt_STRING_cb(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index,
- dcerpc_callback_fnct_t *callback,
- void *callback_args);
-
-int
-dissect_ndr_nt_STRING(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- char *drep, int hf_index);
+dissect_ndr_counted_string(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *parent_tree,
+ char *drep, int hf_index, int levels);
int
dissect_ndr_nt_acct_ctrl(tvbuff_t *tvb, int offset, packet_info *pinfo,
@@ -218,4 +203,12 @@ void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
void dcerpc_smb_init(int proto_dcerpc);
+int
+dissect_ndr_wchar_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep);
+
+int
+dissect_ndr_char_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep);
+
#endif /* packet-dcerpc-nt.h */