mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
ndrdump: print public structures
Add a struct option to ndrdump that will allow it to print public structures. i.e. binn/ndrdump dns dns_name_packet struct data.file Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
5d67e87d1c
commit
3bf05fbfd7
@ -21,8 +21,8 @@
|
||||
<command>ndrdump</command>
|
||||
<arg choice="opt">-c context</arg>
|
||||
<arg choice="req">pipe</arg>
|
||||
<arg choice="req">function</arg>
|
||||
<arg choice="req">in|out</arg>
|
||||
<arg choice="req">format</arg>
|
||||
<arg choice="req">in|out|struct</arg>
|
||||
<arg choice="req">filename</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
@ -38,15 +38,18 @@
|
||||
<title>DESCRIPTION</title>
|
||||
|
||||
<para>ndrdump tries to parse the specified <replaceable>filename</replaceable>
|
||||
using Samba's parser for the specified pipe and function. The
|
||||
using Samba's parser for the specified pipe and format. The
|
||||
third argument should be
|
||||
either <emphasis>in</emphasis> or <emphasis>out</emphasis>, depending
|
||||
on whether the data should be parsed as a request or a reply.</para>
|
||||
either <emphasis>in</emphasis>, <emphasis>out</emphasis>
|
||||
or <emphasis>struct</emphasis>depending
|
||||
on whether the data should be parsed as a request, reply or a
|
||||
public structure.</para>
|
||||
|
||||
<para>Running ndrdump without arguments will list the pipes for which
|
||||
parsers are available.</para>
|
||||
|
||||
<para>Running ndrdump with one argument will list the functions that
|
||||
<para>Running ndrdump with one argument will list the functions and
|
||||
public structures that
|
||||
Samba can parse for the specified pipe.</para>
|
||||
|
||||
<para>The primary function of ndrdump is debugging Samba's internal
|
||||
|
@ -48,6 +48,35 @@ static const struct ndr_interface_call *find_function(
|
||||
return &p->calls[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a public structure on the pipe and return it as if it were
|
||||
* a function (as the rest of ndrdump is based around functions)
|
||||
*/
|
||||
static const struct ndr_interface_call *find_struct(
|
||||
const struct ndr_interface_table *p,
|
||||
const char *struct_name,
|
||||
struct ndr_interface_call *out_buffer)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<p->num_public_structs;i++) {
|
||||
if (strcmp(p->public_structs[i].name, struct_name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == p->num_public_structs) {
|
||||
printf("Public structure '%s' not found\n", struct_name);
|
||||
exit(1);
|
||||
}
|
||||
*out_buffer = (struct ndr_interface_call) {
|
||||
.name = p->public_structs[i].name,
|
||||
.struct_size = p->public_structs[i].struct_size,
|
||||
.ndr_pull = p->public_structs[i].ndr_pull,
|
||||
.ndr_push = p->public_structs[i].ndr_push,
|
||||
.ndr_print = p->public_structs[i].ndr_print
|
||||
};
|
||||
return out_buffer;
|
||||
}
|
||||
|
||||
_NORETURN_ static void show_pipes(void)
|
||||
{
|
||||
const struct ndr_interface_list *l;
|
||||
@ -71,6 +100,10 @@ _NORETURN_ static void show_functions(const struct ndr_interface_table *p)
|
||||
for (i=0;i<p->num_calls;i++) {
|
||||
printf("\t0x%02x (%2d) %s\n", i, i, p->calls[i].name);
|
||||
}
|
||||
printf("known public structures on '%s' are:\n", p->name);
|
||||
for (i=0;i<p->num_public_structs;i++) {
|
||||
printf("\t%s\n", p->public_structs[i].name);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -194,7 +227,21 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
{
|
||||
const struct ndr_interface_table *p = NULL;
|
||||
const struct ndr_interface_call *f;
|
||||
const char *pipe_name, *function, *inout, *filename;
|
||||
struct ndr_interface_call f_buffer;
|
||||
const char *pipe_name = NULL;
|
||||
const char *filename = NULL;
|
||||
/*
|
||||
* The format type:
|
||||
* in: a request
|
||||
* out: a response
|
||||
* struct: a public structure
|
||||
*/
|
||||
const char *type = NULL;
|
||||
/*
|
||||
* Format is either the name of the decoding function or the
|
||||
* name of a public structure
|
||||
*/
|
||||
const char *format = NULL;
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
DATA_BLOB blob;
|
||||
@ -244,7 +291,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
pc = poptGetContext("ndrdump", argc, argv, long_options, 0);
|
||||
|
||||
poptSetOtherOptionHelp(
|
||||
pc, "<pipe|uuid> <function> <inout> [<filename>]");
|
||||
pc, "<pipe|uuid> <format> <in|out|struct> [<filename>]");
|
||||
|
||||
while ((opt = poptGetNextOpt(pc)) != -1) {
|
||||
switch (opt) {
|
||||
@ -302,29 +349,34 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function = poptGetArg(pc);
|
||||
inout = poptGetArg(pc);
|
||||
format = poptGetArg(pc);
|
||||
type = poptGetArg(pc);
|
||||
filename = poptGetArg(pc);
|
||||
|
||||
if (!function || !inout) {
|
||||
if (!format || !type) {
|
||||
poptPrintUsage(pc, stderr, 0);
|
||||
show_functions(p);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = find_function(p, function);
|
||||
|
||||
if (strcmp(inout, "in") == 0 ||
|
||||
strcmp(inout, "request") == 0) {
|
||||
flags |= NDR_IN;
|
||||
} else if (strcmp(inout, "out") == 0 ||
|
||||
strcmp(inout, "response") == 0) {
|
||||
flags |= NDR_OUT;
|
||||
if (strcmp(type, "struct") == 0) {
|
||||
flags = 0; /* neither NDR_IN nor NDR_OUT */
|
||||
f = find_struct(p, format, &f_buffer);
|
||||
} else {
|
||||
printf("Bad inout value '%s'\n", inout);
|
||||
exit(1);
|
||||
f = find_function(p, format);
|
||||
if (strcmp(type, "in") == 0 ||
|
||||
strcmp(type, "request") == 0) {
|
||||
flags |= NDR_IN;
|
||||
} else if (strcmp(type, "out") == 0 ||
|
||||
strcmp(type, "response") == 0) {
|
||||
flags |= NDR_OUT;
|
||||
} else {
|
||||
printf("Bad type value '%s'\n", type);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mem_ctx = talloc_init("ndrdump");
|
||||
|
||||
st = talloc_zero_size(mem_ctx, f->struct_size);
|
||||
@ -442,7 +494,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
TALLOC_FREE(sec_vt);
|
||||
|
||||
if (flags & NDR_OUT) {
|
||||
status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->out_pipes);
|
||||
status = ndrdump_pull_and_print_pipes(format,
|
||||
ndr_pull,
|
||||
ndr_print,
|
||||
&f->out_pipes);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("dump FAILED\n");
|
||||
exit(1);
|
||||
@ -472,7 +527,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
ndrdump_data(blob.data, blob.length, dumpdata);
|
||||
}
|
||||
|
||||
f->ndr_print(ndr_print, function, flags, st);
|
||||
f->ndr_print(ndr_print, format, flags, st);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("dump FAILED\n");
|
||||
@ -480,7 +535,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
}
|
||||
|
||||
if (flags & NDR_IN) {
|
||||
status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->in_pipes);
|
||||
status = ndrdump_pull_and_print_pipes(format,
|
||||
ndr_pull,
|
||||
ndr_print,
|
||||
&f->in_pipes);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("dump FAILED\n");
|
||||
exit(1);
|
||||
@ -554,7 +612,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
|
||||
ndr_v_print = talloc_zero(mem_ctx, struct ndr_print);
|
||||
ndr_v_print->print = ndr_print_debug_helper;
|
||||
ndr_v_print->depth = 1;
|
||||
f->ndr_print(ndr_v_print, function, flags, v_st);
|
||||
f->ndr_print(ndr_v_print,
|
||||
format,
|
||||
flags, v_st);
|
||||
|
||||
if (blob.length != v_blob.length) {
|
||||
printf("WARNING! orig bytes:%llu validated pushed bytes:%llu\n",
|
||||
|
@ -1 +0,0 @@
|
||||
^samba.tests.blackbox.ndrdump.samba.tests.blackbox.ndrdump.NdrDumpTests.test_ndrdump_with_hex_struct_name\(none\)
|
Loading…
x
Reference in New Issue
Block a user