From 8ded5420e3312f19c85e65eaa7464ce4de160a3f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Jul 2004 04:11:18 +0000 Subject: r1586: Finally, a technique for putting buffers in scalars in the same protocol tree that actually works. Instead of trying really hard to do this in code, just remember a list of strings and subtrees for every tree. (This does require the addition of a void *user_data field to ethereal's proto_node structure). (This used to be commit 5bc61162602f84c8a3a0b22c74c69318b92e087a) --- source4/build/pidl/eparser.pm | 109 +++++++++-------------------- source4/build/pidl/packet-dcerpc-eparser.c | 68 ++++++++++++++++-- source4/build/pidl/packet-dcerpc-eparser.h | 13 ++-- 3 files changed, 102 insertions(+), 88 deletions(-) (limited to 'source4/build') diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm index d8dbd4195f..fca359d41d 100644 --- a/source4/build/pidl/eparser.pm +++ b/source4/build/pidl/eparser.pm @@ -347,13 +347,14 @@ sub ParseElementPullScalar($$) { my($e) = shift; my($ndr_flags) = shift; + my $cprefix = util::c_pull_prefix($e); my $sub_size = util::has_property($e, "subcontext"); start_flags($e); if (util::has_property($e, "relative")) { - pidl "\tndr_pull_relative(ndr, subtree_$e->{NAME}, ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_relative(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), ndr_pull_$e->{TYPE});\n"; } elsif (util::is_inline_array($e)) { ParseArrayPull($e, "NDR_SCALARS"); } elsif (util::need_wire_pointer($e)) { @@ -369,14 +370,14 @@ sub ParseElementPullScalar($$) ParseElementPullSwitch($e, $ndr_flags, $switch); } elsif (defined $sub_size) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_subcontext_fn(ndr, tree, $sub_size, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, &elt_$e->{NAME});\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, subtree_$e->{NAME}, $ndr_flags);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $ndr_flags);\n"; } end_flags($e); @@ -418,17 +419,17 @@ sub ParseElementPullBuffer($$) } elsif (defined $sub_size) { if ($e->{POINTERS}) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_subcontext_fn(ndr, tree, $sub_size, _pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, _pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_subcontext_flags_fn(ndr, tree, $sub_size, ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_flags_fn(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $sub_size, ndr_pull_$e->{TYPE});\n"; } } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\tndr_pull_$e->{TYPE}(ndr, tree, hf_$e->{NAME}_$e->{TYPE}, &elt_$e->{NAME});\n"; } elsif ($e->{POINTERS}) { - pidl "\tndr_pull_$e->{TYPE}(ndr, tree, NDR_SCALARS|NDR_BUFFERS);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), NDR_SCALARS|NDR_BUFFERS);\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, subtree_$e->{NAME}, $ndr_flags);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, get_subtree(tree, \"$e->{NAME}\", ndr, ett_dcerpc_$module), $ndr_flags);\n"; } if (util::need_wire_pointer($e)) { @@ -446,8 +447,9 @@ sub ParseStructPull($) my $conform_e; for my $x (@{$struct->{ELEMENTS}}) { - pidl "\tg$x->{TYPE} elt_$x->{NAME};\n", - if util::is_builtin_type($x->{TYPE}); + if (util::is_builtin_type($x->{TYPE})) { + pidl "\tg$x->{TYPE} elt_$x->{NAME};\n"; + } } if (! defined $struct->{ELEMENTS}) { @@ -472,38 +474,23 @@ sub ParseStructPull($) !util::has_property($e, "relative")) { pidl "\tguint32 ptr_$e->{NAME};\n"; } - if (!util::is_scalar_type($e->{TYPE})) { - pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n"; - } } pidl "\n"; - # Some debugging stuff + # Some debugging stuff. Put a note in the proto tree saying + # which function was called with what NDR flags. - pidl "\tif ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS))\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"NDR_SCALARS|NDR_BUFFERS\");\n"; - pidl "\telse if (ndr_flags & NDR_SCALARS)\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"NDR_SCALARS\");\n"; - pidl "\telse if (ndr_flags & NDR_BUFFERS)\n"; - pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"NDR_BUFFERS\");\n"; +# pidl "\tif ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS))\n"; +# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_SCALARS|NDR_BUFFERS)\", __FUNCTION__);\n"; +# pidl "\telse if (ndr_flags & NDR_SCALARS)\n"; +# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_SCALARS)\", __FUNCTION__);\n"; +# pidl "\telse if (ndr_flags & NDR_BUFFERS)\n"; +# pidl "\t\tproto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"%s(NDR_BUFFERS)\", __FUNCTION__);\n"; +# pidl "\n"; - pidl "\n"; start_flags($struct); - pidl "\tif ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS)) {\n"; - pidl "\t\tproto_item *item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$struct->{PARENT}{NAME}\");\n"; - pidl "\t\ttree = proto_item_add_subtree(item, ett_$struct->{PARENT}{NAME});\n"; - - foreach my $e (@{$struct->{ELEMENTS}}) { - if (!util::is_scalar_type($e->{TYPE})) { - pidl "\t\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n"; - pidl "\t\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n"; - } - } - - pidl "\t}\n\n"; - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n\n"; pidl "\tndr_pull_struct_start(ndr);\n"; @@ -558,7 +545,6 @@ sub ParseUnionPull($) $have_default = 1; } else { pidl "\tcase $el->{CASE}: {\n"; - pidl "\tproto_tree *subtree_$el->{DATA}{NAME} = tree;\n"; } if ($el->{TYPE} eq "UNION_ELEMENT") { my $e2 = $el->{DATA}; @@ -584,7 +570,6 @@ sub ParseUnionPull($) pidl "\tdefault:\n"; } else { pidl "\tcase $el->{CASE}: {\n"; - pidl "\tproto_tree *subtree_$el->{DATA}{NAME} = tree;\n"; } if ($el->{TYPE} eq "UNION_ELEMENT") { ParseElementPullBuffer($el->{DATA}, "NDR_BUFFERS"); @@ -731,11 +716,9 @@ sub ParseFunctionPull($) # Request - pidl $static . "int $fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *toplevel_tree, guint8 *drep)\n"; + pidl $static . "int $fn->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n"; pidl "{\n"; pidl "\tstruct e_ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; - pidl "\tproto_item *item;\n"; - pidl "\tproto_tree *tree = toplevel_tree;\n"; # declare any internal pointers we need foreach my $e (@{$fn->{DATA}}) { @@ -743,31 +726,17 @@ sub ParseFunctionPull($) if (util::has_property($e, "in")) { if (util::need_wire_pointer($e)) { - pidl "\tguint32 ptr_$e->{NAME};\n"; + pidl "\tguint32 ptr_$e->{NAME};\n"; } - pidl "\tg$e->{TYPE} elt_$e->{NAME};\n", - if util::is_builtin_type($e->{TYPE}); - - if (util::need_wire_pointer($e) || - !util::is_scalar_type($e->{TYPE})) { - pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n"; + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tg$e->{TYPE} elt_$e->{NAME};\n"; } } } pidl "\n"; - foreach my $e (@{$fn->{DATA}}) { - if (util::has_property($e, "in") && - !util::is_scalar_type($e->{TYPE})) { - pidl "\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n"; - pidl "\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n"; - } - } - - pidl "\n"; - foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "in")) { ParseFunctionElementPull($e, "in"); @@ -782,12 +751,9 @@ sub ParseFunctionPull($) # Response - pidl $static . "int $fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *toplevel_tree, guint8 *drep)\n"; + pidl $static . "int $fn->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n"; pidl "{\n"; pidl "\tstruct e_ndr_pull *ndr = ndr_pull_init(tvb, offset, pinfo, drep);\n"; - pidl "\tproto_item *item;\n"; - pidl "\tproto_tree *tree = toplevel_tree;\n"; - # declare any internal pointers we need foreach my $e (@{$fn->{DATA}}) { @@ -797,28 +763,14 @@ sub ParseFunctionPull($) pidl "\tguint32 ptr_$e->{NAME};\n"; } - pidl "\tg$e->{TYPE} elt_$e->{NAME};\n", - if util::is_builtin_type($e->{TYPE}); - - if (util::need_wire_pointer($e) || - !util::is_scalar_type($e->{TYPE})) { - pidl "\tproto_tree *subtree_$e->{NAME} = tree;\n"; + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tg$e->{TYPE} elt_$e->{NAME};\n"; } } } pidl "\n"; - foreach my $e (@{$fn->{DATA}}) { - if (util::has_property($e, "out") && - !util::is_scalar_type($e->{TYPE})) { - pidl "\titem = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, \"$e->{NAME}\");\n"; - pidl "\tsubtree_$e->{NAME} = proto_item_add_subtree(item, ett_dcerpc_$module);\n"; - } - } - - pidl "\n"; - foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "out")) { ParseFunctionElementPull($e, "out"); @@ -1007,11 +959,14 @@ sub ParseHeader($$) foreach my $x (@{$idl}) { if ($x->{TYPE} eq "INTERFACE") { foreach my $d (@{$x->{DATA}}) { + + # Make prototypes for [public] push/pull functions + if ($d->{TYPE} eq "TYPEDEF" and util::has_property($d->{DATA}, "public")) { if ($d->{DATA}{TYPE} eq "STRUCT") { - pidl "void ndr_pull_$d->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags);\n"; + pidl "void ndr_pull_$d->{NAME}(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags);\n\n"; } if ($d->{DATA}{TYPE} eq "UNION") { diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c index 8debaf0aab..9217f3a87e 100644 --- a/source4/build/pidl/packet-dcerpc-eparser.c +++ b/source4/build/pidl/packet-dcerpc-eparser.c @@ -3,6 +3,7 @@ #endif #include "tvbuff.h" +#include #include "packet-dcerpc.h" #include "packet-dcerpc-nt.h" @@ -12,6 +13,7 @@ static int hf_string4_len = -1; static int hf_string4_offset = -1; static int hf_string4_len2 = -1; static int hf_string_data = -1; +static int hf_subtree_list = -1; static gint ett_array = -1; @@ -319,6 +321,7 @@ void ndr_pull_HYPER_T(struct e_ndr_pull *ndr, proto_tree *tree, int hf, void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags) { guint32 num_auths; + if (!(flags & NDR_SCALARS)) { return; } @@ -339,9 +342,9 @@ void ndr_pull_align(struct e_ndr_pull *ndr, int size) } } -void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, proto_tree *tree, - size_t sub_size, - void (*fn)(struct e_ndr_pull *, +void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, + proto_tree *tree, size_t sub_size, + void (*fn)(struct e_ndr_pull *, proto_tree *tree, int ndr_flags)) { struct e_ndr_pull ndr2; @@ -447,7 +450,7 @@ void ndr_pull_set_offset(struct e_ndr_pull *ndr, guint32 ofs) static int hf_relative_ofs = -1; void ndr_pull_relative(struct e_ndr_pull *ndr, proto_tree *tree, - void (*fn)(struct e_ndr_pull *, + void (*fn)(struct e_ndr_pull *, proto_tree *tree, int ndr_flags)) { struct e_ndr_pull ndr2; @@ -535,17 +538,69 @@ void ndr_pull_array(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags, proto_item *item; item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, "Array entry"); subtrees[i] = proto_item_add_subtree(item, ett_array); - pull_fn(ndr, subtrees[i], NDR_SCALARS); + + if ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS)) + pull_fn(ndr, subtrees[i], NDR_SCALARS); + else + pull_fn(ndr, tree, NDR_SCALARS); + } if (!(ndr_flags & NDR_BUFFERS)) goto done; buffers: for (i=0;iuser_data; + + /* Look for name */ + + for (l = list; l; l = g_slist_next(l)) { + info = list->data; + if (strcmp(name, info->name) == 0) + return info->subtree; + } + + /* Create new subtree entry */ + + info = (struct subtree_info *)g_malloc(sizeof(struct subtree_info)); + + info->name = g_strdup(name); + item = proto_tree_add_text(tree, ndr->tvb, ndr->offset, 0, name); + info->subtree = proto_item_add_subtree(item, ett); + + /* Don't forget to add new list head */ + + list = g_slist_append(list, info); + + tree->user_data = list; + + return info->subtree; +} + void proto_register_eparser(void) { static hf_register_info hf[] = { @@ -556,6 +611,7 @@ void proto_register_eparser(void) { &hf_subcontext_size_2, { "Subcontext size2", "eparser.subcontext_size2", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size2", HFILL }}, { &hf_subcontext_size_4, { "Subcontext size4", "eparser.subcontext_size4", FT_UINT16, BASE_DEC, NULL, 0x0, "Subcontext size4", HFILL }}, { &hf_relative_ofs, { "Relative offset", "eparser.relative_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "Relative offset", HFILL }}, + { &hf_subtree_list, { "Subtree list", "", FT_UINT64, BASE_DEC, NULL, 0, "", HFILL }}, }; static gint *ett[] = { &ett_array, diff --git a/source4/build/pidl/packet-dcerpc-eparser.h b/source4/build/pidl/packet-dcerpc-eparser.h index 37d92293a9..6c51ccd708 100644 --- a/source4/build/pidl/packet-dcerpc-eparser.h +++ b/source4/build/pidl/packet-dcerpc-eparser.h @@ -69,9 +69,9 @@ void ndr_pull_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint8 *da void ndr_pull_uint16(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint16 *data); void ndr_pull_uint32(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint32 *data); void ndr_pull_advance(struct e_ndr_pull *ndr, int offset); -void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, proto_tree *tree, - size_t sub_size, - void (*fn)(struct e_ndr_pull *, +void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, + proto_tree *tree, size_t sub_size, + void (*fn)(struct e_ndr_pull *, proto_tree *tree, int ndr_flags)); void ndr_pull_subcontext_header(struct e_ndr_pull *ndr, proto_tree *tree, size_t sub_size, struct e_ndr_pull *ndr2); @@ -82,11 +82,11 @@ void ndr_pull_NTTIME(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTTIME * void ndr_pull_HYPER_T(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gHYPER_T *data); void ndr_pull_int64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gint64 *data); void ndr_pull_uint64(struct e_ndr_pull *ndr, proto_tree *tree, int hf, guint64 *data); -void ndr_pull_string(struct e_ndr_pull *ndr, proto_tree *tree, int hf); +void ndr_pull_string(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags); void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags); void ndr_pull_relative(struct e_ndr_pull *ndr, proto_tree *tree, - void (*fn)(struct e_ndr_pull *ndr, + void (*fn)(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags)); int lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t tvb, int offset, @@ -108,4 +108,7 @@ void ndr_pull_array(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags, guint32 n, void (*fn)(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags)); +proto_tree *get_subtree(proto_tree *tree, char *name, struct e_ndr_pull *ndr, + gint ett); + #endif /* _packet_dcerpc_eparser_h */ -- cgit