Ethereal-dev: [Ethereal-dev] a few things for dcerpc
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Todd Sabin <tas@xxxxxxxxxxx>
Date: 18 Nov 2001 19:44:51 -0500
Here's a patch (and a new file) for some dcerpc stuff. It does the following: o Modifies the dcerpc handoff to subdissectors slightly. It also needs to pass the data representation to the subdissector. Also, if no subdissector is found, it puts a "Stub data" entry in the tree. o Adds optional TCP desegmentation to the dcerpc layer. Note that dcerpc has it's own ability to fragment PDUs. This isn't for dealing with that, but with the case of a single PDU being broken over more than one TCP segment. o Adds a little bit of dissection to packet-dcerpc-epm.c. Mainly just proof of concept for the dcerpc handoff stuff. (Writing this is how I realized the need for the drep.) o Adds packet-dcerpc-ndr.c, which will contain NDR dissection routines for use by subdissectors. Todd
? packet-dcerpc-ndr.c
Index: Makefile.am
===================================================================
RCS file: /cvsroot/ethereal/Makefile.am,v
retrieving revision 1.381
diff -u -r1.381 Makefile.am
--- Makefile.am 2001/11/15 21:11:01 1.381
+++ Makefile.am 2001/11/19 00:17:40
@@ -100,6 +100,7 @@
packet-dcerpc-conv.c \
packet-dcerpc-epm.c \
packet-dcerpc-mgmt.c \
+ packet-dcerpc-ndr.c \
packet-dcerpc-remact.c \
packet-dcerpc-oxid.c \
packet-ddtp.c \
Index: packet-dcerpc-epm.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc-epm.c,v
retrieving revision 1.1
diff -u -r1.1 packet-dcerpc-epm.c
--- packet-dcerpc-epm.c 2001/07/11 01:25:44 1.1
+++ packet-dcerpc-epm.c 2001/11/19 00:17:40
@@ -41,6 +41,18 @@
static int proto_epm = -1;
+static int hf_epm_inquiry_type = -1;
+static int hf_epm_object_p = -1;
+static int hf_epm_object = -1;
+static int hf_epm_if_id_p = -1;
+static int hf_epm_if_id = -1;
+static int hf_epm_ver_maj = -1;
+static int hf_epm_ver_min = -1;
+static int hf_epm_ver_opt = -1;
+static int hf_epm_lookup_hnd = -1;
+static int hf_epm_max_ents = -1;
+static int hf_epm_num_ents = -1;
+
static gint ett_epm = -1;
@@ -48,10 +60,69 @@
static guint16 ver_epm = 3;
+static int
+epm_dissect_ept_lookup_rqst (tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ guint32 dummy;
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_inquiry_type, NULL);
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_object_p, &dummy);
+ if (dummy) {
+ offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep,
+ hf_epm_object, NULL);
+ }
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_if_id_p, &dummy);
+ if (dummy) {
+ offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep,
+ hf_epm_if_id, NULL);
+ offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
+ hf_epm_ver_maj, NULL);
+ offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
+ hf_epm_ver_min, NULL);
+ }
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_ver_opt, NULL);
+ if (tree) {
+ proto_tree_add_bytes (tree, hf_epm_lookup_hnd, tvb, offset, 20,
+ tvb_get_ptr (tvb, offset, 20));
+ }
+ offset += 20;
+
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_max_ents, NULL);
+ return offset;
+}
+
+
+static int
+epm_dissect_ept_lookup_resp (tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ guint32 dummy;
+
+ /* need a dissect_ndr_ctx_handle */
+ if (tree) {
+ proto_tree_add_bytes (tree, hf_epm_lookup_hnd, tvb, offset, 20,
+ tvb_get_ptr (tvb, offset, 20));
+ }
+ offset += 20;
+
+ offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+ hf_epm_num_ents, NULL);
+ /* FIXME: more to do here */
+ return offset;
+}
+
+
static dcerpc_sub_dissector epm_dissectors[] = {
{ 0, "ept_insert", NULL, NULL },
{ 1, "ept_delete", NULL, NULL },
- { 2, "ept_lookup", NULL, NULL },
+ { 2, "ept_lookup", epm_dissect_ept_lookup_rqst, epm_dissect_ept_lookup_resp },
{ 3, "ept_map", NULL, NULL },
{ 4, "ept_lookup_handle_free", NULL, NULL },
{ 5, "ept_inq_object", NULL, NULL },
@@ -63,18 +134,36 @@
void
proto_register_epm (void)
{
-#if 0
static hf_register_info hf[] = {
- };
-#endif
+ { &hf_epm_inquiry_type,
+ { "Inquiry type", "epm.inq_type", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_object_p,
+ { "Object pointer", "epm.object_p", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_object,
+ { "Object", "epm.object", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_epm_if_id_p,
+ { "Interface pointer", "epm.if_id_p", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_if_id,
+ { "Interface", "epm.if_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_epm_ver_maj,
+ { "Version Major", "epm.ver_maj", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_ver_min,
+ { "Version Minor", "epm.ver_min", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_ver_opt,
+ { "Version Option", "epm.ver_opt", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_lookup_hnd,
+ { "Lookup Handle", "epm.lookup_hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_epm_max_ents,
+ { "Max entries", "epm.max_ents", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_epm_num_ents,
+ { "Num entries", "epm.num_ents", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ };
static gint *ett[] = {
&ett_epm,
};
proto_epm = proto_register_protocol ("DCE/RPC Endpoint Mapper", "EPM", "epm");
-#if 0
proto_register_field_array (proto_epm, hf, array_length (hf));
-#endif
proto_register_subtree_array (ett, array_length (ett));
}
Index: packet-dcerpc.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.c,v
retrieving revision 1.14
diff -u -r1.14 packet-dcerpc.c
--- packet-dcerpc.c 2001/11/12 09:04:11 1.14
+++ packet-dcerpc.c 2001/11/19 00:17:40
@@ -38,6 +38,7 @@
#include "packet.h"
#include "packet-dcerpc.h"
#include "conversation.h"
+#include "prefs.h"
static const value_string pckt_vals[] = {
{ 0, "Request"},
@@ -169,6 +170,9 @@
static gint ett_dcerpc_dg_flags1 = -1;
static gint ett_dcerpc_dg_flags2 = -1;
+/* try to desegment big DCE/RPC packets over TCP? */
+static gboolean dcerpc_cn_desegment = TRUE;
+
/*
* Subdissectors
*/
@@ -425,15 +429,16 @@
proto_tree *dcerpc_tree,
tvbuff_t *tvb, gint offset,
e_uuid_t *uuid, guint16 ver,
- guint16 opnum, gboolean is_rqst)
+ guint16 opnum, gboolean is_rqst,
+ char *drep)
{
dcerpc_uuid_key key;
dcerpc_uuid_value *sub_proto;
int length;
- proto_item *sub_item;
proto_tree *sub_tree = NULL;
dcerpc_sub_dissector *proc;
gchar *name = NULL;
+ dcerpc_dissect_fnct_t *sub_dissect;
key.uuid = *uuid;
key.ver = ver;
@@ -450,6 +455,7 @@
}
if (tree) {
+ proto_item *sub_item;
sub_item = proto_tree_add_item (tree, sub_proto->proto, tvb, offset,
tvb_length (tvb) - offset, FALSE);
if (sub_item) {
@@ -476,14 +482,17 @@
col_set_str (pinfo->fd, COL_PROTOCOL, sub_proto->name);
}
- if (is_rqst) {
- if (proc->dissect_rqst)
- return proc->dissect_rqst(tvb, offset, pinfo, sub_tree);
+ sub_dissect = is_rqst ? proc->dissect_rqst : proc->dissect_resp;
+ if (sub_dissect) {
+ sub_dissect (tvb, offset, pinfo, sub_tree, drep);
} else {
- if (proc->dissect_resp)
- return proc->dissect_resp(tvb, offset, pinfo, sub_tree);
+ length = tvb_length_remaining (tvb, offset);
+ if (length > 0) {
+ proto_tree_add_text (sub_tree, tvb, offset, length,
+ "Stub data (%d byte%s)", length,
+ plurality(length, "", "s"));
+ }
}
-
return 0;
}
@@ -817,7 +826,7 @@
tvb_new_subset (tvb, offset, length,
reported_length),
0, &value->uuid, value->ver,
- opnum, TRUE);
+ opnum, TRUE, hdr->drep);
}
}
}
@@ -870,7 +879,7 @@
tvb_new_subset (tvb, offset, length,
reported_length),
0, &value->uuid, value->ver,
- value->opnum, FALSE);
+ value->opnum, FALSE, hdr->drep);
}
}
}
@@ -929,6 +938,13 @@
hdr.call_id = dcerpc_tvb_get_ntohl (tvb, offset, hdr.drep);
offset += 4;
+ if (dcerpc_cn_desegment && pinfo->can_desegment
+ && hdr.frag_len > tvb_length_remaining (tvb, 0)) {
+ pinfo->desegment_offset = 0;
+ pinfo->desegment_len = hdr.frag_len - tvb_length_remaining (tvb, 0);
+ return TRUE;
+ }
+
if (tree) {
ti = proto_tree_add_item (tree, proto_dcerpc, tvb, 0, tvb_length(tvb), FALSE);
if (ti) {
@@ -1213,17 +1229,17 @@
dcerpc_call_add_map (hdr.seqnum, conv, hdr.opnum,
hdr.if_ver, &hdr.if_id);
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, tvb, offset,
- &hdr.if_id, hdr.if_ver, hdr.opnum, TRUE);
+ &hdr.if_id, hdr.if_ver, hdr.opnum, TRUE, hdr.drep);
break;
case PDU_RESP:
{
dcerpc_call_value *v = dcerpc_call_lookup (hdr.seqnum, conv);
if (v) {
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, tvb, offset,
- &v->uuid, v->ver, v->opnum, FALSE);
+ &v->uuid, v->ver, v->opnum, FALSE, hdr.drep);
} else {
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, tvb, offset,
- &hdr.if_id, hdr.if_ver, hdr.opnum, FALSE);
+ &hdr.if_id, hdr.if_ver, hdr.opnum, FALSE, hdr.drep);
}
}
break;
@@ -1438,6 +1454,12 @@
proto_register_subtree_array (ett, array_length (ett));
register_init_routine (dcerpc_init_protocol);
+ prefs_register_bool_preference (prefs_register_protocol (proto_dcerpc,
+ NULL),
+ "desegment_dcerpc",
+ "Desegment all DCE/RPC over TCP",
+ "Whether the DCE/RPC dissector should desegment all DCE/RPC over TCP",
+ &dcerpc_cn_desegment);
dcerpc_uuids = g_hash_table_new (dcerpc_uuid_hash, dcerpc_uuid_equal);
}
Index: packet-dcerpc.h
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.h,v
retrieving revision 1.2
diff -u -r1.2 packet-dcerpc.h
--- packet-dcerpc.h 2001/07/11 01:25:45 1.2
+++ packet-dcerpc.h 2001/11/19 00:17:40
@@ -83,12 +83,43 @@
#define PDU_ALTER_ACK 15
#define PDU_AUTH3 16
-
+/*
+ * helpers for packet-dcerpc.c and packet-dcerpc-ndr.c
+ * If you're writing a subdissector, you almost certainly want the
+ * NDR functions below.
+ */
guint16 dcerpc_tvb_get_ntohs (tvbuff_t *tvb, gint offset, char *drep);
guint32 dcerpc_tvb_get_ntohl (tvbuff_t *tvb, gint offset, char *drep);
void dcerpc_tvb_get_uuid (tvbuff_t *tvb, gint offset, char *drep, e_uuid_t *uuid);
+int dissect_dcerpc_uint8 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint8 *pdata);
+int dissect_dcerpc_uint16 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint16 *pdata);
+int dissect_dcerpc_uint32 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint32 *pdata);
+
+
+/*
+ * NDR routines for subdissectors.
+ */
+int dissect_ndr_uint8 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint8 *pdata);
+int dissect_ndr_uint16 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint16 *pdata);
+int dissect_ndr_uint32 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint32 *pdata);
+int dissect_ndr_uuid_t (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, e_uuid_t *pdata);
+
-typedef int (dcerpc_dissect_fnct_t)(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+typedef int (dcerpc_dissect_fnct_t)(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *drep);
typedef struct _dcerpc_sub_dissector {
guint16 num;
/* packet-dcerpc-ndr.c
* Routines for DCERPC NDR dissection
* Copyright 2001, Todd Sabin <tas@xxxxxxxxxxx>
*
* $Id: $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <string.h>
#include <ctype.h>
#include <glib.h>
#include "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, char *drep,
int hfindex, guint8 *pdata)
{
/* no alignment needed */
return dissect_dcerpc_uint8 (tvb, offset, pinfo,
tree, drep, hfindex, pdata);
}
int
dissect_ndr_uint16 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep,
int hfindex, guint16 *pdata)
{
if (offset % 2) {
offset++;
}
return dissect_dcerpc_uint16 (tvb, offset, pinfo,
tree, drep, hfindex, pdata);
}
int
dissect_ndr_uint32 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep,
int hfindex, guint32 *pdata)
{
if (offset % 4) {
offset += 4 - (offset % 4);
}
return dissect_dcerpc_uint32 (tvb, offset, pinfo,
tree, drep, hfindex, pdata);
}
int
dissect_ndr_uuid_t (tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, char *drep,
int hfindex, e_uuid_t *pdata)
{
e_uuid_t uuid;
/* uuid's are aligned to 4 bytes, due to initial uint32 in struct */
if (offset % 4) {
offset += 4 - (offset % 4);
}
dcerpc_tvb_get_uuid (tvb, offset, drep, &uuid);
if (tree) {
proto_tree_add_string_format (tree, hfindex, tvb, offset, 16, "",
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid.Data1, uuid.Data2, uuid.Data3,
uuid.Data4[0], uuid.Data4[1],
uuid.Data4[2], uuid.Data4[3],
uuid.Data4[4], uuid.Data4[5],
uuid.Data4[6], uuid.Data4[7]);
}
if (pdata) {
*pdata = uuid;
}
return offset + 16;
}
- Follow-Ups:
- Re: [Ethereal-dev] a few things for dcerpc
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] a few things for dcerpc
- From: Guy Harris
- Re: [Ethereal-dev] a few things for dcerpc
- Prev by Date: Re: [Ethereal-dev] [PATCH] fid tracking
- Next by Date: Re: [Ethereal-dev] [PATCH] Ethereal dissectors for Microsoft Windows NT DCE/RPC
- Previous by thread: Re: [Ethereal-dev] Time codes for text2pcap?
- Next by thread: Re: [Ethereal-dev] a few things for dcerpc
- Index(es):





