From 9130e707c14dea336c934351a252a592d7d557c0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 12 Aug 2004 07:25:11 +0000 Subject: r1767: Checkin of workarea. Sorry Jelmer but this overwrites some of your changes which I will have to merge in later on. This latest version of eparser tries to stick more closely to the original parser.pm. (This used to be commit 456a4d1d72807da037417073f346451421638c2f) --- source4/build/pidl/eparser.c | 540 +++++++++++++++++++++++ source4/build/pidl/eparser.h | 145 ++++++ source4/build/pidl/eparser.pm | 684 +++++++++++++++-------------- source4/build/pidl/includes.h | 3 + source4/build/pidl/moduleinfo.c | 5 + source4/build/pidl/packet-dcerpc-eparser.c | 675 ---------------------------- source4/build/pidl/packet-dcerpc-eparser.h | 126 ------ 7 files changed, 1039 insertions(+), 1139 deletions(-) create mode 100644 source4/build/pidl/eparser.c create mode 100644 source4/build/pidl/eparser.h create mode 100644 source4/build/pidl/includes.h create mode 100644 source4/build/pidl/moduleinfo.c delete mode 100644 source4/build/pidl/packet-dcerpc-eparser.c delete mode 100644 source4/build/pidl/packet-dcerpc-eparser.h (limited to 'source4/build/pidl') diff --git a/source4/build/pidl/eparser.c b/source4/build/pidl/eparser.c new file mode 100644 index 0000000000..541c712d51 --- /dev/null +++ b/source4/build/pidl/eparser.c @@ -0,0 +1,540 @@ +#include "eparser.h" +#include + +static gint ett_array = -1; + +struct ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, + guint8 *drep) +{ + struct ndr_pull *ndr; + + ndr = (struct ndr_pull *)g_malloc(sizeof(*ndr)); + + ndr->tvb = tvb_new_subset(tvb, offset, -1, -1); + ndr->offset = 0; + ndr->pinfo = pinfo; + ndr->drep = drep; + ndr->flags = NDR_SCALARS|NDR_BUFFERS|LIBNDR_FLAG_REF_ALLOC; + return ndr; +} + +/* + mark the start of a structure +*/ +void ndr_pull_struct_start(struct ndr_pull *ndr) +{ + struct ndr_ofs_list *ofs; + + ofs = g_malloc(sizeof(*ofs)); + ofs->offset = ndr->offset; + ofs->next = ndr->ofs_list; + ndr->ofs_list = ofs; +} + +/* + mark the end of a structure +*/ +void ndr_pull_struct_end(struct ndr_pull *ndr) +{ + ndr->ofs_list = ndr->ofs_list->next; +} + +void ndr_pull_align(struct ndr_pull *ndr, int size) +{ + if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { + ndr->offset = (ndr->offset + (size-1)) & ~(size-1); + } +} + +void ndr_pull_ptr(struct ndr_pull *ndr, proto_tree *tree, int hf, guint32 *ptr) +{ + ndr_pull_uint32(ndr, tree, hf, ptr); +} + +static int hf_string4_len = -1; +static int hf_string4_offset = -1; +static int hf_string4_len2 = -1; +static int hf_string_data = -1; + +void ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, + char **s) +{ + guint32 len1, ofs, len2; + char *data; + + if (!(ndr_flags & NDR_SCALARS)) { + return; + } + + switch (ndr->flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + + ndr_pull_uint32(ndr, tree, hf_string4_len, &len1); + ndr_pull_uint32(ndr, tree, hf_string4_offset, &ofs); + ndr_pull_uint32(ndr, tree, hf_string4_len2, &len2); + + if (len2 > 65535) + return; + + data = g_malloc(len2*2); + + proto_tree_add_bytes(tree, hf_string_data, ndr->tvb, + ndr->offset, len2 * 2, data); + + g_free(data); + + ndr->offset += len2 * 2; + +#if 0 + + ndr_pull_uint32(ndr, &len1)); + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + if (len2 > len1) { + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); + } + if (len2 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + NDR_PULL_NEED_BYTES(ndr, len2*2); + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len2*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len2*2); + + /* this is a way of detecting if a string is sent with the wrong + termination */ + if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) { + if (strlen(as) < len2) { + DEBUG(6,("short string '%s'\n", as)); + } + } else { + if (strlen(as) == len2) { + DEBUG(6,("long string '%s'\n", as)); + } + } + *s = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_SIZE4: + +#if 0 + + ndr_pull_uint32(ndr, &len1); + NDR_PULL_NEED_BYTES(ndr, len1*2); + if (len1 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len1*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len1*2); + *s = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_NULLTERM: + +#if 0 + + len1 = strnlen_w(ndr->data+ndr->offset, + (ndr->data_size - ndr->offset)/2); + if (len1*2+2 <= ndr->data_size - ndr->offset) { + len1++; + } + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len1*2, + (const void **)s); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len1*2); + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + +#if 0 + + ndr_pull_uint32(ndr, &len1); + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + if (len2 > len1) { + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad ascii string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); + } + NDR_ALLOC_N(ndr, as, (len2+1)); + ndr_pull_bytes(ndr, as, len2); + as[len2] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: + +#if 0 + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + NDR_ALLOC_N(ndr, as, (len2+1)); + ndr_pull_bytes(ndr, as, len2); + as[len2] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2: + +#if 0 + + ndr_pull_uint16(ndr, &len3); + NDR_ALLOC_N(ndr, as, (len3+1)); + ndr_pull_bytes(ndr, as, len3); + as[len3] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM: + +#if 0 + + len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset)); + if (len1+1 <= ndr->data_size - ndr->offset) { + len1++; + } + NDR_ALLOC_N(ndr, as, (len1+1)); + ndr_pull_bytes(ndr, as, len1); + as[len1] = 0; + (*s) = as; + +#endif + + break; + + default: + +#if 0 + + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); + +#endif + + } +} + +void ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, + proto_tree *tree, char *name, int hf, void *data, + int count) +{ + int i; + if (!(ndr_flags & NDR_SCALARS)) { + return; + } + for (i=0;itvb, ndr->offset, 0, "Array entry"); + subtrees[i] = proto_item_add_subtree(item, ett_array); + + if ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS)) + pull_fn(ndr, NDR_SCALARS, subtrees[i], data); + else + pull_fn(ndr, NDR_SCALARS, tree, data); + + } + if (!(ndr_flags & NDR_BUFFERS)) goto done; +buffers: + for (i=0;ioffset = dissect_ndr_uint8( + ndr->tvb, ndr->offset, ndr->pinfo, + tree, ndr->drep, hf, data); +} + +void ndr_pull_uint16(struct ndr_pull *ndr, proto_tree *tree, int hf, uint16 *data) +{ + ndr->offset = dissect_ndr_uint16( + ndr->tvb, ndr->offset, ndr->pinfo, + tree, ndr->drep, hf, data); +} + +void ndr_pull_uint32(struct ndr_pull *ndr, proto_tree *tree, int hf, uint32 *data) +{ + ndr->offset = dissect_ndr_uint32( + ndr->tvb, ndr->offset, ndr->pinfo, + tree, ndr->drep, hf, data); +} + +void ndr_pull_uint64(struct ndr_pull *ndr, proto_tree *tree, int hf, uint64 *data) +{ + ndr->offset = dissect_ndr_uint64( + ndr->tvb, ndr->offset, ndr->pinfo, + tree, ndr->drep, hf, data); +} + +void ndr_pull_int8(struct ndr_pull *ndr, proto_tree *tree, int hf, int8 *data) +{ +} + +void ndr_pull_int16(struct ndr_pull *ndr, proto_tree *tree, int hf, int16 *data) +{ +} + +void ndr_pull_int32(struct ndr_pull *ndr, proto_tree *tree, int hf, int32 *data) +{ +} + +void ndr_pull_int64(struct ndr_pull *ndr, proto_tree *tree, int hf, int64 *data) +{ +} + +void ndr_pull_NTTIME(struct ndr_pull *ndr, proto_tree *tree, int hf, NTTIME *data) +{ +} + +void ndr_pull_NTSTATUS(struct ndr_pull *ndr, proto_tree *tree, int hf, NTSTATUS *data) +{ + ndr->offset = dissect_ntstatus( + ndr->tvb, ndr->offset, ndr->pinfo, + tree, ndr->drep, hf, data); +} + +void ndr_pull_HYPER_T(struct ndr_pull *ndr, proto_tree *tree, int hf, HYPER_T *data) +{ +} + +void ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, struct dom_sid2 *data) +{ +} + +void ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, proto_tree *tree, + size_t sub_size, void *data, + void (*fn)(struct ndr_pull *, int ndr_flags, + proto_tree *tree, void *data)) +{ + struct ndr_pull ndr2; + + ndr_pull_subcontext_header(ndr, tree, sub_size, &ndr2); + fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, tree, data); + if (sub_size) { + ndr_pull_advance(ndr, tvb_length(ndr2.tvb)); + } else { + ndr_pull_advance(ndr, ndr2.offset); + } +} + +void ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, + guint32 size) +{ + ndr2->tvb = tvb_new_subset( + ndr->tvb, ndr->offset, + (tvb_length_remaining(ndr->tvb, ndr->offset) > size) ? size : + tvb_length_remaining(ndr->tvb, ndr->offset), + (tvb_reported_length_remaining(ndr->tvb, ndr->offset) > size) ? size : + tvb_reported_length_remaining(ndr->tvb, ndr->offset)); + + ndr2->offset = 0; + ndr2->flags = ndr->flags; + + ndr2->pinfo = ndr->pinfo; + ndr2->drep = ndr->drep; + ndr2->ofs_list = ndr->ofs_list; +} + +static int hf_subcontext_size_2 = -1; +static int hf_subcontext_size_4 = -1; + +void ndr_pull_subcontext_header(struct ndr_pull *ndr, proto_tree *tree, + size_t sub_size, struct ndr_pull *ndr2) +{ + switch (sub_size) { + case 0: { + guint32 size = tvb_length(ndr->tvb) - ndr->offset; + if (size == 0) return; + ndr_pull_subcontext(ndr, ndr2, size); + break; + } + + case 2: { + guint16 size; + ndr_pull_uint16(ndr, tree, hf_subcontext_size_2, &size); + if (size == 0) return; + ndr_pull_subcontext(ndr, ndr2, size); + break; + } + + case 4: { + guint32 size; + ndr_pull_uint32(ndr, tree, hf_subcontext_size_4, &size); + if (size == 0) return; + ndr_pull_subcontext(ndr, ndr2, size); + break; + } + default: ; +// return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", sub_size); + } +} + +void ndr_pull_advance(struct ndr_pull *ndr, int offset) +{ + ndr->offset += offset; +} + +struct subtree_info { + char *name; + proto_tree *subtree; +}; + +proto_tree *get_subtree(proto_tree *tree, char *name, struct ndr_pull *ndr, + gint ett) +{ + GSList *list, *l; + proto_item *item; + struct subtree_info *info; + + /* Get current list value */ + + if (!tree) + return NULL; + + list = (GSList *)tree->user_data; + + /* Look for name */ + + for (l = list; l; l = g_slist_next(l)) { + info = l->data; + + if (strcmp(name, info->name) == 0) + return info->subtree; + } + + /* Create new subtree entry */ + + info = (struct subtree_info *)g_malloc(sizeof(struct subtree_info)); + + info->name = g_strdup(name); + item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, name); + info->subtree = proto_item_add_subtree(item, ett); + + /* Don't forget to add new list head */ + + list = g_slist_append(list, info); + + tree->user_data = list; + + return info->subtree; +} + +void proto_register_eparser(void) +{ + static hf_register_info hf[] = { + { &hf_string4_len, { "String4 length", "eparser.string4_length", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 length", HFILL }}, + { &hf_string4_offset, { "String4 offset", "eparser.string4_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 offset", HFILL }}, + { &hf_string4_len2, { "String4 length2", "eparser.string4_length2", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 length2", HFILL }}, + { &hf_string_data, { "String data", "eparser.string_data", FT_BYTES, BASE_NONE, NULL, 0x0, "String data", HFILL }}, + { &hf_subcontext_size_2, { "Subcontext size2", "eparser.subcontext_size2", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size2", HFILL }}, + { &hf_subcontext_size_4, { "Subcontext size4", "eparser.subcontext_size4", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size4", HFILL }}, +// { &hf_relative_ofs, { "Relative offset", "eparser.relative_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "Relative offset", HFILL }}, +// { &hf_subtree_list, { "Subtree list", "", FT_UINT64, BASE_DEC, NULL, 0,"", HFILL }}, + }; + + static gint *ett[] = { + &ett_array, + }; + + int proto_dcerpc; + + proto_dcerpc = proto_get_id_by_filter_name("dcerpc"); + proto_register_field_array(proto_dcerpc, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} diff --git a/source4/build/pidl/eparser.h b/source4/build/pidl/eparser.h new file mode 100644 index 0000000000..93aaddff38 --- /dev/null +++ b/source4/build/pidl/eparser.h @@ -0,0 +1,145 @@ +/* Glue code for sticking code generated by pidl to ethereal. */ + +#ifndef _eparser_h +#define _eparser_h + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#define NDR_SCALARS 1 +#define NDR_BUFFERS 2 + +#define LIBNDR_FLAG_BIGENDIAN (1<<0) +#define LIBNDR_FLAG_NOALIGN (1<<1) + +#define LIBNDR_FLAG_STR_ASCII (1<<2) +#define LIBNDR_FLAG_STR_LEN4 (1<<3) +#define LIBNDR_FLAG_STR_SIZE4 (1<<4) +#define LIBNDR_FLAG_STR_NOTERM (1<<5) +#define LIBNDR_FLAG_STR_NULLTERM (1<<6) +#define LIBNDR_FLAG_STR_SIZE2 (1<<7) +#define LIBNDR_STRING_FLAGS (0xFC) + +#define LIBNDR_FLAG_REF_ALLOC (1<<10) +#define LIBNDR_FLAG_REMAINING (1<<11) +#define LIBNDR_FLAG_ALIGN2 (1<<12) +#define LIBNDR_FLAG_ALIGN4 (1<<13) +#define LIBNDR_FLAG_ALIGN8 (1<<14) + +#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8) + +#define LIBNDR_PRINT_ARRAY_HEX (1<<15) +#define LIBNDR_PRINT_SET_VALUES (1<<16) + +/* used to force a section of IDL to be little-endian */ +#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<17) + +#define NDR_ALLOC_SIZE(ndr, s, size) do { \ + (s) = g_malloc(size); \ + } while (0); + +#define NDR_ALLOC_N_SIZE(ndr, s, n, elsize) do { \ + if ((n) == 0) { \ + (s) = NULL; \ + } else { \ + (s) = g_malloc((n) * elsize); \ + } \ +} while (0) + +#define NDR_ALLOC_N(ndr, s, n) NDR_ALLOC_N_SIZE(ndr, s, n, sizeof(*(s))) +#define NDR_ALLOC(ndr, s) NDR_ALLOC_SIZE(ndr, s, sizeof(*(s))) + +/* zero a structure */ +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/* zero a structure given a pointer to the structure */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +struct ndr_ofs_list { + guint32 offset; + struct ndr_ofs_list *next; +}; + +struct ndr_pull { + tvbuff_t *tvb; + int offset; + packet_info *pinfo; + guint8 *drep; + struct ndr_ofs_list *ofs_list; + int flags; +}; + +typedef int NTSTATUS; +typedef guint64 uint64; +typedef guint32 uint32; +typedef guint16 uint16; +typedef guint8 uint8; +typedef gint64 int64; +typedef gint32 int32; +typedef gint16 int16; +typedef gint8 int8; +typedef guint64 NTTIME; +typedef guint64 HYPER_T; +#define dom_sid2 dom_sid + +typedef void (*ndr_pull_flags_fn_t)(struct ndr_pull *, int ndr_flags, void *); + +#include "packet-dcerpc-proto.h" +#include "glib.h" + +struct ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, guint8 *drep); + +void ndr_pull_struct_start(struct ndr_pull *ndr); +void ndr_pull_struct_end(struct ndr_pull *ndr); +void ndr_pull_align(struct ndr_pull *ndr, int size); + +void ndr_pull_uint8(struct ndr_pull *ndr, proto_tree *tree, int hf, uint8 *data); +void ndr_pull_uint16(struct ndr_pull *ndr, proto_tree *tree, int hf, uint16 *data); +void ndr_pull_uint32(struct ndr_pull *ndr, proto_tree *tree, int hf, uint32 *data); +void ndr_pull_uint64(struct ndr_pull *ndr, proto_tree *tree, int hf, uint64 *data); + +void ndr_pull_int8(struct ndr_pull *ndr, proto_tree *tree, int hf, int8 *data); +void ndr_pull_int16(struct ndr_pull *ndr, proto_tree *tree, int hf, int16 *data); +void ndr_pull_int32(struct ndr_pull *ndr, proto_tree *tree, int hf, int32 *data); +void ndr_pull_int64(struct ndr_pull *ndr, proto_tree *tree, int hf, int64 *data); + +void ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, char *name, int hf, void *data, int count); +void ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, char *name, int hf, void *data, int count); +void ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, char *name, int hf, void *data, int count); + +void ndr_pull_array(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, + char *name, void *data, int size, int count, + void (*pull_fn)(struct ndr_pull *, int ndr_flags, + proto_tree *tree, void *data)); + +void ndr_pull_relative(struct ndr_pull *ndr, void *data, int size, + void (*fn)(struct ndr_pull *, int ndr_flags, + char *name)); + +void ndr_pull_ptr(struct ndr_pull *ndr, proto_tree *tree, int hf, guint32 *ptr); + +void ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, char **data); + +void ndr_pull_NTTIME(struct ndr_pull *ndr, proto_tree *tree, int hf, NTTIME *data); + +void ndr_pull_NTSTATUS(struct ndr_pull *ndr, proto_tree *tree, int hf, NTSTATUS *data); + +void ndr_pull_HYPER_T(struct ndr_pull *ndr, proto_tree *tree, int hf, HYPER_T *data); + +void ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, struct dom_sid2 *data); + +void ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, proto_tree *tree, size_t sub_size, void *data, void (*fn)(struct ndr_pull *, int ndr_flags, proto_tree *tree, void *data)); + +void ndr_pull_subcontext_header(struct ndr_pull *ndr, proto_tree *tree, size_t sub_size, struct ndr_pull *ndr2); + +void ndr_pull_advance(struct ndr_pull *ndr, int offset); + +proto_tree *get_subtree(proto_tree *tree, char *name, struct ndr_pull *ndr, gint ett); + +void ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, guint32 size); + +#endif /* _eparser_h */ diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm index acc8fddc80..1223c0ca77 100644 --- a/source4/build/pidl/eparser.pm +++ b/source4/build/pidl/eparser.pm @@ -2,7 +2,6 @@ # Samba4 parser generator for IDL structures # Copyright tridge@samba.org 2000-2003 # Copyright tpot@samba.org 2001,2004 -# Copyright jelmer@samba.org 2004 # released under the GNU GPL package IdlEParser; @@ -14,6 +13,9 @@ my %needed; my %structs; my $module; +my $if_uuid; +my $if_version; +my $if_endpoints; sub pidl($) { @@ -66,10 +68,11 @@ sub find_sibling($$) #################################################################### # work out the name of a size_is() variable -sub find_size_var($$) +sub find_size_var($$$) { my($e) = shift; my($size) = shift; + my($var_prefix) = shift; my($fn) = $e->{PARENT}; @@ -78,7 +81,7 @@ sub find_size_var($$) } if ($size =~ /ndr->|\(/) { - return $size; + return $size; } my $prefix = ""; @@ -89,19 +92,19 @@ sub find_size_var($$) } if ($fn->{TYPE} ne "FUNCTION") { - return $prefix . "elt_$size"; + return $prefix . "r->$size"; } my $e2 = find_sibling($e, $size); if (util::has_property($e2, "in") && util::has_property($e2, "out")) { - return $prefix . "elt_$size"; + return $prefix . "$var_prefix$size"; } if (util::has_property($e2, "in")) { - return $prefix . "elt_$size"; + return $prefix . "r->in.$size"; } if (util::has_property($e2, "out")) { - return $prefix . "elt_$size"; + return $prefix . "r->out.$size"; } die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n"; @@ -220,12 +223,13 @@ sub union_alignment ##################################################################### # parse an array - pull side -sub ParseArrayPull($$) +sub ParseArrayPull($$$) { my $e = shift; + my $var_prefix = shift; my $ndr_flags = shift; - my $size = find_size_var($e, util::array_size($e)); + my $size = find_size_var($e, util::array_size($e), $var_prefix); my $alloc_size = $size; # if this is a conformant array then we use that size to allocate, and make sure @@ -234,133 +238,148 @@ sub ParseArrayPull($$) $alloc_size = $e->{CONFORMANT_SIZE}; pidl "\tif ($size > $alloc_size) {\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"Bad conformant size (%u should be %u)\", $alloc_size, $size);\n"; - pidl "\t\tif (check_col(ndr->pinfo->cinfo, COL_INFO))\n"; - pidl "\t\t\tcol_append_fstr(ndr->pinfo->cinfo, COL_INFO, \", Bad conformant size (%u should be %u)\", $alloc_size, $size);\n"; + pidl "\t\treturn; // ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n"; pidl "\t}\n"; } elsif (!util::is_inline_array($e)) { -# if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) { -# my $size2 = substr($size, 1); -# pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_ALLOC(ndr, $size2); }\n"; -# } + if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) { + my $size2 = substr($size, 1); + pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_ALLOC(ndr, $size2); }\n"; + } # non fixed arrays encode the size just before the array + pidl "\t{\n"; + pidl "\t\tuint32_t _array_size;\n"; + pidl "\t\tndr_pull_uint32(ndr, tree, hf_array_size, &_array_size);\n"; + if ($size =~ /r->in/) { + pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n"; + } else { + pidl "\t\tif ($size != _array_size) {\n"; + } + pidl "\t\t\t//return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should be %u\", _array_size, $size);\n"; + pidl "\t\t\treturn;\n"; + pidl "\t\t}\n"; + if ($size =~ /r->in/) { + pidl "else { $size = _array_size; }\n"; + } + pidl "\t}\n"; + } - if (!($size =~ /\d+/)) { - pidl "\t\tndr_pull_uint32(ndr, tree, hf_array_size, &$size);\n"; - } else { - pidl "\t\tndr_pull_uint32(ndr, tree, hf_array_size, NULL);\n"; - } + if ((util::need_alloc($e) && !util::is_fixed_array($e)) || + ($var_prefix eq "r->in." && util::has_property($e, "ref"))) { + if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { + pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n"; + } } -# if ((util::need_alloc($e) && !util::is_fixed_array($e)) || -# ($var_prefix eq "r->in." && util::has_property($e, "ref"))) { -# if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { -# pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n"; -# } -# } + if (($var_prefix eq "r->out." && util::has_property($e, "ref"))) { + if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { + pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"; + pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n"; + pidl "\t}\n"; + } + } -# if (($var_prefix eq "r->out." && util::has_property($e, "ref"))) { -# if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { -# pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"; -# pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n"; -# pidl "\t}\n"; -# } -# } + pidl "\t{\n"; if (my $length = util::has_property($e, "length_is")) { - $length = find_size_var($e, $length); + $length = find_size_var($e, $length, $var_prefix); + pidl "\t\tuint32_t _offset, _length;\n"; pidl "\t\tndr_pull_uint32(ndr, tree, hf_array_offset, &_offset);\n"; pidl "\t\tndr_pull_uint32(ndr, tree, hf_array_length, &_length);\n"; + pidl "\t\tif (_offset != 0) return; // ndr_pull_error(ndr, NDR_ERR_OFFSET, \"Bad array offset 0x%08x\", _offset);\n"; + pidl "\t\tif (_length > $size || _length != $length) return; // ndr_pull_error(ndr, NDR_ERR_LENGTH, \"Bad array length 0x%08x > size 0x%08x\", _offset, $size);\n\n"; $size = "_length"; } if (util::is_scalar_type($e->{TYPE})) { - pidl "\tndr_pull_array_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, $ndr_flags, $size);\n"; + pidl "\t\tndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, tree, \"$e->{NAME}\", hf_$e->{NAME}_$e->{TYPE}, $var_prefix$e->{NAME}, $size);\n"; } else { - pidl "\tndr_pull_array(ndr, tree, $ndr_flags, $size, ndr_pull_$e->{TYPE});\n"; + pidl "\t\tndr_pull_array(ndr, $ndr_flags, tree, \"$e->{NAME}\", (void **)$var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE});\n"; } + + pidl "\t}\n"; } ##################################################################### # parse scalars in a structure element - pull size -sub ParseElementPullSwitch($$$) +sub ParseElementPullSwitch($$$$) { my($e) = shift; + my($var_prefix) = shift; my($ndr_flags) = shift; my $switch = shift; - my $switch_var = find_size_var($e, $switch); + my $switch_var = find_size_var($e, $switch, $var_prefix); my $cprefix = util::c_pull_prefix($e); - pidl "\t{\n"; - pidl "\t\tguint16 _level;\n"; - my $utype = $structs{$e->{TYPE}}; if (!defined $utype || !util::has_property($utype->{DATA}, "nodiscriminant")) { my $e2 = find_sibling($e, $switch); pidl "\tif (($ndr_flags) & NDR_SCALARS) {\n"; - pidl "\t\tndr_pull_level(ndr, tree, hf_level, &_level);\n"; + pidl "\t\t $e2->{TYPE} _level;\n"; + pidl "\t\tndr_pull_$e2->{TYPE}(ndr, tree, hf_level, &_level);\n"; + if ($switch_var =~ /r->in/) { + pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n"; + } else { + pidl "\t\tif (_level != $switch_var) {\n"; + } + pidl "\t\t\treturn; // ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u in $e->{NAME}\", _level);\n"; + pidl "\t\t}\n"; + if ($switch_var =~ /r->/) { + pidl "else { $switch_var = _level; }\n"; + } pidl "\t}\n"; - } else { - pidl "\t_level = $switch_var;\n"; } my $sub_size = util::has_property($e, "subcontext"); if (defined $sub_size) { - pidl "\tndr_pull_subcontext_union_fn(ndr, tree, $sub_size, $switch_var, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, tree, $ndr_flags, _level);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, tree, $switch_var, $cprefix$var_prefix$e->{NAME});\n"; } - pidl "\t}\n"; + + } ##################################################################### # parse scalars in a structure element - pull size -sub ParseElementPullScalar($$) +sub ParseElementPullScalar($$$) { my($e) = shift; + my($var_prefix) = shift; my($ndr_flags) = shift; - my $cprefix = util::c_pull_prefix($e); my $sub_size = util::has_property($e, "subcontext"); start_flags($e); if (util::has_property($e, "relative")) { - pidl "\tndr_pull_relative(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_relative(ndr, (const void **)&$var_prefix$e->{NAME}, sizeof(*$var_prefix$e->{NAME}), (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE});\n"; } elsif (util::is_inline_array($e)) { - ParseArrayPull($e, "NDR_SCALARS"); + ParseArrayPull($e, "r->", "NDR_SCALARS"); } elsif (util::need_wire_pointer($e)) { - pidl "\tndr_pull_ptr(ndr, tree, hf_ptr, &ptr_$e->{NAME});\n"; -# pidl "\tif (ptr_$e->{NAME}) {\n"; -# pidl "\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n"; -# pidl "\t} else {\n"; -# pidl "\t\t$var_prefix$e->{NAME} = NULL;\n"; -# pidl "\t}\n"; + pidl "\tndr_pull_ptr(ndr, tree, hf_ptr, &_ptr_$e->{NAME});\n"; + pidl "\tif (_ptr_$e->{NAME}) {\n"; + pidl "\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n"; + pidl "\t} else {\n"; + pidl "\t\t$var_prefix$e->{NAME} = NULL;\n"; + pidl "\t}\n"; } elsif (util::need_alloc($e)) { # no scalar component } elsif (my $switch = util::has_property($e, "switch_is")) { - ParseElementPullSwitch($e, $ndr_flags, $switch); + ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch); } elsif (defined $sub_size) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $sub_size, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_fn(ndr, tree, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $sub_size, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; } - } elsif (util::is_builtin_type($e->{TYPE})) { - $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { - 'name' => $e->{NAME}, - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => type2base($e->{TYPE}) - }; - - pidl "\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, &elt_$e->{NAME});\n"; + } elsif (util::is_builtin_type($e->{TYPE})) { + pidl "\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, $cprefix$var_prefix$e->{NAME});\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $ndr_flags);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $cprefix$var_prefix$e->{NAME});\n"; } end_flags($e); @@ -368,9 +387,10 @@ sub ParseElementPullScalar($$) ##################################################################### # parse buffers in a structure element - pull side -sub ParseElementPullBuffer($$) +sub ParseElementPullBuffer($$$) { my($e) = shift; + my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_pull_prefix($e); my $sub_size = util::has_property($e, "subcontext"); @@ -386,33 +406,33 @@ sub ParseElementPullBuffer($$) start_flags($e); if (util::need_wire_pointer($e)) { - pidl "\tif (ptr_$e->{NAME}) {\n"; + pidl "\tif ($var_prefix$e->{NAME}) {\n"; } if (util::is_inline_array($e)) { - ParseArrayPull($e, "NDR_BUFFERS"); + ParseArrayPull($e, "r->", "NDR_BUFFERS"); } elsif (util::array_size($e)) { - ParseArrayPull($e, "NDR_SCALARS|NDR_BUFFERS"); + ParseArrayPull($e, "r->", "NDR_SCALARS|NDR_BUFFERS"); } elsif (my $switch = util::has_property($e, "switch_is")) { if ($e->{POINTERS}) { - ParseElementPullSwitch($e, "NDR_SCALARS|NDR_BUFFERS", $switch); + ParseElementPullSwitch($e, $var_prefix, "NDR_SCALARS|NDR_BUFFERS", $switch); } else { - ParseElementPullSwitch($e, "NDR_BUFFERS", $switch); + ParseElementPullSwitch($e, $var_prefix, "NDR_BUFFERS", $switch); } } elsif (defined $sub_size) { if ($e->{POINTERS}) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $sub_size, _pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $sub_size, ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; } } } elsif (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, &elt_$e->{NAME});\n"; + pidl "\t\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, $cprefix$var_prefix$e->{NAME});\n"; } elsif ($e->{POINTERS}) { - pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), NDR_SCALARS|NDR_BUFFERS);\n"; + pidl "\t\tndr_pull_$e->{TYPE}(ndr, NDR_SCALARS|NDR_BUFFERS, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $cprefix$var_prefix$e->{NAME});\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $ndr_flags);\n"; + pidl "\t\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, get_subtree(tree, \"$e->{NAME}\", ndr, ett_$e->{TYPE}), $cprefix$var_prefix$e->{NAME});\n"; } if (util::need_wire_pointer($e)) { @@ -429,14 +449,6 @@ sub ParseStructPull($) my($struct) = shift; my $conform_e; - pidl "\tguint32 _U_ _offset, _U_ _length, _U_ _level;\n"; - - for my $e (@{$struct->{ELEMENTS}}) { - if (util::is_builtin_type($e->{TYPE})) { - pidl "\tg$e->{TYPE} elt_$e->{NAME};\n"; - } - } - if (! defined $struct->{ELEMENTS}) { return; } @@ -449,7 +461,7 @@ sub ParseStructPull($) my $e = $struct->{ELEMENTS}[-1]; if (defined $e->{ARRAY_LEN} && $e->{ARRAY_LEN} eq "*") { $conform_e = $e; - pidl "\tguint32 _conformant_size;\n"; + pidl "\tuint32_t _conformant_size;\n"; $conform_e->{CONFORMANT_SIZE} = "_conformant_size"; } @@ -457,26 +469,13 @@ sub ParseStructPull($) foreach my $e (@{$struct->{ELEMENTS}}) { if (util::need_wire_pointer($e) && !util::has_property($e, "relative")) { - pidl "\tguint32 ptr_$e->{NAME};\n"; + pidl "\tuint32_t _ptr_$e->{NAME};\n"; } } - pidl "\n"; - - # Some debugging stuff. Put a note in the proto tree saying - # which function was called with what NDR flags. - -# pidl "\tif ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS))\n"; -# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_SCALARS|NDR_BUFFERS)\", __FUNCTION__);\n"; -# pidl "\telse if (ndr_flags & NDR_SCALARS)\n"; -# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_SCALARS)\", __FUNCTION__);\n"; -# pidl "\telse if (ndr_flags & NDR_BUFFERS)\n"; -# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_BUFFERS)\", __FUNCTION__);\n"; -# pidl "\n"; - start_flags($struct); - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n\n"; + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tndr_pull_struct_start(ndr);\n"; @@ -488,22 +487,23 @@ sub ParseStructPull($) pidl "\tndr_pull_align(ndr, $align);\n"; foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPullScalar($e, "NDR_SCALARS"); + ParseElementPullScalar($e, "r->", "NDR_SCALARS"); } - pidl "\nbuffers:\n\n"; + pidl "buffers:\n"; pidl "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPullBuffer($e, "NDR_BUFFERS"); + ParseElementPullBuffer($e, "r->", "NDR_BUFFERS"); } pidl "\tndr_pull_struct_end(ndr);\n"; - pidl "done: ;\n"; + pidl "done:\n"; end_flags($struct); } + ##################################################################### # parse a union - pull side sub ParseUnionPull($) @@ -513,42 +513,33 @@ sub ParseUnionPull($) start_flags($e); - pidl "\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{PARENT}{NAME}\");\n"; - pidl "\ttree = proto_item_add_subtree(item, ett_$e->{PARENT}{NAME});\n"; - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tndr_pull_struct_start(ndr);\n"; - foreach my $el (@{$e->{DATA}}) { - my $e2 = $el->{DATA}; - if ($e2->{POINTERS}) { - pidl "\tguint32 ptr_$e2->{NAME};\n"; - } - } - # my $align = union_alignment($e); # pidl "\tndr_pull_align(ndr, $align);\n"; pidl "\tswitch (level) {\n"; foreach my $el (@{$e->{DATA}}) { if ($el->{CASE} eq "default") { - pidl "\t\tdefault: {\n"; + pidl "\tdefault: {\n"; $have_default = 1; } else { pidl "\tcase $el->{CASE}: {\n"; } if ($el->{TYPE} eq "UNION_ELEMENT") { - ParseElementPullScalar($el->{DATA}, "NDR_SCALARS"); + my $e2 = $el->{DATA}; + if ($e2->{POINTERS}) { + pidl "\t\tuint32_t _ptr_$e2->{NAME};\n"; + } + ParseElementPullScalar($el->{DATA}, "r->", "NDR_SCALARS"); } - pidl "\t\tbreak;\n\t}\n"; + pidl "\tbreak; }\n\n"; } if (! $have_default) { - pidl "\tdefault: {\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"Bad switch value %u\", level);\n"; - pidl "\t\tif (check_col(ndr->pinfo->cinfo, COL_INFO))\n"; - pidl "\t\t\tcol_append_fstr(ndr->pinfo->cinfo, COL_INFO, \", Bad switch value %u\", level);\n"; - pidl "\t}\n"; + pidl "\tdefault:\n"; + pidl "\t\treturn; // ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; pidl "buffers:\n"; @@ -556,51 +547,25 @@ sub ParseUnionPull($) pidl "\tswitch (level) {\n"; foreach my $el (@{$e->{DATA}}) { if ($el->{CASE} eq "default") { - pidl "\tdefault: {\n"; + pidl "\tdefault:\n"; } else { - pidl "\tcase $el->{CASE}: {\n"; + pidl "\tcase $el->{CASE}:\n"; } if ($el->{TYPE} eq "UNION_ELEMENT") { - ParseElementPullBuffer($el->{DATA}, "NDR_BUFFERS"); + ParseElementPullBuffer($el->{DATA}, "r->", "NDR_BUFFERS"); } - pidl "\t\tbreak;\n\t}\n"; + pidl "\tbreak;\n\n"; } if (! $have_default) { pidl "\tdefault:\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"Bad switch value %u\", level);\n"; - pidl "\t\tif (check_col(ndr->pinfo->cinfo, COL_INFO))\n"; - pidl "\t\t\tcol_append_fstr(ndr->pinfo->cinfo, COL_INFO, \", 7Bad switch value %u\", level);\n"; + pidl "\t\treturn; // ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; pidl "\tndr_pull_struct_end(ndr);\n"; pidl "done:\n"; - pidl "return;\n"; end_flags($e); } -##################################################################### -# parse a enum - pull side -sub ParseEnumPull($) -{ - my $enum = shift; - - my $name; - my $ndx = 0; - - for my $e (@{$enum->{ELEMENTS}}) { - if ($e =~ /([a-zA-Z0-9_]+)=([0-9x]+)/) { - $name = $1; - $ndx = $2; - } else { - $name = $e; - } - pidl "#define $name $ndx\n"; - $ndx++; - } - - pidl "\n"; -} - ##################################################################### # parse a type sub ParseTypePull($) @@ -612,8 +577,6 @@ sub ParseTypePull($) ParseStructPull($data); ($data->{TYPE} eq "UNION") && ParseUnionPull($data); - ($data->{TYPE} eq "ENUM") && - ParseEnumPull($data); } } @@ -624,36 +587,32 @@ sub ParseTypedefPull($) my($e) = shift; my $static = fn_prefix($e); -# if (! $needed{"pull_$e->{NAME}"}) { + if (! $needed{"pull_$e->{NAME}"}) { # print "pull_$e->{NAME} not needed\n"; -# return; -# } + return; + } pidl "/*\n\n"; pidl IdlDump::DumpTypedef($e); pidl "*/\n\n"; if ($e->{DATA}->{TYPE} eq "STRUCT") { - pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags)"; + pidl $static . "void ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, struct $e->{NAME} *r)"; pidl "\n{\n"; ParseTypePull($e->{DATA}); + pidl "\treturn;\n"; pidl "}\n\n"; } if ($e->{DATA}->{TYPE} eq "UNION") { - pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags, int level)"; + pidl $static . "void ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, uint16_t level, union $e->{NAME} *r)"; pidl "\n{\n"; - pidl "\tproto_item *item = NULL;\n"; ParseTypePull($e->{DATA}); + pidl "\treturn;\n"; pidl "}\n\n"; } - - if ($e->{DATA}->{TYPE} eq "ENUM") { - ParseEnumPull($e->{DATA}); - } } - ##################################################################### # parse a function element sub ParseFunctionElementPull($$) @@ -663,23 +622,66 @@ sub ParseFunctionElementPull($$) if (util::array_size($e)) { if (util::need_wire_pointer($e)) { - pidl "\tndr_pull_ptr(ndr, tree, hf_ptr, &ptr_$e->{NAME});\n"; - pidl "\tif (ptr_$e->{NAME}) {\n"; - pidl "\t\tguint32 " . find_size_var($e, util::array_size($e)) . ";\n"; + pidl "\tndr_pull_ptr(ndr, &_ptr_$e->{NAME});\n"; + pidl "\tif (_ptr_$e->{NAME}) {\n"; + } elsif ($inout eq "out" && util::has_property($e, "ref")) { + pidl "\tif (r->$inout.$e->{NAME}) {\n"; } else { pidl "\t{\n"; } - ParseArrayPull($e, "NDR_SCALARS|NDR_BUFFERS"); + ParseArrayPull($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); pidl "\t}\n"; } else { + if ($inout eq "out" && util::has_property($e, "ref")) { + pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\n"; + pidl "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n"; + pidl "\t}\n"; + } + if ($inout eq "in" && util::has_property($e, "ref")) { + pidl "\tNDR_ALLOC(ndr, r->in.$e->{NAME});\n"; + } - ParseElementPullScalar($e, "NDR_SCALARS|NDR_BUFFERS"); + ParseElementPullScalar($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); if ($e->{POINTERS}) { - ParseElementPullBuffer($e, "NDR_SCALARS|NDR_BUFFERS"); + ParseElementPullBuffer($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + } + } +} + + +############################################################ +# allocate ref variables +sub AllocateRefVars($) +{ + my $e = shift; + my $asize = util::array_size($e); + + # note that if the variable is also an "in" + # variable then we copy the initial value from + # the in side + + if (!defined $asize) { + # its a simple variable + pidl "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n"; + if (util::has_property($e, "in")) { + pidl "\t*r->out.$e->{NAME} = *r->in.$e->{NAME};\n"; + } else { + pidl "\tZERO_STRUCTP(r->out.$e->{NAME});\n"; } + return; + } + + # its an array + my $size = find_size_var($e, $asize, "r->out."); + pidl "\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, MAX(1, $size));\n"; + if (util::has_property($e, "in")) { + pidl "\tmemcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));\n"; + } else { + pidl "\tmemset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));\n"; } } + ##################################################################### # parse a function sub ParseFunctionPull($) @@ -687,84 +689,78 @@ sub ParseFunctionPull($) my($fn) = shift; my $static = fn_prefix($fn); - # Comment displaying IDL for this function - pidl "/*\n\n"; pidl IdlDump::DumpFunction($fn); pidl "*/\n\n"; - # Request + # request function + pidl "int $fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n{\n"; - pidl $static . "int $fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n"; - pidl "{\n"; - pidl "\tstruct e_ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; - pidl "\tguint32 _U_ _offset, _U_ _length, _U_ _level;\n"; + pidl "\tstruct ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; + pidl "\tstruct $fn->{NAME} *r = (struct $fn->{NAME} *)g_malloc(sizeof(struct $fn->{NAME}));\n\n"; # declare any internal pointers we need foreach my $e (@{$fn->{DATA}}) { + if (util::need_wire_pointer($e) && + util::has_property($e, "in")) { + pidl "\tuint32_t _ptr_$e->{NAME};\n"; + } + } - if (util::has_property($e, "in")) { + pidl "\n\tZERO_STRUCTP(r);\n\n"; - if (util::need_wire_pointer($e)) { - pidl "\tguint32 ptr_$e->{NAME};\n"; - } - - if (util::is_builtin_type($e->{TYPE})) { - pidl "\tg$e->{TYPE} elt_$e->{NAME};\n"; + # auto-init the out section of a structure. I originally argued that + # this was a bad idea as it hides bugs, but coping correctly + # with initialisation and not wiping ref vars is turning + # out to be too tricky (tridge) + foreach my $e (@{$fn->{DATA}}) { + if (util::has_property($e, "out")) { + pidl "\tZERO_STRUCT(r->out);\n\n"; + last; } - } } - pidl "\n"; - foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "in")) { ParseFunctionElementPull($e, "in"); - } + } + # we need to allocate any reference output variables, so that + # a dcerpc backend can be sure they are non-null + if (util::has_property($e, "out") && util::has_property($e, "ref")) { + AllocateRefVars($e); + } } - pidl "\toffset = ndr->offset;\n"; - pidl "\tndr_pull_free(ndr);\n"; - pidl "\n"; - pidl "\treturn offset;\n"; + pidl "\n\treturn ndr->offset;\n"; pidl "}\n\n"; - # Response + # response function + pidl "int $fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n{\n"; + + pidl "\tstruct ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; + pidl "\tstruct $fn->{NAME} *r = (struct $fn->{NAME} *)g_malloc(sizeof(struct $fn->{NAME}));\n\n"; - pidl $static . "int $fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n"; - pidl "{\n"; - pidl "\tstruct e_ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; # declare any internal pointers we need foreach my $e (@{$fn->{DATA}}) { - - if (util::has_property($e, "out")) { - - if (util::need_wire_pointer($e)) { - pidl "\tguint32 ptr_$e->{NAME};\n"; - } - - if (util::is_builtin_type($e->{TYPE})) { - pidl "\tg$e->{TYPE} elt_$e->{NAME};\n"; + if (util::need_wire_pointer($e) && + util::has_property($e, "out")) { + pidl "\tuint32_t _ptr_$e->{NAME};\n"; } - } } - pidl "\n"; + pidl "\tZERO_STRUCTP(r);\n\n"; foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "out")) { ParseFunctionElementPull($e, "out"); - } + } } if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") { - pidl "\tndr_pull_$fn->{RETURN_TYPE}(ndr, tree, hf_rc, NULL);\n"; + pidl "\tndr_pull_$fn->{RETURN_TYPE}(ndr, tree, hf_rc, &r->out.result);\n"; } - pidl "\toffset = ndr->offset;\n"; - pidl "\tndr_pull_free(ndr);\n"; - pidl "\n"; - pidl "\treturn offset;\n"; + pidl "\n\treturn ndr->offset;\n"; pidl "}\n\n"; } @@ -774,18 +770,8 @@ sub FunctionTable($) { my($interface) = shift; my($data) = $interface->{DATA}; - my $count = 0; - my $uname = uc $interface->{NAME}; - - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return; - } - pidl "static dcerpc_sub_dissector dcerpc_" . $interface->{NAME} . "_dissectors[] = {\n"; + pidl "static dcerpc_sub_dissector dcerpc_dissectors[] = {\n"; my $num = 0; foreach my $d (@{$data}) { if ($d->{TYPE} eq "FUNCTION") { @@ -810,7 +796,7 @@ sub ParseInterface($) my($data) = $interface->{DATA}; foreach my $d (@{$data}) { - if ($d->{TYPE} eq "TYPEDEF") { + if ($d->{TYPE} eq "TYPEDEF") { $structs{$d->{NAME}} = $d; } } @@ -823,6 +809,7 @@ sub ParseInterface($) } FunctionTable($interface); + } sub type2ft($) @@ -847,70 +834,74 @@ sub type2base($) sub NeededFunction($) { my $fn = shift; + $needed{"pull_$fn->{NAME}"} = 1; foreach my $e (@{$fn->{DATA}}) { - - if (util::is_scalar_type($e->{TYPE})) { - - $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { - 'name' => $e->{NAME}, - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => type2base($e->{TYPE}) - }; $e->{PARENT} = $fn; - } else { - $needed{"ett_$e->{TYPE}"} = 1; - } + $needed{"pull_$e->{TYPE}"} = 1; + + if (util::is_scalar_type($e->{TYPE})) { + $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { + 'name' => $e->{NAME}, + 'type' => $e->{TYPE}, + 'ft' => type2ft($e->{TYPE}), + 'base' => type2base($e->{TYPE}) + }; + $e->{PARENT} = $fn; + } else { + $needed{"ett_$e->{TYPE}"} = 1; + } } } sub NeededTypedef($) { my $t = shift; - if (util::has_property($t->{DATA}, "public")) { $needed{"pull_$t->{NAME}"} = 1; } if ($t->{DATA}->{TYPE} eq "STRUCT") { - $needed{"ett_$t->{NAME}"} = 1; - - for my $e (@{$t->{DATA}->{ELEMENTS}}) { - - if (util::is_scalar_type($e->{TYPE})) { - - $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { - 'name' => $e->{NAME}, - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => type2base($e->{TYPE}) - }; - - $e->{PARENT} = $t->{DATA}; - - if ($needed{"pull_$t->{NAME}"}) { - $needed{"pull_$e->{TYPE}"} = 1; - } - } else { - - $needed{"ett_$e->{TYPE}"} = 1; - + for my $e (@{$t->{DATA}->{ELEMENTS}}) { + $e->{PARENT} = $t->{DATA}; + if ($needed{"pull_$t->{NAME}"}) { + $needed{"pull_$e->{TYPE}"} = 1; + } + + if (util::is_scalar_type($e->{TYPE})) { + + $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { + 'name' => $e->{NAME}, + 'type' => $e->{TYPE}, + 'ft' => type2ft($e->{TYPE}), + 'base' => type2base($e->{TYPE}) + }; + + $e->{PARENT} = $t->{DATA}; + + if ($needed{"pull_$t->{NAME}"}) { + $needed{"pull_$e->{TYPE}"} = 1; } + } else { + + $needed{"ett_$e->{TYPE}"} = 1; + } + } } - if ($t->{DATA}->{TYPE} eq "UNION") { - - $needed{"ett_$t->{NAME}"} = 1; + if ($t->{DATA}->{TYPE} eq "UNION") { for my $e (@{$t->{DATA}->{DATA}}) { $e->{PARENT} = $t->{DATA}; if ($e->{TYPE} eq "UNION_ELEMENT") { if ($needed{"pull_$t->{NAME}"}) { $needed{"pull_$e->{DATA}->{TYPE}"} = 1; } + $needed{"ett_$e->{DATA}{TYPE}"} = 1; } } + + $needed{"ett_$t->{NAME}"} = 1; } } @@ -930,6 +921,20 @@ sub BuildNeeded($) } } +##################################################################### +# parse the interface definitions +sub ModuleHeader($) +{ + my($h) = shift; + + $if_uuid = $h->{PROPERTIES}->{uuid}; + $if_version = $h->{PROPERTIES}->{version}; + $if_endpoints = $h->{PROPERTIES}->{endpoints}; +} + +##################################################################### +# Generate a header file that contains function prototypes for +# structs and typedefs. sub ParseHeader($$) { my($idl) = shift; @@ -939,21 +944,24 @@ sub ParseHeader($$) pidl "/* parser auto-generated by pidl */\n\n"; + pidl "#include \"ndr_$module.h\"\n\n"; + foreach my $x (@{$idl}) { if ($x->{TYPE} eq "INTERFACE") { foreach my $d (@{$x->{DATA}}) { - # Make prototypes for [public] push/pull functions + # Make prototypes for [public] structures and + # unions. if ($d->{TYPE} eq "TYPEDEF" and util::has_property($d->{DATA}, "public")) { if ($d->{DATA}{TYPE} eq "STRUCT") { - pidl "void ndr_pull_$d->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags);\n\n"; + pidl "void ndr_pull_$d->{NAME}(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, struct $d->{NAME} *r);\n\n"; } if ($d->{DATA}{TYPE} eq "UNION") { - pidl "void ndr_pull_$d->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags, int level);\n"; + pidl "void ndr_pull_$d->{NAME}(struct ndr_pull *ndr, int ndr_flags, proto_tree *tree, struct $d->{NAME} *r, uint16 level);\n\n"; } } } @@ -970,38 +978,35 @@ sub Parse($$) my($idl) = shift; my($filename) = shift; - %needed = (); + %needed = (); # Clear after generating header file open(OUT, ">$filename") || die "can't open $filename"; + # Look for name of module + foreach my $x (@{$idl}) { - if ($x->{TYPE} eq "INTERFACE") { - $module = $x->{NAME}; - BuildNeeded($x); - } - } + ($x->{TYPE} eq "MODULEHEADER") && ModuleHeader($x); + + if ($x->{TYPE} eq "INTERFACE") { + $module = $x->{NAME}; + BuildNeeded($x); + } + } + pidl "/* parser auto-generated by pidl */\n\n"; - pidl "#ifdef HAVE_CONFIG_H\n"; - pidl "#include \"config.h\"\n"; - pidl "#endif\n\n"; - - pidl "#include \"packet-dcerpc.h\"\n"; - pidl "#include \"packet-dcerpc-nt.h\"\n\n"; - pidl "#include \"packet-dcerpc-eparser.h\"\n\n"; + pidl "#include \"eparser.h\"\n\n"; pidl "extern const value_string NT_errors[];\n\n"; - pidl "static gint ett_dcerpc_$module = -1;\n\n"; - pidl "static int hf_opnum = -1;\n"; pidl "static int hf_rc = -1;\n"; pidl "static int hf_ptr = -1;\n"; pidl "static int hf_array_size = -1;\n"; pidl "static int hf_array_offset = -1;\n"; pidl "static int hf_array_length = -1;\n"; - pidl "static int hf_conformant_size = -1;\n"; pidl "static int hf_level = -1;\n"; + pidl "static int hf_conformant_size = -1;\n"; # Declarations for hf variables @@ -1014,40 +1019,45 @@ sub Parse($$) # Declarations for ett variables foreach my $y (keys(%needed)) { - pidl "static gint $y = -1;\n", if $y =~ /^ett_/; } pidl "\n"; - for my $x (@{$idl}) { - ParseInterface($x); - } + foreach my $x (@{$idl}) { + ($x->{TYPE} eq "MODULEHEADER") && + ModuleHeader($x); - # Only perform module initialisation if we found a uuid - - for my $x (@{$idl}) { - pidl "static int proto_dcerpc_" . $x->{NAME} ." = -1;\n\n"; - if ((my $if_uuid = $x->{PROPERTIES}->{uuid})) { - pidl "static e_uuid_t uuid_dcerpc_" . $x->{NAME} ." = {\n"; - pidl "\t0x" . substr($if_uuid, 0, 8); - pidl ", 0x" . substr($if_uuid, 9, 4); - pidl ", 0x" . substr($if_uuid, 14, 4) . ",\n"; - pidl "\t{ 0x" . substr($if_uuid, 19, 2); - pidl ", 0x" . substr($if_uuid, 21, 2); - pidl ", 0x" . substr($if_uuid, 24, 2); - pidl ", 0x" . substr($if_uuid, 26, 2); - pidl ", 0x" . substr($if_uuid, 28, 2); - pidl ", 0x" . substr($if_uuid, 30, 2); - pidl ", 0x" . substr($if_uuid, 32, 2); - pidl ", 0x" . substr($if_uuid, 34, 2) . " }\n"; - pidl "};\n\n"; - - pidl "static guint16 ver_dcerpc_" . $x->{NAME} . " = " . $x->{PROPERTIES}->{version}. ";\n\n"; + if ($x->{TYPE} eq "INTERFACE") { + BuildNeeded($x); + ParseInterface($x); } } - pidl "void proto_register_dcerpc_$module(void)\n"; + pidl "int proto_dcerpc_pidl_$module = -1;\n\n"; + + pidl "static gint ett_dcerpc_$module = -1;\n\n"; + + if (defined($if_uuid)) { + + pidl "static e_uuid_t uuid_dcerpc_$module = {\n"; + pidl "\t0x" . substr($if_uuid, 0, 8); + pidl ", 0x" . substr($if_uuid, 9, 4); + pidl ", 0x" . substr($if_uuid, 14, 4) . ",\n"; + pidl "\t{ 0x" . substr($if_uuid, 19, 2); + pidl ", 0x" . substr($if_uuid, 21, 2); + pidl ", 0x" . substr($if_uuid, 24, 2); + pidl ", 0x" . substr($if_uuid, 26, 2); + pidl ", 0x" . substr($if_uuid, 28, 2); + pidl ", 0x" . substr($if_uuid, 30, 2); + pidl ", 0x" . substr($if_uuid, 32, 2); + pidl ", 0x" . substr($if_uuid, 34, 2) . " }\n"; + pidl "};\n\n"; + + pidl "static guint16 ver_dcerpc_$module = " . $if_version . ";\n\n"; + } + + pidl "void proto_register_dcerpc_pidl_$module(void)\n"; pidl "{\n"; pidl "\tstatic hf_register_info hf[] = {\n"; @@ -1057,10 +1067,10 @@ sub Parse($$) pidl "\t{ &hf_array_size, { \"Array size\", \"$module.array_size\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Array size\", HFILL }},\n"; pidl "\t{ &hf_array_offset, { \"Array offset\", \"$module.array_offset\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Array offset\", HFILL }},\n"; pidl "\t{ &hf_array_length, { \"Array length\", \"$module.array_length\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Array length\", HFILL }},\n"; - pidl "\t{ &hf_conformant_size, { \"Conformant size\", \"$module.conformant_size\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Conformant size\", HFILL }},\n"; - pidl "\t{ &hf_level, { \"Level\", \"$module.level\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Level\", HFILL }},\n"; pidl "\t{ &hf_ptr, { \"Pointer\", \"$module.ptr\", FT_UINT32, BASE_HEX, NULL, 0x0, \"Pointer\", HFILL }},\n"; - + pidl "\t{ &hf_level, { \"Level\", \"$module.level\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Level\", HFILL }},\n"; + pidl "\t{ &hf_conformant_size, { \"Conformant size\", \"$module.conformant_size\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Conformant size\", HFILL }},\n"; + foreach my $x (keys(%needed)) { next, if !($x =~ /^hf_/); pidl "\t{ &$x,\n"; @@ -1076,33 +1086,31 @@ sub Parse($$) } pidl "\t};\n\n"; - for my $x (@{$idl}) { - if (defined($x->{PROPERTIES}->{uuid})) { - $module = $x->{NAME}; + if (defined($if_uuid)) { - pidl "\tproto_dcerpc_$module = proto_register_protocol(\"$module\", \"$module\", \"$module\");\n\n"; + pidl "\tproto_dcerpc_pidl_$module = proto_register_protocol(\"pidl_$module\", \"pidl_$module\", \"pidl_$module\");\n\n"; - pidl "\tproto_register_field_array(proto_dcerpc_$module, hf, array_length (hf));\n"; - pidl "\tproto_register_subtree_array(ett, array_length(ett));\n"; + pidl "\tproto_register_field_array(proto_dcerpc_pidl_$module, hf, array_length (hf));\n"; + pidl "\tproto_register_subtree_array(ett, array_length(ett));\n"; - pidl "}\n\n"; + pidl "}\n\n"; - pidl "void proto_reg_handoff_dcerpc_$module(void)\n"; - pidl "{\n"; - pidl "\tdcerpc_init_uuid(proto_dcerpc_$module, ett_dcerpc_$module, \n"; - pidl "\t\t&uuid_dcerpc_$module, ver_dcerpc_$module, \n"; - pidl "\t\tdcerpc_" . $module . "_dissectors, hf_opnum);\n"; - pidl "}\n"; + pidl "void proto_reg_handoff_dcerpc_pidl_$module(void)\n"; + pidl "{\n"; + pidl "\tdcerpc_init_uuid(proto_dcerpc_pidl_$module, ett_dcerpc_$module, \n"; + pidl "\t\t&uuid_dcerpc_$module, ver_dcerpc_$module, \n"; + pidl "\t\tdcerpc_dissectors, hf_opnum);\n"; + pidl "}\n"; - } else { + } else { - pidl "\tint proto_dcerpc;\n\n"; - pidl "\tproto_dcerpc = proto_get_id_by_filter_name(\"dcerpc\");\n"; - pidl "\tproto_register_field_array(proto_dcerpc, hf, array_length(hf));\n"; - pidl "\tproto_register_subtree_array(ett, array_length(ett));\n"; + pidl "\tint proto_dcerpc;\n\n"; + pidl "\tproto_dcerpc = proto_get_id_by_filter_name(\"dcerpc\");\n"; + pidl "\tproto_register_field_array(proto_dcerpc, hf, array_length(hf));\n"; + pidl "\tproto_register_subtree_array(ett, array_length(ett));\n"; + + pidl "}\n"; - pidl "}\n"; - } } close(OUT); diff --git a/source4/build/pidl/includes.h b/source4/build/pidl/includes.h new file mode 100644 index 0000000000..3aa5323190 --- /dev/null +++ b/source4/build/pidl/includes.h @@ -0,0 +1,3 @@ +#include "packet-dcerpc-proto.h" + + diff --git a/source4/build/pidl/moduleinfo.c b/source4/build/pidl/moduleinfo.c new file mode 100644 index 0000000000..584f81d710 --- /dev/null +++ b/source4/build/pidl/moduleinfo.c @@ -0,0 +1,5 @@ +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; +#endif diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c deleted file mode 100644 index bf2b6e7981..0000000000 --- a/source4/build/pidl/packet-dcerpc-eparser.c +++ /dev/null @@ -1,675 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tvbuff.h" -#include - -#include "packet-dcerpc.h" -#include "packet-dcerpc-nt.h" -#include "packet-dcerpc-eparser.h" - -static int hf_string4_len = -1; -static int hf_string4_offset = -1; -static int hf_string4_len2 = -1; -static int hf_string_data = -1; -static int hf_subtree_list = -1; - -static gint ett_array = -1; - -/* Create a ndr_pull structure from data stored in a tvb at a given offset. */ - -struct e_ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, - guint8 *drep) -{ - struct e_ndr_pull *ndr; - - ndr = (struct e_ndr_pull *)g_malloc(sizeof(*ndr)); - - ndr->tvb = tvb_new_subset(tvb, offset, -1, -1); - ndr->offset = 0; - ndr->pinfo = pinfo; - ndr->drep = drep; - ndr->flags = NDR_SCALARS|NDR_BUFFERS; - return ndr; -} - -/* Dispose of a dynamically allocated ndr_pull structure */ - -void ndr_pull_free(struct e_ndr_pull *ndr) -{ - g_free(ndr); -} - -void ndr_pull_ptr(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - guint32 *ptr) -{ - ndr->offset = dissect_ndr_uint32( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, ptr); -} - -void ndr_pull_level(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - gint16 *data) -{ - ndr->offset = dissect_ndr_uint16( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTSTATUS *data) -{ - ndr->offset = dissect_ntstatus( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_WERROR(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gWERROR *data) -{ - ndr->offset = dissect_werror( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - guint8 *data) -{ - ndr->offset = dissect_ndr_uint8( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_uint16(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - guint16 *data) -{ - ndr->offset = dissect_ndr_uint16( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_uint32(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - guint32 *data) -{ - ndr->offset = dissect_ndr_uint32( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_int64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - gint64 *data) -{ - ndr->offset = dissect_ndr_uint64( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_uint64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - guint64 *data) -{ - ndr->offset = dissect_ndr_uint64( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_DATA_BLOB(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gDATA_BLOB *h) -{ - guint32 length; - - if (!(ndr_flags & NDR_SCALARS)) { - return; - } - - if (ndr->flags & LIBNDR_ALIGN_FLAGS) { - if (ndr->flags & LIBNDR_FLAG_ALIGN2) { - length = NDR_ALIGN(ndr, 2); - } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) { - length = NDR_ALIGN(ndr, 4); - } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) { - length = NDR_ALIGN(ndr, 8); - } - if (ndr->data_size - ndr->offset < length) { - length = ndr->data_size - ndr->offset; - } - } else if (ndr->flags & LIBNDR_FLAG_REMAINING) { - length = ndr->data_size - ndr->offset; - } else { - ndr_pull_uint32(ndr, &length); - } - - h->data = g_malloc(length); - proto_tree_add_bytes(tree, hf_bytes_data, ndr->tvb, ndr->offset, length, h->data); - - ndr->offset += length; -} - -void ndr_pull_string(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags) -{ - guint32 len1, ofs, len2; - char *data; - - if (!(ndr_flags & NDR_SCALARS)) { - return; - } - - switch (ndr->flags & LIBNDR_STRING_FLAGS) { - case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: - case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: - - ndr_pull_uint32(ndr, tree, hf_string4_len, &len1); - ndr_pull_uint32(ndr, tree, hf_string4_offset, &ofs); - ndr_pull_uint32(ndr, tree, hf_string4_len2, &len2); - - if (len2 > 65535) - return; - - data = g_malloc(len2*2); - - proto_tree_add_bytes(tree, hf_string_data, ndr->tvb, - ndr->offset, len2 * 2, data); - - g_free(data); - - ndr->offset += len2 * 2; - -#if 0 - - ndr_pull_uint32(ndr, &len1)); - ndr_pull_uint32(ndr, &ofs); - ndr_pull_uint32(ndr, &len2); - if (len2 > len1) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "Bad string lengths len1=%u ofs=%u len2=%u\n", - len1, ofs, len2); - } - if (len2 == 0) { - *s = talloc_strdup(ndr->mem_ctx, ""); - break; - } - NDR_PULL_NEED_BYTES(ndr, len2*2); - ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, - ndr->data+ndr->offset, - len2*2, - (const void **)&as); - if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_CHARCNV, - "Bad character conversion"); - } - ndr_pull_advance(ndr, len2*2); - - /* this is a way of detecting if a string is sent with the wrong - termination */ - if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) { - if (strlen(as) < len2) { - DEBUG(6,("short string '%s'\n", as)); - } - } else { - if (strlen(as) == len2) { - DEBUG(6,("long string '%s'\n", as)); - } - } - *s = as; - -#endif - - break; - - case LIBNDR_FLAG_STR_SIZE4: - -#if 0 - - ndr_pull_uint32(ndr, &len1); - NDR_PULL_NEED_BYTES(ndr, len1*2); - if (len1 == 0) { - *s = talloc_strdup(ndr->mem_ctx, ""); - break; - } - ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, - ndr->data+ndr->offset, - len1*2, - (const void **)&as); - if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_CHARCNV, - "Bad character conversion"); - } - ndr_pull_advance(ndr, len1*2); - *s = as; - -#endif - - break; - - case LIBNDR_FLAG_STR_NULLTERM: - -#if 0 - - len1 = strnlen_w(ndr->data+ndr->offset, - (ndr->data_size - ndr->offset)/2); - if (len1*2+2 <= ndr->data_size - ndr->offset) { - len1++; - } - ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, - ndr->data+ndr->offset, - len1*2, - (const void **)s); - if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_CHARCNV, - "Bad character conversion"); - } - ndr_pull_advance(ndr, len1*2); - -#endif - - break; - - case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: - case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: - -#if 0 - - ndr_pull_uint32(ndr, &len1); - ndr_pull_uint32(ndr, &ofs); - ndr_pull_uint32(ndr, &len2); - if (len2 > len1) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "Bad ascii string lengths len1=%u ofs=%u len2=%u\n", - len1, ofs, len2); - } - NDR_ALLOC_N(ndr, as, (len2+1)); - ndr_pull_bytes(ndr, as, len2); - as[len2] = 0; - (*s) = as; - -#endif - - break; - - case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: - -#if 0 - ndr_pull_uint32(ndr, &ofs); - ndr_pull_uint32(ndr, &len2); - NDR_ALLOC_N(ndr, as, (len2+1)); - ndr_pull_bytes(ndr, as, len2); - as[len2] = 0; - (*s) = as; - -#endif - - break; - - case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2: - -#if 0 - - ndr_pull_uint16(ndr, &len3); - NDR_ALLOC_N(ndr, as, (len3+1)); - ndr_pull_bytes(ndr, as, len3); - as[len3] = 0; - (*s) = as; - -#endif - - break; - - case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM: - -#if 0 - - len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset)); - if (len1+1 <= ndr->data_size - ndr->offset) { - len1++; - } - NDR_ALLOC_N(ndr, as, (len1+1)); - ndr_pull_bytes(ndr, as, len1); - as[len1] = 0; - (*s) = as; - -#endif - - break; - - default: - -#if 0 - - return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", - ndr->flags & LIBNDR_STRING_FLAGS); - -#endif - - } -} - -void ndr_pull_NTTIME(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - gNTTIME *data) -{ - ndr->offset = dissect_ndr_uint64( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_HYPER_T(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - gHYPER_T *data) -{ - ndr->offset = dissect_ndr_uint64( - ndr->tvb, ndr->offset, ndr->pinfo, - tree, ndr->drep, hf, data); -} - -void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags) -{ - guint32 num_auths; - - if (!(flags & NDR_SCALARS)) { - return; - } - ndr_pull_uint32(ndr, tree, hf_string4_len, &num_auths); - - ndr_pull_dom_sid(ndr, tree, flags); -} - -void ndr_pull_advance(struct e_ndr_pull *ndr, int offset) -{ - ndr->offset += offset; -} - -void ndr_pull_align(struct e_ndr_pull *ndr, int size) -{ - if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { - ndr->offset = (ndr->offset + (size-1)) & ~(size-1); - } -} - -void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, - proto_tree *tree, size_t sub_size, - void (*fn)(struct e_ndr_pull *, - proto_tree *tree, int ndr_flags)) -{ - struct e_ndr_pull ndr2; - - ndr_pull_subcontext_header(ndr, tree, sub_size, &ndr2); - fn(&ndr2, tree, NDR_SCALARS|NDR_BUFFERS); - if (sub_size) { - ndr_pull_advance(ndr, tvb_length(ndr2.tvb)); - } else { - ndr_pull_advance(ndr, ndr2.offset); - } -} - -/* - mark the start of a structure -*/ -void ndr_pull_struct_start(struct e_ndr_pull *ndr) -{ - struct ndr_ofs_list *ofs; - - ofs = g_malloc(sizeof(*ofs)); - ofs->offset = ndr->offset; - ofs->next = ndr->ofs_list; - ndr->ofs_list = ofs; -} - -/* - mark the end of a structure -*/ -void ndr_pull_struct_end(struct e_ndr_pull *ndr) -{ - ndr->ofs_list = ndr->ofs_list->next; -} - -void ndr_pull_subcontext(struct e_ndr_pull *ndr, struct e_ndr_pull *ndr2, guint32 size) -{ - ndr2->tvb = tvb_new_subset( - ndr->tvb, ndr->offset, - (tvb_length_remaining(ndr->tvb, ndr->offset) > size) ? size : - tvb_length_remaining(ndr->tvb, ndr->offset), - (tvb_reported_length_remaining(ndr->tvb, ndr->offset) > size) ? size : - tvb_reported_length_remaining(ndr->tvb, ndr->offset)); - - ndr2->offset = 0; - ndr2->flags = ndr->flags; - - ndr2->pinfo = ndr->pinfo; - ndr2->drep = ndr->drep; - ndr2->ofs_list = ndr->ofs_list; -} - -static int hf_subcontext_size_2 = -1; -static int hf_subcontext_size_4 = -1; - -void ndr_pull_subcontext_header(struct e_ndr_pull *ndr, proto_tree *tree, - size_t sub_size, struct e_ndr_pull *ndr2) -{ - switch (sub_size) { - case 0: { - guint32 size = tvb_length(ndr->tvb) - ndr->offset; - if (size == 0) return; - ndr_pull_subcontext(ndr, ndr2, size); - break; - } - - case 2: { - guint16 size; - ndr_pull_uint16(ndr, tree, hf_subcontext_size_2, &size); - if (size == 0) return; - ndr_pull_subcontext(ndr, ndr2, size); - break; - } - - case 4: { - guint32 size; - ndr_pull_uint32(ndr, tree, hf_subcontext_size_4, &size); - if (size == 0) return; - ndr_pull_subcontext(ndr, ndr2, size); - break; - } - default: -// return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", sub_size); - } -} - -/* save the offset/size of the current ndr state */ -void ndr_pull_save(struct e_ndr_pull *ndr, struct ndr_pull_save *save) -{ - save->offset = ndr->offset; -} - -/* restore the size/offset of a ndr structure */ -void ndr_pull_restore(struct e_ndr_pull *ndr, struct ndr_pull_save *save) -{ - ndr->offset = save->offset; -} - -void ndr_pull_set_offset(struct e_ndr_pull *ndr, guint32 ofs) -{ - ndr->offset = ofs; -} - -static int hf_relative_ofs = -1; - -void ndr_pull_relative(struct e_ndr_pull *ndr, proto_tree *tree, - void (*fn)(struct e_ndr_pull *, - proto_tree *tree, int ndr_flags)) -{ - struct e_ndr_pull ndr2; - guint32 ofs; - struct ndr_pull_save save; - - ndr_pull_uint32(ndr, tree, hf_relative_ofs, &ofs); - if (ofs == 0) { - return; - } - ndr_pull_save(ndr, &save); - ndr_pull_set_offset(ndr, ofs + ndr->ofs_list->offset); - ndr_pull_subcontext(ndr, &ndr2, tvb_length(ndr->tvb) - ndr->offset); - /* strings must be allocated by the backend functions */ - if (ndr->flags & LIBNDR_STRING_FLAGS) { - fn(&ndr2, tree, NDR_SCALARS|NDR_BUFFERS); - } else { - fn(&ndr2, tree, NDR_SCALARS|NDR_BUFFERS); - } - ndr_pull_restore(ndr, &save); -} - -int lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep) -{ - return offset; -} - -int lsa_dissect_LSA_SECURITY_DESCRIPTOR_data(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep) -{ - return offset; -} - -int lsa_dissect_POLICY_DNS_DOMAIN_INFO(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep) -{ - return offset; -} - -void ndr_pull_bytes(struct e_ndr_pull *ndr, guint32 n) -{ - ndr->offset += n; -} - -void ndr_pull_array_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, - int ndr_flags, guint32 n) -{ - guint32 i; - if (!(ndr_flags & NDR_SCALARS)) { - return; - } - for (i=0;itvb, ndr->offset, 0, "Array entry"); - subtrees[i] = proto_item_add_subtree(item, ett_array); - - if ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS)) - pull_fn(ndr, subtrees[i], NDR_SCALARS); - else - pull_fn(ndr, tree, NDR_SCALARS); - - } - if (!(ndr_flags & NDR_BUFFERS)) goto done; -buffers: - for (i=0;iuser_data; - - /* Look for name */ - - for (l = list; l; l = g_slist_next(l)) { - info = l->data; - - if (strcmp(name, info->name) == 0) - return info->subtree; - } - - /* Create new subtree entry */ - - info = (struct subtree_info *)g_malloc(sizeof(struct subtree_info)); - - info->name = g_strdup(name); - item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, name); - info->subtree = proto_item_add_subtree(item, ett); - - /* Don't forget to add new list head */ - - list = g_slist_append(list, info); - - tree->user_data = list; - - return info->subtree; -} - -void proto_register_eparser(void) -{ - static hf_register_info hf[] = { - { &hf_string4_len, { "String4 length", "eparser.string4_length", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 length", HFILL }}, - { &hf_string4_offset, { "String4 offset", "eparser.string4_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 offset", HFILL }}, - { &hf_string4_len2, { "String4 length2", "eparser.string4_length2", FT_UINT32, BASE_DEC, NULL, 0x0, "String4 length2", HFILL }}, - { &hf_string_data, { "String data", "eparser.string_data", FT_BYTES, BASE_NONE, NULL, 0x0, "String data", HFILL }}, - { &hf_subcontext_size_2, { "Subcontext size2", "eparser.subcontext_size2", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size2", HFILL }}, - { &hf_subcontext_size_4, { "Subcontext size4", "eparser.subcontext_size4", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size4", HFILL }}, - { &hf_relative_ofs, { "Relative offset", "eparser.relative_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "Relative offset", HFILL }}, - { &hf_subtree_list, { "Subtree list", "", FT_UINT64, BASE_DEC, NULL, 0, "", HFILL }}, - }; - static gint *ett[] = { - &ett_array, - }; - int proto_dcerpc; - - proto_dcerpc = proto_get_id_by_filter_name("dcerpc"); - proto_register_field_array(proto_dcerpc, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); -} diff --git a/source4/build/pidl/packet-dcerpc-eparser.h b/source4/build/pidl/packet-dcerpc-eparser.h deleted file mode 100644 index f48badbdf1..0000000000 --- a/source4/build/pidl/packet-dcerpc-eparser.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef _packet_dcerpc_eparser_h -#define _packet_dcerpc_eparser_h - -#define NDR_SCALARS 1 -#define NDR_BUFFERS 2 - -#define LIBNDR_FLAG_BIGENDIAN (1<<0) -#define LIBNDR_FLAG_NOALIGN (1<<1) - -#define LIBNDR_FLAG_STR_ASCII (1<<2) -#define LIBNDR_FLAG_STR_LEN4 (1<<3) -#define LIBNDR_FLAG_STR_SIZE4 (1<<4) -#define LIBNDR_FLAG_STR_NOTERM (1<<5) -#define LIBNDR_FLAG_STR_NULLTERM (1<<6) -#define LIBNDR_FLAG_STR_SIZE2 (1<<7) -#define LIBNDR_STRING_FLAGS (0xFC) - -#define LIBNDR_FLAG_REF_ALLOC (1<<10) -#define LIBNDR_FLAG_REMAINING (1<<11) -#define LIBNDR_FLAG_ALIGN2 (1<<12) -#define LIBNDR_FLAG_ALIGN4 (1<<13) -#define LIBNDR_FLAG_ALIGN8 (1<<14) - -#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8) - -#define LIBNDR_PRINT_ARRAY_HEX (1<<15) -#define LIBNDR_PRINT_SET_VALUES (1<<16) - -/* used to force a section of IDL to be little-endian */ -#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<17) - -/* Ethereal version of struct ndr_pull */ - -struct e_ndr_pull { - tvbuff_t *tvb; - int offset; - packet_info *pinfo; - guint8 *drep; - struct ndr_ofs_list *ofs_list; - int flags; -}; - -struct ndr_pull_save { - guint32 offset; - struct ndr_pull_save *next; -}; - -/* offset lists are used to allow a push/pull function to find the - start of an encapsulating structure */ -struct ndr_ofs_list { - guint32 offset; - struct ndr_ofs_list *next; -}; - - -typedef long long gNTTIME; -typedef long long gHYPER_T; -typedef guint32 gNTSTATUS; -typedef guint32 gWERROR; - -typedef struct -{ - guint8 *data; - guint32 length; -} gDATA_BLOB; - -#include "packet-dcerpc-proto.h" - -/* Create a ndr_pull structure from data stored in a tvb at a given offset. */ - -struct e_ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, - guint8 *drep); -void ndr_pull_free(struct e_ndr_pull *ndr); -void ndr_pull_ptr(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint32 *ptr); -void ndr_pull_level(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gint16 *data); -void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTSTATUS *data); -void ndr_pull_WERROR(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gWERROR *data); -void ndr_pull_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint8 *data); -void ndr_pull_uint16(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint16 *data); -void ndr_pull_uint32(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint32 *data); -void ndr_pull_advance(struct e_ndr_pull *ndr, int offset); -void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, - proto_tree *tree, size_t sub_size, - void (*fn)(struct e_ndr_pull *, - proto_tree *tree, int ndr_flags)); -void ndr_pull_subcontext_header(struct e_ndr_pull *ndr, proto_tree *tree, - size_t sub_size, struct e_ndr_pull *ndr2); -void ndr_pull_struct_start(struct e_ndr_pull *ndr); -void ndr_pull_struct_end(struct e_ndr_pull *ndr); -void ndr_pull_align(struct e_ndr_pull *ndr, int size); -void ndr_pull_NTTIME(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTTIME *data); -void ndr_pull_HYPER_T(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gHYPER_T *data); -void ndr_pull_int64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gint64 *data); -void ndr_pull_uint64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint64 *data); -void ndr_pull_DATA_BLOB(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gDATA_BLOB *data); -void ndr_pull_string(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags); -void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags); - -void ndr_pull_relative(struct e_ndr_pull *ndr, proto_tree *tree, - void (*fn)(struct e_ndr_pull *ndr, - proto_tree *tree, int ndr_flags)); - -int lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep); - -int lsa_dissect_LSA_SECURITY_DESCRIPTOR_data(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep); - -int lsa_dissect_POLICY_DNS_DOMAIN_INFO(tvbuff_t tvb, int offset, - packet_info *pinfo, proto_tree *tree, - guint8 *drep); - -void ndr_pull_array_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, int ndr_flags, guint32 n); -void ndr_pull_array_uint16(struct e_ndr_pull *ndr, proto_tree *tree, int hf, int ndr_flags, guint32 n); -void ndr_pull_array_uint32(struct e_ndr_pull *ndr, proto_tree *tree, int hf, int ndr_flags, guint32 n); - -void ndr_pull_array(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags, - guint32 n, void (*fn)(struct e_ndr_pull *ndr, - proto_tree *tree, int ndr_flags)); - -proto_tree *get_subtree(proto_tree *tree, char *name, struct e_ndr_pull *ndr, - gint ett); - -#endif /* _packet_dcerpc_eparser_h */ -- cgit