Support for dissectors of protocols running atop DCE RPC registering

themselves with the DCE RPC dissector, and support for some of the
protocols atop DCE RPC that are part of DCE RPC, from Todd Sabin.

svn path=/trunk/; revision=3681
This commit is contained in:
Guy Harris 2001-07-11 01:25:45 +00:00
parent 08b6ae0306
commit 317a2651f9
9 changed files with 983 additions and 179 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.346 2001/07/11 00:59:50 guy Exp $
# $Id: Makefile.am,v 1.347 2001/07/11 01:25:44 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -94,6 +94,11 @@ DISSECTOR_SRC = \
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 \

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.122 2001/07/11 00:59:50 guy Exp $
# $Id: Makefile.nmake,v 1.123 2001/07/11 01:25:44 guy Exp $
include config.nmake
include <win32.mak>
@ -48,6 +48,11 @@ DISSECTOR_SRC = \
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 \

84
packet-dcerpc-conv.c Normal file
View File

@ -0,0 +1,84 @@
/* packet-dcerpc-conv.c
* Routines for dcerpc conv dissection
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc-conv.c,v 1.1 2001/07/11 01:25:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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)
{
#if 0
static hf_register_info hf[] = {
};
#endif
static gint *ett[] = {
&ett_conv,
};
proto_conv = proto_register_protocol ("DCE/RPC Conversation Manager", "CONV", "conv");
#if 0
proto_register_field_array (proto_conv, hf, array_length (hf));
#endif
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);
}

86
packet-dcerpc-epm.c Normal file
View File

@ -0,0 +1,86 @@
/* packet-dcerpc-epm.c
* Routines for dcerpc endpoint mapper dissection
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc-epm.c,v 1.1 2001/07/11 01:25:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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)
{
#if 0
static hf_register_info hf[] = {
};
#endif
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));
}
void
proto_reg_handoff_epm (void)
{
/* Register the protocol as dcerpc */
dcerpc_init_uuid (proto_epm, ett_epm, &uuid_epm, ver_epm, epm_dissectors);
}

84
packet-dcerpc-mgmt.c Normal file
View File

@ -0,0 +1,84 @@
/* packet-dcerpc-mgmt.c
* Routines for dcerpc mgmt dissection
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc-mgmt.c,v 1.1 2001/07/11 01:25:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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)
{
#if 0
static hf_register_info hf[] = {
};
#endif
static gint *ett[] = {
&ett_mgmt,
};
proto_mgmt = proto_register_protocol ("DCE/RPC Remote Management", "MGMT", "mgmt");
#if 0
proto_register_field_array (proto_mgmt, hf, array_length (hf));
#endif
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);
}

82
packet-dcerpc-oxid.c Normal file
View File

@ -0,0 +1,82 @@
/* packet-dcerpc-oxid.c
* Routines for DCOM OXID Resolver
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc-oxid.c,v 1.1 2001/07/11 01:25:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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)
{
#if 0
static hf_register_info hf[] = {
};
#endif
static gint *ett[] = {
&ett_oxid,
};
proto_oxid = proto_register_protocol ("DCOM OXID Resolver", "OXID", "oxid");
#if 0
proto_register_field_array (proto_oxid, hf, array_length (hf));
#endif
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);
}

80
packet-dcerpc-remact.c Normal file
View File

@ -0,0 +1,80 @@
/* packet-dcerpc-remact.c
* Routines for DCOM Remote Activation
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc-remact.c,v 1.1 2001/07/11 01:25:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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)
{
#if 0
static hf_register_info hf[] = {
};
#endif
static gint *ett[] = {
&ett_remact,
};
proto_remact = proto_register_protocol ("DCOM Remote Activation", "REMACT", "remact");
#if 0
proto_register_field_array (proto_remact, hf, array_length (hf));
#endif
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);
}

View File

@ -2,10 +2,10 @@
* Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc.c,v 1.5 2001/06/18 02:17:45 guy Exp $
* $Id: packet-dcerpc.c,v 1.6 2001/07/11 01:25:45 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
@ -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_ctx_id = -1;
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_sec_addr_len = -1;
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,224 @@ static gint ett_dcerpc_cn_flags = -1;
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;
static GMemChunk *dcerpc_conv_key_chunk;
typedef struct _dcerpc_conv_value {
e_uuid_t uuid;
guint16 ver;
} dcerpc_conv_value;
static GMemChunk *dcerpc_conv_value_chunk;
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;
static GMemChunk *dcerpc_call_key_chunk;
typedef struct _dcerpc_call_value {
e_uuid_t uuid;
guint16 ver;
guint16 opnum;
} dcerpc_call_value;
static GMemChunk *dcerpc_call_value_chunk;
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_mem_chunk_alloc (dcerpc_call_key_chunk);
dcerpc_call_value *value = g_mem_chunk_alloc (dcerpc_call_value_chunk);
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 +391,166 @@ dcerpc_tvb_get_uuid (tvbuff_t *tvb, gint offset, char *drep, e_uuid_t *uuid)
}
}
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;
proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_bind_trans_ver, tvb, offset, 4, trans_ver);
offset += 4;
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;
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_mem_chunk_alloc (dcerpc_conv_key_chunk);
key->conv = conv;
key->ctx_id = ctx_id;
value = g_mem_chunk_alloc (dcerpc_conv_value_chunk);
value->uuid = if_id;
value->ver = if_ver;
g_hash_table_insert (dcerpc_convs, key, value);
}
static void
@ -294,7 +558,6 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerp
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 +565,77 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerp
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 +648,75 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
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 +806,21 @@ dissect_dcerpc_cn (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
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 +842,7 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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 +1009,89 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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)
g_hash_table_destroy (dcerpc_convs);
if (dcerpc_calls)
g_hash_table_destroy (dcerpc_calls);
if (dcerpc_conv_key_chunk)
g_mem_chunk_destroy (dcerpc_conv_key_chunk);
if (dcerpc_conv_value_chunk)
g_mem_chunk_destroy (dcerpc_conv_value_chunk);
if (dcerpc_call_key_chunk)
g_mem_chunk_destroy (dcerpc_call_key_chunk);
if (dcerpc_call_value_chunk)
g_mem_chunk_destroy (dcerpc_call_value_chunk);
dcerpc_convs = g_hash_table_new (dcerpc_conv_hash, dcerpc_conv_equal);
dcerpc_calls = g_hash_table_new (dcerpc_call_hash, dcerpc_call_equal);
dcerpc_conv_key_chunk = g_mem_chunk_new ("dcerpc_conv_key_chunk",
sizeof (dcerpc_conv_key),
200 * sizeof (dcerpc_conv_key),
G_ALLOC_ONLY);
dcerpc_conv_value_chunk = g_mem_chunk_new ("dcerpc_conv_value_chunk",
sizeof (dcerpc_conv_value),
200 * sizeof (dcerpc_conv_value),
G_ALLOC_ONLY);
dcerpc_call_key_chunk = g_mem_chunk_new ("dcerpc_call_key_chunk",
sizeof (dcerpc_call_key),
200 * sizeof (dcerpc_call_key),
G_ALLOC_ONLY);
dcerpc_call_value_chunk = g_mem_chunk_new ("dcerpc_call_value_chunk",
sizeof (dcerpc_call_value),
200 * sizeof (dcerpc_call_value),
G_ALLOC_ONLY);
}
void
proto_register_dcerpc(void)
proto_register_dcerpc (void)
{
static hf_register_info hf[] = {
{ &hf_dcerpc_ver,
@ -779,7 +1139,9 @@ proto_register_dcerpc(void)
{ &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 +1156,8 @@ proto_register_dcerpc(void)
{ "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 +1235,13 @@ proto_register_dcerpc(void)
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);
}
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);

View File

@ -1,10 +1,10 @@
/* packet-dcerpc.h
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc.h,v 1.1 2001/04/19 23:39:27 guy Exp $
* $Id: packet-dcerpc.h,v 1.2 2001/07/11 01:25:45 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
@ -88,6 +88,17 @@ 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);
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 */