mirror of
https://github.com/samba-team/samba.git
synced 2025-01-19 10:03:58 +03:00
r9081: Work on new ethereal parser generator, partially based on
Ronnie Sahlberg's idl2eth.c
This commit is contained in:
parent
69ade058fd
commit
561aeca649
99
source/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
Normal file
99
source/build/pidl/Parse/Pidl/Ethereal/Conformance.pm
Normal file
@ -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;
|
595
source/build/pidl/Parse/Pidl/Ethereal/NDR.pm
Normal file
595
source/build/pidl/Parse/Pidl/Ethereal/NDR.pm
Normal file
@ -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;
|
@ -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;
|
File diff suppressed because it is too large
Load Diff
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user