summaryrefslogtreecommitdiff
path: root/source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm
diff options
context:
space:
mode:
Diffstat (limited to 'source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm')
-rw-r--r--source4/build/pidl/Parse/Pidl/Ethereal/NDR.pm108
1 files changed, 76 insertions, 32 deletions
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;