Fix a typo in the multiple-include protection in "packet-dcerpc-nt.h".

Rename "dissect_ndr_element_array()" to "dissect_ndr_character_array()",
move it out of "packet-dcerpc-nt.c" to "packet-dcerpc.c", and have it
use the standard DCE RPC array max count/offset/count fields rather than
their own private versions of those fields.  Give it an option to create
a subtree, and an argument to specify the field to use for the actual
data buffer, and export it.

Move the routines for handling arrays of "char" and "wchar" as strings
out of "packet-dcerpc-nt.c" to "packet-dcerpc.c".

Add a routine to handle an array of "char" as an opaque blob of bytes.

Use "dissect_ndr_character_array()" to dissect character strings in MAPI
(the strings in question are ASCII, not Unicode), and use the routine to
handle an array of "char" as an opaque blob of bytes to dissect
encrypted data (again, it's bytes, not 16-bit quantities).  Show them as
encrypted data, not unknown data.

Use "dissect_ndr_character_array()" to dissect a form name in
"dissect_form_name()" in the SPOOLSS dissector.

svn path=/trunk/; revision=7091
This commit is contained in:
Guy Harris 2003-02-07 08:56:12 +00:00
parent 09052b88d2
commit 579d05d1f3
6 changed files with 209 additions and 190 deletions

View File

@ -2,7 +2,7 @@
* Routines for MS Exchange MAPI
* Copyright 2002, Ronnie Sahlberg
*
* $Id: packet-dcerpc-mapi.c,v 1.17 2003/02/03 02:14:00 tpot Exp $
* $Id: packet-dcerpc-mapi.c,v 1.18 2003/02/07 08:56:11 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -37,11 +37,11 @@
static int proto_dcerpc_mapi = -1;
static int hf_mapi_unknown_string = -1;
static int hf_mapi_unknown_data = -1;
static int hf_mapi_unknown_short = -1;
static int hf_mapi_hnd = -1;
static int hf_mapi_rc = -1;
static int hf_mapi_encap_datalen = -1;
static int hf_mapi_encrypted_data = -1;
static int hf_mapi_decrypted_data_maxlen = -1;
static int hf_mapi_decrypted_data_offset = -1;
static int hf_mapi_decrypted_data_len = -1;
@ -236,9 +236,8 @@ static int
mapi_logon_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, char *drep)
{
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_array, NDR_POINTER_REF,
"unknown string", hf_mapi_unknown_string);
offset = dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint8), hf_mapi_unknown_string, TRUE);
DISSECT_UNKNOWN(tvb_length_remaining(tvb, offset));
@ -257,15 +256,13 @@ mapi_logon_reply(tvbuff_t *tvb, int offset,
DISSECT_UNKNOWN(20); /* this is 20 bytes, unless there are pointers */
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_array, NDR_POINTER_REF,
"unknown string", hf_mapi_unknown_string);
offset = dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint8), hf_mapi_unknown_string, TRUE);
DISSECT_UNKNOWN(6); /* possibly 1 or 2 bytes padding here */
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_array, NDR_POINTER_REF,
"unknown string", hf_mapi_unknown_string);
offset = dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint8), hf_mapi_unknown_string, TRUE);
DISSECT_UNKNOWN( tvb_length_remaining(tvb, offset)-4 );
@ -286,8 +283,8 @@ mapi_unknown_02_request(tvbuff_t *tvb, int offset,
/* this is a unidimensional varying and conformant array of
encrypted data */
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_array, NDR_POINTER_REF,
"unknown data", hf_mapi_unknown_data);
dissect_ndr_byte_array, NDR_POINTER_REF,
"Encrypted data", hf_mapi_encrypted_data);
} else {
offset = mapi_decrypt_pdu(tvb, offset, pinfo, tree, drep);
}
@ -312,8 +309,8 @@ mapi_unknown_02_reply(tvbuff_t *tvb, int offset,
/* this is a unidimensional varying and conformant array of
encrypted data */
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_array, NDR_POINTER_REF,
"unknown data", hf_mapi_unknown_data);
dissect_ndr_byte_array, NDR_POINTER_REF,
"Encrypted data", hf_mapi_encrypted_data);
} else {
offset = mapi_decrypt_pdu(tvb, offset, pinfo, tree, drep);
}
@ -387,14 +384,14 @@ static hf_register_info hf[] = {
{ "Unknown short", "mapi.unknown_short", FT_UINT16, BASE_HEX,
NULL, 0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
{ &hf_mapi_unknown_data,
{ "unknown encrypted data", "mapi.unknown_data", FT_BYTES, BASE_HEX,
NULL, 0, "Unknown data. If you know what this is, contact ethereal developers.", HFILL }},
{ &hf_mapi_encap_datalen,
{ "Length", "mapi.encap_len", FT_UINT16, BASE_DEC,
NULL, 0x0, "Length of encapsulated/encrypted data", HFILL }},
{ &hf_mapi_encrypted_data,
{ "Encrypted data", "mapi.encrypted_data", FT_BYTES, BASE_HEX,
NULL, 0, "Encrypted data", HFILL }},
{ &hf_mapi_decrypted_data_maxlen,
{ "Max Length", "mapi.decrypted.data.maxlen", FT_UINT32, BASE_DEC,
NULL, 0x0, "Maximum size of buffer for decrypted data", HFILL }},

View File

@ -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.63 2003/02/07 06:01:49 tpot Exp $
* $Id: packet-dcerpc-nt.c,v 1.64 2003/02/07 08:56:11 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -39,116 +39,10 @@
* dissectors for ethereal.
*/
/* Convert a string from little-endian unicode to ascii. At the moment we
fake it by taking every odd byte. )-: The caller must free the
result returned. */
char *fake_unicode(tvbuff_t *tvb, int offset, int len)
{
char *buffer;
int i;
guint16 character;
/* Make sure we have enough data before allocating the buffer,
so we don't blow up if the length is huge.
We do so by attempting to fetch the last character; it'll
throw an exception if it's past the end. */
tvb_get_letohs(tvb, offset + 2*(len - 1));
/* We know we won't throw an exception, so we don't have to worry
about leaking this buffer. */
buffer = g_malloc(len + 1);
for (i = 0; i < len; i++) {
character = tvb_get_letohs(tvb, offset);
buffer[i] = character & 0xff;
offset += 2;
}
buffer[len] = 0;
return buffer;
}
/* Dissect an NDR array of elements. The length of each element is
given by the 'size_is' parameter. */
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;
static int hf_nt_string_length = -1;
static int hf_nt_string_size = -1;
/* Parse some common RPC structures */
gint ett_nt_unicode_string = -1; /* FIXME: make static */
static int
dissect_ndr_element_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep, int size_is)
{
guint32 len, buffer_len;
/* NDR array header */
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_max_len, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_off, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_nt_str_len, &len);
buffer_len = size_is * len;
/* Adjust offset */
if (offset % size_is)
offset += size_is - (offset % size_is);
if (tree && buffer_len)
proto_tree_add_item(
tree, hf_nt_str_buffer, tvb, offset, buffer_len,
drep[0] & 0x10);
offset += buffer_len;
return offset;
}
/* Dissect an array of wchars (wide characters). This corresponds to
IDL of the form '[string] wchar *foo' */
int
dissect_ndr_wchar_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
dcerpc_info *di = pinfo->private_data;
if (di->conformant_run)
return offset;
return dissect_ndr_element_array(
tvb, offset, pinfo, tree, drep, sizeof(guint16));
}
/* Dissect an array of wchars (wide characters). This corresponds to
IDL of the form '[string] wchar *foo' */
int
dissect_ndr_char_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
dcerpc_info *di = pinfo->private_data;
if (di->conformant_run)
return offset;
return dissect_ndr_element_array(
tvb, offset, pinfo, tree, drep, sizeof(guint8));
}
/* Dissect a counted string as a callback to dissect_ndr_pointer_cb() */
static int hf_nt_cs_len = -1;
@ -796,32 +690,6 @@ void dcerpc_smb_init(int proto_dcerpc)
/* 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",

View File

@ -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.39 2003/02/07 06:01:49 tpot Exp $
* $Id: packet-dcerpc-nt.h,v 1.40 2003/02/07 08:56:11 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -24,17 +24,13 @@
*/
#ifndef __PACKET_DCERPC_NT_H
#define __PACKET_DCEPRC_NT_H
#define __PACKET_DCERPC_NT_H
/*
* ett_ value for Unicode strings.
*/
extern gint ett_nt_unicode_string;
/* Parse some common RPC structures */
char *fake_unicode(tvbuff_t *tvb, int offset, int len);
/* Routines for handling deferral of referants in NDR */
#define ALIGN_TO_4_BYTES \
@ -193,12 +189,4 @@ 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 */

View File

@ -2,7 +2,7 @@
* Routines for SMB \PIPE\spoolss packet disassembly
* Copyright 2001-2003, Tim Potter <tpot@samba.org>
*
* $Id: packet-dcerpc-spoolss.c,v 1.82 2003/02/07 06:04:28 tpot Exp $
* $Id: packet-dcerpc-spoolss.c,v 1.83 2003/02/07 08:56:11 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -4206,25 +4206,9 @@ static int dissect_FORM_CTR(tvbuff_t *tvb, int offset,
static int dissect_form_name(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
extern int hf_nt_str_len;
extern int hf_nt_str_off;
extern int hf_nt_str_max_len;
guint32 len;
offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
hf_nt_str_max_len, NULL);
offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
hf_nt_str_off, NULL);
offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
hf_nt_str_len, &len);
offset = dissect_ndr_uint16s(
tvb, offset, pinfo, tree, drep,
hf_spoolss_form_name, len);
return offset;
return dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint16),
hf_spoolss_form_name, TRUE);
}

View File

@ -2,7 +2,7 @@
* Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc.c,v 1.100 2003/02/05 01:23:41 tpot Exp $
* $Id: packet-dcerpc.c,v 1.101 2003/02/07 08:56:11 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -387,6 +387,7 @@ static int hf_dcerpc_dg_status = -1;
static int hf_dcerpc_array_max_count = -1;
static int hf_dcerpc_array_offset = -1;
static int hf_dcerpc_array_actual_count = -1;
static int hf_dcerpc_array_buffer = -1;
static int hf_dcerpc_op = -1;
static int hf_dcerpc_referent_id = -1;
static int hf_dcerpc_fragments = -1;
@ -403,6 +404,7 @@ static gint ett_dcerpc_drep = -1;
static gint ett_dcerpc_dg_flags1 = -1;
static gint ett_dcerpc_dg_flags2 = -1;
static gint ett_dcerpc_pointer_data = -1;
static gint ett_dcerpc_string = -1;
static gint ett_dcerpc_fragments = -1;
static gint ett_dcerpc_fragment = -1;
static gint ett_decrpc_krb5_auth_verf = -1;
@ -910,6 +912,172 @@ dissect_ndr_ucvarray(tvbuff_t *tvb, gint offset, packet_info *pinfo,
return offset;
}
/* Dissect an array of bytes. This corresponds to
IDL of the form '[string] char *foo'. Used when the bytes
should be shown as a big blob, rather than showing each one
as an individual element.
XXX - does this need to do all the conformant array stuff that
"dissect_ndr_ucvarray()" does? */
int
dissect_ndr_byte_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
dcerpc_info *di;
guint32 len;
di=pinfo->private_data;
if(di->conformant_run){
/* just a run to handle conformant arrays, no scalars to dissect */
return offset;
}
/* NDR array header */
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_dcerpc_array_max_count, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_dcerpc_array_offset, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_dcerpc_array_actual_count, &len);
if (tree && len)
proto_tree_add_item(tree, hf_dcerpc_array_buffer,
tvb, offset, len, drep[0] & 0x10);
offset += len;
return offset;
}
/* For dissecting arrays that are to be interpreted as strings. */
/* Convert a string from little-endian unicode to ascii. At the moment we
fake it by taking every odd byte. )-: The caller must free the
result returned. */
char *
fake_unicode(tvbuff_t *tvb, int offset, int len)
{
char *buffer;
int i;
guint16 character;
/* Make sure we have enough data before allocating the buffer,
so we don't blow up if the length is huge.
We do so by attempting to fetch the last character; it'll
throw an exception if it's past the end. */
tvb_get_letohs(tvb, offset + 2*(len - 1));
/* We know we won't throw an exception, so we don't have to worry
about leaking this buffer. */
buffer = g_malloc(len + 1);
for (i = 0; i < len; i++) {
character = tvb_get_letohs(tvb, offset);
buffer[i] = character & 0xff;
offset += 2;
}
buffer[len] = 0;
return buffer;
}
/* Dissect an NDR array of elements, assumed to be a string.
The length of each element is given by the 'size_is' parameter;
the elements are assumed to be characters or wide characters.
XXX - does this need to do all the conformant array stuff that
"dissect_ndr_ucvarray()" does? */
int
dissect_ndr_character_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep, int size_is,
int hfinfo, gboolean add_subtree)
{
dcerpc_info *di;
proto_item *string_item;
proto_tree *string_tree;
guint32 len, buffer_len;
char *s;
di=pinfo->private_data;
if(di->conformant_run){
/* just a run to handle conformant arrays, no scalars to dissect */
return offset;
}
if (add_subtree) {
string_item = proto_tree_add_text(tree, tvb, offset, 0, "%s",
proto_registrar_get_name(hfinfo));
string_tree = proto_item_add_subtree(string_item, ett_dcerpc_string);
} else {
string_item = NULL;
string_tree = tree;
}
/* NDR array header */
offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
hf_dcerpc_array_max_count, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
hf_dcerpc_array_offset, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
hf_dcerpc_array_actual_count, &len);
buffer_len = size_is * len;
/* Adjust offset */
if (offset % size_is)
offset += size_is - (offset % size_is);
if (tree && buffer_len)
proto_tree_add_item(string_tree, hfinfo, tvb, offset, buffer_len,
drep[0] & 0x10);
if (string_item != NULL) {
if (size_is == sizeof(guint16))
s = fake_unicode(tvb, offset, buffer_len);
else {
s = g_malloc(buffer_len + 1);
tvb_memcpy(tvb, s, offset, buffer_len);
}
proto_item_append_text(string_item, ": %s", s);
g_free(s);
}
offset += buffer_len;
return offset;
}
/* Dissect an array of chars. This corresponds to
IDL of the form '[string] char *foo' */
int
dissect_ndr_char_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
return dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint8), hf_dcerpc_array_buffer,
FALSE);
}
/* Dissect an array of wchars (wide characters). This corresponds to
IDL of the form '[string] wchar *foo' */
int
dissect_ndr_wchar_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
return dissect_ndr_character_array(tvb, offset, pinfo, tree, drep,
sizeof(guint16), hf_dcerpc_array_buffer,
FALSE);
}
/* ndr pointer handling */
/* list of pointers encountered so far */
@ -3855,6 +4023,9 @@ proto_register_dcerpc (void)
{ &hf_dcerpc_array_actual_count,
{ "Actual Count", "dcerpc.array.actual_count", FT_UINT32, BASE_DEC, NULL, 0x0, "Actual Count: Actual number of elements in the array", HFILL }},
{ &hf_dcerpc_array_buffer,
{ "Buffer", "dcerpc.array.buffer", FT_BYTES, BASE_NONE, NULL, 0x0, "Buffer: Buffer containing elements of the array", HFILL }},
{ &hf_dcerpc_op,
{ "Operation", "dcerpc.op", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
@ -3892,6 +4063,7 @@ proto_register_dcerpc (void)
&ett_dcerpc_dg_flags1,
&ett_dcerpc_dg_flags2,
&ett_dcerpc_pointer_data,
&ett_dcerpc_string,
&ett_dcerpc_fragments,
&ett_dcerpc_fragment,
&ett_decrpc_krb5_auth_verf,

View File

@ -1,7 +1,7 @@
/* packet-dcerpc.h
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc.h,v 1.26 2003/01/28 06:17:09 tpot Exp $
* $Id: packet-dcerpc.h,v 1.27 2003/02/07 08:56:12 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -159,7 +159,6 @@ int dissect_ndr_ctx_hnd (tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep,
int hfindex, e_ctx_hnd *pdata);
typedef int (dcerpc_dissect_fnct_t)(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *drep);
typedef void (dcerpc_callback_fnct_t)(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, int start_offset, int end_offset, void *callback_args);
@ -189,7 +188,18 @@ int dissect_ndr_ucvarray(tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep,
dcerpc_dissect_fnct_t *fnct);
int dissect_ndr_byte_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep);
char *fake_unicode(tvbuff_t *tvb, int offset, int len);
int dissect_ndr_character_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep, int size_is,
int hfinfo, gboolean add_subtree);
int dissect_ndr_char_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep);
int dissect_ndr_wchar_array(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep);
typedef struct _dcerpc_sub_dissector {
guint16 num;