diff options
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | Makefile.nmake | 7 | ||||
-rw-r--r-- | packet-dcerpc-conv.c | 84 | ||||
-rw-r--r-- | packet-dcerpc-epm.c | 86 | ||||
-rw-r--r-- | packet-dcerpc-mgmt.c | 84 | ||||
-rw-r--r-- | packet-dcerpc-oxid.c | 82 | ||||
-rw-r--r-- | packet-dcerpc-remact.c | 80 | ||||
-rw-r--r-- | packet-dcerpc.c | 715 | ||||
-rw-r--r-- | packet-dcerpc.h | 15 |
9 files changed, 982 insertions, 178 deletions
diff --git a/Makefile.am b/Makefile.am index ea3a3bc75f..0e292d7b62 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/Makefile.nmake b/Makefile.nmake index f0f025e347..9c032a5e57 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -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 \ diff --git a/packet-dcerpc-conv.c b/packet-dcerpc-conv.c new file mode 100644 index 0000000000..14254a0dd7 --- /dev/null +++ b/packet-dcerpc-conv.c @@ -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); +} diff --git a/packet-dcerpc-epm.c b/packet-dcerpc-epm.c new file mode 100644 index 0000000000..459976fa95 --- /dev/null +++ b/packet-dcerpc-epm.c @@ -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); +} diff --git a/packet-dcerpc-mgmt.c b/packet-dcerpc-mgmt.c new file mode 100644 index 0000000000..0eaff99b4b --- /dev/null +++ b/packet-dcerpc-mgmt.c @@ -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); +} diff --git a/packet-dcerpc-oxid.c b/packet-dcerpc-oxid.c new file mode 100644 index 0000000000..2f08bbff44 --- /dev/null +++ b/packet-dcerpc-oxid.c @@ -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); +} diff --git a/packet-dcerpc-remact.c b/packet-dcerpc-remact.c new file mode 100644 index 0000000000..20b2d80f2d --- /dev/null +++ b/packet-dcerpc-remact.c @@ -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); +} diff --git a/packet-dcerpc.c b/packet-dcerpc.c index 9534a23d3f..3666333429 100644 --- a/packet-dcerpc.c +++ b/packet-dcerpc.c @@ -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; + 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_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); diff --git a/packet-dcerpc.h b/packet-dcerpc.h index 2739382aea..76829bf688 100644 --- a/packet-dcerpc.h +++ b/packet-dcerpc.h @@ -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 */ |