summaryrefslogtreecommitdiff
path: root/source4/build
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-08-06 01:54:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:31:25 -0500
commit97eac1a46a38eb5ae9e9d15caa96d1c3e1fb57dd (patch)
tree500289ea6166dcbc031eb98db6aafcd841d12d70 /source4/build
parent8658136f26488d9e9838afc5f2424b9721bc50db (diff)
downloadsamba-97eac1a46a38eb5ae9e9d15caa96d1c3e1fb57dd.tar.gz
samba-97eac1a46a38eb5ae9e9d15caa96d1c3e1fb57dd.tar.bz2
samba-97eac1a46a38eb5ae9e9d15caa96d1c3e1fb57dd.zip
r9161: More etheral parser generator fixes
(This used to be commit b323e83e8df6ba331b3f0b3abe28aa8ddf9127ef)
Diffstat (limited to 'source4/build')
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm120
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm108
-rwxr-xr-xsource4/build/pidl/pidl4
3 files changed, 137 insertions, 95 deletions
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm b/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
index 910b604158..19c8ff2563 100644
--- a/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
+++ b/source4/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
@@ -8,26 +8,17 @@ package Parse::Pidl::Ethereal::Conformance;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT_OK = qw(EmitProhibited FindDissectorParam %hf_renames %protocols);
+@EXPORT_OK = qw(ReadConformance);
use strict;
use Parse::Pidl::Util qw(has_property);
-sub handle_union_tag_size($$)
+sub handle_type($$$$$$$$)
{
- my ($union,$size) = @_;
+ my ($data,$name,$dissectorname,$ft_type,$base_type,$mask,$valsstring,$alignment) = @_;
- #FIXME
-}
-
-use vars qw(%hf_renames %types %header_fields %protocols);
-
-sub handle_type($$$$$$$)
-{
- my ($name,$dissectorname,$ft_type,$base_type,$mask,$valsstring,$alignment) = @_;
-
- $types{$name} = {
+ $data->{types}->{$name} = {
NAME => $name,
DISSECTOR_NAME => $dissectorname,
FT_TYPE => $ft_type,
@@ -39,27 +30,24 @@ sub handle_type($$$$$$$)
}
-sub handle_hf_rename($$)
+sub handle_hf_rename($$$)
{
- my ($old,$new) = @_;
- $hf_renames{$old} = $new;
+ my ($data,$old,$new) = @_;
+ $data->{hf_renames}{$old} = $new;
}
-my %dissectorparams = ();
-
-sub handle_param_value($$)
+sub handle_param_value($$$)
{
- my ($dissector_name,$value) = @_;
-
- $dissectorparams{$dissector_name} = $value;
+ my ($data,$dissector_name,$value) = @_;
+ $data->{dissectorparams}->{$dissector_name} = $value;
}
-sub handle_hf_field($$$$$$$$)
+sub handle_hf_field($$$$$$$$$)
{
- my ($hf,$title,$filter,$ft_type,$base_type,$valsstring,$mask,$blurb) = @_;
+ my ($data,$hf,$title,$filter,$ft_type,$base_type,$valsstring,$mask,$blurb) = @_;
- $header_fields{$hf} = {
+ $data->{header_fields}->{$hf} = {
HF => $hf,
TITLE => $title,
FILTER => $filter,
@@ -71,42 +59,39 @@ sub handle_hf_field($$$$$$$$)
};
}
-sub handle_strip_prefix($)
+sub handle_strip_prefix($$)
{
- my $x = shift;
- #FIXME
-}
+ my ($data,$x) = @_;
-my @noemit = ();
+ push (@{$data->{strip_prefixes}}, $x);
+}
-sub handle_noemit($)
+sub handle_noemit($$)
{
- my $type = shift;
+ my ($data,$type) = @_;
- push (@noemit, $type);
+ $data->{noemit}->{$type} = 1;
}
-
-sub handle_protocol($$$$)
+sub handle_protocol($$$$$)
{
- my ($name, $longname, $shortname, $filtername) = @_;
+ my ($data, $name, $longname, $shortname, $filtername) = @_;
- $protocols{$name} = {
+ $data->{protocols}->{$name} = {
LONGNAME => $longname,
SHORTNAME => $shortname,
FILTERNAME => $filtername
};
}
-sub handle_fielddescription($$)
+sub handle_fielddescription($$$)
{
- my ($field,$desc) = @_;
+ my ($data,$field,$desc) = @_;
- #FIXME
+ $data->{fielddescription}->{$field} = $desc;
}
my %field_handlers = (
- UNION_TAG_SIZE => \&handle_union_tag_size,
TYPE => \&handle_type,
NOEMIT => \&handle_noemit,
PARAM_VALUE => \&handle_param_value,
@@ -117,40 +102,51 @@ my %field_handlers = (
FIELD_DESCRIPTION => \&handle_fielddescription
);
-sub Parse($)
+sub ReadConformance($$)
{
- my $f = shift;
+ my ($f,$data) = @_;
+
+ $data->{override} = "";
+
+ my $incodeblock = 0;
+
+ open(IN,"<$f") or return undef;
- open(IN,$f) or return undef;
+ my $ln = 0;
foreach (<IN>) {
+ $ln++;
next if (/^#.*$/);
next if (/^$/);
- my @fields = split(/ /);
-
- $field_handlers{$fields[0]}(@fields);
- }
+ s/[\r\n]//g;
- close(IN);
-}
-
-sub EmitProhibited($)
-{
- my $type = shift;
+ if ($_ eq "CODE START") {
+ $incodeblock = 1;
+ next;
+ } elsif ($incodeblock and $_ eq "CODE END") {
+ $incodeblock = 0;
+ next;
+ } elsif ($incodeblock) {
+ $data->{override}.="$_\n";
+ next;
+ }
- return 1 if (grep(/$type/,@noemit));
+ my @fields = split(/ /);
- return 0;
-}
+ my $cmd = $fields[0];
-sub FindDissectorParam($)
-{
- my $type = shift;
+ shift @fields;
- return $dissectorparams{$type} if defined ($dissectorparams{$type});
+ if (not defined($field_handlers{$cmd})) {
+ print "$f:$ln: Warning: Unknown command `$cmd'\n";
+ next;
+ }
+
+ $field_handlers{$cmd}($data, @fields);
+ }
- return 0;
+ close(IN);
}
1;
diff --git a/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm b/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
index 76a83b5ecb..6c6d8c08ef 100644
--- a/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
+++ b/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
@@ -7,11 +7,11 @@
# released under the GNU GPL
# TODO:
-# - order of functions generated per element level
# - subcontexts using tvb_new_subset()
# - fixed arrays
-# - strip prefixes
# - allow overrides in conformance file
+# - more built-in types:
+# sec_desc_buf -> lsa_dissect_sec_desc_buf
package Parse::Pidl::Ethereal::NDR;
@@ -20,10 +20,12 @@ use Parse::Pidl::Typelist;
use Parse::Pidl::Util qw(has_property ParseExpr property_matches);
use Parse::Pidl::NDR;
use Parse::Pidl::Dump qw(DumpTypedef DumpFunction);
-use Parse::Pidl::Ethereal::Conformance qw(EmitProhibited FindDissectorParam %hf_renames %protocols);
+use Parse::Pidl::Ethereal::Conformance qw(ReadConformance);
my %types;
+my $conformance = {};
+
my %ptrtype_mappings = (
"unique" => "NDR_POINTER_UNIQUE",
"ref" => "NDR_POINTER_REF",
@@ -44,6 +46,17 @@ sub type2ft($)
return "FT_NONE";
}
+sub StripPrefixes($)
+{
+ my ($s) = @_;
+
+ foreach (@{$conformance->{strip_prefixes}}) {
+ $s =~ s/^$_\_//g;
+ }
+
+ return $s;
+}
+
# Convert a IDL structure field name (e.g access_mask) to a prettier
# string like 'Access Mask'.
@@ -104,7 +117,8 @@ sub Enum($$$)
{
my ($e,$name,$ifname) = @_;
my $valsstring = "$ifname\_$name\_vals";
- my $dissectorname = "$ifname\_dissect\_$name";
+ my $dissectorname = "$ifname\_dissect\_".StripPrefixes($name);
+ return if (defined($conformance->{noemit}->{$dissectorname}));
foreach (@{$e->{ELEMENTS}}) {
if (/([^=]*)=(.*)/) {
@@ -142,7 +156,7 @@ sub Enum($$$)
sub Bitmap($$$)
{
my ($e,$name,$ifname) = @_;
- my $dissectorname = "$ifname\_dissect\_$name";
+ my $dissectorname = "$ifname\_dissect\_".StripPrefixes($name);
register_ett("ett_$ifname\_$name");
@@ -217,7 +231,7 @@ sub ElementLevel($$$$$)
} elsif ($l->{LEVEL} eq "EMBEDDED") {
$type = "embedded";
}
- pidl_code "offset=dissect_ndr_$type\_pointer(tvb,offset,pinfo,tree,drep,$myname\_,$ptrtype_mappings{$l->{POINTER_TYPE}},\"".field2name($e->{NAME}) . " ($e->{TYPE})\",$hf);";
+ pidl_code "offset=dissect_ndr_$type\_pointer(tvb,offset,pinfo,tree,drep,$myname\_,$ptrtype_mappings{$l->{POINTER_TYPE}},\"".field2name(StripPrefixes($e->{NAME})) . " (".StripPrefixes($e->{TYPE}).")\",$hf);";
} elsif ($l->{TYPE} eq "ARRAY") {
my $af = "";
@@ -240,7 +254,10 @@ sub ElementLevel($$$$$)
pidl_code "offset=dissect_ndr_vstring(tvb,offset,pinfo,tree,drep,$bs,$hf,FALSE,NULL);";
}
} elsif (defined($types{$l->{DATA_TYPE}})) {
- my $param = FindDissectorParam($myname);
+ my $param = 0;
+ if (defined($conformance->{dissectorparams}->{$myname})) {
+ $param = $conformance->{dissectorparams}->{$myname};
+ }
my $x = $types{$l->{DATA_TYPE}}->{CALL};
$x =~ s/\@HF\@/$hf/g;
$x =~ s/\@PARAM\@/$param/g;
@@ -249,7 +266,15 @@ sub ElementLevel($$$$$)
warn("Unknown data type `$l->{DATA_TYPE}'");
}
} elsif ($_->{TYPE} eq "SUBCONTEXT") {
- die("subcontext() not supported")
+ my $num_bits = ($l->{HEADER_SIZE}*8);
+ pidl_code "guint$num_bits size;";
+ pidl_code "int start_offset=offset;";
+ pidl_code "tvbuff_t *subtvb;";
+ pidl_code "offset=dissect_ndr_uint$num_bits(tvb,offset,pinfo,drep,&size);";
+ pidl_code "proto_tree_add_text(tree,tvb,start_offset,offset-start_offset+size,\"Subcontext size\");";
+
+ pidl_code "subtvb = tvb_new_subset(tvb,offset,size,-1);";
+ pidl_code "$myname\_(subtvb,0,pinfo,tree,drep);";
}
}
@@ -257,13 +282,17 @@ sub Element($$$)
{
my ($e,$pn,$ifname) = @_;
- my $dissectorname = "$ifname\_dissect\_$ifname\_$pn\_$e->{NAME}";
+ my $dissectorname = "$ifname\_dissect\_".StripPrefixes($pn)."\_".StripPrefixes($e->{NAME});
- return if (EmitProhibited($dissectorname));
+ my $call_code = "offset=$dissectorname(tvb,offset,pinfo,tree,drep);";
my $hf = register_hf_field("hf_$ifname\_$pn\_$e->{NAME}", field2name($e->{NAME}), "$ifname.$pn.$e->{NAME}", type2ft($e->{TYPE}), "BASE_HEX", "NULL", 0, "");
- my $add = "";
+ if (defined($conformance->{noemit}->{$dissectorname})) {
+ return $call_code;
+ }
+
+ my $add = "";
foreach (@{$e->{LEVELS}}) {
next if ($_->{TYPE} eq "SWITCH");
@@ -281,7 +310,7 @@ sub Element($$$)
$add.="_";
}
- return "offset=$dissectorname(tvb,offset,pinfo,tree,drep);";
+ return $call_code;
}
sub Function($$$)
@@ -306,6 +335,14 @@ sub Function($$$)
pidl_code "";
}
}
+
+ if (not defined($fn->{RETURN_TYPE})) {
+ } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
+ pidl_code "offset=dissect_ntstatus(tvb,offset,pinfo,tree,drep,hf\_$ifname\_status, NULL);";
+ } elsif ($fn->{RETURN_TYPE} eq "WERROR") {
+ pidl_code "offset=dissect_ndr_uint32(tvb,offset,pinfo,tree,drep,hf\_$ifname\_werror, NULL);";
+ }
+
pidl_code "return offset;";
deindent;
pidl_code "}\n";
@@ -321,6 +358,7 @@ sub Function($$$)
}
}
+
pidl_code "return offset;";
deindent;
pidl_code "}\n";
@@ -329,9 +367,9 @@ sub Function($$$)
sub Struct($$$)
{
my ($e,$name,$ifname) = @_;
- my $dissectorname = "$ifname\_dissect\_$name";
+ my $dissectorname = "$ifname\_dissect\_".StripPrefixes($name);
- return if (EmitProhibited($dissectorname));
+ return if (defined($conformance->{noemit}->{$dissectorname}));
register_ett("ett_$ifname\_$name");
@@ -377,7 +415,8 @@ sub Union($$$)
{
my ($e,$name,$ifname) = @_;
- my $dissectorname = "$ifname\_dissect_$name";
+ my $dissectorname = "$ifname\_dissect_".StripPrefixes($name);
+ return if (defined($conformance->{noemit}->{$dissectorname}));
register_ett("ett_$ifname\_$name");
@@ -411,6 +450,7 @@ sub Union($$$)
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);";
+ deindent;
pidl_code "}";
pidl_code "";
@@ -464,10 +504,10 @@ sub RegisterInterface($)
$name = $x->{PROPERTIES}->{helpstring};
}
- if (defined($protocols{$x->{NAME}})) {
- $short_name = $protocols{$x->{NAME}}->{SHORTNAME};
- $name = $protocols{$x->{NAME}}->{LONGNAME};
- $filter_name = $protocols{$x->{NAME}}->{FILTERNAME};
+ if (defined($conformance->{protocols}->{$x->{NAME}})) {
+ $short_name = $conformance->{protocols}->{$x->{NAME}}->{SHORTNAME};
+ $name = $conformance->{protocols}->{$x->{NAME}}->{LONGNAME};
+ $filter_name = $conformance->{protocols}->{$x->{NAME}}->{FILTERNAME};
}
pidl_code "proto_dcerpc_$x->{NAME} = proto_register_protocol($name, \"$short_name\", \"$filter_name\");";
@@ -499,7 +539,9 @@ sub RegisterInterfaceHandoff($)
sub ProcessInterface($)
{
- my $x = shift;
+ my ($x) = @_;
+
+ push(@{$conformance->{strip_prefixes}}, $x->{NAME});
my $define = "__PACKET_DCERPC_" . uc($_->{NAME}) . "_H";
pidl_hdr "#ifndef $define";
@@ -515,6 +557,8 @@ sub ProcessInterface($)
pidl_def "static gint proto_dcerpc_$x->{NAME} = -1;";
register_ett("ett_dcerpc_$x->{NAME}");
register_hf_field("hf_$x->{NAME}_opnum", "Operation", "$x->{NAME}.opnum", "FT_UINT16", "BASE_DEC", "NULL", 0, "");
+ register_hf_field("hf_$x->{NAME}_status", "Status", "$x->{NAME}.status", "FT_UINT32", "BASE_HEX", "VALS(NT_errors)", 0, "");
+ register_hf_field("hf_$x->{NAME}_werror", "Windows Error", "$x->{NAME}.werror", "FT_UINT32", "BASE_HEX", "NULL", 0, "");
if (defined($x->{UUID})) {
my $if_uuid = $x->{UUID};
@@ -568,8 +612,14 @@ sub register_type($$$$$$$)
}
# Loads the default types
-sub Initialize()
+sub Initialize($)
{
+ my $cnf_file = shift;
+
+ $conformance = {};
+
+ ReadConformance($cnf_file, $conformance) or print "Warning: Not using conformance file `$cnf_file'\n";
+
foreach my $bytes (qw(1 2 4 8)) {
my $bits = $bytes * 8;
register_type("uint$bits", "offset=dissect_ndr_uint$bits(tvb,offset,pinfo,tree,drep,\@HF\@,NULL);", "FT_UINT$bits", "BASE_DEC", 0, "NULL", $bytes);
@@ -601,18 +651,12 @@ sub Initialize()
#####################################################################
# Generate ethereal parser and header code
-sub Parse($$$)
+sub Parse($$)
{
- my($ndr,$module,$filename) = @_;
-
- Initialize();
+ my($ndr,$h_filename,$cnf_file) = @_;
+ Initialize($cnf_file);
$tabs = "";
- my $h_filename = $filename;
-
- if ($h_filename =~ /(.*)\.c/) {
- $h_filename = "$1.h";
- }
%res = (code=>"",def=>"",hdr=>"");
@@ -644,6 +688,7 @@ sub Parse($$$)
$parser.=$res{ett};
$parser.=$res{hf};
$parser.=$res{def};
+ $parser.=$conformance->{override};
$parser.=$res{code};
my $header = "/* autogenerated by pidl */\n\n";
@@ -695,7 +740,7 @@ sub register_hf_field($$$$$$$$)
{
my ($index,$name,$filter_name,$ft_type,$base_type,$valsstring,$mask,$blurb) = @_;
- return $hf_renames{$index} if defined ($hf_renames{$index});
+ return $conformance->{hf_renames}->{$index} if defined ($conformance->{hf_renames}->{$index});
$hf{$index} = {
INDEX => $index,
@@ -760,5 +805,4 @@ sub DumpFunctionTable($)
return "$res};\n";
}
-
1;
diff --git a/source4/build/pidl/pidl b/source4/build/pidl/pidl
index eb5e635b7f..324f30b10e 100755
--- a/source4/build/pidl/pidl
+++ b/source4/build/pidl/pidl
@@ -318,8 +318,10 @@ $dcom
my($eparser) = ($opt_eth_parser or "$outputdir/packet-dcerpc-$basename.c");
my $eheader = $eparser;
$eheader =~ s/\.c$/\.h/;
+ my $cnffile = $idl_file;
+ $cnffile =~ s/\.idl$/\.cnf/;
- my ($dp, $dh) = Parse::Pidl::Ethereal::NDR::Parse($ndr, $eheader, $eparser);
+ my ($dp, $dh) = Parse::Pidl::Ethereal::NDR::Parse($ndr, $eheader, $cnffile);
FileSave($eparser, $dp);
FileSave($eheader, $dh);
}