#endif
#include "tvbuff.h"
+#include <string.h>
#include "packet-dcerpc.h"
#include "packet-dcerpc-nt.h"
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;
/* Create a ndr_pull structure from data stored in a tvb at a given offset. */
tree, ndr->drep, hf, data);
}
-void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, proto_tree *tree, int hf)
+void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gNTSTATUS *data)
{
ndr->offset = dissect_ntstatus(
ndr->tvb, ndr->offset, ndr->pinfo,
- tree, ndr->drep, hf, NULL);
+ tree, ndr->drep, hf, data);
+}
+
+void ndr_pull_WERROR(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gWERROR *data)
+{
+ ndr->offset = dissect_werror(
+ ndr->tvb, ndr->offset, ndr->pinfo,
+ tree, ndr->drep, hf, data);
}
void ndr_pull_uint8(struct e_ndr_pull *ndr, proto_tree *tree, int hf,
tree, ndr->drep, hf, data);
}
+void ndr_pull_DATA_BLOB(struct e_ndr_pull *ndr, proto_tree *tree, int hf, gDATA_BLOB *h)
+{
+ guint32 length;
+
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return;
+ }
+
+ if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
+ if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
+ length = NDR_ALIGN(ndr, 2);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
+ length = NDR_ALIGN(ndr, 4);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
+ length = NDR_ALIGN(ndr, 8);
+ }
+ if (ndr->data_size - ndr->offset < length) {
+ length = ndr->data_size - ndr->offset;
+ }
+ } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+ length = ndr->data_size - ndr->offset;
+ } else {
+ ndr_pull_uint32(ndr, &length);
+ }
+
+ h->data = g_malloc(length);
+ proto_tree_add_bytes(tree, hf_bytes_data, ndr->tvb, ndr->offset, length, h->data);
+
+ ndr->offset += length;
+}
+
void ndr_pull_string(struct e_ndr_pull *ndr, proto_tree *tree, int ndr_flags)
{
guint32 len1, ofs, len2;
void ndr_pull_dom_sid2(struct e_ndr_pull *ndr, proto_tree *tree, int flags)
{
guint32 num_auths;
+
if (!(flags & NDR_SCALARS)) {
return;
}
}
}
-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;
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;
}
}
+void ndr_pull_array_uint16(struct e_ndr_pull *ndr, proto_tree *tree, int hf,
+ int ndr_flags, guint32 n)
+{
+ guint32 i;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return;
+ }
+ for (i=0;i<n;i++) {
+ ndr_pull_uint16(ndr, tree, hf, NULL);
+ }
+}
+
void ndr_pull_array_uint32(struct e_ndr_pull *ndr, proto_tree *tree, int hf,
int ndr_flags, guint32 n)
{
proto_tree *tree,
int ndr_flags))
{
+ proto_tree **subtrees;
int i;
+
+ subtrees = (proto_tree **)g_malloc(sizeof(proto_tree **) * count);
+
if (!(ndr_flags & NDR_SCALARS)) goto buffers;
for (i=0;i<count;i++) {
- pull_fn(ndr, tree, NDR_SCALARS);
+ 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);
+
+ 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;i<count;i++) {
- pull_fn(ndr, tree, NDR_BUFFERS);
+ if ((ndr_flags & (NDR_SCALARS|NDR_BUFFERS)) == (NDR_SCALARS|NDR_BUFFERS))
+ pull_fn(ndr, subtrees[i], NDR_BUFFERS);
+ else
+ pull_fn(ndr, tree, NDR_BUFFERS);
}
- done: ;
+ done:
+ g_free(subtrees);
+}
+
+struct subtree_info {
+ char *name;
+ proto_tree *subtree;
+};
+
+proto_tree *get_subtree(proto_tree *tree, char *name, struct e_ndr_pull *ndr,
+ gint ett)
+{
+ GSList *list, *l;
+ proto_item *item;
+ struct subtree_info *info;
+
+ /* Get current list value */
+
+ if (!tree)
+ return NULL;
+
+ list = (GSList *)tree->user_data;
+
+ /* Look for name */
+
+ for (l = list; l; l = g_slist_next(l)) {
+ info = l->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)
{ &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,
};
-
int proto_dcerpc;
proto_dcerpc = proto_get_id_by_filter_name("dcerpc");
proto_register_field_array(proto_dcerpc, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
}