Ethereal-dev: dcerpc patch (was Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector
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: 09 Jul 2001 08:03:02 -0400
ulf.lamping@xxxxxx writes: > > Do you know, if the .idl syntax for the DCE-RPC and DCOM are identical? If > not, do you have an example DCE-RPC idl file (just for my information at this > devel stage)? > > Do you have some further information about the DCE-RPC protocol? > The IDL for DCOM is defined by Microsoft. I don't know if there's an official spec for it, other than what their IDL compiler accepts. It is based on the original dce-rpc idl, but has many extensions. The original is documented at http://www.opengroup.org. Search for DCE RPC 1.1. It used to be freely available, but seems you may have to register for it now. That document also describes the basic DCE/RPC wire protocol. > Is the "handoff stage" on your to-do list, or are you already working on it? > Well, I hadn't started, and I was describing what I was going to do, when it suddenly seemed like it wouldn't be all that bad. :-) Naturally, it turned out to be more than expected. Anyway, here's a patch to do almost all of the handoff, and a few subdissectors which use it. None of them dissect any of the actual payload, yet, but they do show the names of the calls. Could someone double-check the conversation/hash stuff for leaks? I used pretty much the same approach used by packet-rpc.c, so assuming it's ok, then I think this is as well, but... Todd p.s. I tend to agree with the other poster about putting the subdissectors for GIOP in a subdirectory or something. The same is true for dcerpc. There are literally hundreds of these things which can be written.
Index: packet-dcerpc.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.c,v
retrieving revision 1.5
diff -u -r1.5 packet-dcerpc.c
--- packet-dcerpc.c 2001/06/18 02:17:45 1.5
+++ packet-dcerpc.c 2001/07/09 11:16:58
@@ -37,6 +37,7 @@
#include <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
+#include "conversation.h"
static const value_string pckt_vals[] = {
{ 0, "Request"},
@@ -92,6 +93,7 @@
static int hf_dcerpc_cn_num_trans_items = -1;
static int hf_dcerpc_cn_bind_if_id = -1;
static int hf_dcerpc_cn_bind_if_ver = -1;
+static int hf_dcerpc_cn_bind_if_ver_minor = -1;
static int hf_dcerpc_cn_bind_trans_id = -1;
static int hf_dcerpc_cn_bind_trans_ver = -1;
static int hf_dcerpc_cn_alloc_hint = -1;
@@ -99,6 +101,7 @@
static int hf_dcerpc_cn_num_results = -1;
static int hf_dcerpc_cn_ack_result = -1;
static int hf_dcerpc_cn_ack_reason = -1;
+static int hf_dcerpc_cn_cancel_count = -1;
static int hf_dcerpc_dg_flags1 = -1;
static int hf_dcerpc_dg_flags1_rsrvd_01 = -1;
static int hf_dcerpc_dg_flags1_last_frag = -1;
@@ -137,7 +140,216 @@
static gint ett_dcerpc_dg_flags1 = -1;
static gint ett_dcerpc_dg_flags2 = -1;
+/*
+ * Subdissectors
+ */
+
+/* the registered subdissectors */
+static GHashTable *dcerpc_uuids;
+
+typedef struct _dcerpc_uuid_key {
+ e_uuid_t uuid;
+ guint16 ver;
+} dcerpc_uuid_key;
+
+typedef struct _dcerpc_uuid_value {
+ int proto;
+ int ett;
+ gchar *name;
+ dcerpc_sub_dissector *procs;
+} dcerpc_uuid_value;
+
+static gint
+dcerpc_uuid_equal (gconstpointer k1, gconstpointer k2)
+{
+ dcerpc_uuid_key *key1 = (dcerpc_uuid_key *)k1;
+ dcerpc_uuid_key *key2 = (dcerpc_uuid_key *)k2;
+ return ((memcmp (&key1->uuid, &key2->uuid, sizeof (e_uuid_t)) == 0)
+ && (key1->ver == key2->ver));
+}
+
+static guint
+dcerpc_uuid_hash (gconstpointer k)
+{
+ dcerpc_uuid_key *key = (dcerpc_uuid_key *)k;
+ /* This isn't perfect, but the Data1 part of these is almost always
+ unique. */
+ return key->uuid.Data1;
+}
+
+void
+dcerpc_init_uuid (int proto, int ett, e_uuid_t *uuid, guint16 ver,
+ dcerpc_sub_dissector *procs)
+{
+ dcerpc_uuid_key *key = g_malloc (sizeof (*key));
+ dcerpc_uuid_value *value = g_malloc (sizeof (*value));
+
+ key->uuid = *uuid;
+ key->ver = ver;
+
+ value->proto = proto;
+ value->ett = ett;
+ value->name = proto_get_protocol_short_name (proto);
+ value->procs = procs;
+
+ g_hash_table_insert (dcerpc_uuids, key, value);
+}
+
+
+/*
+ * To keep track of ctx_id mappings. Should really use some
+ * generic conversation support instead.
+ */
+static GHashTable *dcerpc_convs;
+
+typedef struct _dcerpc_conv_key {
+ conversation_t *conv;
+ guint16 ctx_id;
+} dcerpc_conv_key;
+
+typedef struct _dcerpc_conv_value {
+ e_uuid_t uuid;
+ guint16 ver;
+} dcerpc_conv_value;
+
+static gint
+dcerpc_conv_equal (gconstpointer k1, gconstpointer k2)
+{
+ dcerpc_conv_key *key1 = (dcerpc_conv_key *)k1;
+ dcerpc_conv_key *key2 = (dcerpc_conv_key *)k2;
+ return (key1->conv == key2->conv
+ && key1->ctx_id == key2->ctx_id);
+}
+
+static guint
+dcerpc_conv_hash (gconstpointer k)
+{
+ dcerpc_conv_key *key = (dcerpc_conv_key *)k;
+ return ((guint)key->conv) + key->ctx_id;
+}
+
+
+
+/*
+ * To keep track of callid mappings. Should really use some generic
+ * conversation support instead.
+ */
+static GHashTable *dcerpc_calls;
+
+typedef struct _dcerpc_call_key {
+ conversation_t *conv;
+ guint32 call_id;
+} dcerpc_call_key;
+
+typedef struct _dcerpc_call_value {
+ e_uuid_t uuid;
+ guint16 ver;
+ guint16 opnum;
+} dcerpc_call_value;
+
+static gint
+dcerpc_call_equal (gconstpointer k1, gconstpointer k2)
+{
+ dcerpc_call_key *key1 = (dcerpc_call_key *)k1;
+ dcerpc_call_key *key2 = (dcerpc_call_key *)k2;
+ return (key1->conv == key2->conv
+ && key1->call_id == key2->call_id);
+}
+
+static guint
+dcerpc_call_hash (gconstpointer k)
+{
+ dcerpc_call_key *key = (dcerpc_call_key *)k;
+ return ((guint32)key->conv) ^ key->call_id;
+}
+
+static void
+dcerpc_call_add_map (guint32 call_id, conversation_t *conv,
+ guint16 opnum, guint16 ver, e_uuid_t *uuid)
+{
+ dcerpc_call_key *key = g_malloc (sizeof (*key));
+ dcerpc_call_value *value = g_malloc (sizeof (*value));
+
+ key->call_id = call_id;
+ key->conv = conv;
+ value->uuid = *uuid;
+ value->ver = ver;
+ value->opnum = opnum;
+ g_hash_table_insert (dcerpc_calls, key, value);
+}
+
+static dcerpc_call_value*
+dcerpc_call_lookup (guint32 call_id, conversation_t *conv)
+{
+ dcerpc_call_key key;
+
+ key.call_id = call_id;
+ key.conv = conv;
+ return g_hash_table_lookup (dcerpc_calls, &key);
+}
+
+
+/*
+ * Utility functions. Modeled after packet-rpc.c
+ */
+
+int
+dissect_dcerpc_uint8 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint8 *pdata)
+{
+ guint8 data;
+
+ data = tvb_get_guint8 (tvb, offset);
+ if (tree) {
+ proto_tree_add_item (tree, hfindex, tvb, offset, 1, (drep[0] & 0x10));
+ }
+ if (pdata)
+ *pdata = data;
+ return offset + 1;
+}
+
+int
+dissect_dcerpc_uint16 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint16 *pdata)
+{
+ guint16 data;
+
+ data = ((drep[0] & 0x10)
+ ? tvb_get_letohs (tvb, offset)
+ : tvb_get_ntohs (tvb, offset));
+
+ if (tree) {
+ proto_tree_add_item (tree, hfindex, tvb, offset, 2, (drep[0] & 0x10));
+ }
+ if (pdata)
+ *pdata = data;
+ return offset + 2;
+}
+int
+dissect_dcerpc_uint32 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, char *drep,
+ int hfindex, guint32 *pdata)
+{
+ guint32 data;
+
+ data = ((drep[0] & 0x10)
+ ? tvb_get_letohl (tvb, offset)
+ : tvb_get_ntohl (tvb, offset));
+
+ if (tree) {
+ proto_tree_add_item (tree, hfindex, tvb, offset, 4, (drep[0] & 0x10));
+ }
+ if (pdata)
+ *pdata = data;
+ return offset+4;
+}
+
+/*
+ * a couple simpler things
+ */
guint16
dcerpc_tvb_get_ntohs (tvbuff_t *tvb, gint offset, char *drep)
{
@@ -171,122 +383,166 @@
}
}
+static int
+dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, gint offset,
+ e_uuid_t *uuid, guint16 ver,
+ guint16 opnum, gboolean is_rqst)
+{
+ dcerpc_uuid_key key;
+ dcerpc_uuid_value *sub_proto;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ dcerpc_sub_dissector *proc;
+ gchar *name = NULL;
+
+ key.uuid = *uuid;
+ key.ver = ver;
+
+
+ if ((sub_proto = g_hash_table_lookup (dcerpc_uuids, &key)) == 0)
+ return -1;
+ if (tree) {
+ sub_item = proto_tree_add_item (tree, sub_proto->proto, tvb, offset,
+ tvb_length (tvb) - offset, FALSE);
+ if (sub_item) {
+ sub_tree = proto_item_add_subtree (sub_item, sub_proto->ett);
+ }
+
+ }
+ for (proc = sub_proto->procs; proc->name; proc++) {
+ if (proc->num == opnum) {
+ name = proc->name;
+ break;
+ }
+ }
+
+ if (!name)
+ name = "Unknown?!";
+
+ if (check_col (pinfo->fd, COL_INFO)) {
+ col_add_fstr (pinfo->fd, COL_INFO, "%s %s:%s(...)",
+ is_rqst ? "rqst" : "rply",
+ sub_proto->name, name);
+ }
+
+ if (check_col (pinfo->fd, COL_PROTOCOL)) {
+ col_set_str (pinfo->fd, COL_PROTOCOL, sub_proto->name);
+ }
+ // FIXME: call approp. dissector
+ return 0;
+}
+
+
+/*
+ * Connection oriented packet types
+ */
+
static void
dissect_dcerpc_cn_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
e_dce_cn_common_hdr_t *hdr)
{
- guint16 max_xmit, max_recv;
- guint32 assoc_group;
+ conversation_t *conv = NULL;
+ dcerpc_conv_key *key;
+ dcerpc_conv_value *value;
guint8 num_ctx_items;
guint16 ctx_id;
guint16 num_trans_items;
e_uuid_t if_id;
e_uuid_t trans_id;
- guint32 if_ver, trans_ver;
+ guint32 trans_ver;
+ guint16 if_ver, if_ver_minor;
int offset = 16;
- max_xmit = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_max_xmit, NULL);
- max_recv = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_max_recv, NULL);
- assoc_group = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
- offset += 4;
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_assoc_group, NULL);
- num_ctx_items = tvb_get_guint8 (tvb, offset);
- offset++;
+ offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_num_ctx_items, &num_ctx_items);
/* padding */
offset += 3;
- ctx_id = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_ctx_id, &ctx_id);
- num_trans_items = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_num_trans_items, &num_trans_items);
dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &if_id);
- offset += 16;
-
- if_ver = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
- offset += 4;
-
- dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &trans_id);
- offset += 16;
-
- trans_ver = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
- offset += 4;
-
- if (check_col (pinfo->fd, COL_INFO)) {
- col_add_fstr (pinfo->fd, COL_INFO, "Bind: UUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ver %d",
- if_id.Data1, if_id.Data2, if_id.Data3,
- if_id.Data4[0], if_id.Data4[1],
- if_id.Data4[2], if_id.Data4[3],
- if_id.Data4[4], if_id.Data4[5],
- if_id.Data4[6], if_id.Data4[7],
- if_ver);
- }
-
if (dcerpc_tree) {
- offset = 16;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_max_xmit, tvb, offset, 2, max_xmit);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_max_recv, tvb, offset, 2, max_recv);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_assoc_group, tvb, offset, 4, assoc_group);
- offset += 4;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_num_ctx_items, tvb, offset, 1, num_ctx_items);
- offset++;
-
- /* padding */
- offset += 3;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_ctx_id, tvb, offset, 2, ctx_id);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_num_trans_items, tvb, offset, 2, num_trans_items);
- offset += 2;
-
proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_cn_bind_if_id, tvb,
offset, 16, "HMMM",
"Interface UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
if_id.Data1, if_id.Data2, if_id.Data3,
- if_id.Data4[0],
- if_id.Data4[1],
- if_id.Data4[2],
- if_id.Data4[3],
- if_id.Data4[4],
- if_id.Data4[5],
- if_id.Data4[6],
- if_id.Data4[7]);
- offset += 16;
+ if_id.Data4[0], if_id.Data4[1],
+ if_id.Data4[2], if_id.Data4[3],
+ if_id.Data4[4], if_id.Data4[5],
+ if_id.Data4[6], if_id.Data4[7]);
+ }
+ offset += 16;
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_bind_if_ver, tvb, offset, 4, if_ver);
- offset += 4;
+ if (hdr->drep[0] & 0x10) {
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_bind_if_ver, &if_ver);
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_bind_if_ver_minor, &if_ver_minor);
+ } else {
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_bind_if_ver_minor, &if_ver_minor);
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_bind_if_ver, &if_ver);
+ }
+ dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &trans_id);
+ if (dcerpc_tree) {
proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_cn_bind_trans_id, tvb,
offset, 16, "HMMM",
"Transfer Syntax: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
trans_id.Data1, trans_id.Data2, trans_id.Data3,
- trans_id.Data4[0],
- trans_id.Data4[1],
- trans_id.Data4[2],
- trans_id.Data4[3],
- trans_id.Data4[4],
- trans_id.Data4[5],
- trans_id.Data4[6],
- trans_id.Data4[7]);
- offset += 16;
+ trans_id.Data4[0], trans_id.Data4[1],
+ trans_id.Data4[2], trans_id.Data4[3],
+ trans_id.Data4[4], trans_id.Data4[5],
+ trans_id.Data4[6], trans_id.Data4[7]);
+ }
+ offset += 16;
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_bind_trans_ver, tvb, offset, 4, trans_ver);
- offset += 4;
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_bind_trans_ver, &trans_ver);
+
+ if (check_col (pinfo->fd, COL_INFO)) {
+ col_add_fstr (pinfo->fd, COL_INFO, "%s: UUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ver %d.%d",
+ hdr->ptype == PDU_BIND ? "Bind" : "Alter Ctx",
+ if_id.Data1, if_id.Data2, if_id.Data3,
+ if_id.Data4[0], if_id.Data4[1],
+ if_id.Data4[2], if_id.Data4[3],
+ if_id.Data4[4], if_id.Data4[5],
+ if_id.Data4[6], if_id.Data4[7],
+ if_ver, if_ver_minor);
+ }
+ conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (conv == NULL) {
+ conv = conversation_new (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, NULL, 0);
}
+
+ key = g_malloc (sizeof (*key));
+ key->conv = conv;
+ key->ctx_id = ctx_id;
+
+ value = g_malloc (sizeof (*value));
+ value->uuid = if_id;
+ value->ver = if_ver;
+
+ g_hash_table_insert (dcerpc_convs, key, value);
}
static void
@@ -294,7 +550,6 @@
e_dce_cn_common_hdr_t *hdr)
{
guint16 max_xmit, max_recv;
- guint32 assoc_group;
guint16 sec_addr_len;
guint8 num_results;
guint16 result = 0;
@@ -302,128 +557,77 @@
int offset = 16;
- max_xmit = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_max_xmit, &max_xmit);
- max_recv = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_max_recv, &max_recv);
- assoc_group = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
- offset += 4;
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_assoc_group, NULL);
- sec_addr_len = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2 + sec_addr_len;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_sec_addr_len, &sec_addr_len);
+ offset += sec_addr_len;
if (offset % 4) {
offset += 4 - offset % 4;
}
- num_results = tvb_get_guint8 (tvb, offset);
- offset++;
+ offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_num_results, &num_results);
/* padding */
offset += 3;
if (num_results == 1) {
- result = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
-
- reason = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree,
+ hdr->drep, hf_dcerpc_cn_ack_result,
+ &result);
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree,
+ hdr->drep, hf_dcerpc_cn_ack_reason,
+ &reason);
}
if (check_col (pinfo->fd, COL_INFO)) {
if (num_results == 1 && result == 0) {
- col_add_fstr (pinfo->fd, COL_INFO, "Bind ack: accept max_xmit: %d max_recv: %d",
- max_xmit, max_recv);
-
+ col_add_fstr (pinfo->fd, COL_INFO, "%s ack: accept max_xmit: %d max_recv: %d",
+ hdr->ptype == PDU_BIND_ACK ? "Bind" : "Alter ctx",
+ max_xmit, max_recv);
} else {
/* FIXME: should put in reason */
- col_add_fstr (pinfo->fd, COL_INFO, "Bind ack: %s",
- result == 1 ? "User reject" :
- result == 2 ? "Provider reject" :
- "Unknown");
- }
- }
-
- if (dcerpc_tree) {
- offset = 16;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_max_xmit, tvb, offset, 2, max_xmit);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_max_recv, tvb, offset, 2, max_recv);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_assoc_group, tvb, offset, 4, assoc_group);
- offset += 4;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_sec_addr_len, tvb, offset, 2, sec_addr_len);
- offset +=2 + sec_addr_len;
-
- if (offset % 4) {
- offset += 4 - offset % 4;
- }
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_num_results, tvb, offset, 1, num_results);
- offset++;
-
- /* padding */
- offset += 3;
-
- if (num_results == 1) {
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_ack_result, tvb, offset, 2, result);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_ack_reason, tvb, offset, 2, reason);
- offset += 2;
+ col_add_fstr (pinfo->fd, COL_INFO, "%s ack: %s",
+ hdr->ptype == PDU_BIND_ACK ? "Bind" : "Alter ctx",
+ result == 1 ? "User reject" :
+ result == 2 ? "Provider reject" :
+ "Unknown");
}
}
}
static void
dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
- e_dce_cn_common_hdr_t *hdr)
+ proto_tree *tree, e_dce_cn_common_hdr_t *hdr)
{
- guint32 alloc_hint;
+ conversation_t *conv;
guint16 ctx_id;
guint16 opnum;
e_uuid_t obj_id;
int offset = 16;
- alloc_hint = dcerpc_tvb_get_ntohl (tvb, offset, hdr->drep);
- offset += 4;
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_alloc_hint, NULL);
- ctx_id = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_ctx_id, &ctx_id);
- opnum = dcerpc_tvb_get_ntohs (tvb, offset, hdr->drep);
- offset += 2;
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_opnum, &opnum);
if (hdr->flags & 0x80) {
dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &obj_id);
- offset += 16;
- }
-
- if (check_col (pinfo->fd, COL_INFO)) {
- col_add_fstr (pinfo->fd, COL_INFO, "Request: opnum: %d ctx_id:%d",
- opnum, ctx_id);
- }
-
- if (dcerpc_tree) {
- offset = 16;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_alloc_hint, tvb, offset, 4, alloc_hint);
- offset += 4;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_ctx_id, tvb, offset, 2, ctx_id);
- offset += 2;
-
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_opnum, tvb, offset, 2, opnum);
- offset += 2;
-
- if (hdr->flags & 0x80) {
+ if (dcerpc_tree) {
proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
offset, 16, "HMMM",
"Object UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
@@ -436,7 +640,75 @@
obj_id.Data4[5],
obj_id.Data4[6],
obj_id.Data4[7]);
- offset += 16;
+ }
+ offset += 16;
+ }
+
+ if (check_col (pinfo->fd, COL_INFO)) {
+ col_add_fstr (pinfo->fd, COL_INFO, "Request: opnum: %d ctx_id:%d",
+ opnum, ctx_id);
+ }
+
+ conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (!conv) {
+
+ } else {
+ dcerpc_conv_key key;
+ dcerpc_conv_value *value;
+
+ key.conv = conv;
+ key.ctx_id = ctx_id;
+
+ value = g_hash_table_lookup (dcerpc_convs, &key);
+ if (value) {
+ /* add an entry for this call, so we can catch the reply */
+ dcerpc_call_add_map (hdr->call_id, conv, opnum,
+ value->ver, &value->uuid);
+
+ /* handoff this call */
+ dcerpc_try_handoff (pinfo, tree, tvb, offset,
+ &value->uuid, value->ver,
+ opnum, TRUE);
+ }
+ }
+}
+
+static void
+dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
+ proto_tree *tree, e_dce_cn_common_hdr_t *hdr)
+{
+ conversation_t *conv;
+ guint16 ctx_id;
+
+ int offset = 16;
+
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_alloc_hint, NULL);
+
+ offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_ctx_id, &ctx_id);
+
+ offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_cancel_count, NULL);
+ /* padding */
+ offset++;
+
+ if (check_col (pinfo->fd, COL_INFO)) {
+ col_add_fstr (pinfo->fd, COL_INFO, "Response: call_id: %d ctx_id:%d",
+ hdr->call_id, ctx_id);
+ }
+
+ conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (!conv) {
+ /* no point in creating one here, really */
+ } else {
+ dcerpc_call_value *value = dcerpc_call_lookup (hdr->call_id, conv);
+ if (value) {
+ dcerpc_try_handoff (pinfo, tree, tvb, offset,
+ &value->uuid, value->ver,
+ value->opnum, FALSE);
}
}
}
@@ -526,15 +798,21 @@
*/
switch (hdr.ptype) {
case PDU_BIND:
+ case PDU_ALTER:
dissect_dcerpc_cn_bind (tvb, pinfo, dcerpc_tree, &hdr);
break;
case PDU_BIND_ACK:
+ case PDU_ALTER_ACK:
dissect_dcerpc_cn_bind_ack (tvb, pinfo, dcerpc_tree, &hdr);
break;
case PDU_REQ:
- dissect_dcerpc_cn_rqst (tvb, pinfo, dcerpc_tree, &hdr);
+ dissect_dcerpc_cn_rqst (tvb, pinfo, dcerpc_tree, tree, &hdr);
+ break;
+
+ case PDU_RESP:
+ dissect_dcerpc_cn_resp (tvb, pinfo, dcerpc_tree, tree, &hdr);
break;
default:
@@ -556,6 +834,7 @@
proto_tree *dg_flags2_tree = NULL;
e_dce_dg_common_hdr_t hdr;
int offset = 0;
+ conversation_t *conv;
/*
* Check if this looks like a CL DCERPC call. All dg packets
@@ -722,16 +1001,65 @@
proto_tree_add_uint (dcerpc_tree, hf_dcerpc_dg_serial_lo, tvb, offset, 1, hdr.serial_lo);
offset++;
}
+ /*
+ * keeping track of the conversation shouldn't really be necessary
+ * for connectionless packets, because everything we need to know
+ * to dissect is in the header for each packet. Unfortunately,
+ * Microsoft's implementation is buggy and often puts the
+ * completely wrong if_id in the header. go figure. So, keep
+ * track of the seqnum and use that if possible. Note: that's not
+ * completely correct. It should really be done based on both the
+ * activity_id and seqnum. I haven't seen anywhere that it would
+ * make a difference, but for future reference...
+ */
+ conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (!conv) {
+ conv = conversation_new (&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, NULL, 0);
+ }
+
/*
* Packet type specific stuff is next.
*/
+ switch (hdr.ptype) {
+ case PDU_REQ:
+ dcerpc_call_add_map (hdr.seqnum, conv, hdr.opnum,
+ hdr.if_ver, &hdr.if_id);
+ dcerpc_try_handoff (pinfo, tree, tvb, offset,
+ &hdr.if_id, hdr.if_ver, hdr.opnum, TRUE);
+ break;
+ case PDU_RESP:
+ {
+ dcerpc_call_value *v = dcerpc_call_lookup (hdr.seqnum, conv);
+ if (v) {
+ dcerpc_try_handoff (pinfo, tree, tvb, offset,
+ &v->uuid, v->ver, v->opnum, FALSE);
+ } else {
+ dcerpc_try_handoff (pinfo, tree, tvb, offset,
+ &hdr.if_id, hdr.if_ver, hdr.opnum, FALSE);
+ }
+ }
+ break;
+ }
return TRUE;
}
+static void
+dcerpc_init_protocol (void)
+{
+ if (dcerpc_convs != NULL)
+ g_hash_table_destroy (dcerpc_convs);
+ if (dcerpc_calls != NULL)
+ g_hash_table_destroy (dcerpc_calls);
+ dcerpc_convs = g_hash_table_new (dcerpc_conv_hash, dcerpc_conv_equal);
+ dcerpc_calls = g_hash_table_new (dcerpc_call_hash, dcerpc_call_equal);
+}
+
void
-proto_register_dcerpc(void)
+proto_register_dcerpc (void)
{
static hf_register_info hf[] = {
{ &hf_dcerpc_ver,
@@ -779,7 +1107,9 @@
{ &hf_dcerpc_cn_bind_if_id,
{ "Interface UUID", "dcerpc.cn_bind_to_uuid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_cn_bind_if_ver,
- { "Interface Ver", "dcerpc.cn_bind_if_ver", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { "Interface Ver", "dcerpc.cn_bind_if_ver", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_dcerpc_cn_bind_if_ver_minor,
+ { "Interface Ver Minor", "dcerpc.cn_bind_if_ver_minor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_cn_bind_trans_id,
{ "Transfer Syntax", "dcerpc.cn_bind_trans_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_cn_bind_trans_ver,
@@ -794,6 +1124,8 @@
{ "Ack result", "dcerpc.cn_ack_result", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_cn_ack_reason,
{ "Ack reason", "dcerpc.cn_ack_reason", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_dcerpc_cn_cancel_count,
+ { "Cancel count", "dcerpc.cn_cancel_count", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_dg_flags1,
{ "Flags1", "dcerpc.dg_flags1", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_dcerpc_dg_flags1_rsrvd_01,
@@ -871,10 +1203,15 @@
proto_dcerpc = proto_register_protocol ("DCE RPC", "DCERPC", "dcerpc");
proto_register_field_array (proto_dcerpc, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
+ register_init_routine (dcerpc_init_protocol);
+
+ dcerpc_uuids = g_hash_table_new (dcerpc_uuid_hash, dcerpc_uuid_equal);
+ dcerpc_convs = g_hash_table_new (dcerpc_conv_hash, dcerpc_conv_equal);
+ dcerpc_calls = g_hash_table_new (dcerpc_call_hash, dcerpc_call_equal);
}
void
-proto_reg_handoff_dcerpc(void)
+proto_reg_handoff_dcerpc (void)
{
heur_dissector_add ("tcp", dissect_dcerpc_cn, proto_dcerpc);
heur_dissector_add ("udp", dissect_dcerpc_dg, proto_dcerpc);
Index: packet-dcerpc.h
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.h,v
retrieving revision 1.1
diff -u -r1.1 packet-dcerpc.h
--- packet-dcerpc.h 2001/04/19 23:39:27 1.1
+++ packet-dcerpc.h 2001/07/09 11:20:25
@@ -88,6 +88,17 @@
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);
+typedef int (dcerpc_dissect_fnct_t)(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+
+typedef struct _dcerpc_sub_dissector {
+ guint16 num;
+ gchar *name;
+ dcerpc_dissect_fnct_t *dissect_rqst;
+ dcerpc_dissect_fnct_t *dissect_resp;
+} dcerpc_sub_dissector;
+
+/* registration function for subdissectors */
+void dcerpc_init_uuid (int proto, int ett, e_uuid_t *uuid, guint16 ver, dcerpc_sub_dissector *procs);
#endif /* packet-dcerpc.h */
Index: Makefile.am =================================================================== RCS file: /cvsroot/ethereal/Makefile.am,v retrieving revision 1.343 diff -u -r1.343 Makefile.am --- Makefile.am 2001/07/04 06:25:03 1.343 +++ Makefile.am 2001/07/09 11:19:59 @@ -94,6 +94,11 @@ packet-cups.c \ packet-data.c \ packet-dcerpc.c \ + packet-dcerpc-conv.c \ + packet-dcerpc-epm.c \ + packet-dcerpc-mgmt.c \ + packet-dcerpc-remact.c \ + packet-dcerpc-oxid.c \ packet-ddtp.c \ packet-dec-bpdu.c \ packet-diameter.c \
/* packet-dcerpc-epm.c
* Routines for dcerpc endpoint mapper 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 <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
static int proto_epm = -1;
static gint ett_epm = -1;
static e_uuid_t uuid_epm = { 0xe1af8308, 0x5d1f, 0x11c9, { 0x91, 0xa4, 0x08, 0x00, 0x2b, 0x14, 0xa0, 0xfa } };
static guint16 ver_epm = 3;
static dcerpc_sub_dissector epm_dissectors[] = {
{ 0, "ept_insert", NULL, NULL },
{ 1, "ept_delete", NULL, NULL },
{ 2, "ept_lookup", NULL, NULL },
{ 3, "ept_map", NULL, NULL },
{ 4, "ept_lookup_handle_free", NULL, NULL },
{ 5, "ept_inq_object", NULL, NULL },
{ 6, "ept_mgmt_delete", NULL, NULL },
{ 0, NULL, NULL, NULL },
};
void
proto_register_epm (void)
{
static hf_register_info hf[] = {
};
static gint *ett[] = {
&ett_epm,
};
proto_epm = proto_register_protocol ("DCE/RPC Endpoint Mapper", "EPM", "epm");
proto_register_field_array (proto_epm, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
}
void
proto_reg_handoff_epm (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_epm, ett_epm, &uuid_epm, ver_epm, epm_dissectors);
}
/* packet-dcerpc-mgmt.c
* Routines for dcerpc mgmt 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 <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
static int proto_mgmt = -1;
static gint ett_mgmt = -1;
static e_uuid_t uuid_mgmt = { 0xafa8bd80, 0x7d8a, 0x11c9, { 0xbe, 0xf4, 0x08, 0x00, 0x2b, 0x10, 0x29, 0x89 } };
static guint16 ver_mgmt = 1;
static dcerpc_sub_dissector mgmt_dissectors[] = {
{ 0, "rpc__mgmt_inq_if_ids", NULL, NULL },
{ 1, "rpc__mgmt_inq_stats", NULL, NULL },
{ 2, "rpc__mgmt_is_server_listening", NULL, NULL },
{ 3, "rpc__mgmt_stop_server_listening", NULL, NULL },
{ 4, "rpc__mgmt_inq_princ_name", NULL, NULL },
{ 0, NULL, NULL, NULL },
};
void
proto_register_mgmt (void)
{
static hf_register_info hf[] = {
};
static gint *ett[] = {
&ett_mgmt,
};
proto_mgmt = proto_register_protocol ("DCE/RPC Remote Management", "MGMT", "mgmt");
proto_register_field_array (proto_mgmt, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
}
void
proto_reg_handoff_mgmt (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_mgmt, ett_mgmt, &uuid_mgmt, ver_mgmt, mgmt_dissectors);
}
/* packet-dcerpc-conv.c
* Routines for dcerpc conv 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 <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
static int proto_conv = -1;
static gint ett_conv = -1;
static e_uuid_t uuid_conv = { 0x333a2276, 0x0000, 0x0000, { 0x0d, 0x00, 0x00, 0x80, 0x9c, 0x00, 0x00, 0x00 } };
static guint16 ver_conv = 3;
static dcerpc_sub_dissector conv_dissectors[] = {
{ 0, "conv_who_are_you", NULL, NULL },
{ 1, "conv_who_are_you2", NULL, NULL },
{ 2, "conv_are_you_there", NULL, NULL },
{ 3, "conv_who_are_you_auth", NULL, NULL },
{ 4, "conv_who_are_you_auth_more", NULL, NULL },
{ 0, NULL, NULL, NULL },
};
void
proto_register_conv (void)
{
static hf_register_info hf[] = {
};
static gint *ett[] = {
&ett_conv,
};
proto_conv = proto_register_protocol ("DCE/RPC Conversation Manager", "CONV", "conv");
proto_register_field_array (proto_conv, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
}
void
proto_reg_handoff_conv (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_conv, ett_conv, &uuid_conv, ver_conv, conv_dissectors);
}
/* packet-dcerpc-remact.c
* Routines for DCOM Remote Activation
* 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 <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
static int proto_remact = -1;
static gint ett_remact = -1;
static e_uuid_t uuid_remact = { 0x4d9f4ab8, 0x7dac, 0x11cf, { 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57 } };
static guint16 ver_remact = 0;
static dcerpc_sub_dissector remact_dissectors[] = {
{ 0, "RemoteActivation", NULL, NULL },
{ 0, NULL, NULL, NULL },
};
void
proto_register_remact (void)
{
static hf_register_info hf[] = {
};
static gint *ett[] = {
&ett_remact,
};
proto_remact = proto_register_protocol ("DCOM Remote Activation", "REMACT", "remact");
proto_register_field_array (proto_remact, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
}
void
proto_reg_handoff_remact (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_remact, ett_remact, &uuid_remact, ver_remact, remact_dissectors);
}
/* packet-dcerpc-oxid.c
* Routines for DCOM OXID Resolver
* 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 <glib.h>
#include "packet.h"
#include "packet-dcerpc.h"
static int proto_oxid = -1;
static gint ett_oxid = -1;
static e_uuid_t uuid_oxid = { 0x99fcfec4, 0x5260, 0x101b, { 0xbb, 0xcb, 0x00, 0xaa, 0x00, 0x21, 0x34, 0x7a } };
static guint16 ver_oxid = 0;
static dcerpc_sub_dissector oxid_dissectors[] = {
{ 0, "ResolveOxid", NULL, NULL },
{ 1, "SimplePing", NULL, NULL },
{ 2, "ComplexPing", NULL, NULL },
{ 3, "ServerAlive", NULL, NULL },
{ 0, NULL, NULL, NULL },
};
void
proto_register_oxid (void)
{
static hf_register_info hf[] = {
};
static gint *ett[] = {
&ett_oxid,
};
proto_oxid = proto_register_protocol ("DCOM OXID Resolver", "OXID", "oxid");
proto_register_field_array (proto_oxid, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
}
void
proto_reg_handoff_oxid (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_oxid, ett_oxid, &uuid_oxid, ver_oxid, oxid_dissectors);
}
- Follow-Ups:
- References:
- Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector?
- From: Todd Sabin
- Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector?
- From: ulf . lamping
- Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector?
- Prev by Date: Re: [Ethereal-dev] Displaying and comparing two traces ...
- Next by Date: Re: [Ethereal-dev] GIOP Subdissector plans
- Previous by thread: Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector?
- Next by thread: Re: dcerpc patch (was Re: [Ethereal-dev] Is someone working on a DCOM/ORPC dissector?)
- Index(es):





