summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/build/pidl/eparser.pm122
-rw-r--r--source4/build/pidl/packet-dcerpc-eparser.c43
-rw-r--r--source4/build/pidl/packet-dcerpc-eparser.h43
3 files changed, 170 insertions, 38 deletions
diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm
index 20ac74f23f..9c96d63852 100644
--- a/source4/build/pidl/eparser.pm
+++ b/source4/build/pidl/eparser.pm
@@ -232,13 +232,14 @@ sub ParseArrayPull($$$)
my $size = find_size_var($e, util::array_size($e), $var_prefix);
my $alloc_size = $size;
+ pidl "\t{ guint32 _array_size;\n";
# if this is a conformant array then we use that size to allocate, and make sure
# we allocate enough to pull the elements
if (defined $e->{CONFORMANT_SIZE}) {
$alloc_size = $e->{CONFORMANT_SIZE};
pidl "\tif ($size > $alloc_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\treturn ndr_pull_error(ndr, \"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/) {
@@ -248,15 +249,14 @@ sub ParseArrayPull($$$)
# non fixed arrays encode the size just before the array
pidl "\t{\n";
- pidl "\t\tguint32 _array_size;\n";
- pidl "\t\tndr_pull_uint32(ndr, &_array_size);\n";
+ pidl "\t\tdissect_ndr_uint32(ndr->tvb, ndr->offset, ndr->pinfo, ndr->tree, ndr->drep, hf_array_size, &_array_size);\n";
if ($size =~ /r->in/) {
- pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n";
+ pidl "\t\t// if (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n";
} else {
- pidl "\t\tif ($size != _array_size) {\n";
+ pidl "\t\t// if ($size != _array_size) {\n";
}
- pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should be %u\", _array_size, $size);\n";
- pidl "\t\t}\n";
+ pidl "\t\t\t// return ndr_pull_error(ndr, \"Bad array size %u should be %u\", _array_size, $size);\n";
+ pidl "\t\t// }\n";
if ($size =~ /r->in/) {
pidl "else { $size = _array_size; }\n";
}
@@ -285,18 +285,19 @@ sub ParseArrayPull($$$)
pidl "\t\tguint32 _offset, _length;\n";
pidl "\t\tndr_pull_uint32(ndr, &_offset);\n";
pidl "\t\tndr_pull_uint32(ndr, &_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";
+ pidl "\t\tif (_offset != 0) return ndr_pull_error(ndr, \"Bad array offset 0x%08x\", _offset);\n";
+ pidl "\t\t//if (_length > $size || _length != $length) return ndr_pull_error(ndr, \"Bad array length 0x%08x > size 0x%08x\", _offset, $size);\n\n";
$size = "_length";
}
if (util::is_scalar_type($e->{TYPE})) {
- pidl "\t\tndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size);\n";
+ pidl "\t\tndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, _array_size);\n";
} else {
- pidl "\t\tndr_pull_array(ndr, $ndr_flags, (void **)$var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE});\n";
+ pidl "\t\tndr_pull_array(ndr, $ndr_flags, /* sizeof($var_prefix$e->{NAME}\[0]), */ _array_size, ndr_pull_$e->{TYPE});\n";
}
pidl "\t}\n";
+ pidl "\t}\n";
}
@@ -316,26 +317,26 @@ sub ParseElementPullSwitch($$$$)
if (!defined $utype ||
!util::has_property($utype->{DATA}, "nodiscriminant")) {
my $e2 = find_sibling($e, $switch);
+ pidl "\t g$e2->{TYPE} _level;\n";
pidl "\tif (($ndr_flags) & NDR_SCALARS) {\n";
- pidl "\t\t $e2->{TYPE} _level;\n";
pidl "\t\tndr_pull_$e2->{TYPE}(ndr, &_level);\n";
if ($switch_var =~ /r->in/) {
- pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n";
+ pidl "\t\t // if (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n";
} else {
- pidl "\t\tif (_level != $switch_var) {\n";
+ pidl "\t\t // if (_level != $switch_var) {\n";
}
- pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u in $e->{NAME}\");\t\t}\n";
+ pidl "\t\t\t // return ndr_pull_error(ndr, \"Bad switch value %u in $e->{NAME}\");\t\t}\n";
if ($switch_var =~ /r->/) {
- pidl "else { $switch_var = _level; }\n";
+ pidl "// else { $switch_var = _level;\n }\n";
}
- pidl "\t}\n";
+ pidl "\t// }\n";
}
my $sub_size = util::has_property($e, "subcontext");
if (defined $sub_size) {
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, $ndr_flags, $switch_var);\n";
+ pidl "\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, _level);\n";
}
@@ -420,9 +421,9 @@ sub ParseElementPullBuffer($$$)
} elsif (defined $sub_size) {
if ($e->{POINTERS}) {
if (util::is_builtin_type($e->{TYPE})) {
- pidl "\tndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_fn(ndr, $sub_size, _pull_$e->{TYPE});\n";
} else {
- pidl "\tndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n";
+ pidl "\tndr_pull_subcontext_flags_fn(ndr, $sub_size, ndr_pull_$e->{TYPE});\n";
}
}
} elsif (util::is_builtin_type($e->{TYPE})) {
@@ -496,7 +497,7 @@ sub ParseStructPull($)
pidl "\tndr_pull_struct_end(ndr);\n";
- pidl "done:\n";
+ pidl "done: ;\n";
end_flags($struct);
}
@@ -536,7 +537,7 @@ sub ParseUnionPull($)
}
if (! $have_default) {
pidl "\tdefault:\n";
- pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
+ pidl "\t\t// return ndr_pull_error(ndr, \"Bad switch value \%u\", level);\n";
}
pidl "\t}\n";
pidl "buffers:\n";
@@ -555,7 +556,7 @@ sub ParseUnionPull($)
}
if (! $have_default) {
pidl "\tdefault:\n";
- pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
+ pidl "\t\t// return ndr_pull_error(ndr, \"Bad switch value \%u\", level);\n";
}
pidl "\t}\n";
pidl "\tndr_pull_struct_end(ndr);\n";
@@ -564,6 +565,27 @@ sub ParseUnionPull($)
}
#####################################################################
+# parse a enum - pull side
+sub ParseEnumPull($)
+{
+ my $e = shift;
+
+ my $name;
+ my $ndx = 0;
+
+ for my $x (@{$e->{ELEMENTS}}) {
+ if ($x =~ /([a-zA-Z_]+)=([0-9]+)/) {
+ $name = $1;
+ $ndx = $2;
+ } else {
+ $name = $x;
+ }
+ pidl "#define $name $ndx\n";
+ $ndx++;
+ }
+}
+
+#####################################################################
# parse a type
sub ParseTypePull($)
{
@@ -574,6 +596,8 @@ sub ParseTypePull($)
ParseStructPull($data);
($data->{TYPE} eq "UNION") &&
ParseUnionPull($data);
+ ($data->{TYPE} eq "ENUM") &&
+ ParseEnumPull($data);
}
}
@@ -594,20 +618,21 @@ sub ParseTypedefPull($)
pidl "*/\n\n";
if ($e->{DATA}->{TYPE} eq "STRUCT") {
- pidl $static . "void dissect_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags)";
+ pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags)";
pidl "\n{\n";
ParseTypePull($e->{DATA});
pidl "}\n\n";
}
if ($e->{DATA}->{TYPE} eq "UNION") {
- pidl $static . "void dissect_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags, guint16 level)";
+ pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags, int level)";
pidl "\n{\n";
ParseTypePull($e->{DATA});
pidl "}\n\n";
}
if ($e->{DATA}->{TYPE} eq "ENUM") {
+ ParseEnumPull($e->{DATA});
}
}
@@ -792,8 +817,6 @@ sub type2base($)
sub NeededFunction($)
{
my $fn = shift;
- $needed{"pull_$fn->{NAME}"} = 1;
- $needed{"push_$fn->{NAME}"} = 1;
foreach my $e (@{$fn->{DATA}}) {
$needed{"hf_$e->{NAME}_$e->{TYPE}"} = {
'name' => $e->{NAME},
@@ -801,40 +824,48 @@ sub NeededFunction($)
'ft' => type2ft($e->{TYPE}),
'base' => type2base($e->{TYPE})
};
+ $needed{"proto_$e->{TYPE}"} = 1,
+ if !util::is_builtin_type($e->{TYPE});
$e->{PARENT} = $fn;
- $needed{"pull_$e->{TYPE}"} = 1;
- $needed{"push_$e->{TYPE}"} = 1;
}
}
sub NeededTypedef($)
{
my $t = shift;
+
if (util::has_property($t->{DATA}, "public")) {
$needed{"pull_$t->{NAME}"} = 1;
- $needed{"push_$t->{NAME}"} = 1;
}
+
if ($t->{DATA}->{TYPE} eq "STRUCT") {
for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+
+ $needed{"hf_$e->{NAME}_$e->{TYPE}"} = {
+ 'name' => $e->{NAME},
+ 'type' => $e->{TYPE},
+ 'ft' => type2ft($e->{TYPE}),
+ 'base' => type2base($e->{TYPE})
+ };
+
+ $needed{"proto_$e->{TYPE}"} = 1,
+ if !util::is_builtin_type($e->{TYPE});
+
$e->{PARENT} = $t->{DATA};
if ($needed{"pull_$t->{NAME}"}) {
$needed{"pull_$e->{TYPE}"} = 1;
}
- if ($needed{"push_$t->{NAME}"}) {
- $needed{"push_$e->{TYPE}"} = 1;
- }
}
}
if ($t->{DATA}->{TYPE} eq "UNION") {
+ $needed{"proto_$t->{NAME}"} = "union";
for my $e (@{$t->{DATA}->{DATA}}) {
$e->{PARENT} = $t->{DATA};
if ($e->{TYPE} eq "UNION_ELEMENT") {
+ $needed{"proto_$e->{DATA}->{TYPE}"} = 1;
if ($needed{"pull_$t->{NAME}"}) {
$needed{"pull_$e->{DATA}->{TYPE}"} = 1;
}
- if ($needed{"push_$t->{NAME}"}) {
- $needed{"push_$e->{DATA}->{TYPE}"} = 1;
- }
}
}
}
@@ -894,6 +925,7 @@ sub Parse($$)
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_policy_handle = -1;\n";
foreach my $x (@{$idl}) {
@@ -903,11 +935,26 @@ sub Parse($$)
if ($x->{TYPE} eq "INTERFACE") {
BuildNeeded($x);
+ # Declarations for hf variables
+
foreach my $y (keys(%needed)) {
pidl "static int $y = -1;\n", if $y =~ /^hf_/;
}
- ParseInterface($x);
+ # Function prototypes
+
+ foreach my $x (keys(%needed)) {
+ next, if !($x =~ /^proto_/);
+ my $name = $x;
+ $name =~ s/^proto_//;
+ pidl "void ndr_pull_$name(struct e_ndr_pull *ndr, int ndr_flags";
+
+ pidl ", int level", if $needed{$x} eq "union";
+
+ pidl ");\n";
+ }
+
+ ParseInterface($x);
}
}
@@ -935,6 +982,7 @@ sub Parse($$)
pidl "\t{ &hf_opnum, { \"Operation\", \"$module.opnum\", FT_UINT16, BASE_DEC, NULL, 0x0, \"Operation\", HFILL }},\n";
pidl "\t{ &hf_policy_handle, { \"Policy handle\", \"$module.policy\", FT_BYTES, BASE_NONE, NULL, 0x0, \"Policy handle\", HFILL }},\n";
pidl "\t{ &hf_rc, { \"Return code\", \"$module.rc\", FT_UINT32, BASE_HEX, VALS(NT_errors), 0x0, \"Return status code\", HFILL }},\n";
+ pidl "\t{ &hf_array_size, { \"Operation\", \"$module.array_size\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Array size\", HFILL }},\n";
pidl "\t{ &hf_ptr, { \"Pointer\", \"$module.ptr\", FT_UINT32, BASE_HEX, NULL, 0x0, \"Pointer\", HFILL }},\n";
foreach my $x (keys(%needed)) {
diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c
index bafdf34006..f7cf575932 100644
--- a/source4/build/pidl/packet-dcerpc-eparser.c
+++ b/source4/build/pidl/packet-dcerpc-eparser.c
@@ -65,3 +65,46 @@ void ndr_pull_policy_handle(struct e_ndr_pull *e_ndr, int hf)
e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, e_ndr->tree,
e_ndr->drep, hf, NULL, NULL, 0, 0);
}
+
+void ndr_pull_advance(struct e_ndr_pull *ndr, int offset)
+{
+ e_ndr->offset += offset;
+}
+
+void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, size_t sub_size,
+ void *base,
+ void (*fn)(struct e_ndr_pull *,
+ int ndr_flags))
+{
+ struct e_ndr_pull ndr2;
+
+ ndr_pull_subcontext_header(ndr, sub_size, &ndr2);
+ fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, base);
+ if (sub_size) {
+ ndr_pull_advance(ndr, ndr2.data_size);
+ } 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)
+{
+ struct ndr_ofs_list *ofs = ndr->ofs_list->next;
+ g_free(ndr->ofs_list);
+ ndr->ofs_list = ofs;
+}
diff --git a/source4/build/pidl/packet-dcerpc-eparser.h b/source4/build/pidl/packet-dcerpc-eparser.h
index 0d181c9c8a..598ae9b08e 100644
--- a/source4/build/pidl/packet-dcerpc-eparser.h
+++ b/source4/build/pidl/packet-dcerpc-eparser.h
@@ -1,6 +1,31 @@
#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 {
@@ -9,6 +34,15 @@ struct e_ndr_pull {
packet_info *pinfo;
proto_tree *tree;
guint8 *drep;
+ struct ndr_ofs_list *ofs_list;
+ int flags;
+};
+
+/* 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;
};
/* Create a ndr_pull structure from data stored in a tvb at a given offset. */
@@ -20,4 +54,11 @@ void ndr_pull_ptr(struct e_ndr_pull *ndr, int hf, guint32 *ptr);
void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, int hf);
void ndr_pull_uint16(struct e_ndr_pull *ndr, int hf);
void ndr_pull_uint32(struct e_ndr_pull *ndr, int hf);
-void ndr_pull_policy_handle(struct e_ndr_pull *e_ndr, int hf);
+void ndr_pull_policy_handle(struct e_ndr_pull *ndr, int hf);
+void ndr_pull_advance(struct e_ndr_pull *ndr, int offset);
+void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, size_t sub_size,
+ void (*fn)(struct e_ndr_pull *,
+ int ndr_flags));
+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);