2 * Routines for DCOM generics
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 /* A few words about DCOM:
27 * DCOM uses DCERPC as its underlying "transport" protocol.
29 * The DCOM dissectors are called by DCERPC request and response calls.
30 * DCOM uses a small header after the DCERPC calls.
31 * (for a DCERPC request call it's called "this",
32 * for a DCERPC response call it's called "that")
34 * DCOM defines itself some interfaces: oxid, remact, remunk and others
36 * Implemented is currently "only" a static dissection of packet fields
37 * (no "object recognition" included)
39 * User's of DCOM can define their own interface's using Microsoft IDL.
41 * Hint: The registered DCOM interface names can be found in the
42 * windows registry at: "HKEY_CLASSES_ROOT\Interface"
45 * Ressources on the web:
47 * "Understanding the DCOM Wire Protocol by Analyzing Network Data Packets"
48 * http:// www.microsoft.com/msj/0398/dcom.htm
50 * "Distributed Component Object Model Protocol -- DCOM/1.0"
51 * http://www.microsoft.com/com/resources/specs.asp (link is currently down)
55 /* Files involved dissecting DCOM:
57 * packet-dcom.c: generic DCOM things (this, that, ...) and
58 * generic DCOM datatype (DWORD, VARIANT, ...)
60 * DCOM common Interfaces:
61 * packet-dcom-oxid.c: IOXIDResolver
62 * packet-dcom-remact.c: IRemoteActivation
63 * packet-dcom-remunk.c: IRemUnknown, IRemUnknown2
64 * packet-dcom-dispatch.c: IDispatch
65 * packet-dcom-sysact.c: ISystemActivator
71 * XXX - are the next two includes necessary?
73 #ifdef HAVE_SYS_TYPES_H
74 # include <sys/types.h>
77 #ifdef HAVE_NETINET_IN_H
78 #include <netinet/in.h>
81 #ifdef HAVE_WINSOCK2_H
89 #include <epan/packet.h>
90 #include <epan/exceptions.h>
91 #include <epan/wmem/wmem.h>
92 #include <epan/addr_resolv.h>
93 #include <wsutil/inet_aton.h>
94 #include <epan/expert.h>
95 #include <epan/prefs.h>
98 #include "packet-dcerpc.h"
99 #include "packet-dcom.h"
101 void proto_register_dcom (void);
102 void proto_reg_handoff_dcom (void);
104 static int proto_dcom
= -1;
106 gboolean dcom_prefs_display_unmarshalling_details
= FALSE
;
109 static gint ett_dcom_this
= -1;
110 /* static int hf_dcom_this_version_major = -1; */
111 /* static int hf_dcom_this_version_minor = -1; */
112 static int hf_dcom_this_flags
= -1;
113 static int hf_dcom_this_res
= -1;
114 static int hf_dcom_this_cid
= -1;
116 static gint ett_dcom_that
= -1;
117 static int hf_dcom_that_flags
= -1;
119 static gint ett_dcom_extent
= -1;
120 static int hf_dcom_extent
= -1;
121 static int hf_dcom_extent_array_count
= -1;
122 static int hf_dcom_extent_array_res
= -1;
123 static int hf_dcom_extent_size
= -1;
124 static int hf_dcom_extent_id
= -1;
126 static int hf_dcom_hresult
= -1;
127 static int hf_dcom_tobedone
= -1;
128 static int hf_dcom_nospec
= -1;
129 static int hf_dcom_array_size
= -1;
130 static int hf_dcom_pointer_val
= -1;
133 static int hf_dcom_version_major
= -1;
134 static int hf_dcom_version_minor
= -1;
136 static gint ett_dcom_lpwstr
= -1;
137 static int hf_dcom_max_count
= -1;
138 static int hf_dcom_offset
= -1;
139 static int hf_dcom_byte_length
= -1;
140 /* static int hf_dcom_actual_count = -1; */
142 static gint ett_dcom_objref
= -1;
143 static int hf_dcom_objref
= -1;
144 static int hf_dcom_objref_signature
= -1;
145 static int hf_dcom_objref_flags
= -1;
146 int hf_dcom_iid
= -1;
147 int hf_dcom_clsid
= -1;
148 static int hf_dcom_objref_resolver_address
= -1;
149 static int hf_dcom_objref_cbextension
= -1;
150 static int hf_dcom_objref_size
= -1;
152 static gint ett_dcom_stdobjref
= -1;
153 static int hf_dcom_stdobjref
= -1;
154 static int hf_dcom_stdobjref_flags
= -1;
155 static int hf_dcom_stdobjref_public_refs
= -1;
156 int hf_dcom_oxid
= -1;
157 int hf_dcom_oid
= -1;
158 int hf_dcom_ipid
= -1;
161 static gint ett_dcom_custobjref
= -1;
162 static int hf_dcom_custobjref
= -1;
164 static gint ett_dcom_dualstringarray
= -1;
165 static gint ett_dcom_dualstringarray_binding
= -1;
166 static int hf_dcom_dualstringarray_num_entries
= -1;
167 static int hf_dcom_dualstringarray_security_offset
= -1;
168 static int hf_dcom_dualstringarray_string
= -1;
169 static int hf_dcom_dualstringarray_string_network_addr
= -1;
170 static int hf_dcom_dualstringarray_string_tower_id
= -1;
171 static int hf_dcom_dualstringarray_security
= -1;
172 static int hf_dcom_dualstringarray_security_authn_svc
= -1;
173 static int hf_dcom_dualstringarray_security_authz_svc
= -1;
174 static int hf_dcom_dualstringarray_security_princ_name
= -1;
176 static gint ett_dcom_interface_pointer
= -1;
177 static int hf_dcom_interface_pointer
= -1;
178 static int hf_dcom_ip_cnt_data
= -1;
180 static gint ett_dcom_safearray
= -1;
181 static int hf_dcom_safearray
= -1;
182 static int hf_dcom_sa_dims32
= -1;
183 static int hf_dcom_sa_dims16
= -1;
184 static int hf_dcom_sa_features
= -1;
185 static int hf_dcom_sa_element_size
= -1;
186 static int hf_dcom_sa_locks
= -1;
187 static int hf_dcom_sa_vartype32
= -1;
188 static int hf_dcom_sa_vartype16
= -1;
189 static int hf_dcom_sa_elements
= -1;
190 static int hf_dcom_sa_bound_elements
= -1;
191 static int hf_dcom_sa_low_bound
= -1;
193 static gint ett_dcom_sa_features
= -1;
194 static int hf_dcom_sa_features_auto
= -1;
195 static int hf_dcom_sa_features_static
= -1;
196 static int hf_dcom_sa_features_embedded
= -1;
197 static int hf_dcom_sa_features_fixedsize
= -1;
198 static int hf_dcom_sa_features_record
= -1;
199 static int hf_dcom_sa_features_have_iid
= -1;
200 static int hf_dcom_sa_features_have_vartype
= -1;
201 static int hf_dcom_sa_features_bstr
= -1;
202 static int hf_dcom_sa_features_unknown
= -1;
203 static int hf_dcom_sa_features_dispatch
= -1;
204 static int hf_dcom_sa_features_variant
= -1;
206 static gint ett_dcom_variant
= -1;
207 /* static int hf_dcom_variant = -1; */
208 static int hf_dcom_variant_type
= -1;
209 static int hf_dcom_variant_size
= -1;
210 static int hf_dcom_variant_rpc_res
= -1;
211 static int hf_dcom_variant_wres
= -1;
212 static int hf_dcom_variant_type32
= -1;
214 static int hf_dcom_vt_bool
= -1;
215 static int hf_dcom_vt_i1
= -1;
216 static int hf_dcom_vt_i2
= -1;
217 static int hf_dcom_vt_i4
= -1;
218 static int hf_dcom_vt_i8
= -1; /* only inside a SAFEARRAY, not in VARIANTs */
219 static int hf_dcom_vt_ui1
= -1;
220 static int hf_dcom_vt_ui2
= -1;
221 static int hf_dcom_vt_ui4
= -1;
222 static int hf_dcom_vt_r4
= -1;
223 static int hf_dcom_vt_r8
= -1;
224 static int hf_dcom_vt_date
= -1;
225 static int hf_dcom_vt_bstr
= -1;
226 static int hf_dcom_vt_byref
= -1;
227 static int hf_dcom_vt_dispatch
= -1;
229 static expert_field ei_dcom_dissetion_incomplete
= EI_INIT
;
230 static expert_field ei_dcom_no_spec
= EI_INIT
;
231 static expert_field ei_dcom_hresult_expert
= EI_INIT
;
232 static expert_field ei_dcom_dualstringarray_mult_ip
= EI_INIT
;
234 /* this/that extension UUIDs */
235 static e_uuid_t uuid_debug_ext
= { 0xf1f19680, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
236 static e_uuid_t uuid_ext_error_ext
={ 0xf1f19681, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
238 /* general DCOM UUIDs */
239 static const e_uuid_t ipid_rem_unknown
= { 0x00000131, 0x1234, 0x5678, { 0xCA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
240 static const e_uuid_t iid_unknown
= { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
241 static const e_uuid_t uuid_null
= { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
242 static const e_uuid_t iid_class_factory
= { 0x00000001, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
244 static const e_uuid_t iid_act_prop_in
= { 0x000001A2, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
245 static const e_uuid_t iid_act_prop_out
= { 0x000001A3, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
248 static GList
*dcom_machines
= NULL
;
249 static GList
*dcom_interfaces
= NULL
;
250 static GList
*dcom_marshalers
= NULL
;
252 static const value_string dcom_thisthat_flag_vals
[] = {
259 static const value_string dcom_boolean_flag_vals
[] = {
260 { 0x00000001, "TRUE" },
261 { 0x00000000, "FALSE" },
266 void dcom_interface_dump(void) {
267 dcom_machine_t
*machine
;
268 dcom_object_t
*object
;
269 dcom_interface_t
*interf
;
275 for(machines
= dcom_machines
; machines
!= NULL
; machines
= g_list_next(machines
)) {
276 machine
= (dcom_machine_t
*)machines
->data
;
277 g_warning("Machine(#%4u): IP:%s", machine
->first_packet
, ip_to_str(machine
->ip
));
279 for(objects
= machine
->objects
; objects
!= NULL
; objects
= g_list_next(objects
)) {
280 object
= (dcom_object_t
*)objects
->data
;
281 g_warning(" Object(#%4u): OID:0x%" G_GINT64_MODIFIER
"x private:%p", object
->first_packet
, object
->oid
, object
->private_data
);
283 for(interfaces
= object
->interfaces
; interfaces
!= NULL
; interfaces
= g_list_next(interfaces
)) {
284 interf
= (dcom_interface_t
*)interfaces
->data
;
285 g_warning(" Interface(#%4u): iid:%s",
286 interf
->first_packet
, guids_resolve_uuid_to_str(&interf
->iid
));
287 g_warning(" ipid:%s", guids_resolve_uuid_to_str(&interf
->ipid
));
294 dcom_interface_t
*dcom_interface_find(packet_info
*pinfo _U_
, const guint8
*ip _U_
, e_uuid_t
*ipid
)
296 dcom_interface_t
*interf
;
300 if(memcmp(ipid
, &uuid_null
, sizeof(uuid_null
)) == 0)
305 for(interfaces
= dcom_interfaces
; interfaces
!= NULL
; interfaces
= g_list_next(interfaces
)) {
306 interf
= (dcom_interface_t
*)interfaces
->data
;
308 if(memcmp(&interf
->ipid
, ipid
, sizeof(e_uuid_t
)) == 0) {
317 dcom_interface_t
*dcom_interface_new(packet_info
*pinfo
, const guint8
*ip
, e_uuid_t
*iid
, guint64 oxid
, guint64 oid
, e_uuid_t
*ipid
)
320 dcom_machine_t
*machine
;
321 dcom_object_t
*object
;
322 dcom_interface_t
*interf
;
325 if( memcmp(iid
, &uuid_null
, sizeof(uuid_null
)) == 0 ||
326 memcmp(ipid
, &uuid_null
, sizeof(uuid_null
)) == 0)
331 if(oxid
== 0 || oid
== 0) {
332 /*g_warning("interface_new#%u", pinfo->fd->num);*/
334 interf
= wmem_new(wmem_file_scope(), dcom_interface_t
);
335 interf
->parent
= NULL
;
336 interf
->private_data
= NULL
;
337 interf
->first_packet
= pinfo
->fd
->num
;
339 interf
->ipid
= *ipid
;
341 dcom_interfaces
= g_list_append(dcom_interfaces
, interf
);
346 dcom_iter
= dcom_machines
;
347 while(dcom_iter
!= NULL
) {
348 machine
= (dcom_machine_t
*)dcom_iter
->data
;
349 if(memcmp(machine
->ip
, ip
, 4) == 0) {
352 dcom_iter
= g_list_next(dcom_iter
);
355 /* create new machine if not found */
356 if(dcom_iter
== NULL
) {
357 machine
= g_new(dcom_machine_t
,1);
358 memcpy(machine
->ip
, ip
, 4);
359 machine
->objects
= NULL
;
360 machine
->first_packet
= pinfo
->fd
->num
;
361 dcom_machines
= g_list_append(dcom_machines
, machine
);
365 dcom_iter
= machine
->objects
;
366 while(dcom_iter
!= NULL
) {
367 object
= (dcom_object_t
*)dcom_iter
->data
;
368 if(object
->oid
== oid
) {
371 dcom_iter
= g_list_next(dcom_iter
);
374 /* create new object if not found */
375 if(dcom_iter
== NULL
) {
376 object
= g_new(dcom_object_t
,1);
377 object
->parent
= machine
;
378 object
->interfaces
= NULL
;
379 object
->private_data
= NULL
;
380 object
->first_packet
= pinfo
->fd
->num
;
384 machine
->objects
= g_list_append(machine
->objects
, object
);
388 dcom_iter
= object
->interfaces
;
389 while(dcom_iter
!= NULL
) {
390 interf
= (dcom_interface_t
*)dcom_iter
->data
;
391 if(memcmp(&interf
->ipid
, ipid
, sizeof(e_uuid_t
)) == 0) {
394 dcom_iter
= g_list_next(dcom_iter
);
397 /* create new interface if not found */
398 if(dcom_iter
== NULL
) {
399 interf
= g_new(dcom_interface_t
,1);
400 interf
->parent
= object
;
401 interf
->private_data
= NULL
;
402 interf
->first_packet
= pinfo
->fd
->num
;
404 interf
->ipid
= *ipid
;
406 object
->interfaces
= g_list_append(object
->interfaces
, interf
);
407 dcom_interfaces
= g_list_append(dcom_interfaces
, interf
);
415 * Flag bits in connection-oriented PDU header.
417 #define WIRESHARK_FADF_AUTO 0x0001
418 #define WIRESHARK_FADF_STATIC 0x0002
419 #define WIRESHARK_FADF_EMBEDDED 0x0004
420 #define WIRESHARK_FADF_FIXEDSIZE 0x0010
421 #define WIRESHARK_FADF_RECORD 0x0020
422 #define WIRESHARK_FADF_HAVEIID 0x0040
423 #define WIRESHARK_FADF_HAVEVARTYPE 0x0080
424 #define WIRESHARK_FADF_BSTR 0x0100
425 #define WIRESHARK_FADF_UNKNOWN 0x0200
426 #define WIRESHARK_FADF_DISPATCH 0x0400
427 #define WIRESHARK_FADF_VARIANT 0x0800
431 WIRESHARK_VT_EMPTY
= 0,
432 WIRESHARK_VT_NULL
= 1,
438 WIRESHARK_VT_DATE
= 7,
439 WIRESHARK_VT_BSTR
= 8,
440 WIRESHARK_VT_DISPATCH
= 9,
441 WIRESHARK_VT_ERROR
= 10,
442 WIRESHARK_VT_BOOL
= 11,
443 WIRESHARK_VT_VARIANT
= 12,
444 WIRESHARK_VT_UNKNOWN
= 13,
445 WIRESHARK_VT_DECIMAL
= 14,
446 WIRESHARK_VT_I1
= 16,
447 WIRESHARK_VT_UI1
= 17,
448 WIRESHARK_VT_UI2
= 18,
449 WIRESHARK_VT_UI4
= 19,
450 WIRESHARK_VT_I8
= 20,
451 WIRESHARK_VT_UI8
= 21,
452 WIRESHARK_VT_INT
= 22,
453 WIRESHARK_VT_UINT
= 23,
454 WIRESHARK_VT_VOID
= 24,
455 WIRESHARK_VT_HRESULT
= 25,
456 WIRESHARK_VT_PTR
= 26,
457 WIRESHARK_VT_SAFEARRAY
= 27,
458 WIRESHARK_VT_CARRAY
= 28,
459 WIRESHARK_VT_USERDEFINED
= 29,
460 WIRESHARK_VT_LPSTR
= 30,
461 WIRESHARK_VT_LPWSTR
= 31,
462 WIRESHARK_VT_RECORD
= 36,
463 WIRESHARK_VT_FILETIME
= 64,
464 WIRESHARK_VT_BLOB
= 65,
465 WIRESHARK_VT_STREAM
= 66,
466 WIRESHARK_VT_STORAGE
= 67,
467 WIRESHARK_VT_STREAMED_OBJECT
= 68,
468 WIRESHARK_VT_STORED_OBJECT
= 69,
469 WIRESHARK_VT_BLOB_OBJECT
= 70,
470 WIRESHARK_VT_CF
= 71,
471 WIRESHARK_VT_CLSID
= 72,
473 WIRESHARK_VT_BSTR_BLOB
= 0x0fff,
475 WIRESHARK_VT_VECTOR
= 0x1000,
476 WIRESHARK_VT_ARRAY
= 0x2000,
477 WIRESHARK_VT_BYREF
= 0x4000,
478 WIRESHARK_VT_RESERVED
= 0x8000,
480 WIRESHARK_VT_ILLEGAL
= 0xffff,
481 WIRESHARK_VT_ILLEGALMASKED
= 0x0fff,
482 WIRESHARK_VT_TYPEMASK
= 0x0fff
485 const value_string dcom_variant_type_vals
[] = {
486 { WIRESHARK_VT_EMPTY
, "VT_EMPTY"},
487 { WIRESHARK_VT_NULL
, "VT_NULL"},
488 { WIRESHARK_VT_I2
, "VT_I2"},
489 { WIRESHARK_VT_I4
, "VT_I4"},
490 { WIRESHARK_VT_R4
, "VT_R4"},
491 { WIRESHARK_VT_R8
, "VT_R8"},
492 { WIRESHARK_VT_CY
, "VT_CY"},
493 { WIRESHARK_VT_DATE
, "VT_DATE"},
494 { WIRESHARK_VT_BSTR
, "VT_BSTR"},
495 { WIRESHARK_VT_DISPATCH
, "VT_DISPATCH"},
496 { WIRESHARK_VT_ERROR
, "VT_ERROR"},
497 { WIRESHARK_VT_BOOL
, "VT_BOOL"},
498 { WIRESHARK_VT_I1
, "VT_I1"},
499 { WIRESHARK_VT_UI1
, "VT_UI1"},
500 { WIRESHARK_VT_UI2
, "VT_UI2"},
501 { WIRESHARK_VT_UI4
, "VT_UI4"},
502 { WIRESHARK_VT_I8
, "VT_I8"},
503 { WIRESHARK_VT_UI8
, "VT_UI8"},
504 { WIRESHARK_VT_ARRAY
, "VT_ARRAY"},
505 { WIRESHARK_VT_UNKNOWN
, "VT_UNKNOWN"},
506 { WIRESHARK_VT_USERDEFINED
, "VT_USERDEFINED"},
508 /* XXX: this could be done better */
509 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_I2
, "VT_ARRAY|VT_I2"},
510 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_I4
, "VT_ARRAY|VT_I4"},
511 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_R4
, "VT_ARRAY|VT_R4"},
512 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_R8
, "VT_ARRAY|VT_R8"},
513 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_DATE
, "VT_ARRAY|VT_DATE"},
514 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_BSTR
, "VT_ARRAY|VT_BSTR"},
515 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_ERROR
, "VT_ARRAY|VT_ERROR"},
516 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_BOOL
, "VT_ARRAY|VT_BOOL"},
517 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_I1
, "VT_ARRAY|VT_I1"},
518 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_UI1
, "VT_ARRAY|VT_UI1"},
519 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_UI2
, "VT_ARRAY|VT_UI2"},
520 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_UI4
, "VT_ARRAY|VT_UI4"},
521 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_I8
, "VT_ARRAY|VT_I8"},
522 { WIRESHARK_VT_ARRAY
| WIRESHARK_VT_UI8
, "VT_ARRAY|VT_UI8"},
524 { WIRESHARK_VT_BYREF
| WIRESHARK_VT_I2
, "VT_BYREF|VT_I2"},
525 { WIRESHARK_VT_BYREF
| WIRESHARK_VT_BSTR
, "VT_BYREF|VT_BSTR"},
526 { WIRESHARK_VT_BYREF
| WIRESHARK_VT_VARIANT
, "VT_BYREF|VT_VARIANT"},
528 /* XXX: append more types here */
533 /* we need an extension mechanism here (be able to append entries by user protocol) */
534 const value_string dcom_hresult_vals
[] = {
535 { 0x00000000, "S_OK" },
536 { 0x00000001, "S_FALSE" },
537 { 0x8000FFFF, "E_UNEXPECTED" },
538 { 0x80004001, "E_NOTIMPL" },
539 { 0x80004002, "E_NOINTERFACE" },
540 { 0x80004003, "E_POINTER" },
541 { 0x80004004, "E_ABORT" },
542 { 0x80004005, "E_FAIL" },
543 { 0x80070005, "E_ACCESSDENIED" },
544 { 0x80070006, "E_HANDLE" },
545 { 0x8007000E, "E_OUTOFMEMORY" },
546 { 0x80070057, "E_INVALIDARG" },
548 { 0x80010108, "RPC_E_DISCONNECTED" },
549 { 0x80010113, "RPC_E_INVALID_IPID" },
550 { 0x8001011F, "RPC_E_TIMEOUT" },
552 { 0x80020003, "DISP_E_MEMBERNOTFOUND" },
553 { 0x80020004, "DISP_E_PARAMNOTFOUND" },
554 { 0x80020005, "DISP_E_TYPEMISMATCH" },
555 { 0x80020006, "DISP_E_UNKNOWNNAME" },
556 { 0x80020008, "DISP_E_BADVARTYPE" },
557 { 0x80020009, "DISP_E_EXCEPTION" },
558 { 0x8002000A, "DISP_E_OVERFLOW" },
560 { 0x8002801D, "TYPE_E_LIBNOTREGISTERED" },
562 { 0x80040154, "REGDB_E_CLASSNOTREG" },
563 { 0x80040201, "CO_E_FAILEDTOGETSECCTX" },
565 /* following are CBA application specific values */
566 { 0x0004CA00, "CBA_S_PERSISTPENDING" },
567 { 0x0004CA01, "CBA_S_ESTABLISHING" },
568 { 0x0004CA02, "CBA_S_NOCONNECTION" },
569 { 0x0004CA03, "CBA_S_VALUEBUFFERED" },
570 { 0x0004CA04, "CBA_S_VALUEUNCERTAIN" },
571 { 0x0004CA05, "CBA_S_NOCONNECTIONDATA" },
572 { 0x0004CA06, "CBA_S_FRAMEEMPTY" },
574 { 0x8004CB00, "CBA_E_MALFORMED" },
575 { 0x8004CB01, "CBA_E_UNKNOWNOBJECT" },
576 { 0x8004CB02, "CBA_E_UNKNOWNMEMBER" },
577 { 0x8004CB03, "CBA_E_TYPEMISMATCH" },
578 { 0x8004CB04, "CBA_E_INVALIDENUMVALUE" },
579 { 0x8004CB05, "CBA_E_INVALIDID" },
580 { 0x8004CB06, "CBA_E_INVALIDEPSILON" },
581 { 0x8004CB07, "CBA_E_INVALIDSUBSTITUTE" },
582 { 0x8004CB08, "CBA_E_INVALIDCONNECTION" },
583 { 0x8004CB09, "CBA_E_INVALIDCOOKIE" },
584 { 0x8004CB0A, "CBA_E_TIMEVALUEUNSUPPORTED" },
585 { 0x8004CB0B, "CBA_E_QOSTYPEUNSUPPORTED" },
586 { 0x8004CB0C, "CBA_E_QOSVALUEUNSUPPORTED" },
587 { 0x8004CB0D, "CBA_E_PERSISTRUNNING" },
588 { 0x8004CB0E, "CBA_E_INUSE" },
589 { 0x8004CB0F, "CBA_E_NOTAPPLICABLE" },
590 { 0x8004CB10, "CBA_E_NONACCESSIBLE" },
591 { 0x8004CB11, "CBA_E_DEFECT" },
592 { 0x8004CB12, "CBA_E_LIMITVIOLATION" },
593 { 0x8004CB13, "CBA_E_QOSTYPENOTAPPLICABLE" },
594 { 0x8004CB14, "CBA_E_QCNOTAPPLICABLE" },
595 { 0x8004CB15, "CBA_E_ACCESSBLOCKED" },
596 { 0x8004CB16, "CBA_E_COUNTEXCEEDED" },
597 { 0x8004CB17, "CBA_E_SIZEEXCEEDED" },
598 { 0x8004CB18, "CBA_E_OUTOFPARTNERACCOS" },
599 { 0x8004CB19, "CBA_E_OUTOFACCOPAIRS" },
600 { 0x8004CB1A, "CBA_E_ITEMTOOLARGE" },
601 { 0x8004CB1B, "CBA_E_CRDATALENGTH" },
602 { 0x8004CB1C, "CBA_E_FLAGUNSUPPORTED" },
603 { 0x8004CB1D, "CBA_E_CAPACITYEXCEEDED" },
604 { 0x8004CB1E, "CBA_E_SUBELEMENTMISMATCH" },
605 { 0x8004CB1F, "CBA_E_STATIONFAILURE" },
606 { 0x8004CB20, "CBA_E_NOTROUTABLE" },
607 { 0x8004CB21, "CBA_E_DISCONNECTRUNNING" },
608 { 0x8004CB22, "CBA_E_LOCATIONCHANGED" },
609 { 0x8004CB23, "CBA_E_FRAMECOUNTUNSUPPORTED" },
610 { 0x8004CB24, "CBA_E_LINKFAILURE" },
611 { 0x8004CB25, "CBA_E_MODECHANGE" },
613 { 0x80080004, "CO_E_BAD_PATH" },
618 static const value_string dcom_objref_flag_vals
[] = {
619 { 0x1, "OBJREF_STANDARD" },
620 { 0x2, "OBJREF_HANDLER" },
621 { 0x4, "OBJREF_CUSTOM" },
625 static const value_string dcom_objref_signature_vals
[] = {
626 { 0x574f454d, "MEOW" },
630 /* although flags, they doesn't seem to be used as such */
631 static const value_string dcom_stdobjref_flag_vals
[] = {
632 { 0x0000, "SORF_NULL" },
633 { 0x0001, "SORF_OXRES1" },
634 { 0x0020, "SORF_OXRES2" },
635 { 0x0040, "SORF_OXRES3" },
636 { 0x0080, "SORF_OXRES4" },
637 { 0x0100, "SORF_OXRES5" },
638 { 0x0200, "SORF_OXRES6" },
639 { 0x0400, "SORF_OXRES7" },
640 { 0x0800, "SORF_OXRES8" },
641 { 0x1000, "SORF_NOPING" },
645 static const value_string dcom_dcerpc_pointer_vals
[] = {
646 { 0x72657355, "User" },
647 { 0x42535452, "BSTR" },
648 { 0x00000000, "NULL" },
652 static const value_string dcom_dualstringarray_authz
[] = {
653 { 0x0000, "RPC_C_AUTHZ_NONE" },
654 { 0x0001, "RPC_C_AUTHZ_NAME"},
655 { 0x0002, "RPC_C_AUTHZ_DCE"},
656 { 0xffff, "Default"},
660 static const value_string dcom_dualstringarray_authn
[] = {
661 { 00, "RPC_C_AUTHN_NONE" },
662 { 1, "RPC_C_AUTHN_DCE_PRIVATE"},
663 { 2, "RPC_C_AUTHN_DCE_PUBLIC"},
664 { 4, "RPC_C_AUTHN_DEC_PUBLIC"},
665 { 9, "RPC_C_AUTHN_GSS_NEGOTIATE"},
666 { 10, "RPC_C_AUTH_WINNT"},
667 { 14, "RPC_C_AUTHN_GSS_SCHANNEL"},
668 { 16, "RPC_C_AUTHN_GSS_KERBEROS"},
669 { 17, "RPC_C_AUTHN_MSN"},
670 { 18, "RPC_C_AUTHN_DPA"},
671 { 100, "RPC_C_AUTHN_MQ"},
672 { 0xffff, "RPC_C_AUTHN_DEFAULT"},
676 const value_string dcom_protseq_vals
[] = {
677 { 0x04, "NCACN_DNET_NSP" },
678 { 0x07, "NCACN_IP_TCP" },
679 { 0x08, "NCADG_IP_UDP" },
680 { 0x09, "NCACN_IP" },
681 { 0x0C, "NCACN_SPX" },
682 { 0x0D, "NCACN_NB_IPX" },
683 { 0x0E, "NCADG_IPX" },
684 { 0x12, "NCACN_NB_NB" },
685 { 0x1F, "NCACN_HTTP" },
689 static const value_string dcom_vt_bool_vals
[] = {
697 /* dissect extension to DCOM "this" and "that" */
699 dissect_dcom_extent(tvbuff_t
*tvb
, int offset
,
700 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
)
702 guint32 u32ArraySize
;
703 guint32 u32ArraySize2
;
705 guint32 u32VariableOffset
;
708 proto_item
*sub_item
;
709 proto_tree
*sub_tree
;
711 guint32 u32ArrayCount
;
714 guint32 u32ExtentSize
;
716 const char *uuid_name
;
719 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
, &u32Pointer
);
721 if (u32Pointer
== 0) {
725 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
726 hf_dcom_extent_array_count
, &u32ArrayCount
);
727 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
728 hf_dcom_extent_array_res
, &u32ArrayRes
);
730 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
, &u32Pointer
);
732 if (u32Pointer
== 0) {
736 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, tree
, di
, drep
,
739 u32VariableOffset
= offset
+ u32ArraySize
*4;
742 while (u32ArraySize
--) {
743 sub_item
= proto_tree_add_item(tree
, hf_dcom_extent
, tvb
, offset
, 0, ENC_NA
);
744 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_extent
);
745 u32SubStart
= offset
;
747 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
749 if(u32Pointer
!= 0) {
750 u32VariableOffset
= dissect_dcom_DWORD(tvb
, u32VariableOffset
, pinfo
, sub_tree
, di
, drep
,
751 hf_dcom_extent_size
, &u32ExtentSize
);
753 dissect_dcom_UUID(tvb
, u32VariableOffset
, pinfo
, NULL
, di
, drep
,
754 hf_dcom_extent_id
, &uuidExtend
);
756 /* look for a registered uuid name */
757 if((uuid_name
= guids_get_uuid_name(&uuidExtend
)) != NULL
) {
758 proto_tree_add_guid_format_value(sub_tree
, hf_dcom_extent_id
, tvb
,
759 offset
, sizeof(e_uuid_t
), (e_guid_t
*) &uuidExtend
,
760 "%s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
762 uuidExtend
.Data1
, uuidExtend
.Data2
, uuidExtend
.Data3
,
763 uuidExtend
.Data4
[0], uuidExtend
.Data4
[1],
764 uuidExtend
.Data4
[2], uuidExtend
.Data4
[3],
765 uuidExtend
.Data4
[4], uuidExtend
.Data4
[5],
766 uuidExtend
.Data4
[6], uuidExtend
.Data4
[7]);
767 u32VariableOffset
+= 16;
769 u32VariableOffset
= dissect_dcom_UUID(tvb
, u32VariableOffset
, pinfo
, sub_tree
, di
, drep
,
770 hf_dcom_extent_id
, &uuidExtend
);
774 u32VariableOffset
= dissect_dcom_dcerpc_array_size(tvb
, u32VariableOffset
, pinfo
, sub_tree
, di
, drep
,
776 u32VariableOffset
= dissect_dcom_nospec_data(tvb
, u32VariableOffset
, pinfo
, sub_tree
, drep
, u32ArraySize2
);
778 /* update subtree header */
779 if(uuid_name
!= NULL
) {
780 proto_item_append_text(sub_item
, "[%u]: %s, Bytes=%u",
781 u32Idx
, uuid_name
, u32ArraySize2
);
783 proto_item_append_text(sub_item
, "[%u]: Bytes=%u",
784 u32Idx
, u32ArraySize2
);
786 proto_item_set_len(sub_item
, offset
- u32SubStart
);
788 /* update subtree header */
789 proto_item_append_text(sub_item
, "[%u]: NULL", u32Idx
);
790 proto_item_set_len(sub_item
, offset
- u32SubStart
);
796 return u32VariableOffset
;
800 /* dissect DCOM "this" (start of every DCOM request) */
802 dissect_dcom_this(tvbuff_t
*tvb
, int offset
,
803 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
)
805 guint16 u16VersionMajor
;
806 guint16 u16VersionMinor
;
809 e_uuid_t uuidCausality
;
810 proto_item
*sub_item
;
811 proto_tree
*sub_tree
;
815 sub_item
= proto_tree_add_protocol_format(tree
, proto_dcom
, tvb
, offset
, 0,
817 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_this
);
819 offset
= dissect_dcom_COMVERSION(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
820 &u16VersionMajor
, &u16VersionMinor
);
821 u32SubStart
= offset
- 4;
823 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
824 hf_dcom_this_flags
, &u32Flags
);
825 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
826 hf_dcom_this_res
, &u32Res
);
828 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
829 hf_dcom_this_cid
, &uuidCausality
);
831 offset
= dissect_dcom_extent(tvb
, offset
, pinfo
, sub_tree
, di
, drep
);
833 /* update subtree header */
834 proto_item_append_text(sub_item
, ", V%u.%u, Causality ID: %s",
835 u16VersionMajor
, u16VersionMinor
, guids_resolve_uuid_to_str(&uuidCausality
));
836 proto_item_set_len(sub_item
, offset
- u32SubStart
);
838 if(memcmp(&di
->call_data
->object_uuid
, &uuid_null
, sizeof(uuid_null
)) != 0) {
839 pi
= proto_tree_add_guid_format(tree
, hf_dcom_ipid
, tvb
, offset
, 0,
840 (e_guid_t
*) &di
->call_data
->object_uuid
,
841 "Object UUID/IPID: %s", guids_resolve_uuid_to_str(&di
->call_data
->object_uuid
));
842 PROTO_ITEM_SET_GENERATED(pi
);
849 /* dissect DCOM "that" (start of every DCOM response) */
851 dissect_dcom_that(tvbuff_t
*tvb
, int offset
,
852 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
) {
854 proto_item
*sub_item
;
855 proto_tree
*sub_tree
;
859 sub_item
= proto_tree_add_protocol_format(tree
, proto_dcom
, tvb
, offset
, 0,
861 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_that
);
863 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
864 hf_dcom_that_flags
, &u32Flags
);
865 u32SubStart
= offset
- 4;
867 offset
= dissect_dcom_extent(tvb
, offset
, pinfo
, sub_tree
, di
, drep
);
869 /* update subtree header */
870 proto_item_set_len(sub_item
, offset
- u32SubStart
);
872 if(memcmp(&di
->call_data
->object_uuid
, &uuid_null
, sizeof(uuid_null
)) != 0) {
873 pi
= proto_tree_add_guid_format(tree
, hf_dcom_ipid
, tvb
, offset
, 0,
874 (e_guid_t
*) &di
->call_data
->object_uuid
,
875 "Object UUID/IPID: %s", guids_resolve_uuid_to_str(&di
->call_data
->object_uuid
));
876 PROTO_ITEM_SET_GENERATED(pi
);
883 /* dissect simple dcom request, DCOM "this" only */
885 dissect_dcom_simple_rqst(tvbuff_t
*tvb
, int offset
,
886 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
)
889 offset
= dissect_dcom_this(tvb
, offset
, pinfo
, tree
, di
, drep
);
895 /* dissect simple dcom response, DCOM "that" and returned HRESULT only */
897 dissect_dcom_simple_resp(tvbuff_t
*tvb
, int offset
,
898 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
)
903 offset
= dissect_dcom_that(tvb
, offset
, pinfo
, tree
, di
, drep
);
905 offset
= dissect_dcom_HRESULT(tvb
, offset
, pinfo
, tree
, di
, drep
,
908 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s",
909 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%08x)") );
916 /* dissect a dcerpc array size */
918 dissect_dcom_dcerpc_array_size(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
919 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, guint32
*pu32ArraySize
)
923 /* en-/disable this by preference setting */
924 if (!dcom_prefs_display_unmarshalling_details
) {
925 /* this will read in the data, but prevent output to tree */
929 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
930 hf_dcom_array_size
, pu32ArraySize
);
936 /* dissect a dcerpc pointer value */
938 dissect_dcom_dcerpc_pointer(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
939 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, guint32
*pu32Pointer
)
942 /* en-/disable this by preference setting */
943 if (!dcom_prefs_display_unmarshalling_details
) {
944 /* this will read in the data, but prevent output to tree */
948 offset
= dissect_ndr_uint32(tvb
, offset
, pinfo
, tree
, di
, drep
,
949 hf_dcom_pointer_val
, pu32Pointer
);
955 /* mark data as "ToBeDone" */
956 /* XXX: handout data to generic "unknown data" dissector? */
958 dissect_dcom_tobedone_data(tvbuff_t
*tvb
, int offset
,
959 packet_info
*pinfo _U_
, proto_tree
*tree
, guint8
*drep _U_
, int length
)
964 item
= proto_tree_add_item(tree
, hf_dcom_tobedone
, tvb
, offset
, length
, ENC_NA
);
965 PROTO_ITEM_SET_GENERATED(item
);
966 expert_add_info(pinfo
, item
, &ei_dcom_dissetion_incomplete
);
974 /* mark data as "No Specification Available" */
975 /* XXX: handout data to generic "unknown data" dissector? */
977 dissect_dcom_nospec_data(tvbuff_t
*tvb
, int offset
,
978 packet_info
*pinfo _U_
, proto_tree
*tree
, guint8
*drep _U_
, int length
)
983 item
= proto_tree_add_item(tree
, hf_dcom_nospec
, tvb
, offset
, length
, ENC_NA
);
984 PROTO_ITEM_SET_GENERATED(item
);
985 expert_add_info(pinfo
, item
, &ei_dcom_no_spec
);
993 /* dissect an indexed WORD, something like: "FieldName[1]: 0x1234" */
995 dissect_dcom_indexed_WORD(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
996 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
997 int hfindex
, guint16
* pu16WORD
, int field_index
)
1002 /* dissect the WORD, but don't add to tree */
1003 dissect_dcom_WORD(tvb
, offset
, pinfo
, NULL
/*tree*/, di
, drep
,
1007 /* special formatted output of indexed value */
1008 proto_tree_add_uint_format(tree
, hfindex
, tvb
, offset
, 2, u16WORD
,
1010 proto_registrar_get_name(hfindex
),
1011 field_index
, u16WORD
);
1017 *pu16WORD
= u16WORD
;
1023 /* dissect an indexed DWORD, something like: "FieldName[1]: 0x12345678" */
1025 dissect_dcom_indexed_DWORD(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1026 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1027 int hfindex
, guint32
* pu32DWORD
, int field_index
)
1032 /* dissect the DWORD, but don't add to tree */
1033 dissect_dcom_DWORD(tvb
, offset
, pinfo
, NULL
/*tree*/, di
, drep
,
1034 hfindex
, &u32DWORD
);
1037 /* special formatted output of indexed value */
1038 proto_tree_add_uint_format(tree
, hfindex
, tvb
, offset
, 4, u32DWORD
,
1040 proto_registrar_get_name(hfindex
),
1041 field_index
, u32DWORD
);
1047 *pu32DWORD
= u32DWORD
;
1053 /* dissect hresult field of a usual DCOM call (create "raw" item) */
1055 dissect_dcom_HRESULT_item(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1056 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1057 guint32
* pu32HResult
, int field_index
, proto_item
**item
)
1061 /* dissect the DWORD, but don't add to tree */
1062 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, NULL
/*tree*/, di
, drep
,
1063 field_index
, &u32HResult
);
1066 /* special formatted output of indexed value */
1067 *item
= proto_tree_add_item (tree
, field_index
, tvb
, offset
-4, 4, DREP_ENC_INTEGER(drep
));
1071 *pu32HResult
= u32HResult
;
1077 /* dissect hresult field of a usual DCOM call (separate method, because often used) */
1079 dissect_dcom_HRESULT(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1080 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1081 guint32
* pu32HResult
)
1084 proto_item
*item
= NULL
;
1086 /* dissect the DWORD, but don't add to tree */
1087 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, NULL
/*tree*/, di
, drep
,
1088 hf_dcom_hresult
, &u32HResult
);
1091 /* special formatted output of indexed value */
1092 item
= proto_tree_add_item (tree
, hf_dcom_hresult
, tvb
, offset
-4, 4, DREP_ENC_INTEGER(drep
));
1095 /* expert info only if severity is set */
1096 /* XXX - move this to the callers of this function, to provide a more detailed error output */
1097 if(u32HResult
& 0x80000000) {
1098 expert_add_info_format(pinfo
, item
, &ei_dcom_hresult_expert
, "Hresult: %s",
1099 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%x)"));
1102 *pu32HResult
= u32HResult
;
1108 /* partial results of indexed DCOM subcalls (e.g.: from a kind of array) */
1110 dissect_dcom_indexed_HRESULT(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1111 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1112 guint32
* pu32HResult
, int field_index
)
1115 proto_item
*item
= NULL
;
1118 /* dissect the DWORD, but don't add to tree */
1119 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, NULL
/*tree*/, di
, drep
,
1120 hf_dcom_hresult
, &u32HResult
);
1123 /* special formatted output of indexed value */
1124 item
= proto_tree_add_uint_format(tree
, hf_dcom_hresult
, tvb
, offset
-4, 4, u32HResult
,
1125 "HResult[%u]: %s (0x%08x)", field_index
,
1126 val_to_str_const(u32HResult
, dcom_hresult_vals
, "Unknown"),
1129 /* expert info only if severity flag is set */
1130 /* XXX - move this to the callers of this function, to provide a more detailed error output */
1131 if(u32HResult
& 0x80000000) {
1132 expert_add_info_format(pinfo
, item
, &ei_dcom_hresult_expert
, "Hresult: %s",
1133 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%x)"));
1136 *pu32HResult
= u32HResult
;
1144 dissect_dcom_COMVERSION(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1145 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1146 guint16
* pu16VersionMajor
, guint16
* pu16VersionMinor
)
1149 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
1150 hf_dcom_version_major
, pu16VersionMajor
);
1151 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
1152 hf_dcom_version_minor
, pu16VersionMinor
);
1159 dissect_dcom_SAFEARRAY(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1160 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex _U_
, sa_callback_t sacb
)
1164 guint16 u16Features
;
1165 guint32 u32ElementSize
;
1167 guint32 u32Elements
;
1169 guint32 u32BoundElements
;
1170 guint32 u32LowBound
;
1172 guint32 u32ArraySize
;
1173 guint32 u32VariableOffset
;
1179 proto_item
*sub_item
;
1180 proto_tree
*sub_tree
;
1181 guint32 u32SubStart
;
1182 guint32 u32TmpOffset
;
1184 proto_item
*feature_item
;
1185 proto_tree
*feature_tree
;
1188 /* XXX: which alignment do we need here? */
1190 sub_item
= proto_tree_add_item(tree
, hf_dcom_safearray
, tvb
, offset
, 0, ENC_NA
);
1191 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_safearray
);
1192 u32SubStart
= offset
;
1194 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1195 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1197 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1198 hf_dcom_sa_dims32
, &u32Dims
);
1199 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1200 hf_dcom_sa_dims16
, &u16Dims
);
1203 u32TmpOffset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, NULL
, di
, drep
,
1204 hf_dcom_sa_features
, &u16Features
);
1205 feature_item
= proto_tree_add_uint (sub_tree
, hf_dcom_sa_features
, tvb
, offset
, 2, u16Features
);
1206 feature_tree
= proto_item_add_subtree (feature_item
, ett_dcom_sa_features
);
1208 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_variant
, tvb
, offset
, 2, u16Features
);
1209 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_dispatch
, tvb
, offset
, 2, u16Features
);
1210 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_unknown
, tvb
, offset
, 2, u16Features
);
1211 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_bstr
, tvb
, offset
, 2, u16Features
);
1212 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_have_vartype
, tvb
, offset
, 2, u16Features
);
1213 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_have_iid
, tvb
, offset
, 2, u16Features
);
1214 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_record
, tvb
, offset
, 2, u16Features
);
1215 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_fixedsize
, tvb
, offset
, 2, u16Features
);
1216 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_embedded
, tvb
, offset
, 2, u16Features
);
1217 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_static
, tvb
, offset
, 2, u16Features
);
1218 proto_tree_add_boolean (feature_tree
, hf_dcom_sa_features_auto
, tvb
, offset
, 2, u16Features
);
1220 offset
= u32TmpOffset
;
1222 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1223 hf_dcom_sa_element_size
, &u32ElementSize
);
1224 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1225 hf_dcom_sa_locks
, &u16Locks
);
1226 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1227 hf_dcom_sa_vartype16
, &u16VarType
);
1228 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1229 hf_dcom_sa_vartype32
, &u32VarType
);
1230 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1231 hf_dcom_sa_elements
, &u32Elements
);
1232 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1234 u32BoundElements
= 0;
1236 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1237 hf_dcom_sa_bound_elements
, &u32BoundElements
);
1238 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1239 hf_dcom_sa_low_bound
, &u32LowBound
);
1242 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32ArraySize
);
1244 tvb_ensure_bytes_exist(tvb
, offset
, u32ArraySize
* u32ElementSize
);
1245 u32VariableOffset
= offset
+ u32ArraySize
* u32ElementSize
;
1248 sacb(tvb
, offset
, pinfo
, tree
, di
, drep
, u32VarType
, u32ArraySize
);
1251 while(u32ArraySize
--) {
1252 switch(u32VarType
) {
1253 case(WIRESHARK_VT_ERROR
):
1254 offset
= dissect_dcom_HRESULT(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1257 case(WIRESHARK_VT_I1
):
1258 offset
= dissect_dcom_BYTE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1259 hf_dcom_vt_i1
, &u8Data
);
1261 case(WIRESHARK_VT_I2
):
1262 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1263 hf_dcom_vt_i2
, &u16Data
);
1265 case(WIRESHARK_VT_I4
):
1266 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1267 hf_dcom_vt_i4
, &u32Data
);
1269 case(WIRESHARK_VT_I8
):
1270 offset
= dissect_dcom_I8(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1271 hf_dcom_vt_i8
, NULL
);
1272 /* take care of the 8 byte alignment */
1273 u32VariableOffset
= offset
;
1275 case(WIRESHARK_VT_BSTR
):
1276 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1278 u32VariableOffset
= dissect_dcom_BSTR(tvb
, u32VariableOffset
, pinfo
, sub_tree
, di
, drep
,
1279 hf_dcom_vt_bstr
, cData
, sizeof(cData
) );
1283 /* XXX: other types possible, but still not implemented:
1288 VT_UNKNOWN|VT_RESERVED
1290 u32VariableOffset
= dissect_dcom_tobedone_data(tvb
, u32VariableOffset
, pinfo
, sub_tree
, drep
,
1295 /* update subtree header */
1296 proto_item_append_text(sub_item
, ": Elements: %u/%u VarType: %s",
1297 u32Elements
, u32BoundElements
,
1298 val_to_str(u32VarType
, dcom_variant_type_vals
, "Unknown (0x%08x)") );
1300 proto_item_set_len(sub_item
, u32VariableOffset
- u32SubStart
);
1302 return u32VariableOffset
;
1308 dissect_dcom_VARTYPE(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1309 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1310 guint16
*pu16VarType
)
1313 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
1314 hf_dcom_variant_type
, pu16VarType
);
1321 dissect_dcom_VARIANT(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1322 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
)
1327 guint32 u32SubStart
;
1328 proto_item
*sub_item
;
1329 proto_tree
*sub_tree
;
1342 /* alignment of 8 needed for a VARIANT */
1344 offset
+= 8 - (offset
% 8);
1347 sub_item
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 0, ENC_BIG_ENDIAN
);
1348 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_variant
);
1349 u32SubStart
= offset
;
1351 /* the following size can be VERY confusing:
1352 * It is NOT the maximum size of the variant, as one could expect,
1353 * but the current size of the variant padded to 8 bytes.
1354 * BUT: The following data does not start AFTER this padding,
1355 * it starts just after the variant-data (without padding)!!! */
1356 /* Conclusion: the size given here can be LONGER than the actual size */
1357 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1358 hf_dcom_variant_size
, &u32Size
);
1359 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1360 hf_dcom_variant_rpc_res
, &u32RPCRes
);
1361 offset
= dissect_dcom_VARTYPE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1363 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1364 hf_dcom_variant_wres
, &u16Res
);
1365 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1366 hf_dcom_variant_wres
, &u16Res
);
1367 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1368 hf_dcom_variant_wres
, &u16Res
);
1370 /* 32 bit VarType (slightly different to the 16 bit one) */
1371 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1372 hf_dcom_variant_type32
, &u32VarType
);
1374 if (u32VarType
& WIRESHARK_VT_BYREF
) {
1375 u32VarType
&=~WIRESHARK_VT_BYREF
;
1376 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1379 switch (u32VarType
) {
1380 case(WIRESHARK_VT_EMPTY
):
1382 case(WIRESHARK_VT_BOOL
):
1383 offset
= dissect_dcom_VARIANT_BOOL(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1384 hf_dcom_vt_bool
, &u16Data
);
1386 case(WIRESHARK_VT_I1
):
1387 offset
= dissect_dcom_BYTE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1388 hf_dcom_vt_i1
, &u8Data
);
1390 case(WIRESHARK_VT_UI1
):
1391 offset
= dissect_dcom_BYTE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1392 hf_dcom_vt_ui1
, &u8Data
);
1394 case(WIRESHARK_VT_I2
):
1395 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1396 hf_dcom_vt_i2
, &u16Data
);
1398 case(WIRESHARK_VT_UI2
):
1399 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1400 hf_dcom_vt_ui2
, &u16Data
);
1402 case(WIRESHARK_VT_I4
):
1403 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1404 hf_dcom_vt_i4
, &u32Data
);
1406 case(WIRESHARK_VT_UI4
):
1407 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1408 hf_dcom_vt_ui4
, &u32Data
);
1410 case(WIRESHARK_VT_R4
):
1411 offset
= dissect_dcom_FLOAT(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1412 hf_dcom_vt_r4
, &f32Data
);
1414 case(WIRESHARK_VT_R8
):
1415 offset
= dissect_dcom_DOUBLE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1416 hf_dcom_vt_r8
, &f64Data
);
1418 case(WIRESHARK_VT_DATE
):
1419 offset
= dissect_dcom_DATE(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1420 hf_dcom_vt_date
, &f64Data
);
1422 case(WIRESHARK_VT_BSTR
):
1423 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1425 offset
= dissect_dcom_BSTR(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1426 hf_dcom_vt_bstr
, cData
, sizeof(cData
) );
1429 case(WIRESHARK_VT_DISPATCH
):
1430 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1432 offset
= dissect_dcom_MInterfacePointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1433 hf_dcom_vt_dispatch
, NULL
); /* XXX - how to handle this? */
1436 case(WIRESHARK_VT_ARRAY
):
1437 offset
= dissect_dcom_SAFEARRAY(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1440 case(WIRESHARK_VT_ERROR
):
1441 offset
= dissect_dcom_HRESULT(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1444 case(WIRESHARK_VT_VARIANT
):
1445 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1447 offset
= dissect_dcom_VARIANT(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1448 hf_dcom_vt_byref
/* must be BYREF */);
1451 case(WIRESHARK_VT_UNKNOWN
):
1452 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32Pointer
);
1455 /* XXX: add more types here! */
1456 offset
= dissect_dcom_tobedone_data(tvb
, offset
, pinfo
, sub_tree
, drep
,
1460 /* update subtree header */
1461 proto_item_append_text(sub_item
, ": %s",
1462 val_to_str(u16VarType
, dcom_variant_type_vals
, "Unknown (0x%08x)") );
1464 proto_item_set_len(sub_item
, offset
- u32SubStart
);
1471 dissect_dcom_UUID(tvbuff_t
*tvb
, int offset
,
1472 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1473 int hfindex
, e_uuid_t
*pdata
)
1475 const gchar
*uuid_name
;
1476 header_field_info
*hfi
;
1480 /* get the UUID, but don't put it into the tree */
1481 offset
= dissect_ndr_uuid_t(tvb
, offset
, pinfo
, NULL
, di
, drep
,
1484 /* add to the tree */
1485 hfi
= proto_registrar_get_nth(hfindex
);
1486 uuid_name
= guids_get_uuid_name(&uuid
);
1488 proto_tree_add_guid_format(tree
, hfindex
, tvb
, offset
-16, 16, (e_guid_t
*) &uuid
,
1489 "%s: %s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
1490 hfi
->name
, uuid_name
,
1491 uuid
.Data1
, uuid
.Data2
, uuid
.Data3
,
1492 uuid
.Data4
[0], uuid
.Data4
[1],
1493 uuid
.Data4
[2], uuid
.Data4
[3],
1494 uuid
.Data4
[4], uuid
.Data4
[5],
1495 uuid
.Data4
[6], uuid
.Data4
[7]);
1497 proto_tree_add_guid_format(tree
, hfindex
, tvb
, offset
-16, 16, (e_guid_t
*) &uuid
,
1498 "%s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1500 uuid
.Data1
, uuid
.Data2
, uuid
.Data3
,
1501 uuid
.Data4
[0], uuid
.Data4
[1],
1502 uuid
.Data4
[2], uuid
.Data4
[3],
1503 uuid
.Data4
[4], uuid
.Data4
[5],
1504 uuid
.Data4
[6], uuid
.Data4
[7]);
1516 dissect_dcom_append_UUID(tvbuff_t
*tvb
, int offset
,
1517 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
,
1518 int hfindex
, int field_index
, e_uuid_t
*uuid
)
1520 const gchar
*uuid_name
;
1522 header_field_info
*hfi
;
1525 /* XXX - this is far from being performance optimized! */
1527 /* get the UUID, but don't put it into the tree */
1528 offset
= dissect_ndr_uuid_t(tvb
, offset
, pinfo
, NULL
, di
, drep
,
1531 /* look for a registered uuid name */
1532 uuid_name
= guids_get_uuid_name(uuid
);
1534 /* add to the tree */
1535 hfi
= proto_registrar_get_nth(hfindex
);
1536 pi
= proto_tree_add_guid_format(tree
, hfindex
, tvb
, offset
-16, 16, (e_guid_t
*) uuid
, "%s", hfi
->name
);
1538 if (field_index
!= -1) {
1539 proto_item_append_text(pi
, "[%u]: ", field_index
);
1541 proto_item_append_text(pi
, ": ");
1545 proto_item_append_text(pi
, "%s (", uuid_name
);
1548 proto_item_append_text(pi
, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1549 uuid
->Data1
, uuid
->Data2
, uuid
->Data3
,
1550 uuid
->Data4
[0], uuid
->Data4
[1],
1551 uuid
->Data4
[2], uuid
->Data4
[3],
1552 uuid
->Data4
[4], uuid
->Data4
[5],
1553 uuid
->Data4
[6], uuid
->Data4
[7]);
1556 proto_item_append_text(pi
, ")");
1559 /* update column info now */
1560 if (field_index
!= -1) {
1561 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s[%u]=%s",
1562 hfi
->name
, field_index
, (uuid_name
) ? uuid_name
: "???");
1564 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s=%s",
1565 hfi
->name
, (uuid_name
) ? uuid_name
: "???");
1572 /* get a wide character string from tvb (zero terminated or limited through inLength) */
1573 /* the string will be converted to ASCII if possible or simple hexdump otherwise */
1574 /* outLength is in output bytes including zero termination output */
1576 dcom_tvb_get_nwstringz0(tvbuff_t
*tvb
, gint offset
, guint32 inLength
, gchar
*pszStr
, guint32 outLength
, gboolean
*isPrintable
)
1586 *isPrintable
= TRUE
;
1588 /* we must have at least the space for the zero termination */
1589 DISSECTOR_ASSERT(outLength
>= 1);
1591 /* determine length and printablility of the string */
1592 for(u32Idx
= 0; u32Idx
< inLength
-1; u32Idx
+=2) {
1593 /* the marshalling direction of a WCHAR is fixed! */
1594 u8Tmp1
= tvb_get_guint8(tvb
, offset
+u32Idx
);
1595 u8Tmp2
= tvb_get_guint8(tvb
, offset
+u32Idx
+1);
1597 /* is this the zero termination? */
1598 if (u8Tmp1
== 0 && u8Tmp2
== 0) {
1603 /* is this character printable? */
1604 /* XXX - there are probably more printable chars than isprint() */
1605 if(!isprint(u8Tmp1
) || u8Tmp2
!= 0) {
1606 *isPrintable
= FALSE
;
1610 /* u32Idx now contains the string length in bytes */
1611 /* (including optional zero termination) */
1613 /* if this is a printable string? */
1614 if(*isPrintable
== TRUE
) {
1615 /* convert to ascii (every "2nd char") */
1616 /* XXX - is it possible to convert to UTF8, so the output functions work with it? */
1617 for(u32IdxA
= 0, u32IdxW
= 0;
1618 u32IdxW
< u32Idx
&& u32IdxA
< outLength
-2;
1619 u32IdxW
+=2, u32IdxA
++) {
1620 pszStr
[u32IdxA
] = tvb_get_guint8(tvb
, offset
+u32IdxW
);
1623 /* convert to hexdump */
1624 for(u32IdxA
= 0, u32IdxW
= 0;
1625 u32IdxW
< u32Idx
&& u32IdxA
< outLength
-2;
1626 u32IdxW
++, u32IdxA
+=2) {
1627 g_snprintf(&pszStr
[u32IdxA
], 3, "%02X", tvb_get_guint8(tvb
, offset
+u32IdxW
));
1631 /* zero terminate the string, space must be available */
1632 DISSECTOR_ASSERT(u32IdxA
< outLength
);
1633 pszStr
[u32IdxA
] = 0;
1635 return offset
+ u32Idx
;
1639 /* dissect a LPWSTR into a given buffer */
1640 /* use FT_STRING for hfindex */
1641 /* u32MaxStr is maximum length of string (including trailing zero) */
1643 dissect_dcom_indexed_LPWSTR(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1644 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
,
1645 gchar
*pszStr
, guint32 u32MaxStr
, int field_index
)
1647 guint32 u32MaxCount
;
1649 guint32 u32ArraySize
;
1650 guint32 u32StrStart
;
1651 proto_item
*sub_item
;
1652 proto_tree
*sub_tree
;
1653 guint32 u32SubStart
;
1654 gboolean isPrintable
;
1657 /* alignment of 4 needed */
1659 offset
+= 4 - (offset
% 4);
1662 /* add subtree item */
1663 sub_item
= proto_tree_add_string(tree
, hfindex
, tvb
, offset
, 0, "");
1664 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_lpwstr
);
1665 u32SubStart
= offset
;
1667 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1668 hf_dcom_max_count
, &u32MaxCount
);
1669 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1670 hf_dcom_offset
, &u32Offset
);
1671 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1674 u32StrStart
= offset
;
1675 offset
= dcom_tvb_get_nwstringz0(tvb
, offset
, u32ArraySize
*2, pszStr
, u32MaxStr
, &isPrintable
);
1677 proto_tree_add_string(sub_tree
, hfindex
, tvb
, u32StrStart
, offset
- u32StrStart
, pszStr
);
1679 /* update subtree header */
1680 if (field_index
!= -1) {
1681 proto_item_set_text(sub_item
, "%s[%u]: %s%s%s",
1682 proto_registrar_get_name(hfindex
),
1684 isPrintable
? "\"" : "", pszStr
, isPrintable
? "\"" : "");
1686 proto_item_append_text(sub_item
, "%s%s%s",
1687 isPrintable
? "\"" : "", pszStr
, isPrintable
? "\"" : "");
1689 proto_item_set_len(sub_item
, offset
- u32SubStart
);
1696 dissect_dcom_LPWSTR(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1697 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
,
1698 gchar
*pszStr
, guint32 u32MaxStr
)
1702 return dissect_dcom_indexed_LPWSTR(tvb
, offset
, pinfo
, tree
, di
, drep
,
1703 hfindex
, pszStr
, u32MaxStr
, -1);
1707 /* dissect a BSTR to tree and into a given buffer (use FT_STRING for hfindex) */
1708 /* u32MaxStr is maximum length of string (including trailing zero) */
1709 /* (Hint: the BSTR space is always as long as the maximum size) */
1711 dissect_dcom_BSTR(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1712 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
,
1713 gchar
*pszStr
, guint32 u32MaxStr
)
1715 guint32 u32MaxCount
;
1716 guint32 u32ArraySize
;
1717 guint32 u32StrStart
;
1718 proto_item
*sub_item
;
1719 proto_tree
*sub_tree
;
1720 guint32 u32SubStart
;
1721 guint32 u32ByteLength
;
1722 guint32 u32RealOffset
;
1723 gboolean isPrintable
;
1725 /* alignment of 4 needed */
1727 offset
+= 4 - (offset
% 4);
1730 /* add subtree item */
1731 sub_item
= proto_tree_add_string(tree
, hfindex
, tvb
, offset
, 0, "");
1732 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_lpwstr
);
1733 u32SubStart
= offset
;
1735 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1736 hf_dcom_max_count
, &u32MaxCount
);
1737 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1738 hf_dcom_byte_length
, &u32ByteLength
);
1739 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1742 u32RealOffset
= offset
+ u32ArraySize
*2;
1744 u32StrStart
= offset
;
1745 offset
= dcom_tvb_get_nwstringz0(tvb
, offset
, u32ArraySize
*2, pszStr
, u32MaxStr
, &isPrintable
);
1747 proto_tree_add_string(sub_tree
, hfindex
, tvb
, u32StrStart
, offset
- u32StrStart
, pszStr
);
1749 /* update subtree header */
1750 proto_item_append_text(sub_item
, "%s%s%s",
1751 isPrintable
? "\"" : "", pszStr
, isPrintable
? "\"" : "");
1752 if ((int) (u32RealOffset
- u32SubStart
) <= 0)
1753 THROW(ReportedBoundsError
);
1754 proto_item_set_len(sub_item
, u32RealOffset
- u32SubStart
);
1756 return u32RealOffset
;
1760 /* dissect an DUALSTRINGARRAY */
1762 dissect_dcom_DUALSTRINGARRAY(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1763 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
, gchar
*ip
)
1765 guint16 u16NumEntries
;
1766 guint16 u16SecurityOffset
;
1768 guint32 u32MaxStr
= sizeof(szStr
);
1771 guint16 u16SecurityAuthnSvc
;
1772 guint16 u16SecurityAuthzSvc
;
1773 proto_item
*sub_item
;
1774 proto_tree
*sub_tree
;
1775 guint32 u32SubStart
;
1776 guint32 u32StringBindings
= 0;
1777 guint32 u32SecurityBindings
= 0;
1778 proto_item
*subsub_item
;
1779 proto_tree
*subsub_tree
;
1780 guint32 u32SubSubStart
;
1781 gboolean isPrintable
;
1782 guint32 first_ip
= 0;
1783 guint32 curr_ip
= 0;
1784 struct in_addr ipaddr
;
1788 /* add subtree header */
1789 sub_item
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 0, ENC_BIG_ENDIAN
);
1790 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_dualstringarray
);
1792 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1793 hf_dcom_dualstringarray_num_entries
, &u16NumEntries
);
1794 /* from here, alignment is ok */
1795 u32SubStart
= offset
- 2;
1796 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1797 hf_dcom_dualstringarray_security_offset
, &u16SecurityOffset
);
1799 /* STRINGBINDINGs until first wchar zero */
1800 while ( tvb_get_ntohs(tvb
, offset
) ) {
1801 u32StringBindings
++;
1803 subsub_item
= proto_tree_add_item(sub_tree
, hf_dcom_dualstringarray_string
, tvb
, offset
, 0, ENC_NA
);
1804 subsub_tree
= proto_item_add_subtree(subsub_item
, ett_dcom_dualstringarray_binding
);
1805 u32SubSubStart
= offset
;
1807 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, subsub_tree
, di
, drep
,
1808 hf_dcom_dualstringarray_string_tower_id
, &u16TowerId
);
1810 /* we don't know the (zero terminated) input length, use the buffer length instead */
1811 offset
= dcom_tvb_get_nwstringz0(tvb
, offset
, u32MaxStr
, szStr
, u32MaxStr
, &isPrintable
);
1812 pi
= proto_tree_add_string(subsub_tree
, hf_dcom_dualstringarray_string_network_addr
,
1813 tvb
, u32Start
, offset
- u32Start
, szStr
);
1815 /* convert ip address (if it is dotted decimal) */
1816 /* XXX - this conversion is ugly */
1817 if (inet_aton(szStr
, &ipaddr
)) {
1818 if(get_host_ipaddr(szStr
, &curr_ip
)) {
1820 /*expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "DUALSTRINGARRAY: IP:%s",
1821 ip_to_str( (guint8 *) &curr_ip));*/
1825 memcpy(ip
, &curr_ip
, sizeof(curr_ip
));
1829 if(first_ip
!= curr_ip
) {
1830 expert_add_info_format(pinfo
, pi
, &ei_dcom_dualstringarray_mult_ip
,
1831 "DUALSTRINGARRAY: multiple IP's %s %s",
1832 ip_to_str( (guint8
*) &first_ip
), ip_to_str( (guint8
*) &curr_ip
));
1838 proto_item_append_text(subsub_item
, "[%u]: TowerId=%s, NetworkAddr=\"%s\"",
1840 val_to_str(u16TowerId
, dcom_protseq_vals
, "Unknown (0x%04x"),
1842 proto_item_set_len(subsub_item
, offset
- u32SubSubStart
);
1846 /* SECURITYBINDINGs until first wchar zero */
1847 while ( tvb_get_ntohs(tvb
, offset
) ) {
1848 u32SecurityBindings
++;
1850 subsub_item
= proto_tree_add_item(sub_tree
, hf_dcom_dualstringarray_security
, tvb
, offset
, 0, ENC_NA
);
1851 subsub_tree
= proto_item_add_subtree(subsub_item
, ett_dcom_dualstringarray_binding
);
1852 u32SubSubStart
= offset
;
1854 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, subsub_tree
, di
, drep
,
1855 hf_dcom_dualstringarray_security_authn_svc
,
1856 &u16SecurityAuthnSvc
);
1857 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, subsub_tree
, di
, drep
,
1858 hf_dcom_dualstringarray_security_authz_svc
,
1859 &u16SecurityAuthzSvc
);
1862 /* we don't know the (zero terminated) input length, use the buffer length instead */
1863 offset
= dcom_tvb_get_nwstringz0(tvb
, offset
, u32MaxStr
, szStr
, u32MaxStr
, &isPrintable
);
1864 proto_tree_add_string(subsub_tree
, hf_dcom_dualstringarray_security_princ_name
,
1865 tvb
, u32Start
, offset
- u32Start
, szStr
);
1867 proto_item_append_text(subsub_item
, "[%u]: AuthnSvc=0x%04x, AuthzSvc=0x%04x, PrincName=\"%s\"",
1868 u32SecurityBindings
, u16SecurityAuthnSvc
, u16SecurityAuthzSvc
, szStr
);
1869 proto_item_set_len(subsub_item
, offset
- u32SubSubStart
);
1873 /* append info to subtree header */
1874 proto_item_append_text(sub_item
, ": STRINGBINDINGs=%u, SECURITYBINDINGs=%u",
1875 u32StringBindings
, u32SecurityBindings
);
1876 proto_item_set_len(sub_item
, offset
- u32SubStart
);
1882 /* dissect an STDOBJREF */
1884 dissect_dcom_STDOBJREF(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1885 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex _U_
,
1886 guint64
*oxid
, guint64
*oid
, e_uuid_t
*ipid
)
1889 guint32 u32PublicRefs
;
1890 proto_item
*sub_item
;
1891 proto_tree
*sub_tree
;
1892 guint32 u32SubStart
;
1895 /* add subtree header */
1896 sub_item
= proto_tree_add_item(tree
, hf_dcom_stdobjref
, tvb
, offset
, 0, ENC_NA
);
1897 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_stdobjref
);
1899 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1900 hf_dcom_stdobjref_flags
, &u32Flags
);
1901 /* from here, alignment is ok */
1902 u32SubStart
= offset
- 4;
1903 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1904 hf_dcom_stdobjref_public_refs
, &u32PublicRefs
);
1905 offset
= dissect_dcom_ID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1906 hf_dcom_oxid
, oxid
);
1907 offset
= dissect_dcom_ID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1909 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
1910 hf_dcom_ipid
, ipid
);
1912 /* append info to subtree header */
1913 proto_item_append_text(sub_item
, ": PublicRefs=%u IPID=%s",
1914 u32PublicRefs
, guids_resolve_uuid_to_str(ipid
));
1915 proto_item_set_len(sub_item
, offset
- u32SubStart
);
1925 *print_uuid(const e_uuid_t* uuid)
1927 * proto_tree_add_debug_text(NULL, "UUID:(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)\n",
1928 * uuid->Data1, uuid->Data2, uuid->Data3,
1929 * uuid->Data4[0], uuid->Data4[1],
1930 * uuid->Data4[2], uuid->Data4[3],
1931 * uuid->Data4[4], uuid->Data4[5],
1932 * uuid->Data4[6], uuid->Data4[7]);
1940 dcom_register_rountine(dcom_dissect_fn_t routine
, e_uuid_t
* uuid
)
1942 dcom_marshaler_t
*marshaler
;
1945 /* check if exists already */
1946 if (dcom_get_rountine_by_uuid(uuid
))
1949 marshaler
= wmem_new(wmem_file_scope(), dcom_marshaler_t
);
1955 marshaler
->parent
= NULL
;
1956 marshaler
->private_data
= NULL
;
1957 marshaler
->uuid
= *uuid
;
1958 marshaler
->routine
= routine
;
1960 dcom_marshalers
= g_list_append(dcom_marshalers
, marshaler
);
1967 dcom_get_rountine_by_uuid(const e_uuid_t
* uuid
)
1969 dcom_marshaler_t
*marsh
;
1972 if(memcmp(uuid
, &uuid_null
, sizeof(uuid_null
)) == 0) {
1976 for(marshalers
= dcom_marshalers
; marshalers
!= NULL
;
1977 marshalers
= g_list_next(marshalers
)) {
1978 marsh
= (dcom_marshaler_t
*)marshalers
->data
;
1979 /*print_uuid(&marsh->uuid);*/
1980 /*print_uuid(uuid);*/
1981 if(memcmp(&marsh
->uuid
, uuid
, sizeof(e_uuid_t
)) == 0) {
1982 return marsh
->routine
;
1989 /* dissect an CUSTOM */
1991 dissect_dcom_CUSTOBJREF(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
1992 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
,
1993 e_uuid_t
*clsid
, e_uuid_t
*iid
)
1995 guint32 u32CBExtension
;
1997 guint32 u32SubStart
;
1998 proto_item
*sub_item
;
1999 proto_tree
*sub_tree
;
2000 dcom_dissect_fn_t routine
= NULL
;
2003 /* add subtree header */
2004 hfindex
= hf_dcom_custobjref
;
2005 sub_item
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 0, ENC_NA
);
2006 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_custobjref
);
2008 u32SubStart
= offset
;
2009 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2010 hf_dcom_clsid
, clsid
);
2011 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2012 hf_dcom_objref_cbextension
, &u32CBExtension
);
2013 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2014 hf_dcom_objref_size
, &u32Size
);
2016 /* the following data depends on the iid, get the routine by iid */
2017 routine
= dcom_get_rountine_by_uuid(iid
);
2019 offset
= routine(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, 0);
2022 /* append info to subtree header */
2023 /* proto_item_append_text(sub_item, ": ActivationPropertiesIn"); */
2024 proto_item_set_len(sub_item
, offset
- u32SubStart
);
2029 /* dissect an OBJREF */
2031 dissect_dcom_OBJREF(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
2032 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
, dcom_interface_t
**interf
)
2034 guint32 u32Signature
;
2038 proto_item
*sub_item
;
2039 proto_tree
*sub_tree
;
2040 guint32 u32SubStart
;
2044 dcom_interface_t
*dcom_if
= NULL
;
2047 memset(&ipid
, 0, sizeof(ipid
));
2049 /* add subtree header */
2050 sub_item
= proto_tree_add_item(tree
, hf_dcom_objref
, tvb
, offset
, 0, ENC_NA
);
2051 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_objref
);
2053 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2054 hf_dcom_objref_signature
, &u32Signature
);
2055 /* from here, alignment is ok */
2056 u32SubStart
= offset
- 4;
2057 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2058 hf_dcom_objref_flags
, &u32Flags
);
2059 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2063 case(0x1): /* standard */
2064 offset
= dissect_dcom_STDOBJREF(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, hfindex
,
2065 &oxid
, &oid
, &ipid
);
2066 offset
= dissect_dcom_DUALSTRINGARRAY(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2067 hf_dcom_objref_resolver_address
, ip
);
2069 case(0x2): /* handler (untested) */
2070 offset
= dissect_dcom_STDOBJREF(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, hfindex
,
2072 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2073 hf_dcom_clsid
, &clsid
);
2074 offset
= dissect_dcom_DUALSTRINGARRAY(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2075 hf_dcom_objref_resolver_address
, ip
);
2077 case(0x4): /* custom */
2078 offset
= dissect_dcom_CUSTOBJREF(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, hfindex
,
2083 if(u32Flags
== 0x1 || u32Flags
== 0x2) {
2084 /* add interface instance to database (we currently only handle IPv4) */
2085 if(pinfo
->net_src
.type
== AT_IPv4
) {
2086 dcom_if
= dcom_interface_new(pinfo
,
2088 &iid
, oxid
, oid
, &ipid
);
2092 if(interf
!= NULL
) {
2096 /* append info to subtree header */
2097 proto_item_set_len(sub_item
, offset
- u32SubStart
);
2102 /* dissect an MInterfacePointer */
2104 dissect_dcom_MInterfacePointer(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
2105 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
, dcom_interface_t
**interf
)
2108 guint32 u32ArraySize
;
2109 proto_item
*sub_item
;
2110 proto_tree
*sub_tree
;
2111 guint32 u32SubStart
;
2115 hfindex
= hf_dcom_interface_pointer
;
2118 /* add subtree header */
2119 sub_item
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 0, ENC_BIG_ENDIAN
);
2120 sub_tree
= proto_item_add_subtree(sub_item
, ett_dcom_interface_pointer
);
2122 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, &u32ArraySize
);
2123 u32SubStart
= offset
- 4; /* should use this trick to deal with align pad if any */
2125 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
2126 hf_dcom_ip_cnt_data
, &u32CntData
);
2128 offset
= dissect_dcom_OBJREF(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, hfindex
, interf
);
2130 /* append info to subtree header */
2131 proto_item_set_len(sub_item
, offset
- u32SubStart
);
2136 /* dissect a pointer to a MInterfacePointer */
2138 dissect_dcom_PMInterfacePointer(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
2139 proto_tree
*tree
, dcerpc_info
*di
, guint8
*drep
, int hfindex
, dcom_interface_t
**interf
)
2144 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
, &u32Pointer
);
2147 offset
= dissect_dcom_MInterfacePointer(tvb
, offset
, pinfo
, tree
, di
, drep
, hfindex
, interf
);
2149 if(interf
!= NULL
) {
2157 static void dcom_reinit( void) {
2159 if (dcom_machines
!= NULL
) {
2162 for(machines
= dcom_machines
; machines
!= NULL
; machines
= g_list_next(machines
)) {
2163 dcom_machine_t
*machine
= (dcom_machine_t
*)machines
->data
;
2165 if (machine
->objects
!= NULL
) {
2167 for(objects
= machine
->objects
; objects
!= NULL
; objects
= g_list_next(objects
)) {
2168 dcom_object_t
*object
= (dcom_object_t
*)objects
->data
;
2170 if (object
->interfaces
!= NULL
) {
2172 for(interface
= object
->interfaces
; interface
!= NULL
; interface
= g_list_next(interface
)) {
2173 g_free(interface
->data
);
2174 interface
->data
= NULL
; /* for good measure */
2176 g_list_free(object
->interfaces
);
2177 object
->interfaces
= NULL
; /* for good measure */
2180 g_free(objects
->data
);
2181 objects
->data
= NULL
; /* for good measure */
2183 g_list_free(machine
->objects
);
2184 machine
->objects
= NULL
; /* for good measure */
2187 g_free(machines
->data
);
2188 machines
->data
= NULL
; /* for good measure */
2190 g_list_free(dcom_machines
);
2191 dcom_machines
= NULL
;
2194 /* The data in dcom_interfaces is se_alloc'd so there's no need to free
2195 * the data pointers.
2197 if (dcom_interfaces
!= NULL
) {
2198 g_list_free(dcom_interfaces
);
2199 dcom_interfaces
= NULL
;
2207 proto_register_dcom (void)
2209 static hf_register_info hf_dcom_this_array
[] = {
2211 { &hf_dcom_this_version_major
,
2212 { "VersionMajor", "dcom.this.version_major", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2215 { &hf_dcom_this_version_minor
,
2216 { "VersionMinor", "dcom.this.version_minor", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2218 { &hf_dcom_this_flags
,
2219 { "Flags", "dcom.this.flags", FT_UINT32
, BASE_HEX
, VALS(dcom_thisthat_flag_vals
), 0x0, NULL
, HFILL
}},
2220 { &hf_dcom_this_res
,
2221 { "Reserved", "dcom.this.res", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2222 { &hf_dcom_this_cid
,
2223 { "Causality ID", "dcom.this.uuid", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}}
2226 static hf_register_info hf_dcom_that_array
[] = {
2227 { &hf_dcom_that_flags
,
2228 { "Flags", "dcom.that.flags", FT_UINT32
, BASE_HEX
, VALS(dcom_thisthat_flag_vals
), 0x0, NULL
, HFILL
}}
2231 static hf_register_info hf_dcom_extent_array
[] = {
2233 { "Extension", "dcom.extent", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2234 { &hf_dcom_extent_array_count
,
2235 { "Extension Count", "dcom.extent.array_count", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2236 { &hf_dcom_extent_array_res
,
2237 { "Reserved", "dcom.extent.array_res", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2238 { &hf_dcom_extent_size
,
2239 { "Extension Size", "dcom.extent.size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2240 { &hf_dcom_extent_id
,
2241 { "Extension Id", "dcom.extent.id", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}}
2244 static hf_register_info hf_dcom_array
[] = {
2245 { &hf_dcom_version_major
,
2246 { "VersionMajor", "dcom.version_major", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2247 { &hf_dcom_version_minor
,
2248 { "VersionMinor", "dcom.version_minor", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2250 { "HResult", "dcom.hresult", FT_UINT32
, BASE_HEX
, VALS(dcom_hresult_vals
), 0x0, NULL
, HFILL
}},
2251 { &hf_dcom_max_count
,
2252 { "MaxCount", "dcom.max_count", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2254 { "Offset", "dcom.offset", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2255 { &hf_dcom_byte_length
,
2256 { "ByteLength", "dcom.byte_length", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2258 { &hf_dcom_actual_count
,
2259 { "ActualCount", "dcom.actual_count", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2261 { &hf_dcom_tobedone
,
2262 { "To Be Done", "dcom.tobedone", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2264 { "No Specification Available", "dcom.nospec", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2267 { "Variant", "dcom.variant", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2269 { &hf_dcom_variant_type
,
2270 { "VarType", "dcom.variant_type", FT_UINT16
, BASE_HEX
, VALS(dcom_variant_type_vals
), 0x0, NULL
, HFILL
}},
2271 { &hf_dcom_variant_type32
,
2272 { "VarType32", "dcom.variant_type32", FT_UINT32
, BASE_HEX
, VALS(dcom_variant_type_vals
), 0x0, NULL
, HFILL
}},
2273 { &hf_dcom_variant_size
,
2274 { "Size", "dcom.variant_size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2275 { &hf_dcom_variant_rpc_res
,
2276 { "RPC-Reserved", "dcom.variant_rpc_res", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2277 { &hf_dcom_variant_wres
,
2278 { "Reserved", "dcom.variant_wres", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2279 { &hf_dcom_array_size
,
2280 { "(ArraySize)", "dcom.array_size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2281 { &hf_dcom_pointer_val
,
2282 { "(PointerVal)", "dcom.pointer_val", FT_UINT32
, BASE_HEX
, VALS(dcom_dcerpc_pointer_vals
), 0x0, NULL
, HFILL
}}
2285 static hf_register_info hf_dcom_interface_pointer_array
[] = {
2286 { &hf_dcom_interface_pointer
,
2287 { "InterfacePointer", "dcom.ifp", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2288 { &hf_dcom_ip_cnt_data
,
2289 { "CntData", "dcom.ip_cnt_data", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}}
2292 static hf_register_info hf_dcom_objref_array
[] = {
2294 { "OBJREF", "dcom.objref", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2295 { &hf_dcom_objref_signature
,
2296 { "Signature", "dcom.objref.signature", FT_UINT32
, BASE_HEX
, VALS(dcom_objref_signature_vals
), 0x0, NULL
, HFILL
}},
2297 { &hf_dcom_objref_flags
,
2298 { "Flags", "dcom.objref.flags", FT_UINT32
, BASE_HEX
, VALS(dcom_objref_flag_vals
), 0x0, NULL
, HFILL
}},
2300 { "IID", "dcom.iid", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2302 { "CLSID", "dcom.clsid", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2303 { &hf_dcom_objref_resolver_address
,
2304 { "ResolverAddress", "dcom.objref.resolver_address", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2305 { &hf_dcom_objref_cbextension
,
2306 { "CBExtension", "dcom.objref.cbextension", FT_UINT32
, BASE_DEC
, NULL
, 0x0, "Size of extension data", HFILL
}},
2307 { &hf_dcom_objref_size
,
2308 { "Size", "dcom.objref.size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}}
2311 static hf_register_info hf_dcom_stdobjref_array
[] = {
2312 { &hf_dcom_stdobjref
,
2313 { "STDOBJREF", "dcom.stdobjref", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2314 { &hf_dcom_stdobjref_flags
,
2315 { "Flags", "dcom.stdobjref.flags", FT_UINT32
, BASE_HEX
, VALS(dcom_stdobjref_flag_vals
), 0x0, NULL
, HFILL
}},
2316 { &hf_dcom_stdobjref_public_refs
,
2317 { "PublicRefs", "dcom.stdobjref.public_refs", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2319 { "OXID", "dcom.oxid", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2321 { "OID", "dcom.oid", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2323 { "IPID", "dcom.ipid", FT_GUID
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}}
2326 static hf_register_info hf_dcom_custobjref_array
[] = {
2327 { &hf_dcom_custobjref
,
2328 { "CUSTOMOBJREF", "dcom.custobjref", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2332 static hf_register_info hf_dcom_dualstringarray_array
[] = {
2333 { &hf_dcom_dualstringarray_num_entries
,
2334 { "NumEntries", "dcom.dualstringarray.num_entries", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2335 { &hf_dcom_dualstringarray_security_offset
,
2336 { "SecurityOffset", "dcom.dualstringarray.security_offset", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2337 { &hf_dcom_dualstringarray_string
,
2338 { "StringBinding", "dcom.dualstringarray.string", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2339 { &hf_dcom_dualstringarray_string_tower_id
,
2340 { "TowerId", "dcom.dualstringarray.tower_id", FT_UINT16
, BASE_HEX
, VALS(dcom_protseq_vals
), 0x0, NULL
, HFILL
}},
2341 { &hf_dcom_dualstringarray_string_network_addr
,
2342 { "NetworkAddr", "dcom.dualstringarray.network_addr", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2343 { &hf_dcom_dualstringarray_security
,
2344 { "SecurityBinding", "dcom.dualstringarray.security", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2345 { &hf_dcom_dualstringarray_security_authn_svc
,
2346 { "AuthnSvc", "dcom.dualstringarray.security_authn_svc", FT_UINT16
, BASE_HEX
, VALS(dcom_dualstringarray_authn
), 0x0, NULL
, HFILL
}},
2347 { &hf_dcom_dualstringarray_security_authz_svc
,
2348 { "AuthzSvc", "dcom.dualstringarray.security_authz_svc", FT_UINT16
, BASE_HEX
, VALS(dcom_dualstringarray_authz
), 0x0, NULL
, HFILL
}},
2349 { &hf_dcom_dualstringarray_security_princ_name
,
2350 { "PrincName", "dcom.dualstringarray.security_princ_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}}
2353 static hf_register_info hf_dcom_vt_array
[] = {
2355 { "VT_BOOL", "dcom.vt.bool", FT_UINT16
, BASE_HEX
, VALS(dcom_vt_bool_vals
), 0x0, NULL
, HFILL
}},
2357 { "VT_I1", "dcom.vt.i1", FT_INT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2359 { "VT_I2", "dcom.vt.i2", FT_INT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2361 { "VT_I4", "dcom.vt.i4", FT_INT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2363 { "VT_I8", "dcom.vt.i8", FT_INT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2365 { "VT_UI1", "dcom.vt.ui1", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2367 { "VT_UI2", "dcom.vt.ui2", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2369 { "VT_UI4", "dcom.vt.ui4", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2371 { "VT_R4", "dcom.vt.r4", FT_FLOAT
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2373 { "VT_R8", "dcom.vt.r8", FT_DOUBLE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2375 { "VT_DATE", "dcom.vt.date", FT_DOUBLE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2377 { "VT_BSTR", "dcom.vt.bstr", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2378 { &hf_dcom_vt_byref
,
2379 { "BYREF", "dcom.vt.byref", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2380 { &hf_dcom_vt_dispatch
,
2381 { "VT_DISPATCH", "dcom.vt.dispatch", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}}
2384 static hf_register_info hf_dcom_sa_array
[] = {
2385 { &hf_dcom_safearray
,
2386 { "SAFEARRAY", "dcom.sa", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2387 { &hf_dcom_sa_dims32
,
2388 { "Dims32", "dcom.sa.dims32", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2389 { &hf_dcom_sa_dims16
,
2390 { "Dims16", "dcom.sa.dims16", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2391 { &hf_dcom_sa_features
,
2392 { "Features", "dcom.sa.features", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2393 { &hf_dcom_sa_element_size
,
2394 { "ElementSize", "dcom.sa.element_size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2395 { &hf_dcom_sa_locks
,
2396 { "Locks", "dcom.sa.locks", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2397 { &hf_dcom_sa_vartype32
,
2398 { "VarType32", "dcom.sa.vartype", FT_UINT32
, BASE_DEC
, VALS(dcom_variant_type_vals
), 0x0, NULL
, HFILL
}},
2399 { &hf_dcom_sa_vartype16
,
2400 { "VarType16", "dcom.sa.vartype", FT_UINT16
, BASE_DEC
, VALS(dcom_variant_type_vals
), 0x0, NULL
, HFILL
}},
2401 { &hf_dcom_sa_elements
,
2402 { "Elements", "dcom.sa.elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2403 { &hf_dcom_sa_bound_elements
,
2404 { "BoundElements", "dcom.sa.bound_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2405 { &hf_dcom_sa_low_bound
,
2406 { "LowBound", "dcom.sa.low_bound", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2408 { &hf_dcom_sa_features_auto
,
2409 { "AUTO", "dcom.sa.features_auto", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_AUTO
, NULL
, HFILL
}},
2410 { &hf_dcom_sa_features_static
,
2411 { "STATIC", "dcom.sa.features_static", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_STATIC
, NULL
, HFILL
}},
2412 { &hf_dcom_sa_features_embedded
,
2413 { "EMBEDDED", "dcom.sa.features_embedded", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_EMBEDDED
, NULL
, HFILL
}},
2414 { &hf_dcom_sa_features_fixedsize
,
2415 { "FIXEDSIZE", "dcom.sa.features_fixedsize", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_FIXEDSIZE
, NULL
, HFILL
}},
2416 { &hf_dcom_sa_features_record
,
2417 { "RECORD", "dcom.sa.features_record", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_RECORD
, NULL
, HFILL
}},
2418 { &hf_dcom_sa_features_have_iid
,
2419 { "HAVEIID", "dcom.sa.features_have_iid", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_HAVEIID
, NULL
, HFILL
}},
2420 { &hf_dcom_sa_features_have_vartype
,
2421 { "HAVEVARTYPE", "dcom.sa.features_have_vartype", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_HAVEVARTYPE
, NULL
, HFILL
}},
2422 { &hf_dcom_sa_features_bstr
,
2423 { "BSTR", "dcom.sa.features_bstr", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_BSTR
, NULL
, HFILL
}},
2424 { &hf_dcom_sa_features_unknown
,
2425 { "UNKNOWN", "dcom.sa.features_unknown", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_UNKNOWN
, NULL
, HFILL
}},
2426 { &hf_dcom_sa_features_dispatch
,
2427 { "DISPATCH", "dcom.sa.features_dispatch", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_DISPATCH
, NULL
, HFILL
}},
2428 { &hf_dcom_sa_features_variant
,
2429 { "VARIANT", "dcom.sa.features_variant", FT_BOOLEAN
, 16, TFS (&tfs_set_notset
), WIRESHARK_FADF_VARIANT
, NULL
, HFILL
}}
2432 static gint
*ett_dcom
[] = {
2437 &ett_dcom_interface_pointer
,
2439 &ett_dcom_stdobjref
,
2440 &ett_dcom_custobjref
,
2441 &ett_dcom_dualstringarray
,
2442 &ett_dcom_dualstringarray_binding
,
2444 &ett_dcom_safearray
,
2445 &ett_dcom_sa_features
,
2448 static ei_register_info ei
[] = {
2449 { &ei_dcom_dissetion_incomplete
, { "dcom.dissetion_incomplete", PI_UNDECODED
, PI_WARN
, "Dissection incomplete", EXPFILL
}},
2450 { &ei_dcom_no_spec
, { "dcom.no_spec", PI_UNDECODED
, PI_NOTE
, "No specification available, dissection not possible", EXPFILL
}},
2451 { &ei_dcom_hresult_expert
, { "dcom.hresult.expert", PI_RESPONSE_CODE
, PI_NOTE
, "Hresult", EXPFILL
}},
2452 { &ei_dcom_dualstringarray_mult_ip
, { "dcom.dualstringarray.mult_ip", PI_UNDECODED
, PI_NOTE
, "DUALSTRINGARRAY Multiple IP", EXPFILL
}},
2455 module_t
*dcom_module
;
2456 expert_module_t
* expert_dcom
;
2458 /* currently, the DCOM protocol "itself" has no real protocol dissector */
2459 /* we only need this, to register some generic elements */
2460 proto_dcom
= proto_register_protocol ("DCOM", "DCOM", "dcom");
2461 proto_register_field_array(proto_dcom
, hf_dcom_this_array
, array_length(hf_dcom_this_array
));
2462 proto_register_field_array(proto_dcom
, hf_dcom_that_array
, array_length(hf_dcom_that_array
));
2463 proto_register_field_array(proto_dcom
, hf_dcom_extent_array
, array_length(hf_dcom_extent_array
));
2464 proto_register_field_array(proto_dcom
, hf_dcom_array
, array_length(hf_dcom_array
));
2465 proto_register_field_array(proto_dcom
, hf_dcom_objref_array
, array_length(hf_dcom_objref_array
));
2466 proto_register_field_array(proto_dcom
, hf_dcom_stdobjref_array
, array_length(hf_dcom_stdobjref_array
));
2467 proto_register_field_array(proto_dcom
, hf_dcom_custobjref_array
, array_length(hf_dcom_custobjref_array
));
2468 proto_register_field_array(proto_dcom
, hf_dcom_dualstringarray_array
, array_length(hf_dcom_dualstringarray_array
));
2469 proto_register_field_array(proto_dcom
, hf_dcom_interface_pointer_array
, array_length(hf_dcom_interface_pointer_array
));
2470 proto_register_field_array(proto_dcom
, hf_dcom_vt_array
, array_length(hf_dcom_vt_array
));
2471 proto_register_field_array(proto_dcom
, hf_dcom_sa_array
, array_length(hf_dcom_sa_array
));
2472 proto_register_subtree_array (ett_dcom
, array_length (ett_dcom
));
2474 expert_dcom
= expert_register_protocol(proto_dcom
);
2475 expert_register_field_array(expert_dcom
, ei
, array_length(ei
));
2478 dcom_module
= prefs_register_protocol(proto_dcom
, NULL
);
2480 prefs_register_bool_preference(dcom_module
, "display_unmarshalling_details",
2481 "Display DCOM unmarshalling details",
2482 "Display some DCOM unmarshalled fields "
2484 &dcom_prefs_display_unmarshalling_details
);
2486 register_init_routine(dcom_reinit
);
2491 proto_reg_handoff_dcom (void)
2493 /* register some "well known" UUID's */
2494 guids_add_uuid(&uuid_debug_ext
, "Debug Information Body Extension");
2495 guids_add_uuid(&uuid_ext_error_ext
, "Extended Error Info Body Extension");
2496 guids_add_uuid(&ipid_rem_unknown
, "IRemUnknown");
2497 guids_add_uuid(&iid_unknown
, "IUnknown");
2498 guids_add_uuid(&uuid_null
, "NULL");
2499 guids_add_uuid(&iid_class_factory
, "IClassFactory");
2501 /* Currently, we have nothing to register for DCOM */