{
my($t) = shift;
- return "FT_UINT32", if ($t eq "uint32");
- return "FT_UINT16", if ($t eq "uint16");
- return "FT_UINT8", if ($t eq "uint8");
- return "FT_BYTES";
+ 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");
+
+ # Type is an enum
+
+ return "FT_UINT16";
}
# Determine the display base for an element
return "BASE_" . uc($base);
}
- return "BASE_DEC", if ($e->{TYPE} eq "uint32") or
- ($e->{TYPE} eq "uint16") or ($e->{TYPE} eq "uint8");
- return "BASE_NONE";
+ 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
$needed{"ett_$t->{NAME}"} = 1;
}
+
+ if ($t->{DATA}->{TYPE} eq "ENUM") {
+ $needed{"hf_$t->{NAME}"} = {
+ 'name' => $t->{NAME},
+ 'ft' => 'FT_UINT16',
+ 'base' => 'BASE_DEC'
+ };
+ }
}
#####################################################################
open(IN, "<$input") || die "can't open $input for reading";
open(OUT, ">$output") || die "can't open $output for writing";
- # Read in entire file
-
- undef $/;
+ # Read through file
while(<IN>) {
# Get rid of async send and receive function.
- s/^NTSTATUS dcerpc_.*?;\n//smg;
- s/^struct rpc_request.*?;\n\n//smg;
+ s/^NTSTATUS dcerpc_.*?;//smg;
+ s/^struct rpc_request.*?;//smg;
# Rewrite librpc includes
- s/^\#include \"librpc\/gen_ndr\/ndr_(.*?).h\"$/\#include \"packet-dcerpc-$1.h\"/smg;
+ s/^\#include\ \"librpc\/gen_ndr\/ndr_(.*?).h\"$
+ /\#include \"packet-dcerpc-$1.h\"/smgx;
# Convert samba fixed width types to stdint types
s/(struct pidl_pull \*ndr, int ndr_flags)/$1, pidl_tree *tree/smg;
+ # Bitmaps
+
+ s/(uint32_t \*r\);)/pidl_tree *tree, int hf, $1/smg;
+
pidl $_;
}
pidl "\n";
- # Read in entire file for post-processing
-
- undef $/;
+ # Read through file
while(<IN>) {
- # Ethereal take care of this for us. It also makes the other
- # regular expressions easier to write and understand.
+ #
+ # Regexps to do a first pass at removing stuff we aren't
+ # interested in for ehtereal parsers.
+ #
+
+ # Remove the NDR_CHECK() macro calls. Ethereal take care of
+ # this for us as part of the tvbuff_t structure.
s/NDR_CHECK\((.*)\)/$1/g;
- # We're not interested in ndr_print or ndr_push functions.
+ # We're not interested in ndr_{print,push,size} functions so
+ # just delete them.
- s/^(static )?NTSTATUS (ndr_push[^\(]+).*?^\}\n\n//smg;
- s/^void (ndr_print[^\(]+).*?^\}\n\n//smg;
+ next, if /^(static )?NTSTATUS ndr_push/ .. /^}/;
+ next, if /^void ndr_print/ .. /^}/;
+ next, if /^size_t ndr_size/ .. /^}/;
- # Get rid of dcerpc interface structures and functions
+ # Get rid of dcerpc interface structures and functions since
+ # they are also not very interesting.
- s/^static const struct dcerpc_interface_call .*?^\};\n\n//smg;
- s/^static const char \* const ([a-z]+)_endpoint_strings.*?^\};\n\n//smg;
- s/^static const struct dcerpc_endpoint_list .*?^\};\n\n\n//smg;
- s/^const struct dcerpc_interface_table .*?^\};\n\n//smg;
- s/^static NTSTATUS dcerpc_ndr_([a-z]+)_init.*?^\}\n\n//smg;
- s/^NTSTATUS dcerpc_([a-z]+)_init.*?^\}\n\n//smg;
+next, if /^static const struct dcerpc_interface_call/ .. /^};/;
+next, if /^static const char \* const [a-z]+_endpoint_strings/ ../^};/;
+next, if /^static const struct dcerpc_endpoint_list/ .. /^};/;
+next, if /^const struct dcerpc_interface_table/ .. /^};/;
+next, if /^static NTSTATUS dcerpc_ndr_[a-z]+_init/ .. /^}/;
+next, if /^NTSTATUS dcerpc_[a-z]+_init/ .. /^}/;
- # Include packet-dcerpc-foo.h instead of ndr_foo.h
+ # Rewrite includes to packet-dcerpc-foo.h instead of ndr_foo.h
s/^\#include \".*?ndr_(.*?).h\"$/\#include \"packet-dcerpc-$1.h\"/smg;
- # Call ethereal wrapper for ndr_pull_ptr() function.
-
- s/(ndr_pull_ptr\(ndr, ([^\)]*?)\);)/ndr_pull_ptr(ndr, tree, hf_ptr, $2);/smg;
-
- # Wrap ndr_pull_array_size() - generate wrapper that won't get
- # caught by the regex for wrapping scalar values below (i.e
- # the leading space in front of the first parameter).
-
- s/(ndr_pull_array_(size|length)\(ndr, ([^\)]*?)\);)/ndr_pull_array_$2( ndr, tree, $3);/smg;
-
- # Add tree argument to ndr_pull_array()
-
- s/(ndr_pull_array\(ndr, ([^,]*?), ([^\)].*?)\);)/ndr_pull_array( ndr, $2, tree, $3);/smg;
-
- s/(ndr_pull_array_([^\(]*?)\(ndr, ([^,]*?), (r->((in|out).)?([^,]*?)), (.*?)\);)/ndr_pull_array_$2( ndr, $3, tree, hf_$7_$2_array, $4, $8);/smg;
+ #
+ # OK start wrapping the ndr_pull functions that actually
+ # implement the NDR decoding routines. This mainly consists
+ # of adding a couple of parameters to each function call.
+ #
+
+ # Add proto tree and hf argument to ndr_pull_ptr() calls.
+
+ s/(ndr_pull_ptr\(ndr,\ ([^\)]*?)\);)
+ /ndr_pull_ptr(ndr, tree, hf_ptr, $2);/smgx;
+
+ # Wrap ndr_pull_array_size() and ndr_pull_array_length()
+ # functions. Add leading space in front of first parameter so
+ # we won't get caught by later regexps.
+
+ s/(ndr_pull_array_(size|length)\(ndr,\ ([^\)]*?)\);)
+ /ndr_pull_array_$2( ndr, tree, $3);/smgx;
+
+ # Add tree argument to ndr_pull_array() and
+ # ndr_pull_array_foo() calls.
+
+ s/(ndr_pull_array\(
+ ndr,\
+ ([^,]*?),\ # NDR_SCALARS etc
+ (\(void\ \*\*\)r->(in|out|)\.?([^,]*?)),\ # Pointer to array entries
+ ([^\)].*?)\);) # All other arguments
+ /ndr_pull_array( ndr, $2, tree, $3, $6);/smgx;
+
+ s/(ndr_pull_array_([^\(]*?)\(
+ ndr,\
+ ([^,]*?),\ # NDR_SCALARS etc
+ (r->((in|out).)?([^,]*?)),\ # Pointer to array elements
+ (.*?)\);) # Number of elements
+ /ndr_pull_array_$2( ndr, $3, tree, hf_$7_$2_array, $4, $8);/smgx;
- # Save ndr_pull_relative[12]() calls from being wrapped by the
- # proceeding regexp.
+ # Save ndr_pull_relative{1,2}() calls from being wrapped by the
+ # proceeding regexp by adding a leading space.
- s/ndr_pull_(relative1|relative2)\((.*?);/ndr_pull_$1( $2;/smg;
+ s/ndr_pull_(relative1|relative2)\((.*?)\);/
+ ndr_pull_$1( $2);/smgx;
# Call ethereal wrappers for pull of scalar values in
- # structures and functions:
+ # structures and functions, e.g
#
# ndr_pull_uint32(ndr, &r->in.access_mask);
# ndr_pull_uint32(ndr, &r->idx);
- s/(ndr_pull_([^\)]*?)\(ndr, (&?r->((in|out)\.)?([^\)]*?))\);)/ndr_pull_$2(ndr, tree, hf_$6_$2, $3);/smg;
+ s/(ndr_pull_([^\)]*?)
+ \(ndr,\
+ (&?r->((in|out)\.)? # Function args contain leading junk
+ ([^\)]*?)) # Element name
+ \);)
+ /ndr_pull_$2(ndr, tree, hf_$6_$2, $3);/smgx;
- # Pull of "internal" scalars like array sizes, levels, etcetera.
+ # Add tree and hf argument to pulls of "internal" scalars like
+ # array sizes, levels, etc.
- s/(ndr_pull_(uint32|uint16)\(ndr, (&_([^\)]*?))\);)/ndr_pull_$2(ndr, tree, hf_$4, $3);/smg;
+ s/(ndr_pull_(uint32|uint16)\(
+ ndr,\
+ (&_([^\)]*?)) # Internal arg names have leading underscore
+ \);)
+ /ndr_pull_$2(ndr, tree, hf_$4, $3);/smgx;
- # Call ethereal wrappers for pull of buffers in structures and
- # functions:
+ # Add subtree argument to calls dissecting structures, e.g
#
# ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->command);
# ndr_pull_atsvc_enum_ctr(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.ctr);
- s/(ndr_pull_([^\)]*?)\(ndr, (NDR_[^,]*?), ([^\(].*?)\);)/ndr_pull_$2(ndr, $3, get_subtree(tree, \"$2\", ndr, ett_$2), $4);/smg;
+ s/(ndr_pull_([^\)]*?)\(
+ ndr,\
+ (NDR_[^,]*?),\
+ ([^\(].*?)\);)
+ /ndr_pull_$2(ndr, $3, get_subtree(tree, \"$2\", ndr, ett_$2), $4);
+ /smgx;
- # Add proto_tree parameter to pull functions:
+ # Add proto_tree parameter to pull function prototypes, e.g
#
- # static NTSTATUS ndr_pull_atsvc_JobInfo(struct ndr_pull *ndr, int ndr_flags, struct atsvc_JobInfo *r)
+ # static NTSTATUS ndr_pull_atsvc_JobInfo(struct ndr_pull *ndr,
+ # int ndr_flags, struct atsvc_JobInfo *r)
- s/^((static )?NTSTATUS ndr_pull_([^\(]*?)\(struct ndr_pull \*ndr, int (ndr_)?flags)/$1, proto_tree \*tree/smg;
+ s/^((static\ )?NTSTATUS\ ndr_pull_([^\(]*?)\(
+ struct\ ndr_pull\ \*ndr,\
+ int\ (ndr_)?flags)
+ /$1, proto_tree \*tree/smgx;
# Add proto_tree parameter to ndr_pull_subcontext_flags_fn()
s/(ndr_pull_subcontext_flags_fn\(ndr)(.*?);/$1, tree$2;/smg;
- # Get rid of ndr_pull_error() calls. Ethereal should take
- # care of buffer overruns and inconsistent array sizes for us.
+ # Get rid of ndr_pull_error() calls for the moment. Ethereal
+ # should take care of buffer overruns and inconsistent array
+ # sizes for us but it would be nice to have some error text in
+ # the dissection.
s/(return ndr_pull_error([^;]*?);)/return NT_STATUS_OK; \/\/ $1/smg;
# Fix some internal variable declarations
s/uint(16|32) _level/uint$1_t _level/smg;
- s/ndr_pull_([^\(]*)\(ndr, tree, hf_level, &_level\);/ndr_pull_$1(ndr, tree, hf_level_$1, &_level);/smg;
-
+ s/ndr_pull_([^\(]*)\(ndr,\ tree,\ hf_level,\ &_level\);
+ /ndr_pull_$1(ndr, tree, hf_level_$1, &_level);/smgx;
+
+ # Enums
+
+ s/(^static\ NTSTATUS\ ndr_pull_(.+?),\ (enum\ .+?)\))
+ /static NTSTATUS ndr_pull_$2, pidl_tree *tree, int hf, $3)/smgx;
+ s/uint(8|16|32) v;/uint$1_t v;/smg;
+ s/(ndr_pull_([^\)]*?)\(ndr,\ &v\);)
+ /ndr_pull_$2(ndr, tree, hf, &v);/smgx;
+
+ s/(ndr_pull_([^\(]+?)\(ndr,\ &_level\);)
+ /ndr_pull_$2(ndr, tree, hf_$2, &_level);/smgx;
+
+ # Bitmaps
+
+s/(^(static\ )?NTSTATUS\ ndr_pull_(.+?),\ uint32\ \*r\))
+ /NTSTATUS ndr_pull_$3, pidl_tree *tree, int hf, uint32_t *r)/smgx;
+
pidl $_;
}