diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2004-07-18 18:06:47 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2004-07-18 18:06:47 +0000 |
commit | 669db206cb1f270046ad400fff7655e20c63e723 (patch) | |
tree | 4eff24a2e16c8963e497e1fc575f35e6af59bd26 /epan/dissectors/packet-dcerpc-epm.c | |
parent | ae46c27a38700af669ef907491081f09df6f6b2c (diff) |
Move dissectors to epan/dissectors directory.
Also move ncp222.py, x11-fields, process-x11-fields.pl,
make-reg-dotc, and make-reg-dotc.py.
Adjust #include lines in files that include packet-*.h
files.
svn path=/trunk/; revision=11410
Diffstat (limited to 'epan/dissectors/packet-dcerpc-epm.c')
-rw-r--r-- | epan/dissectors/packet-dcerpc-epm.c | 735 |
1 files changed, 735 insertions, 0 deletions
diff --git a/epan/dissectors/packet-dcerpc-epm.c b/epan/dissectors/packet-dcerpc-epm.c new file mode 100644 index 0000000000..548a3a6c90 --- /dev/null +++ b/epan/dissectors/packet-dcerpc-epm.c @@ -0,0 +1,735 @@ +/* packet-dcerpc-epm.c + * Routines for dcerpc endpoint mapper dissection + * Copyright 2001, Todd Sabin <tas@webspan.net> + * + * $Id$ + * + * 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 + + +#include <string.h> + +#include <glib.h> +#include <epan/packet.h> +#include "packet-dcerpc.h" +#include "packet-dcerpc-nt.h" + + +static int proto_epm = -1; + +static int hf_epm_opnum = -1; +static int hf_epm_inquiry_type = -1; +static int hf_epm_object = -1; +static int hf_epm_if_id = -1; +static int hf_epm_ver_maj = -1; +static int hf_epm_ver_min = -1; +static int hf_epm_ver_opt = -1; +static int hf_epm_hnd = -1; +static int hf_epm_max_ents = -1; +static int hf_epm_num_ents = -1; +static int hf_epm_uuid = -1; +static int hf_epm_tower_length = -1; +static int hf_epm_tower_data = -1; +static int hf_epm_max_towers = -1; +static int hf_epm_num_towers = -1; +static int hf_epm_rc = -1; +static int hf_epm_replace = -1; +static int hf_epm_tower_num_floors = -1; +static int hf_epm_tower_rhs_len = -1; +static int hf_epm_tower_lhs_len = -1; +static int hf_epm_tower_proto_id = -1; +static int hf_epm_annotation = -1; +static int hf_epm_ann_offset = -1; +static int hf_epm_ann_len = -1; +static int hf_epm_proto_named_pipes = -1; +static int hf_epm_proto_netbios_name = -1; +static int hf_epm_proto_ip = -1; +static int hf_epm_proto_udp_port = -1; +static int hf_epm_proto_tcp_port = -1; + +static gint ett_epm = -1; +static gint ett_epm_tower_floor = -1; +static gint ett_epm_entry = -1; + +static e_uuid_t uuid_epm = { 0xe1af8308, 0x5d1f, 0x11c9, { 0x91, 0xa4, 0x08, 0x00, 0x2b, 0x14, 0xa0, 0xfa } }; +static guint16 ver_epm = 3; + +static const value_string ep_service[] = { + { 0, "rpc_c_ep_all_elts" }, + { 1, "rpc_c_ep_match_by_if" }, + { 2, "rpc_c_ep_match_by_obj" }, + { 3, "rpc_c_ep_match_by_both" }, + { 0, NULL }, +}; + +/* typedef struct { + unsigned int tower_len, + [size_is(tower_len)] char tower[]; + } twr_t, *twr_p_t; +*/ +static int epm_dissect_tower (tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep); + + +static int +epm_dissect_pointer_IF_ID(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + dcerpc_info *di; + + di=pinfo->private_data; + offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep, + di->hf_index, NULL); + offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep, + hf_epm_ver_maj, NULL); + offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep, + hf_epm_ver_min, NULL); + return offset; +} + +static int +epm_dissect_pointer_UUID(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + dcerpc_info *di; + + di=pinfo->private_data; + offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep, + di->hf_index, NULL); + return offset; +} + +static int +epm_dissect_ept_lookup_rqst (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_inquiry_type, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_pointer_UUID, NDR_POINTER_PTR, + "Object:", hf_epm_object); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_pointer_IF_ID, NDR_POINTER_PTR, + "Interface:", hf_epm_if_id); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_ver_opt, NULL); + + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_max_ents, NULL); + return offset; +} + + +static int +epm_dissect_ept_entry_t(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *parent_tree, + guint8 *drep) +{ + proto_item *item=NULL; + proto_tree *tree=NULL; + int old_offset=offset; + guint32 len; + gint strlen; + dcerpc_info *di; + const char *str; + + di=pinfo->private_data; + if(di->conformant_run){ + return offset; + } + + if(parent_tree){ + item = proto_tree_add_text(parent_tree, tvb, offset, -1, "Entry:"); + tree = proto_item_add_subtree(item, ett_epm_entry); + } + + offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep, + hf_epm_object, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_tower, NDR_POINTER_PTR, + "Tower pointer:", -1); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_ann_offset, NULL); + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_ann_len, &len); + str=(const char *)tvb_get_ptr(tvb, offset, -1); + strlen=len; + strlen=MIN(strlen,tvb_length_remaining(tvb, offset)); + proto_tree_add_item(tree, hf_epm_annotation, tvb, offset, len, TRUE); + offset += len; + + if(str&&str[0]){ + if(parent_tree) { + proto_item_append_text(item, " Service:%*s ", strlen, str); + proto_item_append_text(tree->parent, " Service:%*s ", strlen, str); + } + if (check_col(pinfo->cinfo, COL_INFO)) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Service:%*s", strlen, str); + } + } + + proto_item_set_len(item, offset-old_offset); + return offset; +} + +static int +epm_dissect_ept_entry_t_array(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep, + epm_dissect_ept_entry_t); + + return offset; +} + +static int +epm_dissect_ept_lookup_resp (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_num_ents, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_ept_entry_t_array, NDR_POINTER_REF, + "Entries:", -1); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_rc, NULL); + + return offset; +} + +static int +epm_dissect_uuid (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_uuid_t (tvb, offset, pinfo, tree, drep, + hf_epm_uuid, NULL); + return offset; +} + +#define PROTO_ID_OSI_OID 0x00 +#define PROTO_ID_DNA_SESSCTL 0x02 +#define PROTO_ID_DNA_SESSCTL_V3 0x03 +#define PROTO_ID_DNA_NSP 0x04 +#define PROTO_ID_OSI_TP4 0x05 +#define PROTO_ID_OSI_CLNS 0x06 +#define PROTO_ID_TCP 0x07 +#define PROTO_ID_UDP 0x08 +#define PROTO_ID_IP 0x09 +#define PROTO_ID_RPC_CL 0x0a +#define PROTO_ID_RPC_CO 0x0b +#define PROTO_ID_UUID 0x0d +#define PROTO_ID_NAMED_PIPES 0x0f +#define PROTO_ID_NAMED_PIPES_2 0x10 +#define PROTO_ID_NETBIOS 0x11 +#define PROTO_ID_NETBEUI 0x12 +#define PROTO_ID_NETWARE_SPX 0x13 +#define PROTO_ID_NETWARE_IPX 0x14 +#define PROTO_ID_ATALK_STREAM 0x16 +#define PROTO_ID_ATALK_DATAGRAM 0x17 +#define PROTO_ID_ATALK 0x18 +#define PROTO_ID_NETBIOS_2 0x19 +#define PROTO_ID_VINES_SPP 0x1a +#define PROTO_ID_VINES_IPC 0x1b +#define PROTO_ID_STREETTALK 0x1c +#define PROTO_ID_UNIX_DOMAIN 0x20 +#define PROTO_ID_NULL 0x21 +#define PROTO_ID_NETBIOS_3 0x22 + +static const value_string proto_id_vals[] = { + { PROTO_ID_OSI_OID, "OSI OID"}, + { PROTO_ID_DNA_SESSCTL, "DNA Session Control"}, + { PROTO_ID_DNA_SESSCTL_V3, "DNA Session Control V3"}, + { PROTO_ID_DNA_NSP, "DNA NSP Transport"}, + { PROTO_ID_OSI_TP4, "OSI TP4"}, + { PROTO_ID_OSI_CLNS, "OSI CLNS or DNA Routing"}, + { PROTO_ID_TCP, "DOD TCP"}, + { PROTO_ID_UDP, "DOD UDP"}, + { PROTO_ID_IP, "DOD IP"}, + { PROTO_ID_RPC_CL, "RPC connectionless protocol"}, + { PROTO_ID_RPC_CO, "RPC connection-oriented protocol"}, + { PROTO_ID_UUID, "UUID"}, + { PROTO_ID_NAMED_PIPES, "Named Pipes"}, + { PROTO_ID_NAMED_PIPES_2, "Named Pipes"}, + { PROTO_ID_NETBIOS, "NetBIOS"}, + { PROTO_ID_NETBEUI, "NetBEUI"}, + { PROTO_ID_NETWARE_SPX, "Netware SPX"}, + { PROTO_ID_NETWARE_IPX, "Netware IPX"}, + { PROTO_ID_ATALK_STREAM, "Appletalk Stream"}, + { PROTO_ID_ATALK_DATAGRAM, "Appletalk Datagram"}, + { PROTO_ID_ATALK, "Appletalk"}, + { PROTO_ID_NETBIOS_2, "NetBIOS"}, + { PROTO_ID_VINES_SPP, "Vines SPP"}, + { PROTO_ID_VINES_IPC, "Vines IPC"}, + { PROTO_ID_STREETTALK, "StreetTalk"}, + { PROTO_ID_UNIX_DOMAIN, "Unix Domain Socket"}, + { PROTO_ID_NULL, "null"}, + { PROTO_ID_NETBIOS_3, "NetBIOS"}, + { 0, NULL}, +}; + + +/* XXX this function assumes LE encoding. can not use the NDR routines + since they assume padding. +*/ +static int +epm_dissect_tower_data (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + guint16 num_floors, i; + dcerpc_info *di; + + di=pinfo->private_data; + if(di->conformant_run){ + return offset; + } + + num_floors = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_epm_tower_num_floors, tvb, offset, 2, num_floors); + offset += 2; + + for(i=1;i<=num_floors;i++){ + proto_item *it = NULL; + proto_tree *tr = NULL; + int old_offset = offset; + guint16 len; + guint8 proto_id; + e_uuid_t uuid; + + it = proto_tree_add_text(tree, tvb, offset, 0, "Floor %d ", i); + tr = proto_item_add_subtree(it, ett_epm_tower_floor); + + len = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tr, hf_epm_tower_lhs_len, tvb, offset, 2, len); + offset += 2; + + proto_id = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tr, hf_epm_tower_proto_id, tvb, offset, 1, proto_id); + + switch(proto_id){ + case PROTO_ID_UUID: + dcerpc_tvb_get_uuid (tvb, offset+1, drep, &uuid); + + proto_tree_add_string_format (tr, hf_epm_uuid, tvb, offset+1, 16, "", + "UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.Data1, uuid.Data2, uuid.Data3, + uuid.Data4[0], uuid.Data4[1], + uuid.Data4[2], uuid.Data4[3], + uuid.Data4[4], uuid.Data4[5], + uuid.Data4[6], uuid.Data4[7]); + proto_tree_add_text(tr, tvb, offset+17, 2, "Version %d.%d", tvb_get_guint8(tvb, offset+17), tvb_get_guint8(tvb, offset+18)); + + { + guint16 version = tvb_get_ntohs(tvb, offset+17); + char *service = dcerpc_get_proto_name(&uuid, version); + if (service) + proto_item_append_text(tr, "UUID: %s", service); + else + proto_item_append_text(tr, "UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x Version %d.%d", uuid.Data1, uuid.Data2, uuid.Data3, + uuid.Data4[0], uuid.Data4[1], + uuid.Data4[2], uuid.Data4[3], + uuid.Data4[4], uuid.Data4[5], + uuid.Data4[6], uuid.Data4[7], + tvb_get_guint8(tvb, offset+17), + tvb_get_guint8(tvb, offset+18)); + } + break; + } + offset += len; + + len = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tr, hf_epm_tower_rhs_len, tvb, offset, 2, len); + offset += 2; + + switch(proto_id){ + + case PROTO_ID_TCP: /* this one is always big endian */ + proto_tree_add_item(tr, hf_epm_proto_tcp_port, tvb, offset, 2, FALSE); + proto_item_append_text(tr, "TCP Port:%d", tvb_get_ntohs(tvb, offset)); + break; + + case PROTO_ID_UDP: /* this one is always big endian */ + proto_tree_add_item(tr, hf_epm_proto_udp_port, tvb, offset, 2, FALSE); + proto_item_append_text(tr, "UDP Port:%d", tvb_get_ntohs(tvb, offset)); + break; + + case PROTO_ID_IP: /* this one is always big endian */ + proto_tree_add_item(tr, hf_epm_proto_ip, tvb, offset, 4, TRUE); + proto_item_append_text(tr, "IP:%s", ip_to_str(tvb_get_ptr(tvb, offset, 4))); + break; + + case PROTO_ID_RPC_CO: + proto_item_append_text(tr, "RPC connection-oriented protocol"); + break; + + case PROTO_ID_NAMED_PIPES: /* \\PIPE\xxx named pipe */ + proto_tree_add_item(tr, hf_epm_proto_named_pipes, tvb, offset, len, TRUE); + proto_item_append_text(tr, "NamedPipe:%*s",MIN(len,tvb_length_remaining(tvb, offset)), tvb_get_ptr(tvb, offset, -1)); + break; + + case PROTO_ID_NAMED_PIPES_2: /* PIPENAME named pipe */ + proto_tree_add_item(tr, hf_epm_proto_named_pipes, tvb, offset, len, TRUE); + proto_item_append_text(tr, "PIPE:%*s",MIN(len,tvb_length_remaining(tvb, offset)), tvb_get_ptr(tvb, offset, -1)); + break; + + case PROTO_ID_NETBIOS: /* \\NETBIOS netbios name */ + proto_tree_add_item(tr, hf_epm_proto_netbios_name, tvb, offset, len, TRUE); + proto_item_append_text(tr, "NetBIOS:%*s",MIN(len,tvb_length_remaining(tvb, offset)), tvb_get_ptr(tvb, offset, -1)); + break; + + default: + if(len){ + proto_tree_add_text(tr, tvb, offset, len, "not decoded yet"); + } + } + offset += len; + + proto_item_set_len(it, offset-old_offset); + } + return offset; +} + +/* typedef struct { + unsigned int tower_len, + [size_is(tower_len)] char tower[]; + } twr_t, *twr_p_t; +*/ +static int +epm_dissect_tower (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + guint32 len; + dcerpc_info *di; + + di=pinfo->private_data; + if(di->conformant_run){ + return offset; + } + + /* first one is the header of the conformant array, second one is the + length field */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_tower_length, &len); + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_tower_length, NULL); + offset = epm_dissect_tower_data(tvb, offset, pinfo, tree, drep); + + return offset; +} +static int +epm_dissect_tower_pointer (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_tower, NDR_POINTER_PTR, + "Tower pointer:", -1); + return offset; +} +static int +epm_dissect_tower_array (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep, + epm_dissect_tower_pointer); + + return offset; +} + +static int +epm_dissect_ept_map_rqst (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [in, ptr] uuid_p_t object */ + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_uuid, NDR_POINTER_PTR, + "UUID pointer:", -1); + + /* [in, ptr] twr_p_t map_tower */ + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_tower, NDR_POINTER_PTR, + "Tower pointer:", -1); + + /* [in, out] ept_lookup_handle_t *entry_handle */ + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + /* [in] unsigned32 max_towers */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_max_towers, NULL); + + return offset; +} + +static int +epm_dissect_ept_map_resp (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [in, out] ept_lookup_handle_t *entry_handle */ + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + /* [out, ptr] unsigned32 *num_towers */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_num_towers, NULL); + + /* [out, length_is(*num_towers), size_is(max_towers), ptr] twr_p_t towers[] */ + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_tower_array, NDR_POINTER_REF, + "Tower array:", -1); + + /* [out] error_status_t *status */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_rc, NULL); + + return offset; +} + +static int +epm_dissect_ept_entry_t_ucarray(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, + epm_dissect_ept_entry_t); + + return offset; +} + +static int +epm_dissect_ept_insert_rqst (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_num_ents, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_ept_entry_t_ucarray, NDR_POINTER_REF, + "Entries:", -1); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_replace, NULL); + + return offset; +} + + + +static int +epm_dissect_ept_insert_resp (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [out] error_status_t *status */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_rc, NULL); + + return offset; +} + + +static int +epm_dissect_ept_delete_rqst (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_num_ents, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + epm_dissect_ept_entry_t_ucarray, NDR_POINTER_REF, + "Entries:", -1); + + return offset; +} + + + +static int +epm_dissect_ept_delete_resp (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [out] error_status_t *status */ + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_rc, NULL); + + return offset; +} + + + +static int +epm_dissect_ept_lookup_handle_free_rqst (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [in, out] ept_lookup_handle_t *entry_handle */ + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + return offset; +} + +static int +epm_dissect_ept_lookup_handle_free_resp (tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + /* [in, out] ept_lookup_handle_t *entry_handle */ + offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep, + hf_epm_hnd, NULL); + + offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, + hf_epm_rc, NULL); + + return offset; +} + + +static dcerpc_sub_dissector epm_dissectors[] = { + { 0, "Insert", + epm_dissect_ept_insert_rqst, + epm_dissect_ept_insert_resp }, + { 1, "Delete", + epm_dissect_ept_delete_rqst, + epm_dissect_ept_delete_resp }, + { 2, "Lookup", + epm_dissect_ept_lookup_rqst, + epm_dissect_ept_lookup_resp }, + { 3, "Map", + epm_dissect_ept_map_rqst, + epm_dissect_ept_map_resp }, + { 4, "LookupHandleFree", + epm_dissect_ept_lookup_handle_free_rqst, + epm_dissect_ept_lookup_handle_free_resp }, + { 5, "InqObject", NULL, NULL }, + { 6, "MgmtDelete", NULL, NULL }, + { 0, NULL, NULL, NULL } +}; + +void +proto_register_epm (void) +{ + static hf_register_info hf[] = { + { &hf_epm_opnum, + { "Operation", "epm.opnum", FT_UINT16, BASE_DEC, + NULL, 0x0, "Operation", HFILL }}, + { &hf_epm_inquiry_type, + { "Inquiry type", "epm.inq_type", FT_UINT32, BASE_DEC, VALS(ep_service), 0x0, "", HFILL }}, + { &hf_epm_object, + { "Object", "epm.object", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, + { &hf_epm_if_id, + { "Interface", "epm.if_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, + { &hf_epm_ver_maj, + { "Version Major", "epm.ver_maj", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_ver_min, + { "Version Minor", "epm.ver_min", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_ver_opt, + { "Version Option", "epm.ver_opt", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_hnd, + { "Handle", "epm.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "Context handle", HFILL }}, + { &hf_epm_max_ents, + { "Max entries", "epm.max_ents", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_num_ents, + { "Num entries", "epm.num_ents", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_uuid, + { "UUID", "epm.uuid", FT_STRING, BASE_NONE, NULL, 0x0, "UUID", HFILL }}, + { &hf_epm_annotation, + { "Annotation", "epm.annotation", FT_STRING, BASE_NONE, NULL, 0x0, "Annotation", HFILL }}, + { &hf_epm_proto_named_pipes, + { "Named Pipe", "epm.proto.named_pipe", FT_STRING, BASE_NONE, NULL, 0x0, "Name of the named pipe for this service", HFILL }}, + { &hf_epm_proto_netbios_name, + { "NetBIOS Name", "epm.proto.netbios_name", FT_STRING, BASE_NONE, NULL, 0x0, "NetBIOS name where this service can be found", HFILL }}, + { &hf_epm_tower_length, + { "Length", "epm.tower.len", FT_UINT32, BASE_DEC, NULL, 0x0, "Length of tower data", HFILL }}, + { &hf_epm_tower_data, + { "Tower", "epm.tower", FT_BYTES, BASE_HEX, NULL, 0x0, "Tower data", HFILL }}, + { &hf_epm_max_towers, + { "Max Towers", "epm.max_towers", FT_UINT32, BASE_DEC, NULL, 0x0, "Maximum number of towers to return", HFILL }}, + { &hf_epm_num_towers, + { "Num Towers", "epm.num_towers", FT_UINT32, BASE_DEC, NULL, 0x0, "Number number of towers to return", HFILL }}, + { &hf_epm_ann_offset, + { "Annotation offset", "epm.ann_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_ann_len, + { "Annotation length", "epm.ann_len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_epm_rc, + { "Return code", "epm.rc", FT_UINT32, BASE_HEX, NULL, 0x0, "EPM return value", HFILL }}, + { &hf_epm_replace, + { "Replace", "epm.replace", FT_UINT8, BASE_DEC, NULL, 0x0, "Replace existing objects?", HFILL }}, + { &hf_epm_tower_num_floors, + { "Number of floors", "epm.tower.num_floors", FT_UINT16, BASE_DEC, NULL, 0x0, "Number of floors in tower", HFILL }}, + { &hf_epm_proto_udp_port, + { "UDP Port", "epm.proto.udp_port", FT_UINT16, BASE_DEC, NULL, 0x0, "UDP Port where this service can be found", HFILL }}, + { &hf_epm_proto_tcp_port, + { "TCP Port", "epm.proto.tcp_port", FT_UINT16, BASE_DEC, NULL, 0x0, "TCP Port where this service can be found", HFILL }}, + { &hf_epm_tower_rhs_len, + { "RHS Length", "epm.tower.rhs.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Length of RHS data", HFILL }}, + { &hf_epm_tower_lhs_len, + { "LHS Length", "epm.tower.lhs.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Length of LHS data", HFILL }}, + { &hf_epm_proto_ip, + { "IP", "epm.proto.ip", FT_IPv4, BASE_NONE, NULL, 0x0, "IP address where service is located", HFILL }}, + { &hf_epm_tower_proto_id, + { "Protocol", "epm.tower.proto_id", FT_UINT8, BASE_HEX, VALS(proto_id_vals), 0x0, "Protocol identifier", HFILL }} + }; + + static gint *ett[] = { + &ett_epm, + &ett_epm_tower_floor, + &ett_epm_entry + }; + 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, hf_epm_opnum); +} |