summaryrefslogtreecommitdiff
path: root/source4/build/pidl
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2004-07-26 04:11:18 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:57:42 -0500
commit8ded5420e3312f19c85e65eaa7464ce4de160a3f (patch)
tree4690846b8b95b63de29042384ddb3283edfe0556 /source4/build/pidl
parent144bb17b06ae0df04e2552ec1b19fbc5046434b0 (diff)
downloadsamba-8ded5420e3312f19c85e65eaa7464ce4de160a3f.tar.gz
samba-8ded5420e3312f19c85e65eaa7464ce4de160a3f.tar.bz2
samba-8ded5420e3312f19c85e65eaa7464ce4de160a3f.zip
r1586: Finally, a technique for putting buffers in scalars in the same
protocol tree that actually works. Instead of trying really hard to do this in code, just remember a list of strings and subtrees for every tree. (This does require the addition of a void *user_data field to ethereal's proto_node structure). (This used to be commit 5bc61162602f84c8a3a0b22c74c69318b92e087a)
Diffstat (limited to 'source4/build/pidl')
-rw-r--r--source4/build/pidl/eparser.pm109
-rw-r--r--source4/build/pidl/packet-dcerpc-eparser.c68
-rw-r--r--source4/build/pidl/packet-dcerpc-eparser.h13
3 files changed, 102 insertions, 88 deletions
diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm
index d8dbd4195f..fca359d41d 100644
--- a/source4/build/pidl/eparser.pm
+++ b/source4/build/pidl/eparser.pm
@@ -347,13 +347,14 @@ sub ParseElementPullScalar($$)
{
my($e) = 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, subtree_$e->{NAME}, ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_relative(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), ndr_pull_$e->{TYPE});\n";
} elsif (util::is_inline_array($e)) {
ParseArrayPull($e, "NDR_SCALARS");
} elsif (util::need_wire_pointer($e)) {
@@ -369,14 +370,14 @@ sub ParseElementPullScalar($$)
ParseElementPullSwitch($e, $ndr_flags, $switch);
} elsif (defined $sub_size) {
if (util::is_builtin_type($e->{TYPE})) {
- pidl "\tndr_pull_subcontext_fn(ndr, tree, $sub_size, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n";
} else {
- pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, (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";
} else {
- pidl "\tndr_pull_$e->{TYPE}(ndr, subtree_$e->{NAME}, $ndr_flags);\n";
+ pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $ndr_flags);\n";
}
end_flags($e);
@@ -418,17 +419,17 @@ sub ParseElementPullBuffer($$)
} elsif (defined $sub_size) {
if ($e->{POINTERS}) {
if (util::is_builtin_type($e->{TYPE})) {
- pidl "\tndr_pull_subcontext_fn(ndr, tree, $sub_size, _pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, _pull_$e->{TYPE});\n";
} else {
- pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, 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";
} elsif ($e->{POINTERS}) {
- pidl "\tndr_pull_$e->{TYPE}(ndr, tree, NDR_SCALARS|NDR_BUFFERS);\n";
+ pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), NDR_SCALARS|NDR_BUFFERS);\n";
} else {
- pidl "\tndr_pull_$e->{TYPE}(ndr, subtree_$e->{NAME}, $ndr_flags);\n";
+ pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $ndr_flags);\n";
}
if (util::need_wire_pointer($e)) {
@@ -446,8 +447,9 @@ sub ParseStructPull($)
my $conform_e;
for my $x (@{$struct->{ELEMENTS}}) {
- pidl "\tg$x->{TYPE} elt_$x->{NAME};\n",
- if util::is_builtin_type($x->{TYPE});
+ if (util::is_builtin_type($x->{TYPE})) {
+ pidl "\tg$x->{TYPE} elt_$x->{NAME};\n";
+ }
}
if (! defined $struct->{ELEMENTS}) {
@@ -472,38 +474,23 @@ sub ParseStructPull($)
!util::has_property($e, "relative")) {
pidl "\tguint32 ptr_$e->{NAME};\n";
}
- if (!util::is_scalar_type($e->{TYPE})) {
- pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n";
- }
}
pidl "\n";
- # Some debugging stuff
+ # 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, \"NDR_SCALARS|NDR_BUFFERS\");\n";
- pidl "\telse if (ndr_flags & NDR_SCALARS)\n";
- pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"NDR_SCALARS\");\n";
- pidl "\telse if (ndr_flags & NDR_BUFFERS)\n";
- pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"NDR_BUFFERS\");\n";
+# 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";
- pidl "\n";
start_flags($struct);
- pidl "\tif ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS)) {\n";
- pidl "\t\tproto_item *item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$struct->{PARENT}{NAME}\");\n";
- pidl "\t\ttree = proto_item_add_subtree(item, ett_$struct->{PARENT}{NAME});\n";
-
- foreach my $e (@{$struct->{ELEMENTS}}) {
- if (!util::is_scalar_type($e->{TYPE})) {
- pidl "\t\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n";
- pidl "\t\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n";
- }
- }
-
- pidl "\t}\n\n";
-
pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n\n";
pidl "\tndr_pull_struct_start(ndr);\n";
@@ -558,7 +545,6 @@ sub ParseUnionPull($)
$have_default = 1;
} else {
pidl "\tcase $el->{CASE}: {\n";
- pidl "\tproto_tree *subtree_$el->{DATA}{NAME} = tree;\n";
}
if ($el->{TYPE} eq "UNION_ELEMENT") {
my $e2 = $el->{DATA};
@@ -584,7 +570,6 @@ sub ParseUnionPull($)
pidl "\tdefault:\n";
} else {
pidl "\tcase $el->{CASE}: {\n";
- pidl "\tproto_tree *subtree_$el->{DATA}{NAME} = tree;\n";
}
if ($el->{TYPE} eq "UNION_ELEMENT") {
ParseElementPullBuffer($el->{DATA}, "NDR_BUFFERS");
@@ -731,11 +716,9 @@ sub ParseFunctionPull($)
# Request
- pidl $static . "int $fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *toplevel_tree, guint8 *drep)\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 "\tproto_item *item;\n";
- pidl "\tproto_tree *tree = toplevel_tree;\n";
# declare any internal pointers we need
foreach my $e (@{$fn->{DATA}}) {
@@ -743,15 +726,11 @@ sub ParseFunctionPull($)
if (util::has_property($e, "in")) {
if (util::need_wire_pointer($e)) {
- pidl "\tguint32 ptr_$e->{NAME};\n";
+ pidl "\tguint32 ptr_$e->{NAME};\n";
}
- pidl "\tg$e->{TYPE} elt_$e->{NAME};\n",
- if util::is_builtin_type($e->{TYPE});
-
- if (util::need_wire_pointer($e) ||
- !util::is_scalar_type($e->{TYPE})) {
- pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n";
+ if (util::is_builtin_type($e->{TYPE})) {
+ pidl "\tg$e->{TYPE} elt_$e->{NAME};\n";
}
}
}
@@ -759,16 +738,6 @@ sub ParseFunctionPull($)
pidl "\n";
foreach my $e (@{$fn->{DATA}}) {
- if (util::has_property($e, "in") &&
- !util::is_scalar_type($e->{TYPE})) {
- pidl "\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n";
- pidl "\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n";
- }
- }
-
- pidl "\n";
-
- foreach my $e (@{$fn->{DATA}}) {
if (util::has_property($e, "in")) {
ParseFunctionElementPull($e, "in");
}
@@ -782,12 +751,9 @@ sub ParseFunctionPull($)
# Response
- pidl $static . "int $fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *toplevel_tree, guint8 *drep)\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";
- pidl "\tproto_item *item;\n";
- pidl "\tproto_tree *tree = toplevel_tree;\n";
-
# declare any internal pointers we need
foreach my $e (@{$fn->{DATA}}) {
@@ -797,12 +763,8 @@ sub ParseFunctionPull($)
pidl "\tguint32 ptr_$e->{NAME};\n";
}
- pidl "\tg$e->{TYPE} elt_$e->{NAME};\n",
- if util::is_builtin_type($e->{TYPE});
-
- if (util::need_wire_pointer($e) ||
- !util::is_scalar_type($e->{TYPE})) {
- pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n";
+ if (util::is_builtin_type($e->{TYPE})) {
+ pidl "\tg$e->{TYPE} elt_$e->{NAME};\n";
}
}
}
@@ -810,16 +772,6 @@ sub ParseFunctionPull($)
pidl "\n";
foreach my $e (@{$fn->{DATA}}) {
- if (util::has_property($e, "out") &&
- !util::is_scalar_type($e->{TYPE})) {
- pidl "\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n";
- pidl "\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n";
- }
- }
-
- pidl "\n";
-
- foreach my $e (@{$fn->{DATA}}) {
if (util::has_property($e, "out")) {
ParseFunctionElementPull($e, "out");
}
@@ -1007,11 +959,14 @@ sub ParseHeader($$)
foreach my $x (@{$idl}) {
if ($x->{TYPE} eq "INTERFACE") {
foreach my $d (@{$x->{DATA}}) {
+
+ # Make prototypes for [public] push/pull functions
+
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";
+ pidl "void ndr_pull_$d->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags);\n\n";
}
if ($d->{DATA}{TYPE} eq "UNION") {
diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c
index 8debaf0aab..9217f3a87e 100644
--- a/source4/build/pidl/packet-dcerpc-eparser.c
+++ b/source4/build/pidl/packet-dcerpc-eparser.c
@@ -3,6 +3,7 @@
#endif
#include "tvbuff.h"
+#include <string.h>
#include "packet-dcerpc.h"
#include "packet-dcerpc-nt.h"
@@ -12,6 +13,7 @@ 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;
@@ -319,6 +321,7 @@ void ndr_pull_HYPER_T(struct e_ndr_pull *ndr, proto_tree *tree, int hf,
void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags)
{
guint32 num_auths;
+
if (!(flags & NDR_SCALARS)) {
return;
}
@@ -339,9 +342,9 @@ void ndr_pull_align(struct e_ndr_pull *ndr, int size)
}
}
-void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, proto_tree *tree,
- size_t sub_size,
- void (*fn)(struct e_ndr_pull *,
+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;
@@ -447,7 +450,7 @@ void ndr_pull_set_offset(struct e_ndr_pull *ndr, guint32 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 *,
+ void (*fn)(struct e_ndr_pull *,
proto_tree *tree, int ndr_flags))
{
struct e_ndr_pull ndr2;
@@ -535,17 +538,69 @@ void ndr_pull_array(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags,
proto_item *item;
item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, "Array entry");
subtrees[i] = proto_item_add_subtree(item, ett_array);
- pull_fn(ndr, subtrees[i], NDR_SCALARS);
+
+ 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;i<count;i++) {
- pull_fn(ndr, subtrees[i], NDR_BUFFERS);
+ if ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS))
+ pull_fn(ndr, subtrees[i], NDR_BUFFERS);
+ else
+ pull_fn(ndr, tree, NDR_BUFFERS);
}
done:
g_free(subtrees);
}
+struct subtree_info {
+ char *name;
+ proto_tree *subtree;
+};
+
+proto_tree *get_subtree(proto_tree *tree, char *name, struct e_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 = list->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[] = {
@@ -556,6 +611,7 @@ void proto_register_eparser(void)
{ &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,
diff --git a/source4/build/pidl/packet-dcerpc-eparser.h b/source4/build/pidl/packet-dcerpc-eparser.h
index 37d92293a9..6c51ccd708 100644
--- a/source4/build/pidl/packet-dcerpc-eparser.h
+++ b/source4/build/pidl/packet-dcerpc-eparser.h
@@ -69,9 +69,9 @@ void ndr_pull_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint8 *da
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 *,
+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);
@@ -82,11 +82,11 @@ void ndr_pull_NTTIME(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTTIME *
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_string(struct e_ndr_pull *ndr, proto_tree *tree, int hf);
+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,
+ void (*fn)(struct e_ndr_pull *ndr,
proto_tree *tree, int ndr_flags));
int lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t tvb, int offset,
@@ -108,4 +108,7 @@ 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 */