summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--librpc/tools/ndrdump.c78
1 files changed, 73 insertions, 5 deletions
diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c
index f0f4eaff4e..284dbcedf9 100644
--- a/librpc/tools/ndrdump.c
+++ b/librpc/tools/ndrdump.c
@@ -137,6 +137,53 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
dump_data_cb(d, l, !force, printf_cb, NULL);
}
+static NTSTATUS ndrdump_pull_and_print_pipes(const char *function,
+ struct ndr_pull *ndr_pull,
+ struct ndr_print *ndr_print,
+ const struct ndr_interface_call_pipes *pipes)
+{
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+ uint32_t i;
+
+ for (i=0; i < pipes->num_pipes; i++) {
+ uint64_t idx = 0;
+ while (true) {
+ uint32_t *count;
+ void *c;
+ char *n;
+
+ c = talloc_zero_size(ndr_pull, pipes->pipes[i].chunk_struct_size);
+ talloc_set_name(c, "struct %s", pipes->pipes[i].name);
+ /*
+ * Note: the first struct member is always
+ * 'uint32_t count;'
+ */
+ count = (uint32_t *)c;
+
+ n = talloc_asprintf(c, "%s: %s[%llu]",
+ function, pipes->pipes[i].name,
+ (unsigned long long)idx);
+
+ ndr_err = pipes->pipes[i].ndr_pull(ndr_pull, NDR_SCALARS, c);
+ status = ndr_map_error2ntstatus(ndr_err);
+
+ printf("pull returned %s\n", nt_errstr(status));
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ pipes->pipes[i].ndr_print(ndr_print, n, c);
+
+ if (*count == 0) {
+ break;
+ }
+ idx++;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
int main(int argc, const char *argv[])
{
const struct ndr_interface_table *p = NULL;
@@ -172,6 +219,8 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
POPT_COMMON_VERSION
{ NULL }
};
+ struct ndr_interface_call_pipes *in_pipes = NULL;
+ struct ndr_interface_call_pipes *out_pipes = NULL;
ndr_table_init();
@@ -247,19 +296,21 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
exit(1);
}
+ f = find_function(p, function);
+
if (strcmp(inout, "in") == 0 ||
strcmp(inout, "request") == 0) {
flags = NDR_IN;
+ in_pipes = &f->in_pipes;
} else if (strcmp(inout, "out") == 0 ||
strcmp(inout, "response") == 0) {
flags = NDR_OUT;
+ out_pipes = &f->out_pipes;
} else {
printf("Bad inout value '%s'\n", inout);
exit(1);
}
- f = find_function(p, function);
-
mem_ctx = talloc_init("ndrdump");
st = talloc_zero_size(mem_ctx, f->struct_size);
@@ -331,6 +382,18 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
ndr_pull->flags |= LIBNDR_FLAG_NDR64;
}
+ ndr_print = talloc_zero(mem_ctx, struct ndr_print);
+ ndr_print->print = ndr_print_printf_helper;
+ ndr_print->depth = 1;
+
+ if (out_pipes) {
+ status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, out_pipes);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dump FAILED\n");
+ exit(1);
+ }
+ }
+
ndr_err = f->ndr_pull(ndr_pull, flags, st);
status = ndr_map_error2ntstatus(ndr_err);
@@ -348,9 +411,6 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
ndrdump_data(blob.data, blob.length, dumpdata);
}
- ndr_print = talloc_zero(mem_ctx, struct ndr_print);
- ndr_print->print = ndr_print_printf_helper;
- ndr_print->depth = 1;
f->ndr_print(ndr_print, function, flags, st);
if (!NT_STATUS_IS_OK(status)) {
@@ -358,6 +418,14 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
exit(1);
}
+ if (in_pipes) {
+ status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, in_pipes);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dump FAILED\n");
+ exit(1);
+ }
+ }
+
if (validate) {
DATA_BLOB v_blob;
struct ndr_push *ndr_v_push;