svn commit: lorikeet r149 - in trunk/ethereal/plugins/pidl: .

tpot at samba.org tpot at samba.org
Mon Jan 3 00:34:30 GMT 2005


Author: tpot
Date: 2005-01-03 00:34:30 +0000 (Mon, 03 Jan 2005)
New Revision: 149

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=lorikeet&rev=149

Log:
Add helper functions for arrays and relative structures.

Modified:
   trunk/ethereal/plugins/pidl/eparser.c
   trunk/ethereal/plugins/pidl/eparser.h


Changeset:
Modified: trunk/ethereal/plugins/pidl/eparser.c
===================================================================
--- trunk/ethereal/plugins/pidl/eparser.c	2005-01-03 00:30:03 UTC (rev 148)
+++ trunk/ethereal/plugins/pidl/eparser.c	2005-01-03 00:34:30 UTC (rev 149)
@@ -583,3 +583,192 @@
         proto_register_field_array(proto_dcerpc, hf, array_length(hf));
         proto_register_subtree_array(ett, array_length(ett));
 }
+
+NTSTATUS ndr_pull_relative1(struct pidl_pull *ndr, const void *p, uint32_t rel_offset)
+{
+	if (ndr->flags & LIBNDR_FLAG_RELATIVE_CURRENT) {
+		return ndr_token_store(ndr, &ndr->relative_list, p, 
+				       rel_offset + ndr->offset - 4);
+	} else {
+		return ndr_token_store(ndr, &ndr->relative_list, p, rel_offset);
+	}
+}
+
+/*
+  pull a relative object - stage2
+  called during BUFFERS processing
+*/
+NTSTATUS ndr_pull_relative2(struct ndr_pull *ndr, const void *p)
+{
+	uint32_t rel_offset;
+	ndr_token_retrieve(&ndr->relative_list, p, &rel_offset);
+	return ndr_pull_set_offset(ndr, rel_offset);
+}
+
+/* save the offset/size of the current ndr state */
+void ndr_pull_save(struct pidl_pull *ndr, struct ndr_pull_save *save)
+{
+	save->offset = ndr->offset;
+//	save->data_size = ndr->data_size;
+}
+
+/* restore the size/offset of a ndr structure */
+void ndr_pull_restore(struct pidl_pull *ndr, struct ndr_pull_save *save)
+{
+	ndr->offset = save->offset;
+//	ndr->data_size = save->data_size;
+}
+
+
+static int hf_subcontext_size = -1;
+
+/*
+  handle subcontext buffers, which in midl land are user-marshalled, but
+  we use magic in pidl to make them easier to cope with
+*/
+static NTSTATUS ndr_pull_subcontext_header(struct pidl_pull *ndr, 
+					   pidl_tree *tree,
+					   size_t sub_size,
+					   struct pidl_pull *ndr2)
+{
+	switch (sub_size) {
+	case 0: {
+		uint32_t size = tvb_length(ndr->tvb) - ndr->offset;
+		if (size == 0) return NT_STATUS_OK;
+		ndr_pull_subcontext(ndr, ndr2, size);
+		break;
+	}
+
+	case 2: {
+		uint16_t size;
+		ndr_pull_uint16(ndr, tree, hf_subcontext_size, &size);
+		if (size == 0) return NT_STATUS_OK;
+		ndr_pull_subcontext(ndr, ndr2, size);
+		break;
+	}
+
+	case 4: {
+		uint32_t size;
+		ndr_pull_uint32(ndr, tree, hf_subcontext_size, &size);
+		if (size == 0) return NT_STATUS_OK;
+		ndr_pull_subcontext(ndr, ndr2, size);
+		break;
+	}
+	default:
+		return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", 
+				      sub_size);
+	}
+	return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_subcontext_flags_fn(struct pidl_pull *ndr, pidl_tree *tree,
+				      size_t sub_size, void *base, 
+				      ndr_pull_flags_fn_t fn)
+{
+	struct pidl_pull *ndr2;
+	NDR_ALLOC(ndr, ndr2);
+	ndr_pull_subcontext_header(ndr, tree, sub_size, ndr2);
+	fn(ndr2, NDR_SCALARS|NDR_BUFFERS, base);
+	if (sub_size) {
+		ndr_pull_advance(ndr, tvb_length(ndr2->tvb));
+	} else {
+		ndr_pull_advance(ndr, ndr2->offset);
+	}
+	return NT_STATUS_OK;
+}
+
+/*
+  create an ndr sub-context based on an existing context. The new context starts
+  at the current offset, with the given size limit
+*/
+NTSTATUS ndr_pull_subcontext(struct pidl_pull *ndr, struct pidl_pull *ndr2, uint32_t size)
+{
+	*ndr2 = *ndr;
+	ndr2->tvb = tvb_new_subset(ndr->tvb, ndr->offset, size, size);
+	ndr2->offset = 0;
+	ndr2->flags = ndr->flags;
+	return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_set_offset(struct pidl_pull *ndr, uint32_t ofs)
+{
+	ndr->offset = ofs;
+	if (ndr->offset > tvb_length(ndr->tvb)) {
+		return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, 
+				      "ndr_pull_set_offset %u failed",
+				      ofs);
+	}
+	return NT_STATUS_OK;
+}
+
+/*
+  advance by 'size' bytes
+*/
+NTSTATUS ndr_pull_advance(struct pidl_pull *ndr, uint32_t size)
+{
+	ndr->offset += size;
+	if (ndr->offset > tvb_length(ndr->tvb)) {
+		return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, 
+				      "ndr_pull_advance by %u failed",
+				      size);
+	}
+	return NT_STATUS_OK;
+}
+
+/*
+  check the stored array length field
+*/
+NTSTATUS ndr_check_array_length(struct pidl_pull *ndr, void *p, uint32_t length)
+{
+	uint32_t stored;
+	NDR_CHECK(ndr_token_retrieve(&ndr->array_length_list, p, &stored));
+	if (stored != length) {
+		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
+				      "Bad array length - got %u expected %u\n",
+				      stored, length);
+	}
+	return NT_STATUS_OK;
+}
+
+/*
+  get the stored array length field
+*/
+uint32_t ndr_get_array_length(struct pidl_pull *ndr, const void *p)
+{
+	return ndr_token_peek(&ndr->array_length_list, p);
+}
+
+static gint hf_dom_sid2_num_auths = -1;
+
+/*
+  parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
+*/
+NTSTATUS ndr_pull_dom_sid2(struct pidl_pull *ndr, int ndr_flags, pidl_tree *tree, struct dom_sid *sid)
+{
+	uint32_t num_auths;
+	if (!(ndr_flags & NDR_SCALARS)) {
+		return NT_STATUS_OK;
+	}
+	NDR_CHECK(ndr_pull_uint32(ndr, tree, hf_dom_sid2_num_auths, &num_auths));
+	return ndr_pull_dom_sid(ndr, ndr_flags, tree, sid);
+}
+
+static gint hf_array_length = -1;
+static gint hf_array_offset = -1;
+
+/*
+  pull an array length field and add it to the array_length_list token list
+*/
+NTSTATUS ndr_pull_array_length(struct pidl_pull *ndr, pidl_tree *tree, const void *p)
+{
+	uint32_t length, offset;
+	NDR_CHECK(ndr_pull_uint32(ndr, tree, hf_array_offset, &offset));
+	if (offset != 0) {
+		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
+				      "non-zero array offset %u\n", offset);
+	}
+	NDR_CHECK(ndr_pull_uint32(ndr, tree, hf_array_length, &length));
+	return ndr_token_store(ndr, &ndr->array_length_list, p, length);
+}
+
+gint hf_conformant_size = -1;

Modified: trunk/ethereal/plugins/pidl/eparser.h
===================================================================
--- trunk/ethereal/plugins/pidl/eparser.h	2005-01-03 00:30:03 UTC (rev 148)
+++ trunk/ethereal/plugins/pidl/eparser.h	2005-01-03 00:34:30 UTC (rev 149)
@@ -69,6 +69,8 @@
 
 	int flags;
 	struct ndr_token_list *array_size_list;
+	struct ndr_token_list *array_length_list;
+	struct ndr_token_list *relative_list;
 
 	// Ethereal fields
 
@@ -82,7 +84,14 @@
 struct pidl_pull *pidl_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, guint8 *drep);
 
 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
 
+#define dom_sid2 dom_sid
+
+// Field variables for common stuff
+
+extern gint hf_conformant_size;
+
 // Prototypes for libndr functions
 
 NTSTATUS ndr_pull_struct_start(struct pidl_pull *ndr);
@@ -116,5 +125,21 @@
 			       pidl_tree *tree, uint32_t *data, uint32_t n);
 NTSTATUS ndr_pull_time_t(struct pidl_pull *ndr, pidl_tree *tree, int hf, 
 			 time_t *data);
+NTSTATUS ndr_pull_relative1(struct pidl_pull *ndr, const void *p, uint32_t rel_offset);
+void ndr_pull_save(struct pidl_pull *ndr, struct ndr_pull_save *save);
+void ndr_pull_restore(struct pidl_pull *ndr, struct ndr_pull_save *save);
+NTSTATUS ndr_pull_subcontext_flags_fn(struct pidl_pull *ndr, pidl_tree *tree,
+				      size_t sub_size, void *base, 
+				      ndr_pull_flags_fn_t fn);
+NTSTATUS ndr_pull_subcontext(struct pidl_pull *ndr, struct pidl_pull *ndr2, uint32_t size);
+NTSTATUS ndr_pull_set_offset(struct pidl_pull *ndr, uint32_t ofs);
+NTSTATUS ndr_pull_advance(struct pidl_pull *ndr, uint32_t size);
+NTSTATUS ndr_check_array_length(struct pidl_pull *ndr, void *p, uint32_t length);
+uint32_t ndr_get_array_length(struct pidl_pull *ndr, const void *p);
+NTSTATUS ndr_pull_array_length(struct pidl_pull *ndr, pidl_tree *tree, const void *p);
 
+// Just about everything uses stuff from misc.idl
+
+#include "packet-dcerpc-misc.h"
+
 #endif /* _eparser_h */



More information about the samba-cvs mailing list