summaryrefslogtreecommitdiff
path: root/source4/build
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-08-05 00:30:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:31:14 -0500
commitfe8296e79a3d3c34231cad70ec1c373b1868f8f0 (patch)
treeff0a8341d43cdd64c0fb2ca4bb14bf848f2189c8 /source4/build
parent6243e2a30414ef059fe2fd3636563269f4b12d06 (diff)
downloadsamba-fe8296e79a3d3c34231cad70ec1c373b1868f8f0.tar.gz
samba-fe8296e79a3d3c34231cad70ec1c373b1868f8f0.tar.bz2
samba-fe8296e79a3d3c34231cad70ec1c373b1868f8f0.zip
r9081: Work on new ethereal parser generator, partially based on
Ronnie Sahlberg's idl2eth.c (This used to be commit 561aeca6490bdb7e37f12d60a67c551e5db3fc62)
Diffstat (limited to 'source4/build')
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm99
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm595
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/NDR/Header.pm103
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/NDR/Parser.pm1324
-rwxr-xr-xsource4/build/pidl/pidl26
5 files changed, 704 insertions, 1443 deletions
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm b/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
new file mode 100644
index 0000000000..aeca3d90f8
--- /dev/null
+++ b/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
@@ -0,0 +1,99 @@
+###################################################
+# parse an ethereal conformance file
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Ethereal::Conformance;
+
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(EmitProhibited);
+
+use strict;
+
+use Parse::Pidl::Util qw(has_property);
+
+sub handle_union_tag_size($$)
+{
+ #FIXME
+}
+
+sub handle_type($$$$$$$)
+{
+ my ($name,$dissectorname,$ft_type,$base_type,$mask,$valsstring,$alignment) = @_;
+ #FIXME
+}
+
+my %hf_renames = ();
+
+sub handle_hf_rename($$)
+{
+ my ($old,$new) = @_;
+ $hf_renames{$old} = $new;
+}
+
+sub handle_param_value($$)
+{
+ my ($dissector_name,$value) = @_;
+
+}
+
+sub handle_hf_field($$$$$$$$)
+{
+ my ($hf,$title,$filter,$ft_type,$base_type,$valsstring,$mask,$blub) = @_;
+
+}
+
+sub handle_strip_prefix($)
+{
+ #FIXME
+}
+
+my @noemit = ();
+
+sub handle_noemit($)
+{
+ my $type = shift;
+
+ push (@noemit, $type);
+}
+
+my %field_handlers = (
+ UNION_TAG_SIZE => \&handle_union_tag_size,
+ TYPE => \&handle_type,
+ NOEMIT => \&handle_noemit,
+ PARAM_VALUE => \&handle_param_value,
+ HF_FIELD => \&handle_hf_field,
+ HF_RENAME => \&handle_hf_rename,
+ STRIP_PREFIX => \&handle_strip_prefix
+);
+
+sub Parse($)
+{
+ my $f = shift;
+
+ open(IN,$f) or return undef;
+
+ foreach (<IN>) {
+ next if (/^#.*$/);
+ next if (/^$/);
+
+ my @fields = split(/ /);
+
+ $field_handlers{$fields[0]}(@fields);
+ }
+
+ close(IN);
+}
+
+sub EmitProhibited($)
+{
+ my $type = shift;
+
+ return 1 if (grep(/$type/,@noemit));
+
+ return 0;
+}
+
+1;
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm b/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
new file mode 100644
index 0000000000..c5feab26a4
--- /dev/null
+++ b/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
@@ -0,0 +1,595 @@
+##################################################
+# Samba4 NDR parser generator for IDL structures
+# Copyright tridge@samba.org 2000-2003
+# Copyright tpot@samba.org 2001
+# Copyright jelmer@samba.org 2004-2005
+# Portions based on idl2eth.c by Ronnie Sahlberg
+# released under the GNU GPL
+
+package Parse::Pidl::Ethereal::NDR::Parser;
+
+use strict;
+use Parse::Pidl::Typelist;
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR;
+use Parse::Pidl::Ethereal::Conformance qw(EmitProhibited);
+
+my %ptrtype_define_mappings = (
+ "unique" => "NDR_POINTER_UNIQUE",
+ "ref" => "NDR_POINTER_REF",
+ "ptr" => "NDR_POINTER_PTR"
+);
+
+sub type2ft($)
+{
+ my($t) = shift;
+
+ return "FT_UINT$1" if $t =~ /uint(8|16|32|64)/;
+ return "FT_INT$1" if $t =~ /int(8|16|32|64)/;
+ return "FT_UINT64", if $t eq "HYPER_T" or $t eq "NTTIME"
+ or $t eq "NTTIME_1sec" or $t eq "NTTIME_hyper" or $t eq "hyper";
+
+ # Type is an enum
+
+ return "FT_UINT16";
+}
+
+# Determine the display base for an element
+
+sub elementbase($)
+{
+ my($e) = shift;
+
+ if (my $base = has_property($e, "display")) {
+ return "BASE_" . uc($base);
+ }
+
+ return "BASE_DEC", if $e->{TYPE} eq "ENUM";
+ return "BASE_DEC", if $e->{TYPE} =~ /u?int(8|16|32|64)/;
+ return "BASE_DEC", if $e->{TYPE} eq "NTTIME" or $e->{TYPE} eq "HYPER_T";
+
+ # Probably an enum
+
+ return "BASE_DEC";
+}
+
+# Convert a IDL structure field name (e.g access_mask) to a prettier
+# string like 'Access Mask'.
+
+sub field2name($)
+{
+ my($field) = shift;
+
+ $field =~ s/_/ /g; # Replace underscores with spaces
+ $field =~ s/(\w+)/\u\L$1/g; # Capitalise each word
+
+ return $field;
+}
+
+sub bitmapbase($)
+{
+ my $e = shift;
+
+ return "16", if has_property($e->{DATA}, "bitmap16bit");
+ return "8", if has_property($e->{DATA}, "bitmap8bit");
+
+ return "32";
+}
+
+my %res = ();
+my $tabs = "";
+sub pidl_code($)
+{
+ my $d = shift;
+ if ($d) {
+ $res{code} .= $tabs;
+ $res{code} .= $d;
+ }
+ $res{code} .="\n";
+}
+
+sub pidl_hdr($) { $res{hdr} .= shift; }
+sub pidl_def($) { $res{def} .= shift; }
+
+sub indent()
+{
+ $tabs .= "\t";
+}
+
+sub deindent()
+{
+ $tabs = substr($tabs, 0, -1);
+}
+
+#####################################################################
+# parse the interface definitions
+sub Interface($)
+{
+ my($interface) = @_;
+ Typedef($_) foreach (@{$interface->{TYPEDEFS}});
+ Function($_) foreach (@{$interface->{FUNCTIONS}});
+}
+
+sub Enum($$$)
+{
+ my ($e,$name,$ifname) = @_;
+ my $valsstring = "$ifname\_$name\_vals";
+ my $dissectorname = "$ifname\_dissect\_$name";
+
+ foreach (@{$e->{ELEMENTS}}) {
+ if (/([^=]*)=(.*)/) {
+ pidl_hdr "#define $1 $2";
+ }
+ }
+
+ pidl_hdr "extern const value_string $valsstring;";
+ pidl_hdr "int $dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep, int hf_index, guint32 param);";
+
+ pidl_def "const value_string ".$valsstring."[] = {";
+ indent;
+ foreach (@{$e->{ELEMENTS}}) {
+ next unless (/([^=]*)=(.*)/);
+ pidl_code "{ $1, \"$2\" },";
+ }
+
+ pidl_def "{ 0, NULL }";
+ deindent;
+ pidl_def "};";
+
+ pidl_code "int";
+ pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep, int hf_index, guint32 param _U_)";
+ pidl_code "{";
+ indent;
+ pidl_code "offset=dissect_ndr_$e->{BASE_TYPE}(tvb, offset, pinfo, tree, drep, hf_index, NULL);";
+ pidl_code "return offset;";
+ pidl_code "}";
+
+ register_type($name, $dissectorname, enum_ft($e), "BASE_DEC", "0", "VALS($valsstring)", enum_size($e));
+}
+
+sub Bitmap($$$)
+{
+ my ($e,$name,$ifname) = @_;
+ my $dissectorname = "$ifname\_dissect\_$name";
+
+ register_ett("ett_$ifname\_$name");
+
+ pidl_hdr "int $dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep, int hf_index, guint32 param);";
+
+ pidl_code "int";
+ pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)";
+ pidl_code "{";
+ indent;
+ pidl_code "proto_item *item=NULL;";
+ pidl_code "proto_tree *tree=NULL;";
+
+ if ($e->{ALIGN} == 8) {
+ pidl_code "guint8 flags;";
+ } elsif ($e->{ALIGN} == 4) {
+ pidl_code "guint32 flags;";
+ pidl_code "ALIGN_TO_4_BYTES;";
+ }
+
+ pidl_code "if(parent_tree) {";
+ indent;
+ pidl_code "item=proto_tree_add_item(parent_tree, hf_index, tvb, offset, $e->{ALIGN}, TRUE);";
+ pidl_code "tree=proto_item_add_subtree(item,ett_$ifname\_$name);";
+ deindent;
+ pidl_code "}";
+
+ pidl_code "offset=dissect_ndr_$e->{BASE_TYPE}(tvb, offset, pinfo, NULL, drep, -1, &flags);";
+
+ foreach (@{$e->{ELEMENTS}}) {
+ next unless (/([^=]*)=(.*)/);
+ my ($en,$ev) = ($1,$2);
+ my $hf_bitname = "hf_$ifname\_$name\_$en";
+ my $filtername = "$ifname\.$name\.$en";
+
+ register_hf_field($hf_bitname, $en, $filtername, "FT_BOOLEAN", $e->{ALIGN} * 8, "TFS(&$en\_tfs)", $ev, "");
+
+ pidl_def "static const true_false_string $name\_tfs = {";
+ pidl_def " \"$name is SET\",";
+ pidl_def " \"$name is NOT SET\",";
+ pidl_def "};";
+
+ pidl_code "proto_tree_add_boolean(tree, $hf_bitname, tvb, offset-$e->{ALIGN}, $e->{ALIGN}, flags);";
+ pidl_code "if (flags&$ev){";
+ pidl_code "\tproto_item_append_text(item,\"$en\");";
+ pidl_code "}";
+ pidl_code "flags&=(~$ev);";
+ }
+
+ pidl_code "if(flags){";
+ pidl_code "proto_item_append_text(item, \"UNKNOWN-FLAGS\");";
+ pidl_code "}";
+ deindent;
+ pidl_code "return offset;";
+ pidl_code "}";
+ register_new_type($name, $dissectorname, bitmap_ft($e), "BASE_HEX", "0", "NULL", $e->{ALIGN});
+}
+
+sub Element($$$)
+{
+ my ($e,$pn,$ifname) = @_;
+
+ my $hf_index = "hf_$ifname\_$pn\_$e->{NAME}";
+ my $dissectorname = "$ifname\_dissect\_$ifname\_$pn\_$e->{NAME}";
+
+ return if (EmitProhibited($dissectorname));
+
+ my $type = FindType($e->{DATA_TYPE});
+
+ my $hf = register_hf_field($hf_index, $e->{NAME}, "$ifname.$pn.$e->{NAME}", $type->{FT_TYPE}, $type->{BASE_TYPE}, $type->{VALS}, $type->{MASK}, "");
+
+ pidl_code "static int";
+ pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)";
+ pidl_code "{";
+ indent;
+ pidl_code "guint32 param=" . Conformance::FindDissectorParam($dissectorname).";";
+ pidl_code "offset=$type->{DISSECTOR}(tvb, offset, pinfo, tree, drep, $hf, param);";
+ pidl_code "return offset;";
+ deindent;
+ pidl_code "}";
+}
+
+sub Function($$$)
+{
+ my ($fn,$name,$ifname) = @_;
+
+ register_function($ifname,$fn->{OPCODE}, $fn->{NAME},
+ "$ifname\_dissect\_$fn->{NAME}_request",
+ "$ifname\_dissect\_$fn->{NAME}_response");
+
+ pidl_code "static int";
+ pidl_code "$ifname\_dissect\_$fn->{NAME}_response(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)";
+ pidl_code "{";
+ indent;
+ foreach (@{$fn->{ELEMENTS}}) {
+ Element($_, $name, $ifname) if (grep(/in/,@{$_->{DIRECTION}}));
+ }
+ pidl_code "return offset;";
+ deindent;
+ pidl_code "}";
+
+ pidl_code "static int";
+ pidl_code "$ifname\_dissect\_$fn->{NAME}_request(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)";
+ pidl_code "{";
+ indent;
+ foreach (@{$fn->{ELEMENTS}}) {
+ Element($_, $name, $ifname) if (grep(/out/,@{$_->{DIRECTION}}));
+ }
+ pidl_code "return offset;";
+ deindent;
+ pidl_code "}";
+}
+
+sub Struct($$$)
+{
+ my ($e,$name,$ifname) = @_;
+ my $dissectorname = "$ifname\_dissect\_$name";
+
+ return if (EmitProhibited($dissectorname));
+
+ register_ett("ett_$ifname\_$name");
+
+ pidl_hdr "int $dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_);";
+ pidl_code "int";
+ pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)";
+ indent;
+ pidl_code "proto_item *item = NULL;";
+ pidl_code "proto_tree *tree = NULL;";
+ pidl_code "int old_offset;";
+
+ pidl_code "ALIGN_TO_$e->{ALIGN}_BYTES;";
+
+ pidl_code "old_offset=offset;";
+ pidl_code "if(parent_tree){";
+ indent;
+ pidl_code "item=proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, TRUE);";
+ pidl_code "tree=proto_item_add_subtree(item, ett_$ifname\_$name);";
+ deindent;
+ pidl_code"}";
+
+ Element($_, $name, $ifname) foreach (@{$e->{ELEMENTS}});
+
+ pidl_code "proto_item_set_len(item, offset-old_offset);";
+ pidl_code "return offset;";
+ deindent;
+ pidl_code "}";
+}
+
+sub Union($$$)
+{
+ my ($e,$name,$ifname) = @_;
+
+ my $dissectorname = "$ifname\_dissect_union_$name";
+
+ register_ett("ett_$ifname\_$name");
+
+ pidl_code "static int";
+ pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)";
+ pidl_code "{";
+ indent;
+ pidl_code "proto_item *item=NULL;";
+ pidl_code "proto_tree *tree=NULL;";
+ pidl_code "int old_offset;";
+
+ if ($e->{ALIGN} == 2) {
+ pidl_code "ALIGN_TO_2_BYTES;";
+ } elsif ($e->{ALIGN} == 4) {
+ pidl_code "ALIGN_TO_4_BYTES;";
+ }
+
+ pidl_code "g$e->{SWITCH_TYPE} level;";
+
+ pidl_code "old_offset=offset;";
+ pidl_code "if(parent_tree){";
+ indent;
+ pidl_code "item=proto_tree_add_text(parent_tree,tvb,offset,-1,\"$name\");";
+ pidl_code "tree=proto_item_add_subtree(item,ett_$ifname\_$name);";
+ pidl_code "}";
+
+ pidl_code "offset = dissect_ndr_$e->{SWITCH_TYPE}(tvb, offset, pinfo, tree, drep, hf_index, &level);";
+
+ pidl_code "switch(level) {";
+ foreach (@{$e->{ELEMENTS}}) {
+ pidl_code "$_->{CASE}:";
+ indent;
+ Element($_, $name, $ifname);
+ deindent;
+ pidl_code "break;";
+ }
+
+ pidl_code "proto_item_set_len(item, offset-old_offset);";
+ pidl_code "return offset;";
+ deindent;
+ pidl_code "}";
+
+}
+
+sub Typedef($$)
+{
+ my ($e,$ifname) = @_;
+
+ {
+ ENUM => \&Enum,
+ STRUCT => \&Struct,
+ UNION => \&Union,
+ BITMAP => \&Bitmap
+ }->{$e->{DATA}->{TYPE}}->($e->{DATA}, $e->{NAME}, $ifname);
+}
+
+sub RegisterInterface($)
+{
+ my ($x) = @_;
+
+ pidl_code "void proto_register_dcerpc_$x->{NAME}(void)";
+ pidl_code "{";
+ indent;
+
+ $res{code}.=DumpHfList();
+ $res{code}.=DumpEttList();
+
+ if (defined($x->{UUID})) {
+ # These can be changed to non-pidl_code names if the old dissectors
+ # in epan/dissctors are deleted.
+
+ my $name = "\"" . uc($x->{NAME}) . " (pidl)\"";
+ if (has_property($x, "helpstring")) {
+ $name = $x->{PROPERTIES}->{helpstring};
+ }
+ my $short_name = "idl_$x->{NAME}";
+ my $filter_name = "idl_$x->{NAME}";
+
+ pidl_code "proto_dcerpc_$x->{NAME} = proto_register_protocol($name, \"$short_name\", \"$filter_name\");";
+
+ pidl_code "proto_register_field_array(proto_dcerpc_$x->{NAME}, hf, array_length (hf));";
+ pidl_code "proto_register_subtree_array(ett, array_length(ett));";
+ } else {
+ pidl_code "proto_dcerpc = proto_get_id_by_filter_name(\"dcerpc\");";
+ pidl_code "proto_register_field_array(proto_dcerpc, hf, array_length(hf));";
+ pidl_code "proto_register_subtree_array(ett, array_length(ett));";
+ }
+
+ deindent;
+ pidl_code "}\n";
+}
+
+sub RegisterInterfaceHandoff($)
+{
+ my $x = shift;
+ pidl_code "void proto_reg_handoff_dcerpc_pidl_$x->{NAME}(void)";
+ pidl_code "{";
+ indent;
+ pidl_code "dcerpc_init_uuid(proto_dcerpc_$x->{NAME}, ett_dcerpc_$x->{NAME},";
+ pidl_code "\t&uuid_dcerpc_$x->{NAME}, ver_dcerpc_$x->{NAME},";
+ pidl_code "\t$x->{NAME}_dissectors, hf_$x->{NAME}_opnum);";
+ deindent;
+ pidl_code "}";
+}
+
+sub ProcessInterface($)
+{
+ my $x = shift;
+
+ %res = (code=>"",def=>"",hdr=>"");
+
+ if (defined($x->{UUID})) {
+ my $if_uuid = $x->{UUID};
+
+ pidl_def "static e_uuid_t uuid_dcerpc_$x->{NAME} = {";
+ pidl_def "\t0x" . substr($if_uuid, 1, 8)
+ . ", 0x" . substr($if_uuid, 10, 4)
+ . ", 0x" . substr($if_uuid, 15, 4) . ",";
+ pidl_def "\t{ 0x" . substr($if_uuid, 20, 2)
+ . ", 0x" . substr($if_uuid, 22, 2)
+ . ", 0x" . substr($if_uuid, 25, 2)
+ . ", 0x" . substr($if_uuid, 27, 2)
+ . ", 0x" . substr($if_uuid, 29, 2)
+ . ", 0x" . substr($if_uuid, 31, 2)
+ . ", 0x" . substr($if_uuid, 33, 2)
+ . ", 0x" . substr($if_uuid, 35, 2) . " }";
+ pidl_def "};\n";
+
+ pidl_def "static guint16 ver_dcerpc_$x->{NAME} = $x->{VERSION};";
+ }
+
+ Interface($x);
+
+ $res{functiontable} = DumpFunctionTable($x->{NAME});
+
+ RegisterInterface($x);
+ RegisterInterfaceHandoff($x);
+}
+
+#####################################################################
+# Generate ethereal parser and header code
+sub Parse($$$)
+{
+ my($ndr,$module,$filename) = @_;
+
+ $tabs = "";
+ my $h_filename = $filename;
+
+ if ($h_filename =~ /(.*)\.c/) {
+ $h_filename = "$1.h";
+ }
+
+ pidl_code "/* parser auto-generated by pidl */";
+ pidl_code "#include \"packet-dcerpc.h\"";
+ pidl_code "#include \"$h_filename\"";
+ pidl_code "";
+ pidl_code "static int hf_ptr = -1;";
+ pidl_code "static int hf_array_size = -1;";
+ pidl_code "";
+
+ # Ethereal protocol registration
+
+ ProcessInterface($_) foreach (@$ndr);
+
+ $res{ett} = DumpEttDeclaration();
+ $res{hf} = DumpHfDeclaration();
+
+ my $parser = $res{ett}.$res{hf}.$res{def}.$res{code};
+ my $header = $res{hdr};
+
+ return ($parser,$header);
+}
+
+###############################################################################
+# ETT
+###############################################################################
+
+my @ett = ();
+
+sub register_ett($)
+{
+ my $name = shift;
+
+ push (@ett, $name);
+}
+
+sub DumpEttList()
+{
+ my $res = "\tstatic gint *ett[] = {\n";
+ foreach (@ett) {
+ $res = "\t\t&$_,\n";
+ }
+
+ return "$res\t};\n";
+}
+
+sub DumpEttDeclaration()
+{
+ my $res = "";
+ foreach (@ett) {
+ $res .= "static gint $_ = -1;\n";
+ }
+
+ return $res;
+}
+
+###############################################################################
+# HF
+###############################################################################
+
+my %hf = ();
+
+sub register_hf_field($$$$$$$$)
+{
+ my ($index,$name,$filter_name,$ft_type,$base_type,$valsstring,$mask,$fixme) = @_;
+
+ $hf{$index} = {
+ INDEX => $index,
+ NAME => $name,
+ FILTER => $filter_name,
+ FT_TYPE => $ft_type,
+ BASE_TYPE => $base_type,
+ VALS => $valsstring,
+ MASK => $mask
+ };
+}
+
+sub DumpHfDeclaration()
+{
+ my $res = "";
+
+ foreach (keys %hf)
+ {
+ $res .= "static gint $_ = -1;\n";
+ }
+
+ return $res;
+}
+
+sub DumpHfList()
+{
+ my $res = "\tstatic hf_register_info hf[] = {\n";
+
+ foreach (values %hf)
+ {
+ $res .= "\t{ &$_->{INDEX},
+ { \"$_->{NAME}\", \"$_->{FILTER}\", $_->{FT_TYPE}, $_->{BASE_TYPE}, $_->{VALS}, $_->{MASK}, FIXME, HFILL }},
+";
+ }
+
+ return $res."\t};\n";
+}
+
+
+###############################################################################
+# Function table
+###############################################################################
+
+my %functions = ();
+
+sub register_function($$$$$)
+{
+ my ($ifname, $opcode, $name, $req, $repl) = @_;
+
+ $functions{$ifname}->{$name} = {
+ NAME => $name,
+ OPCODE => $opcode,
+ REQUEST_FUNC => $req,
+ REPLY_FUNC => $repl
+ };
+}
+
+sub DumpFunctionTable($)
+{
+ my $name = shift;
+
+ my $res = "static dcerpc_sub_dissector $name\_dissectors[] = {\n";
+
+ foreach (values %{$functions{$name}}) {
+ $res.= "\t{ $_->{OPCODE}, \"$_->{NAME},\n";
+ $res.= "\t $_->{REQUEST_FUNC}, $_->{REPLY_FUNC} },\n";
+ }
+
+ $res .= "\t{ 0, NULL, NULL, NULL },\n";
+
+ return "$res\t}\n";
+}
+
+
+1;
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Header.pm b/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Header.pm
deleted file mode 100644
index 6fcf949811..0000000000
--- a/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Header.pm
+++ /dev/null
@@ -1,103 +0,0 @@
-###################################################
-# create C header files for an IDL structure
-# Copyright tridge@samba.org 2000
-# Copyright jelmer@samba.org 2005
-# released under the GNU GPL
-
-package Parse::Pidl::Ethereal::NDR::Header;
-
-use strict;
-
-use Parse::Pidl::Util qw(has_property);
-
-my($res);
-my($tab_depth);
-
-sub pidl ($)
-{
- $res .= shift;
-}
-
-sub tabs()
-{
- for (my($i)=0; $i < $tab_depth; $i++) {
- pidl "\t";
- }
-}
-
-#####################################################################
-# prototype a typedef
-sub HeaderTypedefProto($)
-{
- my($d) = shift;
-
- my $tf = Parse::Pidl::Ethereal::NDR::Parser::get_typefamily($d->{DATA}{TYPE});
-
- return unless has_property($d, "public");
-
- unless (has_property($d, "nopull")) {
- pidl "dcerpc_dissect_fnct_t $d->{NAME};\n";
- }
-}
-
-#####################################################################
-# parse a const
-sub HeaderConst($)
-{
- my($const) = shift;
- if (!defined($const->{ARRAY_LEN}[0])) {
- pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
- } else {
- pidl "#define $const->{NAME}\t $const->{VALUE}\n";
- }
-}
-
-my %headerstructs = ();
-
-#####################################################################
-# parse the interface definitions
-sub HeaderInterface($)
-{
- my($interface) = shift;
-
- my $count = 0;
-
- pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
- pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
-
- if (defined $interface->{PROPERTIES}->{depends}) {
- my @d = split / /, $interface->{PROPERTIES}->{depends};
- foreach my $i (@d) {
- pidl "#include \"packet-dcerpc-$i\.h\"\n";
- }
- }
-
- foreach my $d (@{$interface->{CONSTS}}) {
- HeaderConst($d);
- }
-
- foreach my $d (@{$interface->{TYPEDEFS}}) {
- HeaderTypedefProto($d);
- }
-
- pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
-}
-
-#####################################################################
-# parse a parsed IDL into a C header
-sub Parse($)
-{
- my($idl) = shift;
- $tab_depth = 0;
-
- $res = "";
- pidl "/* header auto-generated by pidl */\n\n";
- foreach my $x (@{$idl}) {
- if ($x->{TYPE} eq "INTERFACE") {
- HeaderInterface($x);
- }
- }
- return $res;
-}
-
-1;
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Parser.pm b/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Parser.pm
deleted file mode 100644
index 1038a64b42..0000000000
--- a/source4/build/pidl/Parse/Pidl/Ethereal/NDR/Parser.pm
+++ /dev/null
@@ -1,1324 +0,0 @@
-##################################################
-# Samba4 NDR parser generator for IDL structures
-# Copyright tridge@samba.org 2000-2003
-# Copyright tpot@samba.org 2001
-# Copyright jelmer@samba.org 2004-2005
-# released under the GNU GPL
-
-package Parse::Pidl::Ethereal::NDR::Parser;
-
-use strict;
-use Parse::Pidl::Typelist;
-use Parse::Pidl::Util qw(has_property ParseExpr);
-use Parse::Pidl::NDR;
-
-# the list of needed functions
-
-# list of known types
-my %typefamily;
-
-
-sub NeededFunction($$)
-{
- my $fn = shift;
- my $needed = shift;
- $needed->{"pull_$fn->{NAME}"} = 1;
- foreach my $e (@{$fn->{ELEMENTS}}) {
- $e->{PARENT} = $fn;
- unless(defined($needed->{"pull_$e->{TYPE}"})) {
- $needed->{"pull_$e->{TYPE}"} = 1;
- }
-
- # for Ethereal
- $needed->{"hf_$fn->{NAME}_$e->{NAME}"} = {
- 'name' => field2name($e->{NAME}),
- 'type' => $e->{TYPE},
- 'ft' => type2ft($e->{TYPE}),
- 'base' => elementbase($e)
- };
- $needed->{"hf_$e->{TYPE}"} = {
- 'name' => field2name($e->{NAME}),
- 'type' => $e->{TYPE},
- 'ft' => type2ft($e->{TYPE}),
- 'base' => elementbase($e)
- };
- $needed->{"ett_$e->{TYPE}"} = 1;
- }
-
- # Add entry for return value
- if (defined($fn->{RETURN_TYPE})) {
- $needed->{"hf_$fn->{NAME}_result"} = {
- 'name' => field2name('result'),
- 'type' => $fn->{RETURN_TYPE},
- 'ft' => type2ft($fn->{RETURN_TYPE}),
- 'base' => elementbase($fn)
- };
- }
-}
-
-sub NeededTypedef($$)
-{
- my $t = shift;
- my $needed = shift;
-
- if (has_property($t, "public")) {
- $needed->{"pull_$t->{NAME}"} = not has_property($t, "nopull");
- $needed->{"decl_$t->{NAME}"} = not has_property($t, "nopull");
- }
-
- if ($t->{DATA}->{TYPE} eq "STRUCT" or $t->{DATA}->{TYPE} eq "UNION") {
-
- for my $e (@{$t->{DATA}->{ELEMENTS}}) {
- $e->{PARENT} = $t->{DATA};
- if ($needed->{"pull_$t->{NAME}"} and
- not defined($needed->{"pull_$e->{TYPE}"})) {
- $needed->{"decl_$e->{TYPE}"} = $needed->{"pull_$e->{TYPE}"} = 1;
- }
-
- $needed->{"hf_$t->{NAME}_$e->{NAME}"} = {
- 'name' => field2name($e->{NAME}),
- 'type' => $e->{TYPE},
- 'ft' => type2ft($e->{TYPE}),
- 'base' => elementbase($e)
- };
- $needed->{"ett_$e->{TYPE}"} = 1;
- }
- }
-
- if ($t->{DATA}->{TYPE} eq "ENUM") {
-
- $needed->{"hf_$t->{NAME}"} = {
- 'name' => field2name($t->{NAME}),
- 'ft' => 'FT_UINT16',
- 'base' => 'BASE_DEC',
- 'strings' => "VALS($t->{NAME}_vals)"
- };
- $needed->{"ett_$t->{NAME}"} = 1;
- }
-
- if ($t->{DATA}->{TYPE} eq "BITMAP") {
- $needed->{BITMAPS}->{$t->{NAME}} = $t;
-
- foreach my $e (@{$t->{DATA}{ELEMENTS}}) {
- $e =~ /^(.*?) \( (.*?) \)$/;
- $needed->{"hf_$t->{NAME}_$1"} = {
- 'name' => "$1",
- 'ft' => "FT_BOOLEAN",
- 'base' => bitmapbase($t),
- 'bitmask' => "$2"
- };
- }
- $needed->{"ett_$t->{NAME}"} = 1;
- }
-}
-
-#####################################################################
-# work out what parse functions are needed
-sub NeededInterface($)
-{
- my($interface) = shift;
- my %needed = ();
-
- $needed{"hf_$interface->{NAME}_opnum"} = {
- 'name' => "Operation",
- 'ft' => "FT_UINT16",
- 'base' => "BASE_DEC"
- };
-
- $needed{"ett_dcerpc_$interface->{NAME}"} = 1;
-
- foreach my $d (@{$interface->{FUNCTIONS}}) {
- NeededFunction($d, \%needed);
- }
- foreach my $d (reverse @{$interface->{TYPEDEFS}}) {
- NeededTypedef($d, \%needed);
- }
-
- return \%needed;
-}
-
-sub type2ft($)
-{
- my($t) = shift;
-
- return "FT_UINT$1" if $t =~ /uint(8|16|32|64)/;
- return "FT_INT$1" if $t =~ /int(8|16|32|64)/;
- return "FT_UINT64", if $t eq "HYPER_T" or $t eq "NTTIME"
- or $t eq "NTTIME_1sec" or $t eq "NTTIME_hyper" or $t eq "hyper";
-
- # Type is an enum
-
- return "FT_UINT16";
-}
-
-# Determine the display base for an element
-
-sub elementbase($)
-{
- my($e) = shift;
-
- if (my $base = has_property($e, "display")) {
- return "BASE_" . uc($base);
- }
-
- return "BASE_DEC", if $e->{TYPE} eq "ENUM";
- return "BASE_DEC", if $e->{TYPE} =~ /u?int(8|16|32|64)/;
- return "BASE_DEC", if $e->{TYPE} eq "NTTIME" or $e->{TYPE} eq "HYPER_T";
-
- # Probably an enum
-
- return "BASE_DEC";
-}
-
-# Convert a IDL structure field name (e.g access_mask) to a prettier
-# string like 'Access Mask'.
-
-sub field2name($)
-{
- my($field) = shift;
-
- $field =~ s/_/ /g; # Replace underscores with spaces
- $field =~ s/(\w+)/\u\L$1/g; # Capitalise each word
-
- return $field;
-}
-
-sub bitmapbase($)
-{
- my $e = shift;
-
- return "16", if has_property($e->{DATA}, "bitmap16bit");
- return "8", if has_property($e->{DATA}, "bitmap8bit");
-
- return "32";
-}
-
-sub get_typefamily($)
-{
- my $n = shift;
- return $typefamily{$n};
-}
-
-sub append_prefix($$)
-{
- my $e = shift;
- my $var_name = shift;
- my $pointers = 0;
-
- foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER") {
- $pointers++;
- } elsif ($l->{TYPE} eq "ARRAY") {
- if (($pointers == 0) and
- (not $l->{IS_FIXED}) and
- (not $l->{IS_INLINE})) {
- return get_value_of($var_name)
- }
- } elsif ($l->{TYPE} eq "DATA") {
- if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
- return get_value_of($var_name) unless ($pointers);
- }
- }
- }
-
- return $var_name;
-}
-
-# see if a variable needs to be allocated by the NDR subsystem on pull
-sub need_alloc($)
-{
- my $e = shift;
-
- return 0;
-}
-
-sub get_pointer_to($)
-{
- my $var_name = shift;
-
- if ($var_name =~ /^\*(.*)$/) {
- return $1;
- } elsif ($var_name =~ /^\&(.*)$/) {
- return $var_name;
-# return "&($var_name)";
- } else {
- return "&$var_name";
- }
-}
-
-sub get_value_of($)
-{
- my $var_name = shift;
-
- if ($var_name =~ /^\&(.*)$/) {
- return $1;
- } else {
- return "*$var_name";
- }
-}
-
-my $res;
-my $tabs = "";
-sub pidl($)
-{
- my $d = shift;
- if ($d) {
- $res .= $tabs;
- $res .= $d;
- }
- $res .="\n";
-}
-
-sub indent()
-{
- $tabs .= "\t";
-}
-
-sub deindent()
-{
- $tabs = substr($tabs, 0, -1);
-}
-
-#####################################################################
-# check that a variable we get from ParseExpr isn't a null pointer
-sub check_null_pointer($)
-{
- my $size = shift;
- if ($size =~ /^\*/) {
- my $size2 = substr($size, 1);
- pidl "if ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;";
- }
-}
-
-#####################################################################
-# check that a variable we get from ParseExpr isn't a null pointer
-# void return varient
-sub check_null_pointer_void($)
-{
- my $size = shift;
- if ($size =~ /^\*/) {
- my $size2 = substr($size, 1);
- pidl "if ($size2 == NULL) return;";
- }
-}
-
-#####################################################################
-# work out is a parse function should be declared static or not
-sub fn_prefix($)
-{
- my $fn = shift;
-
- return "" if (has_property($fn, "public"));
- return "static ";
-}
-
-###################################################################
-# setup any special flags for an element or structure
-sub start_flags($)
-{
- my $e = shift;
- my $flags = has_property($e, "flag");
- if (defined $flags) {
- pidl "{ uint32_t _flags_save_$e->{TYPE} = ndr->flags;";
- pidl "ndr_set_flags(&ndr->flags, $flags);";
- indent;
- }
-}
-
-###################################################################
-# end any special flags for an element or structure
-sub end_flags($)
-{
- my $e = shift;
- my $flags = has_property($e, "flag");
- if (defined $flags) {
- pidl "ndr->flags = _flags_save_$e->{TYPE};\n\t}";
- deindent;
- }
-}
-
-sub GenerateStructEnv($)
-{
- my $x = shift;
- my %env;
-
- foreach my $e (@{$x->{ELEMENTS}}) {
- $env{$e->{NAME}} = "r->$e->{NAME}";
- }
-
- $env{"this"} = "r";
-
- return \%env;
-}
-
-sub GenerateFunctionEnv($)
-{
- my $fn = shift;
- my %env;
-
- foreach my $e (@{$fn->{ELEMENTS}}) {
- if (grep (/out/, @{$e->{DIRECTION}})) {
- $env{$e->{NAME}} = "r->out.$e->{NAME}";
- }
- if (grep (/in/, @{$e->{DIRECTION}})) {
- $env{$e->{NAME}} = "r->in.$e->{NAME}";
- }
- }
-
- return \%env;
-}
-
-#####################################################################
-sub ParseArrayPreceding($$$)
-{
- my $e = shift;
- my $l = shift;
- my $var_name = shift;
-
- return if ($l->{NO_METADATA});
-
- # non fixed arrays encode the size just before the array
- pidl "ndr_pull_array_size(ndr, tree, " . get_pointer_to($var_name) . ");";
-}
-
-sub compression_alg($$)
-{
- my $e = shift;
- my $l = shift;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
-
- return $alg;
-}
-
-sub compression_clen($$$)
-{
- my $e = shift;
- my $l = shift;
- my $env = shift;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
-
- return ParseExpr($clen, $env);
-}
-
-sub compression_dlen($$$)
-{
- my $e = shift;
- my $l = shift;
- my $env = shift;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
-
- return ParseExpr($dlen, $env);
-}
-
-sub ParseCompressionStart($$$$)
-{
- my $e = shift;
- my $l = shift;
- my $subndr = shift;
- my $env = shift;
- my $comndr = $subndr."_compressed";
- my $alg = compression_alg($e, $l);
- my $dlen = compression_dlen($e, $l, $env);
-
- pidl "{";
- indent;
- pidl "struct pidl_pull *$comndr;";
- pidl "NDR_ALLOC($subndr, $comndr);";
- pidl "ndr_pull_compression($subndr, $comndr, $alg, $dlen);";
-
- return $comndr;
-}
-
-sub ParseCompressionEnd($$$)
-{
- my $e = shift;
- my $l = shift;
- my $subndr = shift;
- my $comndr = $subndr."_compressed";
-
- deindent;
- pidl "}";
-}
-
-sub ParseObfuscationStart($$)
-{
- my $e = shift;
- my $ndr = shift;
- my $obfuscation = has_property($e, "obfuscation");
-
- pidl "ndr_pull_obfuscation($ndr, $obfuscation);";
-
- return $ndr;
-}
-
-sub ParseObfuscationEnd($$)
-{
- my $e = shift;
- my $ndr = shift;
-
- # nothing to do here
-}
-
-sub ParseSubcontextStart($$$$$$)
-{
- my $e = shift;
- my $l = shift;
- my $ndr = shift;
- my $var_name = shift;
- my $ndr_flags = shift;
- my $env = shift;
- my $retndr = "_ndr_$e->{NAME}";
-
- pidl "/* NDR_FLAGS $ndr_flags */";
- pidl "if ((ndr_flags) & NDR_SCALARS) {";
- indent;
- pidl "struct pidl_pull *$retndr;";
- pidl "NDR_ALLOC(ndr, $retndr);";
- pidl "ndr_pull_subcontext_header($ndr, $l->{HEADER_SIZE}, $l->{SUBCONTEXT_SIZE}, $retndr);";
-
- if (defined $l->{COMPRESSION}) {
- $retndr = ParseCompressionStart($e, $l, $retndr, $env);
- }
-
- if (defined $l->{OBFUSCATION}) {
- $retndr = ParseObfuscationStart($e, $retndr);
- }
-
- return ($retndr,$var_name);
-}
-
-sub ParseSubcontextEnd($$)
-{
- my $e = shift;
- my $l = shift;
- my $ndr = "_ndr_$e->{NAME}";
-
- if (defined $l->{COMPRESSION}) {
- ParseCompressionEnd($e, $l, $ndr);
- }
-
- if (defined $l->{OBFUSCATION}) {
- ParseObfuscationEnd($e, $ndr);
- }
-
- my $advance;
- if (defined($l->{SUBCONTEXT_SIZE}) and ($l->{SUBCONTEXT_SIZE} ne "-1")) {
- $advance = $l->{SUBCONTEXT_SIZE};
- } elsif ($l->{HEADER_SIZE}) {
- $advance = "$ndr->data_size";
- } else {
- $advance = "$ndr->offset";
- }
- pidl "ndr_pull_advance(ndr, $advance);";
- deindent;
- pidl "}";
-}
-
-#####################################################################
-# parse scalars in a structure element - pull size
-sub ParseSwitch($$$$$$)
-{
- my($e) = shift;
- my $l = shift;
- my $ndr = shift;
- my($var_name) = shift;
- my($ndr_flags) = shift;
- my $env = shift;
- my $switch_var = ParseExpr($l->{SWITCH_IS}, $env);
-
- check_null_pointer($switch_var);
-
- $var_name = get_pointer_to($var_name);
- pidl "ndr_pull_set_switch_value($ndr, $var_name, $switch_var);";
-
-}
-
-sub ParseData($$$$$)
-{
- my $e = shift;
- my $l = shift;
- my $ndr = shift;
- my $var_name = shift;
- my $ndr_flags = shift;
-
- #
- # ALAND! for packet-dcerpc-lsa.c, uncommenting this code
- # produces constructs like &(&r->string), to pass to another
- # function, which gives compiler errors.
- #
- if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
- $var_name = get_pointer_to($var_name);
- }
-
- $var_name = get_pointer_to($var_name);
-
- pidl "offset += dissect_$l->{DATA_TYPE}(tvb, offset, pinfo, tree, drep, hf_FIXME, NULL);";
-
- if (my $range = has_property($e, "range")) {
- $var_name = get_value_of($var_name);
- my ($low, $high) = split(/ /, $range, 2);
- if (($l->{DATA_TYPE} =~ /^uint/) and ($low eq "0")) {
- pidl "if ($var_name > $high) {";
- } else {
- pidl "if ($var_name < $low || $var_name > $high) {";
- }
- pidl "\treturn NT_STATUS_OK;";
- pidl "}";
- }
-}
-
-sub CalcNdrFlags($$$)
-{
- my $l = shift;
- my $primitives = shift;
- my $deferred = shift;
-
- my $scalars = 0;
- my $buffers = 0;
-
- # Add NDR_SCALARS if this one is deferred
- # and deferreds may be pushed
- $scalars = 1 if ($l->{IS_DEFERRED} and $deferred);
-
- # Add NDR_SCALARS if this one is not deferred and
- # primitives may be pushed
- $scalars = 1 if (!$l->{IS_DEFERRED} and $primitives);
-
- # Add NDR_BUFFERS if this one contains deferred stuff
- # and deferreds may be pushed
- $buffers = 1 if ($l->{CONTAINS_DEFERRED} and $deferred);
-
- return "NDR_SCALARS|NDR_BUFFERS" if ($scalars and $buffers);
- return "NDR_SCALARS" if ($scalars);
- return "NDR_BUFFERS" if ($buffers);
- return undef;
-}
-
-
-sub ParseElementLevel
-{
- my($e) = shift;
- my $l = shift;
- my $ndr = shift;
- my($var_name) = shift;
- my $env = shift;
- my $primitives = shift;
- my $deferred = shift;
-
- my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
-
- # Only pull something if there's actually something to be pulled
- if (defined($ndr_flags)) {
- if ($l->{TYPE} eq "SUBCONTEXT") {
- ($ndr,$var_name) = ParseSubcontextStart($e, $l, $ndr, $var_name, $ndr_flags, $env);
- ParseElementLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
- ParseSubcontextEnd($e, $l);
- } elsif ($l->{TYPE} eq "ARRAY") {
- my $length = ParseArrayHeader($e, $l, $ndr, $var_name, $env);
- } elsif ($l->{TYPE} eq "POINTER") {
- ParsePtr($e, $l, $ndr, $var_name);
- } elsif ($l->{TYPE} eq "SWITCH") {
- ParseSwitch($e, $l, $ndr, $var_name, $ndr_flags, $env);
- } elsif ($l->{TYPE} eq "DATA") {
- ParseData($e, $l, $ndr, $var_name, $ndr_flags);
- }
- }
-
- # add additional constructions
- if ($l->{TYPE} eq "POINTER" and $deferred) {
- if ($l->{POINTER_TYPE} ne "ref") {
- pidl "if ($var_name) {";
- indent;
-
- if ($l->{POINTER_TYPE} eq "relative") {
- pidl "struct ndr_pull_save _relative_save;";
- pidl "ndr_pull_save(ndr, &_relative_save);";
- pidl "NDR_CHECK(ndr_pull_relative_ptr2(ndr, $var_name));";
- }
- }
-
- $var_name = get_value_of($var_name);
- ParseElementLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
-
- if ($l->{POINTER_TYPE} ne "ref") {
- if ($l->{POINTER_TYPE} eq "relative") {
- pidl "ndr_pull_restore(ndr, &_relative_save);";
- }
- deindent;
- pidl "}";
- }
- } elsif ($l->{TYPE} eq "ARRAY") {
- my $length = ParseExpr($l->{LENGTH_IS}, $env);
- my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
-
- $var_name = $var_name . "[$counter]";
- unless ($l->{NO_METADATA}) {
- $var_name = get_pointer_to($var_name);
- }
-
- if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
- pidl "for ($counter = 0; $counter < $length; $counter++) {";
- indent;
- ParseElementLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 0);
- deindent;
- pidl "}";
- }
-
- if ($deferred and Ndr::ContainsDeferred($e, $l)) {
- pidl "for ($counter = 0; $counter < $length; $counter++) {";
- indent;
- ParseElementLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);
- deindent;
- pidl "}";
- }
- } elsif ($l->{TYPE} eq "SWITCH") {
- ParseElementLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
- }
-}
-
-#####################################################################
-# parse scalars in a structure element - pull size
-sub ParseElement($$$$$$)
-{
- my($e) = shift;
- my $ndr = shift;
- my($var_prefix) = shift;
- my $env = shift;
- my $primitives = shift;
- my $deferred = shift;
-
- my $var_name = $var_prefix.$e->{NAME};
-
- $var_name = append_prefix($e, $var_name);
-
- return unless $primitives or ($deferred and Ndr::ContainsDeferred($e, $e->{LEVELS}[0]));
-
- start_flags($e);
-
- ParseElementLevel($e,$e->{LEVELS}[0],$ndr,$var_name,$env,$primitives,$deferred);
-
- end_flags($e);
-}
-
-#####################################################################
-# parse a pointer in a struct element or function
-sub ParsePtr($$$$)
-{
- my($e) = shift;
- my $l = shift;
- my $ndr = shift;
- my($var_name) = shift;
-
- my $nl = Ndr::GetNextLevel($e, $l);
- my $next_is_array = ($nl->{TYPE} eq "ARRAY");
-
- if ($l->{LEVEL} eq "EMBEDDED") {
- pidl "dissect_ndr_embedded_pointer(FIXME);";
- } elsif ($l->{POINTER_TYPE} ne "ref") {
- pidl "dissect_ndr_toplevel_pointer(FIXME);";
- }
-
- #pidl "memset($var_name, 0, sizeof($var_name));";
- if ($l->{POINTER_TYPE} eq "relative") {
- pidl "ndr_pull_relative_ptr1($ndr, $var_name, _ptr_$e->{NAME});";
- }
-}
-
-$typefamily{ENUM} = {
- DECL => \&DeclEnum,
-};
-
-#####################################################################
-# generate a pull function for an bitmap
-sub ParseBitmap($$)
-{
- my($bitmap) = shift;
- my $name = shift;
- my $type_fn = $bitmap->{BASE_TYPE};
- my($type_decl) = typelist::mapType($bitmap->{BASE_TYPE});
-
- pidl "$type_decl v_bitmap;";
- start_flags($bitmap);
- pidl "dissect_$type_fn(ndr, tree, hf, &v_bitmap);";
-
- pidl "{\n\tproto_tree *subtree = NULL;";
- pidl "";
- pidl "\tif (tree->proto_tree)\n\t\tsubtree = proto_item_add_subtree(tree->proto_tree->last_child, ett_$name);";
- pidl "";
- foreach my $e (@{$bitmap->{DATA}{ELEMENTS}}) {
- $e =~ /^(.*?) \( (.*?) \)$/;
- pidl "\tproto_tree_add_boolean(subtree, hf_${name}_$1, ndr->tvb, ndr->offset - sizeof(v_bitmap), sizeof(v_bitmap), v_bitmap);";
- }
- pidl "}";
-
- pidl "*r = v_bitmap;";
-
- end_flags($bitmap);
-}
-
-$typefamily{BITMAP} = {
- FN_BODY => \&ParseBitmap,
-};
-
-#####################################################################
-# parse a struct - pull side
-sub ParseStruct($$)
-{
- my($struct) = shift;
- my $name = shift;
- my $conform_e;
-
- return unless defined $struct->{ELEMENTS};
-
- my $env = GenerateStructEnv($struct);
-
- # see if the structure contains a conformant array. If it
- # does, then it must be the last element of the structure, and
- # we need to pull the conformant length early, as it fits on
- # the wire before the structure (and even before the structure
- # alignment)
- $conform_e = $struct->{SURROUNDING_ELEMENT};
-
- # declare any internal pointers we need
- foreach my $e (@{$struct->{ELEMENTS}}) {
- foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER" and not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) {
- pidl "uint32_t _ptr_$e->{NAME};";
- last;
- }
- }
- }
-
- start_flags($struct);
-
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
-
- if (defined $conform_e) {
- ParseArrayPreceding($conform_e, $conform_e->{LEVELS}[0], "r->$conform_e->{NAME}");
- }
-
- pidl "ndr_pull_align(ndr, $struct->{ALIGN});";
-
- foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElement($e, "ndr", "r->", $env, 1, 0);
- }
- deindent;
- pidl "}";
-
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
- foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElement($e, "ndr", "r->", $env, 0, 0);
- }
-
- pidl "proto_item_set_end(tree->proto_tree, ndr->tvb, ndr->offset);";
- deindent;
- pidl "}";
-
- end_flags($struct);
-}
-
-$typefamily{STRUCT} = {
- FN_BODY => \&ParseStruct,
-};
-
-#####################################################################
-# parse a union - pull side
-sub ParseUnion($$$)
-{
- my $e = shift;
- my $name = shift;
- my $have_default = 0;
- my $switch_type = $e->{SWITCH_TYPE};
-
- pidl "int level;";
- if (defined($switch_type)) {
- if (typelist::typeIs($switch_type, "ENUM")) {
- $switch_type = typelist::enum_type_fn(typelist::getType($switch_type));
- }
- pidl typelist::mapType($switch_type) . " _level;";
- }
-
- start_flags($e);
-
- pidl "level = ndr_pull_get_switch_value(ndr, r);";
-
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
-
- if (defined($switch_type)) {
- pidl "ndr_pull_$switch_type(ndr, tree, hf_${name}, &_level);";
- pidl "if (_level != level) {";
- pidl "\treturn NT_STATUS_OK;";
- pidl "}";
- }
-
-# my $align = union_alignment($e);
-# pidl "\tndr_pull_align(ndr, $align);\n";
-
- pidl "switch (level) {";
- indent;
- foreach my $el (@{$e->{ELEMENTS}}) {
- if ($el->{CASE} eq "default") {
- $have_default = 1;
- }
- pidl "$el->{CASE}: {";
-
- if ($el->{TYPE} ne "EMPTY") {
- indent;
- foreach my $l (@{$el->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER" and not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) {
- pidl "uint32_t _ptr_$el->{NAME};";
- last;
- }
- }
- ParseElement($el, "ndr", "r->", {}, 1, 0);
- deindent;
- }
- pidl "break; }";
- pidl "";
- }
- if (! $have_default) {
- pidl "default:";
- pidl "\treturn NT_STATUS_OK;";
- }
- deindent;
- pidl "}";
- deindent;
- pidl "}";
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
- pidl "switch (level) {";
- indent;
- foreach my $el (@{$e->{ELEMENTS}}) {
- pidl "$el->{CASE}:";
- if ($el->{TYPE} ne "EMPTY") {
- indent;
- ParseElement($el, "ndr", "r->", {}, 0, 1);
- deindent;
- }
- pidl "break;";
- pidl "";
- }
- if (! $have_default) {
- pidl "default:";
- pidl "\treturn NT_STATUS_OK;";
- }
- deindent;
- pidl "}";
- pidl "proto_item_set_end(tree->proto_tree, ndr->tvb, ndr->offset);";
- deindent;
- pidl "}";
- end_flags($e);
-}
-
-$typefamily{UNION} = {
- FN_BODY => \&ParseUnion,
-};
-
-#####################################################################
-# parse an array
-sub ParseArrayHeader($$$$$)
-{
- my $e = shift;
- my $l = shift;
- my $ndr = shift;
- my $var_name = shift;
- my $env = shift;
-
- unless ($l->{NO_METADATA}) {
- $var_name = get_pointer_to($var_name);
- }
-
- # $var_name contains the name of the first argument here
-
- my $length = ParseExpr($l->{SIZE_IS}, $env);
- my $size = $length;
-
- if ($l->{IS_CONFORMANT}) {
- $length = $size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")";
- }
-
- # if this is a conformant array then we use that size to allocate, and make sure
- # we allocate enough to pull the elements
- if (!$l->{IS_SURROUNDING}) {
- ParseArrayPreceding($e, $l, $var_name);
- }
-
-
- if ($l->{IS_VARYING}) {
- pidl "NDR_CHECK(ndr_pull_array_length($ndr, " . get_pointer_to($var_name) . "));";
- $length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
- }
-
- check_null_pointer($length);
-
- if ($length ne $size) {
- pidl "if ($length > $size) {";
- indent;
- pidl "return ndr_pull_error($ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should exceed array length %u\", $size, $length);";
- deindent;
- pidl "}";
- }
-
- if ($l->{IS_CONFORMANT}) {
- my $size = ParseExpr($l->{SIZE_IS}, $env);
- check_null_pointer($size);
- pidl "NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));";
- }
-
- if ($l->{IS_VARYING}) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env);
- check_null_pointer($length);
- pidl "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));";
- }
-
- return $length;
-}
-
-#####################################################################
-# parse a typedef - pull side
-sub ParseTypedef($)
-{
- my($e) = shift;
-
- return unless (defined ($typefamily{$e->{DATA}->{TYPE}}));
-
- pidl fn_prefix($e) . "int dissect_$e->{NAME}(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf_index, guint32 param)";
-
- pidl "{";
- indent;
- $typefamily{$e->{DATA}->{TYPE}}->{FN_BODY}->($e->{DATA}, $e->{NAME});
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
- pidl "";
-}
-
-#####################################################################
-# parse a function
-sub ParseFunctionRqst($)
-{
- my($fn) = shift;
-
- my $env = GenerateFunctionEnv($fn);
-
- # request function
- pidl "static int dissect_$fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)";
- pidl "{";
- indent;
-
- pidl "struct pidl_pull *ndr = pidl_pull_init(tvb, offset, pinfo, drep);";
-
- # declare any internal pointers we need
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless (grep (/in/, @{$e->{DIRECTIONS}}));
- foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER" and
- not ($l->{POINTER_TYPE} eq "ref" and
- $l->{LEVEL} eq "TOP")) {
- pidl "uint32_t _ptr_$e->{NAME};";
- last;
- }
- }
- }
-
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless (grep(/in/, @{$e->{DIRECTION}}));
- ParseElement($e, "ndr", "r->in.", $env, 1, 1);
- }
-
- pidl "return offset;";
- deindent;
- pidl "}";
- pidl "";
-}
-
-sub ParseFunctionResp($)
-{
- my($fn) = shift;
-
- my $env = GenerateFunctionEnv($fn);
-
- # response function
- pidl "static int dissect_$fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)";
- pidl "{";
- indent;
-
- pidl "struct pidl_pull *ndr = pidl_pull_init(tvb, offset, pinfo, drep);";
-
- # declare any internal pointers we need
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless (grep (/out/, @{$e->{DIRECTIONS}}));
- foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER" and
- not ($l->{POINTER_TYPE} eq "ref" and
- $l->{LEVEL} eq "TOP")) {
- pidl "uint32_t _ptr_$e->{NAME};";
- last;
- }
- }
- }
-
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless grep(/out/, @{$e->{DIRECTION}});
- ParseElement($e, "ndr", "r->out.", $env, 1, 1);
- }
-
- if ($fn->{RETURN_TYPE}) {
- pidl "dissect_$fn->{RETURN_TYPE}(ndr, tree, hf_$fn->{NAME}_result, drep);";
- }
-
- pidl "return offset;";
- deindent;
- pidl "}";
- pidl "";
-}
-
-#####################################################################
-# produce a function call table
-sub FunctionTable($)
-{
- my($interface) = shift;
-
- pidl "static dcerpc_sub_dissector dcerpc_dissectors[] = {";
- my $num = 0;
- foreach my $d (@{$interface->{FUNCTIONS}}) {
- # Strip interface name from function name, if present
- my($n) = $d->{NAME};
- $n = substr($d->{NAME}, length($interface->{NAME}) + 1),
- if $interface->{NAME} eq substr($d->{NAME}, 0, length($interface->{NAME}));
- pidl "\t{ $num, \"$n\",";
- pidl "\t\tdissect_$d->{NAME}_rqst,";
- pidl "\t\tdissect_$d->{NAME}_resp },";
- $num++;
- }
- pidl "};\n";
-}
-
-#####################################################################
-# parse the interface definitions
-sub ParseInterface($$)
-{
- my($interface) = shift;
- my $needed = shift;
-
- # Typedefs
- foreach my $d (@{$interface->{TYPEDEFS}}) {
- ($needed->{"pull_$d->{NAME}"}) && ParseTypedef($d);
- # Make sure we don't generate a function twice...
- $needed->{"pull_$d->{NAME}"} = 0;
- }
-
- # Functions
- foreach my $d (@{$interface->{FUNCTIONS}}) {
- if ($needed->{"pull_$d->{NAME}"}) {
- ParseFunctionRqst($d);
- ParseFunctionResp($d);
- }
-
- # Make sure we don't generate a function twice...
- $needed->{"pull_$d->{NAME}"} = 0;
- }
-}
-
-#####################################################################
-# generate code to parse an enum
-sub DeclEnum($$)
-{
- my ($e) = shift;
- my $n = shift;
-
- pidl "static const value_string $n\_vals[] =";
- pidl "{";
-
- foreach my $x (@{$e->{ELEMENTS}}) {
- $x =~ /([^=]*)=(.*)/;
- pidl "\t{ $1, \"$1\" },";
- }
-
- pidl "};\n";
-}
-
-sub DeclInterface($$)
-{
- my($interface) = shift;
- my $needed = shift;
-
- # Typedefs
- foreach my $d (@{$interface->{TYPEDEFS}}) {
- ($needed->{"decl_$d->{NAME}"}) && DeclTypedef($d, $needed);
- }
-}
-
-sub DeclTypedef($$)
-{
- my $e = shift;
- my $needed = shift;
-
- if (defined($typefamily{$e->{DATA}->{TYPE}}->{DECL})) {
- $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e->{DATA}, $e->{NAME});
-
- # Make sure we don't generate a function twice...
- $needed->{"decl_$e->{NAME}"} = 0;
- }
-}
-
-sub RegisterInterface($$)
-{
- my $x = shift;
- my $needed = shift;
-
- pidl "void proto_register_dcerpc_pidl_$x->{NAME}(void)";
- pidl "{";
- indent;
-
- pidl "static hf_register_info hf[] = {";
- pidl "{ &hf_ptr, { \"Pointer\", \"$x->{NAME}.ptr\", FT_UINT32, BASE_HEX, NULL, 0x0, \"Pointer\", HFILL }},";
-
- foreach my $x (sort keys(%{$needed})) {
- next, if !($x =~ /^hf_/);
- pidl "{ &$x,";
- $needed->{$x}->{strings} = "NULL", if !defined($needed->{$x}->{strings});
- $needed->{$x}->{bitmask} = "0", if !defined($needed->{$x}->{bitmask});
- pidl " { \"$needed->{$x}->{name}\", \"$x\", $needed->{$x}->{ft}, $needed->{$x}->{base}, $needed->{$x}->{strings}, $needed->{$x}->{bitmask}, \"$x\", HFILL }},";
- }
-
- pidl "};\n";
-
- pidl "static gint *ett[] = {";
- indent;
- foreach my $x (sort keys(%{$needed})) {
- pidl "&$x,", if $x =~ /^ett_/;
- }
- deindent;
-
- pidl "};\n";
-
- if (defined($x->{UUID})) {
- # These can be changed to non-pidl names if the old dissectors
- # in epan/dissctors are deleted.
-
- my $name = "\"" . uc($x->{NAME}) . " (pidl)\"";
- if (has_property($x, "helpstring")) {
- $name = $x->{PROPERTIES}->{helpstring};
- }
- my $short_name = "pidl_$x->{NAME}";
- my $filter_name = "pidl_$x->{NAME}";
-
- pidl "proto_dcerpc_pidl_$x->{NAME} = proto_register_protocol($name, \"$short_name\", \"$filter_name\");";
-
- pidl "proto_register_field_array(proto_dcerpc_pidl_$x->{NAME}, hf, array_length (hf));";
- pidl "proto_register_subtree_array(ett, array_length(ett));";
- } else {
- pidl "int proto_dcerpc;";
- pidl "proto_dcerpc = proto_get_id_by_filter_name(\"dcerpc\");";
- pidl "proto_register_field_array(proto_dcerpc, hf, array_length(hf));";
- pidl "proto_register_subtree_array(ett, array_length(ett));";
- }
-
- deindent;
- pidl "}\n";
-}
-
-sub RegisterInterfaceHandoff($)
-{
- my $x = shift;
- pidl "void proto_reg_handoff_dcerpc_pidl_$x->{NAME}(void)";
- pidl "{";
- indent;
- pidl "dcerpc_init_uuid(proto_dcerpc_pidl_$x->{NAME}, ett_dcerpc_$x->{NAME},";
- pidl "\t&uuid_dcerpc_$x->{NAME}, ver_dcerpc_$x->{NAME},";
- pidl "\tdcerpc_dissectors, hf_$x->{NAME}_opnum);";
- deindent;
- pidl "}";
-}
-
-sub ProcessInterface($)
-{
- my $x = shift;
- my $needed = NeededInterface($x);
-
- # Required global declarations
- DeclInterface($x, $needed);
-
- foreach my $y (sort keys(%{$needed})) {
- pidl "static int $y = -1;", if $y =~ /^hf_/;
- }
- pidl "";
-
- foreach my $y (sort keys(%{$needed})) {
- pidl "static gint $y = -1;", if $y =~ /^ett_/;
- }
- pidl "";
-
- pidl "int proto_dcerpc_pidl_$x->{NAME} = -1;\n";
-
- if (defined($x->{UUID})) {
- my $if_uuid = $x->{UUID};
-
- pidl "static e_uuid_t uuid_dcerpc_$x->{NAME} = {";
- pidl "\t0x" . substr($if_uuid, 1, 8)
- . ", 0x" . substr($if_uuid, 10, 4)
- . ", 0x" . substr($if_uuid, 15, 4) . ",";
- pidl "\t{ 0x" . substr($if_uuid, 20, 2)
- . ", 0x" . substr($if_uuid, 22, 2)
- . ", 0x" . substr($if_uuid, 25, 2)
- . ", 0x" . substr($if_uuid, 27, 2)
- . ", 0x" . substr($if_uuid, 29, 2)
- . ", 0x" . substr($if_uuid, 31, 2)
- . ", 0x" . substr($if_uuid, 33, 2)
- . ", 0x" . substr($if_uuid, 35, 2) . " }";
- pidl "};\n";
-
- pidl "static guint16 ver_dcerpc_$x->{NAME} = $x->{VERSION};";
- }
-
- # dissect_* functions
- ParseInterface($x, $needed);
-
- # Function call tables
- FunctionTable($x);
-
- RegisterInterface($x, $needed);
- RegisterInterfaceHandoff($x);
-}
-
-#####################################################################
-# parse a parsed IDL structure back into an IDL file
-sub Parse($$$)
-{
- my($ndr) = shift;
- my $module = shift;
- my($filename) = shift;
-
- $tabs = "";
- my $h_filename = $filename;
- $res = "";
-
- if ($h_filename =~ /(.*)\.c/) {
- $h_filename = "$1.h";
- }
-
- pidl "/* parser auto-generated by pidl */";
- pidl "#include \"packet-dcerpc.h\"";
- pidl "#include \"$h_filename\"";
- pidl "";
- pidl "static int hf_ptr = -1;";
- pidl "static int hf_array_size = -1;";
- pidl "";
-
-# print keys %{$needed->{hf_atsvc_JobGetInfo_result}}, "\n";
-
- # Ethereal protocol registration
-
- ProcessInterface($_) foreach (@$ndr);
-
- return $res;
-}
-
-1;
diff --git a/source4/build/pidl/pidl b/source4/build/pidl/pidl
index 699497549a..c24a0a0007 100755
--- a/source4/build/pidl/pidl
+++ b/source4/build/pidl/pidl
@@ -75,7 +75,6 @@ my($opt_ndr_parser);
my($opt_tdr_header);
my($opt_tdr_parser);
my($opt_eth_parser);
-my($opt_eth_header);
my($opt_keep);
my($opt_swig);
my($opt_dcom_proxy);
@@ -111,8 +110,7 @@ Options:
--client[=OUTFILE] create a C NDR client
--server[=OUTFILE] create server boilerplate
--template print a template for a pipe
- --eth-parser[=OUTFILE]create an ethereal parser
- --eth-header[=OUTFILE]create an ethereal header file
+ --eth-parser[=OUTFILE]create ethereal parser and header
--swig[=OUTFILE] create swig wrapper file
--diff run diff on the idl and dumped output
--keep[=OUTFILE] keep the .pidl file
@@ -142,7 +140,6 @@ GetOptions (
'ndr-parser:s' => \$opt_ndr_parser,
'client:s' => \$opt_client,
'eth-parser:s' => \$opt_eth_parser,
- 'eth-header:s' => \$opt_eth_header,
'ejs' => \$opt_ejs,
'diff' => \$opt_diff,
'odl' => \$opt_odl,
@@ -242,9 +239,8 @@ sub process_file($)
}
if (defined($opt_ndr_header) or defined($opt_eth_parser) or
- defined($opt_eth_header) or defined($opt_client) or
- defined($opt_server) or defined($opt_ndr_parser) or
- defined($opt_ejs)) {
+ defined($opt_client) or defined($opt_server) or
+ defined($opt_ndr_parser) or defined($opt_ejs)) {
require Parse::Pidl::NDR;
Parse::Pidl::NDR::Validate($pidl);
$ndr = Parse::Pidl::NDR::Parse($pidl);
@@ -267,13 +263,6 @@ sub process_file($)
}
}
- if (defined($opt_eth_header)) {
- require Parse::Pidl::Ethereal::NDR::Header;
- my($eparserhdr) = ($opt_eth_header or "$outputdir/packet-dcerpc-$basename.h");
-
- FileSave($eparserhdr, Parse::Pidl::Ethereal::NDR::Header::Parse($ndr));
- }
-
my $h_filename = "$outputdir/ndr_$basename.h";
if (defined($opt_client)) {
require Parse::Pidl::Samba::NDR::Client;
@@ -325,9 +314,14 @@ $dcom
}
if (defined($opt_eth_parser)) {
- require Parse::Pidl::Ethereal::NDR::Parser;
+ require Parse::Pidl::Ethereal::NDR;
my($eparser) = ($opt_eth_parser or "$outputdir/packet-dcerpc-$basename.c");
- FileSave($eparser, Parse::Pidl::Ethereal::NDR::Parser::Parse($ndr, $basename, $eparser));
+ my $eheader = $eparser;
+ $eheader =~ s/\.c$/\.h/;
+
+ my ($dp, $dh) = Parse::Pidl::Ethereal::NDR::Parser::Parse($ndr, $basename, $eparser);
+ FileSave($eparser, $dp);
+ FileSave($eheader, $dh);
}
my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c");