diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/build/pidl/eparser.pm | 154 | ||||
-rwxr-xr-x | source4/build/pidl/pidl.pl | 2 |
2 files changed, 148 insertions, 8 deletions
diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm index f32e1b9842..f7d383d297 100644 --- a/source4/build/pidl/eparser.pm +++ b/source4/build/pidl/eparser.pm @@ -10,6 +10,8 @@ use strict; use dump; use Data::Dumper; +my($name); + sub ParamSimpleNdrType($) { my($p) = shift; @@ -25,7 +27,7 @@ sub ParamPolicyHandle($) my($p) = shift; my($res); - $res .= "\toffset = dissect_nt_policy_handle(tvb, offset, pinfo, tree, drep, hf_policy_hnd, NULL, NULL, FALSE, FALSE);\n"; + $res .= "\toffset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep, hf_policy_hnd, NULL, NULL, FALSE, FALSE);\n"; return $res; } @@ -89,7 +91,7 @@ sub ParseFunction($) $res .= ParseParameter($d), if defined($d->{PROPERTIES}{out}); } - + $res .= "\n"; $res .= "\treturn offset;\n"; $res .= "}\n\n"; @@ -98,7 +100,7 @@ sub ParseFunction($) ##################################################################### # parse the interface definitions -sub ParseInterface($) +sub Pass2Interface($) { my($interface) = shift; my($data) = $interface->{DATA}; @@ -111,19 +113,157 @@ sub ParseInterface($) return $res; } +##################################################################### +# Pass 1: Stuff required before structs and functions + +sub Pass1ModuleHeader($) +{ + my($d) = shift; + my($res) = ""; + + $res .= << "EOF"; +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "packet-dcerpc.h" +#include "packet-dcerpc-nt.h" + +EOF + + # UUID + + if ($d->{TYPE} eq "MODULEHEADER" and defined($d->{PROPERTIES}->{uuid})) { + my $uuid = $d->{PROPERTIES}->{uuid}; + $res .= "static e_uuid_t uuid_dcerpc_$name = {\n"; + $res .= "\t0x" . substr($uuid, 0, 8); + $res .= ", 0x" . substr($uuid, 9, 4); + $res .= ", 0x" . substr($uuid, 14, 4) . ",\n"; + $res .= "\t{ 0x" . substr($uuid, 19, 2); + $res .= ", 0x" . substr($uuid, 21, 2); + $res .= ", 0x" . substr($uuid, 24, 2); + $res .= ", 0x" . substr($uuid, 26, 2); + $res .= ", 0x" . substr($uuid, 28, 2); + $res .= ", 0x" . substr($uuid, 30, 2); + $res .= ", 0x" . substr($uuid, 32, 2); + $res .= ", 0x" . substr($uuid, 34, 2) . " }\n"; + $res .= "};\n\n"; + + $res .= "static guint16 ver_dcerpc_samr = " . + $d->{PROPERTIES}->{version} . ";\n\n"; + } + + return $res; +} + +sub Pass1Interface($) +{ + my($interface) = shift; + my($res) = ""; + + $res .= << "EOF"; +static int proto_dcerpc_$name = -1; + +static int hf_${name}_opnum = -1; +static int hf_${name}_rc = -1; +static int hf_policy_hnd = -1; + +static gint ett_dcerpc_$name = -1; + +EOF + + my %p = (); + + foreach my $fn (@{$interface->{DATA}}) { + next, if $fn->{TYPE} ne "FUNCTION"; + foreach my $args ($fn->{DATA}) { + foreach my $params (@{$args}) { + $res .= "static int hf_$params->{NAME} = -1;\n", + if not defined $p{$params->{NAME}}; + $p{$params->{NAME}} = 1; + } + } + } + + $res .= "\n"; + + return $res; +} + +##################################################################### +# Pass 3: trailing stuff + +sub Pass3Interface($) +{ + my($interface) = shift; + my($res) = ""; + + $res .= "static dcerpc_sub_dissector dcerpc_${name}_dissectors[] = {\n"; + + my $num = 0; + + foreach my $d (@{$interface->{DATA}}) { + if ($d->{TYPE} eq "FUNCTION") { + # Strip module name from function name, if present + my $n = $d->{NAME}; + $n = substr($d->{NAME}, length($name) + 1), + if $name eq substr($d->{NAME}, 0, length($name)); + + $res .= "\t{ $num, \"$n\",\n"; + $res .= "\t\t$d->{NAME}_rqst,\n"; + $res .= "\t\t$d->{NAME}_resp },\n"; + $num++; + } + } + + $res .= "};\n\n"; + + return $res; +} ##################################################################### # parse a parsed IDL structure back into an IDL file sub Parse($) { my($idl) = shift; - my($res); + my($res) = "/* parser auto-generated by pidl */\n\n"; + my($d); + + # Pass 0: set module name + + foreach $d (@{$idl}) { + $name = $d->{NAME}, if ($d->{TYPE} eq "INTERFACE"); + } + + # Pass 1: header stuff + + foreach $d (@{$idl}) { + $res .= Pass1ModuleHeader($d), if $d->{TYPE} eq "MODULEHEADER"; + $res .= Pass1Interface($d), if $d->{TYPE} eq "INTERFACE"; + } - $res = "/* parser auto-generated by pidl */\n\n"; - foreach my $d (@{$idl}) { - $res .= ParseInterface($d), if $d->{TYPE} eq "INTERFACE"; + # Pass 2: typedefs and functions + + foreach $d (@{$idl}) { + $res .= Pass2Interface($d), if $d->{TYPE} eq "INTERFACE"; + } + + # Pass 3: trailing stuff + + foreach $d (@{$idl}) { + $res .= Pass3Interface($d), if $d->{TYPE} eq "INTERFACE"; } + $res .= << "EOF"; +void +proto_reg_handoff_dcerpc_$name(void) +{ + dcerpc_init_uuid(proto_dcerpc_$name, ett_dcerpc_$name, + &uuid_dcerpc_$name, ver_dcerpc_$name, + dcerpc_${name}_dissectors, hf_${name}_opnum); +} +EOF + return $res; } diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl index 46585e2ca5..6004ebb145 100755 --- a/source4/build/pidl/pidl.pl +++ b/source4/build/pidl/pidl.pl @@ -144,7 +144,7 @@ sub process_file($) } if ($opt_eparser) { - my($parser) = util::ChangeExtension($output, "_ethereal.c"); + my($parser) = dirname($output) . "/packet-dcerpc-$basename.c"; util::FileSave($parser, IdlEParser::Parse($pidl)); } |