From 97eac1a46a38eb5ae9e9d15caa96d1c3e1fb57dd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Aug 2005 01:54:55 +0000 Subject: r9161: More etheral parser generator fixes (This used to be commit b323e83e8df6ba331b3f0b3abe28aa8ddf9127ef) --- .../build/pidl/Parse/Pidl/Ethereal/Conformance.pm | 120 ++++++++++----------- source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm | 108 +++++++++++++------ source4/build/pidl/pidl | 4 +- 3 files changed, 137 insertions(+), 95 deletions(-) (limited to 'source4/build') 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 () { + $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); } -- cgit