2 * Routines for dcerpc endpoint mapper dissection
3 * Copyright 2001, Todd Sabin <tas@webspan.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
16 #include <epan/expert.h>
17 #include "packet-dcerpc.h"
19 void proto_register_epm (void);
20 void proto_reg_handoff_epm (void);
22 static int proto_epm3
;
23 static int proto_epm4
;
25 static int hf_epm_opnum
;
26 static int hf_epm_inquiry_type
;
27 static int hf_epm_object
;
28 static int hf_epm_if_id
;
29 static int hf_epm_ver_maj
;
30 static int hf_epm_ver_min
;
31 static int hf_epm_ver_opt
;
32 static int hf_epm_hnd
;
33 static int hf_epm_max_ents
;
34 static int hf_epm_num_ents
;
35 static int hf_epm_uuid
;
36 static int hf_epm_uuid_version
;
37 static int hf_epm_tower_length
;
38 /* static int hf_epm_tower_data; */
39 static int hf_epm_max_towers
;
40 static int hf_epm_num_towers
;
42 static int hf_epm_replace
;
43 static int hf_epm_tower_num_floors
;
44 static int hf_epm_tower_rhs_len
;
45 static int hf_epm_tower_lhs_len
;
46 static int hf_epm_tower_proto_id
;
47 static int hf_epm_annotation
;
48 static int hf_epm_ann_offset
;
49 static int hf_epm_ann_len
;
50 static int hf_epm_proto_named_pipes
;
51 static int hf_epm_proto_netbios_name
;
52 static int hf_epm_proto_ip
;
53 static int hf_epm_proto_udp_port
;
54 static int hf_epm_proto_tcp_port
;
55 static int hf_epm_proto_http_port
;
58 static int ett_epm_tower_floor
;
59 static int ett_epm_entry
;
61 static expert_field ei_epm_proto_undecoded
;
64 /* the UUID is identical for interface versions 3 and 4 */
65 static e_guid_t uuid_epm
= { 0xe1af8308, 0x5d1f, 0x11c9, { 0x91, 0xa4, 0x08, 0x00, 0x2b, 0x14, 0xa0, 0xfa } };
66 static uint16_t ver_epm3
= 3;
67 static uint16_t ver_epm4
= 4;
71 static const value_string ep_service
[] = {
72 { 0, "rpc_c_ep_all_elts" },
73 { 1, "rpc_c_ep_match_by_if" },
74 { 2, "rpc_c_ep_match_by_obj" },
75 { 3, "rpc_c_ep_match_by_both" },
80 unsigned int tower_len,
81 [size_is(tower_len)] char tower[];
84 static int epm_dissect_tower (tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, uint8_t *drep
);
88 epm_dissect_pointer_IF_ID(tvbuff_t
*tvb
, int offset
,
89 packet_info
*pinfo
, proto_tree
*tree
,
90 dcerpc_info
*di
, uint8_t *drep
)
92 offset
= dissect_ndr_uuid_t (tvb
, offset
, pinfo
, tree
, di
, drep
,
94 offset
= dissect_ndr_uint16 (tvb
, offset
, pinfo
, tree
, di
, drep
,
95 hf_epm_ver_maj
, NULL
);
96 offset
= dissect_ndr_uint16 (tvb
, offset
, pinfo
, tree
, di
, drep
,
97 hf_epm_ver_min
, NULL
);
102 epm_dissect_pointer_UUID(tvbuff_t
*tvb
, int offset
,
103 packet_info
*pinfo
, proto_tree
*tree
,
104 dcerpc_info
*di
, uint8_t *drep
)
106 offset
= dissect_ndr_uuid_t (tvb
, offset
, pinfo
, tree
, di
, drep
,
112 epm_dissect_ept_lookup_rqst (tvbuff_t
*tvb
, int offset
,
113 packet_info
*pinfo
, proto_tree
*tree
,
114 dcerpc_info
*di
, uint8_t *drep
)
116 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
117 hf_epm_inquiry_type
, NULL
);
119 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
120 epm_dissect_pointer_UUID
, NDR_POINTER_PTR
,
121 "Object:", hf_epm_object
);
123 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
124 epm_dissect_pointer_IF_ID
, NDR_POINTER_PTR
,
125 "Interface:", hf_epm_if_id
);
127 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
128 hf_epm_ver_opt
, NULL
);
130 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
133 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
134 hf_epm_max_ents
, NULL
);
140 epm_dissect_ept_entry_t(tvbuff_t
*tvb
, int offset
,
141 packet_info
*pinfo
, proto_tree
*parent_tree
,
142 dcerpc_info
*di
, uint8_t *drep
)
144 proto_item
*item
=NULL
;
145 proto_tree
*tree
=NULL
;
146 int old_offset
=offset
;
150 if(di
->conformant_run
){
155 tree
= proto_tree_add_subtree(parent_tree
, tvb
, offset
, -1, ett_epm_entry
, &item
, "Entry:");
158 offset
= dissect_ndr_uuid_t (tvb
, offset
, pinfo
, tree
, di
, drep
,
159 hf_epm_object
, NULL
);
161 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
162 epm_dissect_tower
, NDR_POINTER_PTR
,
163 "Tower pointer:", -1);
165 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
166 hf_epm_ann_offset
, NULL
);
167 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
168 hf_epm_ann_len
, &len
);
169 proto_tree_add_item_ret_string(tree
, hf_epm_annotation
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
174 proto_item_append_text(item
, " Service:%s ", str
);
175 proto_item_append_text(tree
->parent
, " Service:%s ", str
);
177 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Service:%s", str
);
180 proto_item_set_len(item
, offset
-old_offset
);
185 epm_dissect_ept_entry_t_array(tvbuff_t
*tvb
, int offset
,
186 packet_info
*pinfo
, proto_tree
*tree
,
187 dcerpc_info
*di
, uint8_t *drep
)
189 offset
= dissect_ndr_ucvarray(tvb
, offset
, pinfo
, tree
, di
, drep
,
190 epm_dissect_ept_entry_t
);
196 epm_dissect_ept_lookup_resp (tvbuff_t
*tvb
, int offset
,
197 packet_info
*pinfo
, proto_tree
*tree
,
198 dcerpc_info
*di
, uint8_t *drep
)
200 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
203 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
204 hf_epm_num_ents
, NULL
);
206 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
207 epm_dissect_ept_entry_t_array
, NDR_POINTER_REF
,
210 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
217 epm_dissect_uuid (tvbuff_t
*tvb
, int offset
,
218 packet_info
*pinfo
, proto_tree
*tree
,
219 dcerpc_info
*di
, uint8_t *drep
)
221 offset
= dissect_ndr_uuid_t (tvb
, offset
, pinfo
, tree
, di
, drep
,
226 #define PROTO_ID_OSI_OID 0x00
227 #define PROTO_ID_DNA_SESSCTL 0x02
228 #define PROTO_ID_DNA_SESSCTL_V3 0x03
229 #define PROTO_ID_DNA_NSP 0x04
230 #define PROTO_ID_OSI_TP4 0x05
231 #define PROTO_ID_OSI_CLNS 0x06
232 #define PROTO_ID_TCP 0x07
233 #define PROTO_ID_UDP 0x08
234 #define PROTO_ID_IP 0x09
235 #define PROTO_ID_RPC_CL 0x0a
236 #define PROTO_ID_RPC_CO 0x0b
237 #define PROTO_ID_SPX 0x0c /* from DCOM spec (is this correct?) */
238 #define PROTO_ID_UUID 0x0d
239 #define PROTO_ID_IPX 0x0e /* from DCOM spec (is this correct?) */
240 #define PROTO_ID_NAMED_PIPES 0x0f
241 #define PROTO_ID_NAMED_PIPES_2 0x10
242 #define PROTO_ID_NETBIOS 0x11
243 #define PROTO_ID_NETBEUI 0x12
244 #define PROTO_ID_NETWARE_SPX 0x13
245 #define PROTO_ID_NETWARE_IPX 0x14
246 #define PROTO_ID_ATALK_STREAM 0x16
247 #define PROTO_ID_ATALK_DATAGRAM 0x17
248 #define PROTO_ID_ATALK 0x18
249 #define PROTO_ID_NETBIOS_2 0x19
250 #define PROTO_ID_VINES_SPP 0x1a
251 #define PROTO_ID_VINES_IPC 0x1b
252 #define PROTO_ID_STREETTALK 0x1c
253 #define PROTO_ID_HTTP 0x1f
254 #define PROTO_ID_UNIX_DOMAIN 0x20
255 #define PROTO_ID_NULL 0x21
256 #define PROTO_ID_NETBIOS_3 0x22
258 static const value_string proto_id_vals
[] = {
259 { PROTO_ID_OSI_OID
, "OSI OID"},
260 { PROTO_ID_DNA_SESSCTL
, "DNA Session Control"},
261 { PROTO_ID_DNA_SESSCTL_V3
, "DNA Session Control V3"},
262 { PROTO_ID_DNA_NSP
, "DNA NSP Transport"},
263 { PROTO_ID_OSI_TP4
, "OSI TP4"},
264 { PROTO_ID_OSI_CLNS
, "OSI CLNS or DNA Routing"},
265 { PROTO_ID_TCP
, "DOD TCP"},
266 { PROTO_ID_UDP
, "DOD UDP"},
267 { PROTO_ID_IP
, "DOD IP"},
268 { PROTO_ID_RPC_CL
, "RPC connectionless protocol"},
269 { PROTO_ID_RPC_CO
, "RPC connection-oriented protocol"},
270 { PROTO_ID_SPX
, "SPX?"},
271 { PROTO_ID_UUID
, "UUID"},
272 { PROTO_ID_IPX
, "IPX?"},
273 { PROTO_ID_NAMED_PIPES
, "Named Pipes"},
274 { PROTO_ID_NAMED_PIPES_2
, "Named Pipes"},
275 { PROTO_ID_NETBIOS
, "NetBIOS"},
276 { PROTO_ID_NETBEUI
, "NetBEUI"},
277 { PROTO_ID_NETWARE_SPX
, "Netware SPX"},
278 { PROTO_ID_NETWARE_IPX
, "Netware IPX"},
279 { PROTO_ID_ATALK_STREAM
, "Appletalk Stream"},
280 { PROTO_ID_ATALK_DATAGRAM
, "Appletalk Datagram"},
281 { PROTO_ID_ATALK
, "Appletalk"},
282 { PROTO_ID_NETBIOS_2
, "NetBIOS"},
283 { PROTO_ID_VINES_SPP
, "Vines SPP"},
284 { PROTO_ID_VINES_IPC
, "Vines IPC"},
285 { PROTO_ID_STREETTALK
, "StreetTalk"},
286 { PROTO_ID_HTTP
, "RPC over HTTP"},
287 { PROTO_ID_UNIX_DOMAIN
, "Unix Domain Socket"},
288 { PROTO_ID_NULL
, "null"},
289 { PROTO_ID_NETBIOS_3
, "NetBIOS"},
294 /* XXX this function assumes LE encoding. can not use the NDR routines
295 since they assume padding.
298 epm_dissect_tower_data (tvbuff_t
*tvb
, int offset
,
299 packet_info
*pinfo
, proto_tree
*tree
,
300 dcerpc_info
*di
, uint8_t *drep _U_
)
302 uint16_t num_floors
, ii
;
303 const char *uuid_name
;
304 uint8_t u8little_endian
= DREP_LITTLE_ENDIAN
;
307 if(di
->conformant_run
){
311 num_floors
= tvb_get_letohs(tvb
, offset
);
312 proto_tree_add_uint(tree
, hf_epm_tower_num_floors
, tvb
, offset
, 2, num_floors
);
315 for(ii
=0;ii
<num_floors
;ii
++){
316 proto_item
*it
= NULL
;
317 proto_tree
*tr
= NULL
;
318 int old_offset
= offset
;
324 tr
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 0, ett_epm_tower_floor
, &it
, "Floor %d ", ii
+1);
326 len
= tvb_get_letohs(tvb
, offset
);
327 proto_tree_add_uint(tr
, hf_epm_tower_lhs_len
, tvb
, offset
, 2, len
);
330 proto_id
= tvb_get_uint8(tvb
, offset
);
331 proto_tree_add_uint(tr
, hf_epm_tower_proto_id
, tvb
, offset
, 1, proto_id
);
335 dcerpc_tvb_get_uuid (tvb
, offset
+1, &u8little_endian
, &uuid
);
337 uuid_name
= guids_get_uuid_name(&uuid
, pinfo
->pool
);
339 if(uuid_name
!= NULL
) {
340 proto_tree_add_guid_format (tr
, hf_epm_uuid
, tvb
, offset
+1, 16, (e_guid_t
*) &uuid
,
341 "UUID: %s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
343 uuid
.data1
, uuid
.data2
, uuid
.data3
,
344 uuid
.data4
[0], uuid
.data4
[1],
345 uuid
.data4
[2], uuid
.data4
[3],
346 uuid
.data4
[4], uuid
.data4
[5],
347 uuid
.data4
[6], uuid
.data4
[7]);
349 proto_tree_add_guid_format (tr
, hf_epm_uuid
, tvb
, offset
+1, 16, (e_guid_t
*) &uuid
,
350 "UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
351 uuid
.data1
, uuid
.data2
, uuid
.data3
,
352 uuid
.data4
[0], uuid
.data4
[1],
353 uuid
.data4
[2], uuid
.data4
[3],
354 uuid
.data4
[4], uuid
.data4
[5],
355 uuid
.data4
[6], uuid
.data4
[7]);
357 proto_tree_add_item(tr
, hf_epm_uuid_version
, tvb
, offset
+17, 2, ENC_BIG_ENDIAN
); /* Major/minor bytes treated as big endian */
360 uint16_t version
= tvb_get_ntohs(tvb
, offset
+17);
361 const char *service
= dcerpc_get_proto_name(&uuid
, version
);
362 if (service
|| uuid_name
) {
363 const char *s
= service
? service
: uuid_name
;
364 proto_item_append_text(tr
, "UUID: %s", s
);
365 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s", s
);
367 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
,
368 uuid
.data4
[0], uuid
.data4
[1],
369 uuid
.data4
[2], uuid
.data4
[3],
370 uuid
.data4
[4], uuid
.data4
[5],
371 uuid
.data4
[6], uuid
.data4
[7],
372 tvb_get_uint8(tvb
, offset
+17),
373 tvb_get_uint8(tvb
, offset
+18));
380 len
= tvb_get_letohs(tvb
, offset
);
381 pi
= proto_tree_add_uint(tr
, hf_epm_tower_rhs_len
, tvb
, offset
, 2, len
);
387 /* XXX - is this big or little endian? */
388 proto_tree_add_item(tr
, hf_epm_ver_min
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
390 case PROTO_ID_TCP
: /* this one is always big endian */
391 proto_tree_add_item(tr
, hf_epm_proto_tcp_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
392 proto_item_append_text(tr
, "TCP Port:%d", tvb_get_ntohs(tvb
, offset
));
395 case PROTO_ID_UDP
: /* this one is always big endian */
396 proto_tree_add_item(tr
, hf_epm_proto_udp_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
397 proto_item_append_text(tr
, "UDP Port:%d", tvb_get_ntohs(tvb
, offset
));
400 case PROTO_ID_IP
: /* this one is always big endian */
401 proto_tree_add_item(tr
, hf_epm_proto_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
402 proto_item_append_text(tr
, "IP:%s", tvb_ip_to_str(pinfo
->pool
, tvb
, offset
));
405 case PROTO_ID_RPC_CO
:
406 proto_item_append_text(tr
, "RPC connection-oriented protocol");
409 case PROTO_ID_RPC_CL
:
410 proto_item_append_text(tr
, "RPC connectionless protocol");
411 /* XXX - is this big or little endian? */
412 proto_tree_add_item(tr
, hf_epm_ver_min
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
415 case PROTO_ID_NAMED_PIPES
: /* \\PIPE\xxx named pipe */
416 proto_tree_add_item_ret_string(tr
, hf_epm_proto_named_pipes
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
417 proto_item_append_text(tr
, "NamedPipe:%s", str
);
420 case PROTO_ID_NAMED_PIPES_2
: /* PIPENAME named pipe */
421 proto_tree_add_item_ret_string(tr
, hf_epm_proto_named_pipes
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
422 proto_item_append_text(tr
, "PIPE:%s", str
);
425 case PROTO_ID_NETBIOS
: /* \\NETBIOS netbios name */
426 proto_tree_add_item_ret_string(tr
, hf_epm_proto_netbios_name
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
427 proto_item_append_text(tr
, "NetBIOS:%s", str
);
429 case PROTO_ID_HTTP
: /* RPC over HTTP */
430 proto_tree_add_item(tr
, hf_epm_proto_http_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
431 proto_item_append_text(tr
, "RPC over HTTP Port:%d", tvb_get_ntohs(tvb
, offset
));
436 expert_add_info_format(pinfo
, pi
, &ei_epm_proto_undecoded
, "RightHandSide not decoded yet for proto_id 0x%x",
442 proto_item_set_len(it
, offset
-old_offset
);
448 epm_fmt_uuid_version( char *result
, uint32_t revision
)
450 snprintf( result
, ITEM_LABEL_LENGTH
, "%d.%02d", (uint8_t)(( revision
& 0xFF00 ) >> 8), (uint8_t)(revision
& 0xFF) );
454 unsigned int tower_len,
455 [size_is(tower_len)] char tower[];
459 epm_dissect_tower (tvbuff_t
*tvb
, int offset
,
460 packet_info
*pinfo
, proto_tree
*tree
,
461 dcerpc_info
*di
, uint8_t *drep
)
465 if(di
->conformant_run
){
469 /* first one is the header of the conformant array, second one is the
471 offset
= dissect_ndr_uint3264 (tvb
, offset
, pinfo
, tree
, di
, drep
,
472 hf_epm_tower_length
, &len
);
473 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
474 hf_epm_tower_length
, NULL
);
475 offset
= epm_dissect_tower_data(tvb
, offset
, pinfo
, tree
, di
, drep
);
480 epm_dissect_tower_pointer (tvbuff_t
*tvb
, int offset
,
481 packet_info
*pinfo
, proto_tree
*tree
,
482 dcerpc_info
*di
, uint8_t *drep
)
484 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
485 epm_dissect_tower
, NDR_POINTER_PTR
,
486 "Tower pointer:", -1);
490 epm_dissect_tower_array (tvbuff_t
*tvb
, int offset
,
491 packet_info
*pinfo
, proto_tree
*tree
,
492 dcerpc_info
*di
, uint8_t *drep
)
494 offset
= dissect_ndr_ucvarray(tvb
, offset
, pinfo
, tree
, di
, drep
,
495 epm_dissect_tower_pointer
);
501 epm_dissect_ept_map_rqst (tvbuff_t
*tvb
, int offset
,
502 packet_info
*pinfo
, proto_tree
*tree
,
503 dcerpc_info
*di
, uint8_t *drep
)
505 /* [in, ptr] uuid_p_t object */
506 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
507 epm_dissect_uuid
, NDR_POINTER_PTR
,
508 "UUID pointer:", -1);
510 /* [in, ptr] twr_p_t map_tower */
511 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
512 epm_dissect_tower
, NDR_POINTER_PTR
,
513 "Tower pointer:", -1);
515 /* [in, out] ept_lookup_handle_t *entry_handle */
516 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
519 /* [in] unsigned32 max_towers */
520 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
521 hf_epm_max_towers
, NULL
);
527 epm_dissect_ept_map_resp (tvbuff_t
*tvb
, int offset
,
528 packet_info
*pinfo
, proto_tree
*tree
,
529 dcerpc_info
*di
, uint8_t *drep
)
531 /* [in, out] ept_lookup_handle_t *entry_handle */
532 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
535 /* [out, ptr] unsigned32 *num_towers */
536 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
537 hf_epm_num_towers
, NULL
);
539 /* [out, length_is(*num_towers), size_is(max_towers), ptr] twr_p_t towers[] */
540 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
541 epm_dissect_tower_array
, NDR_POINTER_REF
,
544 /* [out] error_status_t *status */
545 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
552 epm_dissect_ept_entry_t_ucarray(tvbuff_t
*tvb
, int offset
,
553 packet_info
*pinfo
, proto_tree
*tree
,
554 dcerpc_info
*di
, uint8_t *drep
)
556 offset
= dissect_ndr_ucarray(tvb
, offset
, pinfo
, tree
, di
, drep
,
557 epm_dissect_ept_entry_t
);
563 epm_dissect_ept_insert_rqst (tvbuff_t
*tvb
, int offset
,
564 packet_info
*pinfo
, proto_tree
*tree
,
565 dcerpc_info
*di
, uint8_t *drep
)
567 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
568 hf_epm_num_ents
, NULL
);
570 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
571 epm_dissect_ept_entry_t_ucarray
, NDR_POINTER_REF
,
574 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
575 hf_epm_replace
, NULL
);
583 epm_dissect_ept_insert_resp (tvbuff_t
*tvb
, int offset
,
584 packet_info
*pinfo
, proto_tree
*tree
,
585 dcerpc_info
*di
, uint8_t *drep
)
587 /* [out] error_status_t *status */
588 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
596 epm_dissect_ept_delete_rqst (tvbuff_t
*tvb
, int offset
,
597 packet_info
*pinfo
, proto_tree
*tree
,
598 dcerpc_info
*di
, uint8_t *drep
)
600 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
601 hf_epm_num_ents
, NULL
);
603 offset
= dissect_ndr_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
604 epm_dissect_ept_entry_t_ucarray
, NDR_POINTER_REF
,
613 epm_dissect_ept_delete_resp (tvbuff_t
*tvb
, int offset
,
614 packet_info
*pinfo
, proto_tree
*tree
,
615 dcerpc_info
*di
, uint8_t *drep
)
617 /* [out] error_status_t *status */
618 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
627 epm_dissect_ept_lookup_handle_free_rqst (tvbuff_t
*tvb
, int offset
,
628 packet_info
*pinfo
, proto_tree
*tree
,
629 dcerpc_info
*di
, uint8_t *drep
)
631 /* [in, out] ept_lookup_handle_t *entry_handle */
632 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
639 epm_dissect_ept_lookup_handle_free_resp (tvbuff_t
*tvb
, int offset
,
640 packet_info
*pinfo
, proto_tree
*tree
,
641 dcerpc_info
*di
, uint8_t *drep
)
643 /* [in, out] ept_lookup_handle_t *entry_handle */
644 offset
= dissect_ndr_ctx_hnd (tvb
, offset
, pinfo
, tree
, di
, drep
,
647 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
654 static const dcerpc_sub_dissector epm_dissectors
[] = {
656 epm_dissect_ept_insert_rqst
,
657 epm_dissect_ept_insert_resp
},
659 epm_dissect_ept_delete_rqst
,
660 epm_dissect_ept_delete_resp
},
662 epm_dissect_ept_lookup_rqst
,
663 epm_dissect_ept_lookup_resp
},
665 epm_dissect_ept_map_rqst
,
666 epm_dissect_ept_map_resp
},
667 { 4, "LookupHandleFree",
668 epm_dissect_ept_lookup_handle_free_rqst
,
669 epm_dissect_ept_lookup_handle_free_resp
},
670 { 5, "InqObject", NULL
, NULL
},
671 { 6, "MgmtDelete", NULL
, NULL
},
672 { 0, NULL
, NULL
, NULL
}
676 proto_register_epm (void)
678 static hf_register_info hf
[] = {
680 { "Operation", "epm.opnum", FT_UINT16
, BASE_DEC
,
681 NULL
, 0x0, NULL
, HFILL
}},
682 { &hf_epm_inquiry_type
,
683 { "Inquiry type", "epm.inq_type", FT_UINT32
, BASE_DEC
, VALS(ep_service
), 0x0, NULL
, HFILL
}},
685 { "Object", "epm.object", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
687 { "Interface", "epm.if_id", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
689 { "Version Major", "epm.ver_maj", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
691 { "Version Minor", "epm.ver_min", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
693 { "Version Option", "epm.ver_opt", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
695 { "Handle", "epm.hnd", FT_BYTES
, BASE_NONE
, NULL
, 0x0, "Context handle", HFILL
}},
697 { "Max entries", "epm.max_ents", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
699 { "Num entries", "epm.num_ents", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
701 { "UUID", "epm.uuid", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
702 { &hf_epm_uuid_version
,
703 { "Version", "epm.uuid_version", FT_UINT16
, BASE_CUSTOM
, CF_FUNC(epm_fmt_uuid_version
), 0x0, NULL
, HFILL
}},
704 { &hf_epm_annotation
,
705 { "Annotation", "epm.annotation", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
706 { &hf_epm_proto_named_pipes
,
707 { "Named Pipe", "epm.proto.named_pipe", FT_STRING
, BASE_NONE
, NULL
, 0x0, "Name of the named pipe for this service", HFILL
}},
708 { &hf_epm_proto_netbios_name
,
709 { "NetBIOS Name", "epm.proto.netbios_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, "NetBIOS name where this service can be found", HFILL
}},
710 { &hf_epm_tower_length
,
711 { "Length", "epm.tower.len", FT_UINT32
, BASE_DEC
, NULL
, 0x0, "Length of tower data", HFILL
}},
713 { &hf_epm_tower_data
,
714 { "Tower", "epm.tower", FT_BYTES
, BASE_NONE
, NULL
, 0x0, "Tower data", HFILL
}},
716 { &hf_epm_max_towers
,
717 { "Max Towers", "epm.max_towers", FT_UINT32
, BASE_DEC
, NULL
, 0x0, "Maximum number of towers to return", HFILL
}},
718 { &hf_epm_num_towers
,
719 { "Num Towers", "epm.num_towers", FT_UINT32
, BASE_DEC
, NULL
, 0x0, "Number number of towers to return", HFILL
}},
720 { &hf_epm_ann_offset
,
721 { "Annotation offset", "epm.ann_offset", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
723 { "Annotation length", "epm.ann_len", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
725 { "Return code", "epm.rc", FT_UINT32
, BASE_HEX
, NULL
, 0x0, "EPM return value", HFILL
}},
727 { "Replace", "epm.replace", FT_UINT8
, BASE_DEC
, NULL
, 0x0, "Replace existing objects?", HFILL
}},
728 { &hf_epm_tower_num_floors
,
729 { "Number of floors", "epm.tower.num_floors", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "Number of floors in tower", HFILL
}},
730 { &hf_epm_proto_udp_port
,
731 { "UDP Port", "epm.proto.udp_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "UDP Port where this service can be found", HFILL
}},
732 { &hf_epm_proto_tcp_port
,
733 { "TCP Port", "epm.proto.tcp_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "TCP Port where this service can be found", HFILL
}},
734 { &hf_epm_proto_http_port
,
735 { "TCP Port", "epm.proto.http_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "TCP Port where this service can be found", HFILL
}},
736 { &hf_epm_tower_rhs_len
,
737 { "RHS Length", "epm.tower.rhs.len", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "Length of RHS data", HFILL
}},
738 { &hf_epm_tower_lhs_len
,
739 { "LHS Length", "epm.tower.lhs.len", FT_UINT16
, BASE_DEC
, NULL
, 0x0, "Length of LHS data", HFILL
}},
741 { "IP", "epm.proto.ip", FT_IPv4
, BASE_NONE
, NULL
, 0x0, "IP address where service is located", HFILL
}},
742 { &hf_epm_tower_proto_id
,
743 { "Protocol", "epm.tower.proto_id", FT_UINT8
, BASE_HEX
, VALS(proto_id_vals
), 0x0, "Protocol identifier", HFILL
}}
745 static int *ett
[] = {
747 &ett_epm_tower_floor
,
751 static ei_register_info ei
[] = {
752 { &ei_epm_proto_undecoded
, { "epm.proto_id.undecoded", PI_UNDECODED
, PI_WARN
, "RightHandSide not decoded yet for proto_id", EXPFILL
}},
755 expert_module_t
* expert_epm3
;
757 /* interface version 3 */
758 proto_epm3
= proto_register_protocol ("DCE/RPC Endpoint Mapper", "EPM", "epm");
759 proto_register_field_array (proto_epm3
, hf
, array_length (hf
));
760 proto_register_subtree_array (ett
, array_length (ett
));
761 expert_epm3
= expert_register_protocol(proto_epm3
);
762 expert_register_field_array(expert_epm3
, ei
, array_length(ei
));
764 /* interface version 4 */
765 proto_epm4
= proto_register_protocol ("DCE/RPC Endpoint Mapper v4", "EPMv4", "epm4");
769 proto_reg_handoff_epm (void)
771 /* Register the protocol as dcerpc */
772 dcerpc_init_uuid (proto_epm3
, ett_epm
, &uuid_epm
, ver_epm3
, epm_dissectors
, hf_epm_opnum
);
773 dcerpc_init_uuid (proto_epm4
, ett_epm
, &uuid_epm
, ver_epm4
, epm_dissectors
, hf_epm_opnum
);
777 * Editor modelines - https://www.wireshark.org/tools/modelines.html
782 * indent-tabs-mode: nil
785 * vi: set shiftwidth=4 tabstop=8 expandtab:
786 * :indentSize=4:tabSize=8:noTabs=true: