summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-dcerpc-ndr.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-dcerpc-ndr.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-dcerpc-ndr.c')
-rw-r--r--epan/dissectors/packet-dcerpc-ndr.c576
1 files changed, 576 insertions, 0 deletions
diff --git a/epan/dissectors/packet-dcerpc-ndr.c b/epan/dissectors/packet-dcerpc-ndr.c
new file mode 100644
index 00000000..c4640da0
--- /dev/null
+++ b/epan/dissectors/packet-dcerpc-ndr.c
@@ -0,0 +1,576 @@
+/* packet-dcerpc-ndr.c
+ * Routines for DCERPC NDR dissection
+ * Copyright 2001, Todd Sabin <tas@webspan.net>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include "packet-dcerpc.h"
+
+
+/*
+ * The NDR routines are for use by dcerpc subdissetors. They're
+ * primarily for making sure things are aligned properly according
+ * to the rules of NDR.
+ */
+
+int
+dissect_ndr_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint8 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ /* no alignment needed */
+ return dissect_dcerpc_uint8(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+int
+PIDL_dissect_uint8_val(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param, guint8 *pval)
+{
+ guint8 val;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ /* no alignment needed */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo,
+ tree, drep, hfindex, &val);
+
+ if (param&PIDL_SET_COL_INFO) {
+ header_field_info *hf_info;
+ char *valstr;
+
+ hf_info = proto_registrar_get_nth(hfindex);
+
+ valstr = (char *)wmem_alloc(pinfo->pool, 64);
+ valstr[0]=0;
+
+ switch (hf_info->display) {
+ case BASE_DEC:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "%d", val);
+ }
+ break;
+ case BASE_HEX:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(0x%02x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "0x%02x", val);
+ }
+ break;
+ default:
+ REPORT_DISSECTOR_BUG("Invalid hf->display value");
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr);
+ }
+ if (pval) {
+ *pval = val;
+ }
+
+ return offset;
+}
+
+int
+PIDL_dissect_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param)
+{
+ return PIDL_dissect_uint8_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL);
+}
+
+
+int
+dissect_ndr_uint16(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint16 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+
+ if (!di->no_align && (offset % 2)) {
+ offset++;
+ }
+ return dissect_dcerpc_uint16(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+int
+PIDL_dissect_uint16_val(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param, guint16 *pval)
+{
+ guint16 val;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+
+ if (!di->no_align && (offset % 2)) {
+ offset++;
+ }
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo,
+ tree, drep, hfindex, &val);
+
+ if (param&PIDL_SET_COL_INFO) {
+ header_field_info *hf_info;
+ char *valstr;
+
+ hf_info = proto_registrar_get_nth(hfindex);
+
+ valstr = (char *)wmem_alloc(pinfo->pool, 64);
+ valstr[0]=0;
+
+ switch (hf_info->display) {
+ case BASE_DEC:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "%d", val);
+ }
+ break;
+ case BASE_HEX:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(0x%04x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "0x%04x", val);
+ }
+ break;
+ default:
+ REPORT_DISSECTOR_BUG("Invalid hf->display value");
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr);
+ }
+
+ if (pval) {
+ *pval = val;
+ }
+ return offset;
+}
+
+int
+PIDL_dissect_uint16(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param)
+{
+ return PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL);
+}
+
+int
+dissect_ndr_uint32(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if ((di != NULL) && (di->conformant_run)) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+
+ if ((di != NULL) && (!di->no_align) && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ return dissect_dcerpc_uint32(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+/* This is used to dissect the new datatypes, such as pointers and conformance
+ data, which is 4 bytes in size in NDR but 8 bytes in NDR64.
+*/
+int
+dissect_ndr_uint3264(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint3264 *pdata)
+{
+ if (di->call_data->flags & DCERPC_IS_NDR64) {
+ return dissect_ndr_uint64(tvb, offset, pinfo, tree, di, drep, hfindex, pdata);
+ } else {
+ guint32 val = 0;
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hfindex, &val);
+ if (pdata) {
+ *pdata = val;
+ }
+ return offset;
+ }
+}
+
+/* This is used to dissect the new datatypes, such as enums
+ that are 2 bytes in size in NDR but 4 bytes in NDR64.
+*/
+int
+dissect_ndr_uint1632(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint1632 *pdata)
+{
+ if (di->call_data->flags & DCERPC_IS_NDR64) {
+ return dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hfindex, pdata);
+ } else {
+ guint16 val = 0;
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep, hfindex, &val);
+ if (pdata) {
+ *pdata = val;
+ }
+ return offset;
+ }
+}
+
+int
+PIDL_dissect_uint32_val(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param, guint32 *rval)
+{
+ guint32 val;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo,
+ tree, drep, hfindex, &val);
+
+ if (param&PIDL_SET_COL_INFO) {
+ header_field_info *hf_info;
+ char *valstr;
+
+ hf_info = proto_registrar_get_nth(hfindex);
+
+ valstr = (char *)wmem_alloc(pinfo->pool, 64);
+ valstr[0]=0;
+
+ switch (hf_info->display) {
+ case BASE_DEC:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "%d", val);
+ }
+ break;
+ case BASE_HEX:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(0x%08x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "0x%08x", val);
+ }
+ break;
+ default:
+ REPORT_DISSECTOR_BUG("Invalid hf->display value");
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr);
+ }
+ if (rval != NULL) {
+ *rval = val;
+ }
+ return offset;
+}
+
+int
+PIDL_dissect_uint32(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param)
+{
+ return PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL);
+}
+
+/* Double uint32
+ This function dissects the 64bit datatype that is common for
+ ms interfaces and which is 32bit aligned.
+ It is really just 2 uint32's
+*/
+int
+dissect_ndr_duint32(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint64 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ return dissect_dcerpc_uint64(tvb, offset, pinfo,
+ tree, di, drep, hfindex, pdata);
+}
+
+/* uint64 : hyper
+ a 64 bit integer aligned to proper 8 byte boundaries
+*/
+int
+dissect_ndr_uint64(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint64 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 8)) {
+ gint padding = 8 - (offset % 8);
+ proto_tree_add_item(tree, hf_dcerpc_ndr_padding, tvb, offset, padding, ENC_NA);
+ offset += padding;
+ }
+ return dissect_dcerpc_uint64(tvb, offset, pinfo,
+ tree, di, drep, hfindex, pdata);
+}
+
+int
+PIDL_dissect_uint64_val(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param, guint64 *pval)
+{
+ guint64 val;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 8)) {
+ offset += 8 - (offset % 8);
+ }
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo,
+ tree, di, drep, hfindex, &val);
+
+ if (param&PIDL_SET_COL_INFO) {
+ header_field_info *hf_info;
+ char *valstr;
+
+ hf_info = proto_registrar_get_nth(hfindex);
+
+ valstr = (char *)wmem_alloc(pinfo->pool, 64);
+ valstr[0]=0;
+
+ switch (hf_info->display) {
+ case BASE_DEC:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(%" PRIu64 ")",val_to_str( (guint32) val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "%" PRIu64, val);
+ }
+ break;
+ case BASE_HEX:
+ if (hf_info->strings) {
+ snprintf(valstr, 64, "%s(0x%" PRIx64 ")",val_to_str( (guint32) val, (const value_string *)hf_info->strings, "Unknown:%u"), val);
+ } else {
+ snprintf(valstr, 64, "0x%" PRIx64, val);
+ }
+ break;
+ default:
+ REPORT_DISSECTOR_BUG("Invalid hf->display value");
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr);
+ }
+
+ if (pval) {
+ *pval = val;
+ }
+ return offset;
+}
+
+int
+PIDL_dissect_uint64(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 param)
+{
+ return PIDL_dissect_uint64_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL);
+}
+
+int
+dissect_ndr_float(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, gfloat *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ return dissect_dcerpc_float(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+
+int
+dissect_ndr_double(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, gdouble *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 8)) {
+ offset += 8 - (offset % 8);
+ }
+ return dissect_dcerpc_double(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+/* handles unix 32 bit time_t */
+int
+dissect_ndr_time_t(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, guint32 *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ *pdata = 0;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ return dissect_dcerpc_time_t(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+int
+dissect_ndr_uuid_t(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, e_guid_t *pdata)
+{
+ /* Some callers expect us to initialize pdata, even in error conditions, so
+ * do it right away in case we forget later */
+ if (pdata)
+ memset(pdata, 0, sizeof(*pdata));
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ /* uuid's are aligned to 4 bytes, due to initial uint32 in struct */
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ return dissect_dcerpc_uuid_t(tvb, offset, pinfo,
+ tree, drep, hfindex, pdata);
+}
+
+/*
+ * XXX - at least according to the DCE RPC 1.1 "nbase.idl", an
+ * "ndr_context_handle" is an unsigned32 "context_handle_attributes"
+ * and a uuid_t "context_handle_uuid". The attributes do not appear to
+ * be used, and always appear to be set to 0, in the DCE RPC 1.1 code.
+ *
+ * Should we display an "ndr_context_handle" with a tree holding the
+ * attributes and the uuid_t?
+ */
+int
+dissect_ndr_ctx_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ int hfindex, e_ctx_hnd *pdata)
+{
+ static e_ctx_hnd ctx_hnd;
+
+ if (di->conformant_run) {
+ /* just a run to handle conformant arrays, no scalars to dissect */
+ return offset;
+ }
+
+ if (!di->no_align && (offset % 4)) {
+ offset += 4 - (offset % 4);
+ }
+ ctx_hnd.attributes = dcerpc_tvb_get_ntohl(tvb, offset, drep);
+ dcerpc_tvb_get_uuid(tvb, offset+4, drep, &ctx_hnd.uuid);
+ if (tree) {
+ /* Bytes is bytes - don't worry about the data representation */
+ proto_tree_add_item(tree, hfindex, tvb, offset, 20, ENC_NA);
+ }
+ if (pdata) {
+ *pdata = ctx_hnd;
+ }
+ return offset + 20;
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */