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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 /* A few words about DCOM:
27 * DCOM uses DCERPC as it's 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
73 * XXX - are the next two includes necessary?
75 #ifdef HAVE_SYS_TYPES_H
76 # include <sys/types.h>
79 #ifdef HAVE_NETINET_IN_H
80 #include <netinet/in.h>
83 #ifdef HAVE_WINSOCK2_H
90 #include <epan/packet.h>
91 #include <epan/emem.h>
92 #include <epan/addr_resolv.h>
93 #include <epan/inet_aton.h>
96 #include "packet-dcerpc.h"
97 #include "packet-dcom.h"
102 static int proto_dcom = -1;
104 gboolean dcom_prefs_display_unmarshalling_details = FALSE;
107 gint ett_dcom_this = -1;
108 static int hf_dcom_this_version_major = -1;
109 static int hf_dcom_this_version_minor = -1;
110 static int hf_dcom_this_flags = -1;
111 static int hf_dcom_this_res = -1;
112 static int hf_dcom_this_cid = -1;
114 gint ett_dcom_that = -1;
115 static int hf_dcom_that_flags = -1;
117 gint ett_dcom_extent = -1;
118 static int hf_dcom_extent = -1;
119 static int hf_dcom_extent_array_count = -1;
120 static int hf_dcom_extent_array_res = -1;
121 static int hf_dcom_extent_size = -1;
122 static int hf_dcom_extent_id = -1;
124 static int hf_dcom_hresult = -1;
125 static int hf_dcom_tobedone = -1;
126 static int hf_dcom_nospec = -1;
127 static int hf_dcom_array_size = -1;
128 static int hf_dcom_pointer_val = -1;
131 static int hf_dcom_version_major = -1;
132 static int hf_dcom_version_minor = -1;
134 gint ett_dcom_lpwstr = -1;
135 static int hf_dcom_max_count = -1;
136 static int hf_dcom_offset = -1;
137 static int hf_dcom_byte_length = -1;
138 static int hf_dcom_actual_count = -1;
140 gint ett_dcom_objref = -1;
141 static int hf_dcom_objref = -1;
142 static int hf_dcom_objref_signature = -1;
143 static int hf_dcom_objref_flags = -1;
144 int hf_dcom_iid = -1;
145 int hf_dcom_clsid = -1;
146 static int hf_dcom_objref_resolver_address = -1;
147 static int hf_dcom_objref_cbextension = -1;
148 static int hf_dcom_objref_size = -1;
150 gint ett_dcom_stdobjref = -1;
151 static int hf_dcom_stdobjref = -1;
152 static int hf_dcom_stdobjref_flags = -1;
153 static int hf_dcom_stdobjref_public_refs = -1;
154 int hf_dcom_oxid = -1;
155 int hf_dcom_oid = -1;
156 int hf_dcom_ipid = -1;
158 gint ett_dcom_dualstringarray = -1;
159 gint ett_dcom_dualstringarray_binding = -1;
160 static int hf_dcom_dualstringarray_num_entries = -1;
161 static int hf_dcom_dualstringarray_security_offset = -1;
162 static int hf_dcom_dualstringarray_string = -1;
163 static int hf_dcom_dualstringarray_string_network_addr = -1;
164 static int hf_dcom_dualstringarray_string_tower_id = -1;
165 static int hf_dcom_dualstringarray_security = -1;
166 static int hf_dcom_dualstringarray_security_authn_svc = -1;
167 static int hf_dcom_dualstringarray_security_authz_svc = -1;
168 static int hf_dcom_dualstringarray_security_princ_name = -1;
170 gint ett_dcom_interface_pointer = -1;
171 static int hf_dcom_interface_pointer = -1;
172 static int hf_dcom_ip_cnt_data = -1;
174 gint ett_dcom_safearray = -1;
175 static int hf_dcom_safearray = -1;
176 static int hf_dcom_sa_dims32 = -1;
177 static int hf_dcom_sa_dims16 = -1;
178 static int hf_dcom_sa_features = -1;
179 static int hf_dcom_sa_element_size = -1;
180 static int hf_dcom_sa_locks = -1;
181 static int hf_dcom_sa_vartype32 = -1;
182 static int hf_dcom_sa_vartype16 = -1;
183 static int hf_dcom_sa_elements = -1;
184 static int hf_dcom_sa_bound_elements = -1;
185 static int hf_dcom_sa_low_bound = -1;
187 gint ett_dcom_sa_features = -1;
188 static int hf_dcom_sa_features_auto = -1;
189 static int hf_dcom_sa_features_static = -1;
190 static int hf_dcom_sa_features_embedded = -1;
191 static int hf_dcom_sa_features_fixedsize = -1;
192 static int hf_dcom_sa_features_record = -1;
193 static int hf_dcom_sa_features_have_iid = -1;
194 static int hf_dcom_sa_features_have_vartype = -1;
195 static int hf_dcom_sa_features_bstr = -1;
196 static int hf_dcom_sa_features_unknown = -1;
197 static int hf_dcom_sa_features_dispatch = -1;
198 static int hf_dcom_sa_features_variant = -1;
200 gint ett_dcom_variant = -1;
201 static int hf_dcom_variant = -1;
202 static int hf_dcom_variant_type = -1;
203 static int hf_dcom_variant_size = -1;
204 static int hf_dcom_variant_rpc_res = -1;
205 static int hf_dcom_variant_wres = -1;
206 static int hf_dcom_variant_type32 = -1;
208 static int hf_dcom_vt_bool = -1;
209 static int hf_dcom_vt_i1 = -1;
210 static int hf_dcom_vt_i2 = -1;
211 static int hf_dcom_vt_i4 = -1;
212 static int hf_dcom_vt_i8 = -1; /* only inside a SAFEARRAY, not in VARIANTs */
213 static int hf_dcom_vt_ui1 = -1;
214 static int hf_dcom_vt_ui2 = -1;
215 static int hf_dcom_vt_ui4 = -1;
216 static int hf_dcom_vt_r4 = -1;
217 static int hf_dcom_vt_r8 = -1;
218 static int hf_dcom_vt_date = -1;
219 static int hf_dcom_vt_bstr = -1;
220 static int hf_dcom_vt_byref = -1;
221 static int hf_dcom_vt_dispatch = -1;
223 /* this/that extension UUIDs */
224 static e_uuid_t uuid_debug_ext = { 0xf1f19680, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
225 static e_uuid_t uuid_ext_error_ext ={ 0xf1f19681, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
227 /* general DCOM UUIDs */
228 static const e_uuid_t ipid_rem_unknown = { 0x00000131, 0x1234, 0x5678, { 0xCA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
229 static const e_uuid_t iid_unknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
230 static const e_uuid_t uuid_null = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
231 static const e_uuid_t iid_class_factory = { 0x00000001, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
233 GList *dcom_machines;
234 GList *dcom_interfaces;
236 static const value_string dcom_thisthat_flag_vals[] = {
244 void dcom_interface_dump(void) {
245 dcom_machine_t *machine;
246 dcom_object_t *object;
247 dcom_interface_t *interf;
253 for(machines = dcom_machines; machines != NULL; machines = g_list_next(machines)) {
254 machine = machines->data;
255 g_warning("Machine(#%4u): IP:%s", machine->first_packet, ip_to_str(machine->ip));
257 for(objects = machine->objects; objects != NULL; objects = g_list_next(objects)) {
258 object = objects->data;
259 g_warning(" Object(#%4u): OID:0x%" G_GINT64_MODIFIER "x private:%p", object->first_packet, object->oid, object->private_data);
261 for(interfaces = object->interfaces; interfaces != NULL; interfaces = g_list_next(interfaces)) {
262 interf = interfaces->data;
263 g_warning(" Interface(#%4u): iid:%s",
264 interf->first_packet, guids_resolve_uuid_to_str(&interf->iid));
265 g_warning(" ipid:%s", guids_resolve_uuid_to_str(&interf->ipid));
272 dcom_interface_t *dcom_interface_find(packet_info *pinfo _U_, const guint8 *ip _U_, e_uuid_t *ipid)
274 dcom_interface_t *interf;
278 if(memcmp(ipid, &uuid_null, sizeof(uuid_null)) == 0)
283 for(interfaces = dcom_interfaces; interfaces != NULL; interfaces = g_list_next(interfaces)) {
284 interf = interfaces->data;
286 if(memcmp(&interf->ipid, ipid, sizeof(e_uuid_t)) == 0) {
295 dcom_interface_t *dcom_interface_new(packet_info *pinfo, const guint8 *ip, e_uuid_t *iid, guint64 oxid, guint64 oid, e_uuid_t *ipid)
298 dcom_machine_t *machine;
299 dcom_object_t *object;
300 dcom_interface_t *interf;
303 if( memcmp(iid, &uuid_null, sizeof(uuid_null)) == 0 ||
304 memcmp(ipid, &uuid_null, sizeof(uuid_null)) == 0)
309 if(oxid == 0 || oid == 0) {
310 /*g_warning("interface_new#%u", pinfo->fd->num);*/
312 interf = se_alloc(sizeof(dcom_interface_t));
313 interf->parent = NULL;
314 interf->private_data = NULL;
315 interf->first_packet = pinfo->fd->num;
317 interf->ipid = *ipid;
319 dcom_interfaces = g_list_append(dcom_interfaces, interf);
324 dcom_iter = dcom_machines;
325 while(dcom_iter != NULL) {
326 machine = dcom_iter->data;
327 if(memcmp(machine->ip, ip, 4) == 0) {
330 dcom_iter = g_list_next(dcom_iter);
333 /* create new machine if not found */
334 if(dcom_iter == NULL) {
335 machine = se_alloc(sizeof(dcom_machine_t));
336 memcpy(machine->ip, ip, 4);
337 machine->objects = NULL;
338 machine->first_packet = pinfo->fd->num;
339 dcom_machines = g_list_append(dcom_machines, machine);
343 dcom_iter = machine->objects;
344 while(dcom_iter != NULL) {
345 object = dcom_iter->data;
346 if(object->oid == oid) {
349 dcom_iter = g_list_next(dcom_iter);
352 /* create new object if not found */
353 if(dcom_iter == NULL) {
354 object = se_alloc(sizeof(dcom_object_t));
355 object->parent = machine;
356 object->interfaces = NULL;
357 object->private_data = NULL;
358 object->first_packet = pinfo->fd->num;
362 machine->objects = g_list_append(machine->objects, object);
366 dcom_iter = object->interfaces;
367 while(dcom_iter != NULL) {
368 interf = dcom_iter->data;
369 if(memcmp(&interf->ipid, ipid, sizeof(e_uuid_t)) == 0) {
372 dcom_iter = g_list_next(dcom_iter);
375 /* create new interface if not found */
376 if(dcom_iter == NULL) {
377 interf = se_alloc(sizeof(dcom_interface_t));
378 interf->parent = object;
379 interf->private_data = NULL;
380 interf->first_packet = pinfo->fd->num;
382 interf->ipid = *ipid;
384 object->interfaces = g_list_append(object->interfaces, interf);
385 dcom_interfaces = g_list_append(dcom_interfaces, interf);
393 * Flag bits in connection-oriented PDU header.
395 #define WIRESHARK_FADF_AUTO 0x0001
396 #define WIRESHARK_FADF_STATIC 0x0002
397 #define WIRESHARK_FADF_EMBEDDED 0x0004
398 #define WIRESHARK_FADF_FIXEDSIZE 0x0010
399 #define WIRESHARK_FADF_RECORD 0x0020
400 #define WIRESHARK_FADF_HAVEIID 0x0040
401 #define WIRESHARK_FADF_HAVEVARTYPE 0x0080
402 #define WIRESHARK_FADF_BSTR 0x0100
403 #define WIRESHARK_FADF_UNKNOWN 0x0200
404 #define WIRESHARK_FADF_DISPATCH 0x0400
405 #define WIRESHARK_FADF_VARIANT 0x0800
409 WIRESHARK_VT_EMPTY = 0,
410 WIRESHARK_VT_NULL = 1,
416 WIRESHARK_VT_DATE = 7,
417 WIRESHARK_VT_BSTR = 8,
418 WIRESHARK_VT_DISPATCH = 9,
419 WIRESHARK_VT_ERROR = 10,
420 WIRESHARK_VT_BOOL = 11,
421 WIRESHARK_VT_VARIANT = 12,
422 WIRESHARK_VT_UNKNOWN = 13,
423 WIRESHARK_VT_DECIMAL = 14,
424 WIRESHARK_VT_I1 = 16,
425 WIRESHARK_VT_UI1 = 17,
426 WIRESHARK_VT_UI2 = 18,
427 WIRESHARK_VT_UI4 = 19,
428 WIRESHARK_VT_I8 = 20,
429 WIRESHARK_VT_UI8 = 21,
430 WIRESHARK_VT_INT = 22,
431 WIRESHARK_VT_UINT = 23,
432 WIRESHARK_VT_VOID = 24,
433 WIRESHARK_VT_HRESULT = 25,
434 WIRESHARK_VT_PTR = 26,
435 WIRESHARK_VT_SAFEARRAY = 27,
436 WIRESHARK_VT_CARRAY = 28,
437 WIRESHARK_VT_USERDEFINED = 29,
438 WIRESHARK_VT_LPSTR = 30,
439 WIRESHARK_VT_LPWSTR = 31,
440 WIRESHARK_VT_RECORD = 36,
441 WIRESHARK_VT_FILETIME = 64,
442 WIRESHARK_VT_BLOB = 65,
443 WIRESHARK_VT_STREAM = 66,
444 WIRESHARK_VT_STORAGE = 67,
445 WIRESHARK_VT_STREAMED_OBJECT = 68,
446 WIRESHARK_VT_STORED_OBJECT = 69,
447 WIRESHARK_VT_BLOB_OBJECT = 70,
448 WIRESHARK_VT_CF = 71,
449 WIRESHARK_VT_CLSID = 72,
451 WIRESHARK_VT_BSTR_BLOB = 0x0fff,
453 WIRESHARK_VT_VECTOR = 0x1000,
454 WIRESHARK_VT_ARRAY = 0x2000,
455 WIRESHARK_VT_BYREF = 0x4000,
456 WIRESHARK_VT_RESERVED = 0x8000,
458 WIRESHARK_VT_ILLEGAL = 0xffff,
459 WIRESHARK_VT_ILLEGALMASKED = 0x0fff,
460 WIRESHARK_VT_TYPEMASK = 0x0fff
463 const value_string dcom_variant_type_vals[] = {
464 { WIRESHARK_VT_EMPTY, "VT_EMPTY"},
465 { WIRESHARK_VT_NULL, "VT_NULL"},
466 { WIRESHARK_VT_I2, "VT_I2"},
467 { WIRESHARK_VT_I4, "VT_I4"},
468 { WIRESHARK_VT_R4, "VT_R4"},
469 { WIRESHARK_VT_R8, "VT_R8"},
470 { WIRESHARK_VT_CY, "VT_CY"},
471 { WIRESHARK_VT_DATE, "VT_DATE"},
472 { WIRESHARK_VT_BSTR, "VT_BSTR"},
473 { WIRESHARK_VT_DISPATCH, "VT_DISPATCH"},
474 { WIRESHARK_VT_ERROR, "VT_ERROR"},
475 { WIRESHARK_VT_BOOL, "VT_BOOL"},
476 { WIRESHARK_VT_I1, "VT_I1"},
477 { WIRESHARK_VT_UI1, "VT_UI1"},
478 { WIRESHARK_VT_UI2, "VT_UI2"},
479 { WIRESHARK_VT_UI4, "VT_UI4"},
480 { WIRESHARK_VT_I8, "VT_I8"},
481 { WIRESHARK_VT_UI8, "VT_UI8"},
482 { WIRESHARK_VT_ARRAY, "VT_ARRAY"},
483 { WIRESHARK_VT_UNKNOWN, "VT_UNKNOWN"},
484 { WIRESHARK_VT_USERDEFINED, "VT_USERDEFINED"},
486 /* XXX: this could be done better */
487 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_I2, "VT_ARRAY|VT_I2"},
488 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_I4, "VT_ARRAY|VT_I4"},
489 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_R4, "VT_ARRAY|VT_R4"},
490 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_R8, "VT_ARRAY|VT_R8"},
491 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_DATE, "VT_ARRAY|VT_DATE"},
492 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_BSTR, "VT_ARRAY|VT_BSTR"},
493 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_ERROR, "VT_ARRAY|VT_ERROR"},
494 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_BOOL, "VT_ARRAY|VT_BOOL"},
495 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_I1, "VT_ARRAY|VT_I1"},
496 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_UI1, "VT_ARRAY|VT_UI1"},
497 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_UI2, "VT_ARRAY|VT_UI2"},
498 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_UI4, "VT_ARRAY|VT_UI4"},
499 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_I8, "VT_ARRAY|VT_I8"},
500 { WIRESHARK_VT_ARRAY | WIRESHARK_VT_UI8, "VT_ARRAY|VT_UI8"},
502 { WIRESHARK_VT_BYREF | WIRESHARK_VT_I2, "VT_BYREF|VT_I2"},
503 { WIRESHARK_VT_BYREF | WIRESHARK_VT_BSTR, "VT_BYREF|VT_BSTR"},
504 { WIRESHARK_VT_BYREF | WIRESHARK_VT_VARIANT, "VT_BYREF|VT_VARIANT"},
506 /* XXX: append more types here */
511 /* we need an extension mechanism here (be able to append entries by user protocol) */
512 const value_string dcom_hresult_vals[] = {
513 { 0x00000000, "S_OK" },
514 { 0x00000001, "S_FALSE" },
515 { 0x8000FFFF, "E_UNEXPECTED" },
516 { 0x80004001, "E_NOTIMPL" },
517 { 0x80004002, "E_NOINTERFACE" },
518 { 0x80004003, "E_POINTER" },
519 { 0x80004004, "E_ABORT" },
520 { 0x80004005, "E_FAIL" },
521 { 0x80070005, "E_ACCESSDENIED" },
522 { 0x80070006, "E_HANDLE" },
523 { 0x8007000E, "E_OUTOFMEMORY" },
524 { 0x80070057, "E_INVALIDARG" },
526 { 0x80010108, "RPC_E_DISCONNECTED" },
527 { 0x80010113, "RPC_E_INVALID_IPID" },
528 { 0x8001011F, "RPC_E_TIMEOUT" },
530 { 0x80020003, "DISP_E_MEMBERNOTFOUND" },
531 { 0x80020004, "DISP_E_PARAMNOTFOUND" },
532 { 0x80020005, "DISP_E_TYPEMISMATCH" },
533 { 0x80020006, "DISP_E_UNKNOWNNAME" },
534 { 0x80020008, "DISP_E_BADVARTYPE" },
535 { 0x80020009, "DISP_E_EXCEPTION" },
536 { 0x8002000A, "DISP_E_OVERFLOW" },
538 { 0x8002801D, "TYPE_E_LIBNOTREGISTERED" },
540 { 0x80040154, "REGDB_E_CLASSNOTREG" },
541 { 0x80040201, "CO_E_FAILEDTOGETSECCTX" },
543 /* following are CBA application specific values */
544 { 0x0004CA00, "CBA_S_PERSISTPENDING" },
545 { 0x0004CA01, "CBA_S_ESTABLISHING" },
546 { 0x0004CA02, "CBA_S_NOCONNECTION" },
547 { 0x0004CA03, "CBA_S_VALUEBUFFERED" },
548 { 0x0004CA04, "CBA_S_VALUEUNCERTAIN" },
549 { 0x0004CA05, "CBA_S_NOCONNECTIONDATA" },
550 { 0x0004CA06, "CBA_S_FRAMEEMPTY" },
552 { 0x8004CB00, "CBA_E_MALFORMED" },
553 { 0x8004CB01, "CBA_E_UNKNOWNOBJECT" },
554 { 0x8004CB02, "CBA_E_UNKNOWNMEMBER" },
555 { 0x8004CB03, "CBA_E_TYPEMISMATCH" },
556 { 0x8004CB04, "CBA_E_INVALIDENUMVALUE" },
557 { 0x8004CB05, "CBA_E_INVALIDID" },
558 { 0x8004CB06, "CBA_E_INVALIDEPSILON" },
559 { 0x8004CB07, "CBA_E_INVALIDSUBSTITUTE" },
560 { 0x8004CB08, "CBA_E_INVALIDCONNECTION" },
561 { 0x8004CB09, "CBA_E_INVALIDCOOKIE" },
562 { 0x8004CB0A, "CBA_E_TIMEVALUEUNSUPPORTED" },
563 { 0x8004CB0B, "CBA_E_QOSTYPEUNSUPPORTED" },
564 { 0x8004CB0C, "CBA_E_QOSVALUEUNSUPPORTED" },
565 { 0x8004CB0D, "CBA_E_PERSISTRUNNING" },
566 { 0x8004CB0E, "CBA_E_INUSE" },
567 { 0x8004CB0F, "CBA_E_NOTAPPLICABLE" },
568 { 0x8004CB10, "CBA_E_NONACCESSIBLE" },
569 { 0x8004CB11, "CBA_E_DEFECT" },
570 { 0x8004CB12, "CBA_E_LIMITVIOLATION" },
571 { 0x8004CB13, "CBA_E_QOSTYPENOTAPPLICABLE" },
572 { 0x8004CB14, "CBA_E_QCNOTAPPLICABLE" },
573 { 0x8004CB15, "CBA_E_ACCESSBLOCKED" },
574 { 0x8004CB16, "CBA_E_COUNTEXCEEDED" },
575 { 0x8004CB17, "CBA_E_SIZEEXCEEDED" },
576 { 0x8004CB18, "CBA_E_OUTOFPARTNERACCOS" },
577 { 0x8004CB19, "CBA_E_OUTOFACCOPAIRS" },
578 { 0x8004CB1A, "CBA_E_ITEMTOOLARGE" },
579 { 0x8004CB1B, "CBA_E_CRDATALENGTH" },
580 { 0x8004CB1C, "CBA_E_FLAGUNSUPPORTED" },
581 { 0x8004CB1D, "CBA_E_CAPACITYEXCEEDED" },
582 { 0x8004CB1E, "CBA_E_SUBELEMENTMISMATCH" },
583 { 0x8004CB1F, "CBA_E_STATIONFAILURE" },
584 { 0x8004CB20, "CBA_E_NOTROUTABLE" },
585 { 0x8004CB21, "CBA_E_DISCONNECTRUNNING" },
586 { 0x8004CB22, "CBA_E_LOCATIONCHANGED" },
587 { 0x8004CB23, "CBA_E_FRAMECOUNTUNSUPPORTED" },
588 { 0x8004CB24, "CBA_E_LINKFAILURE" },
589 { 0x8004CB25, "CBA_E_MODECHANGE" },
591 { 0x80080004, "CO_E_BAD_PATH" },
596 static const value_string dcom_objref_flag_vals[] = {
597 { 0x1, "OBJREF_STANDARD" },
598 { 0x2, "OBJREF_HANDLER" },
599 { 0x4, "OBJREF_CUSTOM" },
603 static const value_string dcom_objref_signature_vals[] = {
604 { 0x574f454d, "MEOW" },
608 /* although flags, they doesn't seem to be used as such */
609 static const value_string dcom_stdobjref_flag_vals[] = {
610 { 0x0000, "SORF_NULL" },
611 { 0x0001, "SORF_OXRES1" },
612 { 0x0020, "SORF_OXRES2" },
613 { 0x0040, "SORF_OXRES3" },
614 { 0x0080, "SORF_OXRES4" },
615 { 0x0100, "SORF_OXRES5" },
616 { 0x0200, "SORF_OXRES6" },
617 { 0x0400, "SORF_OXRES7" },
618 { 0x0800, "SORF_OXRES8" },
619 { 0x1000, "SORF_NOPING" },
623 static const value_string dcom_dcerpc_pointer_vals[] = {
624 { 0x72657355, "User" },
625 { 0x42535452, "BSTR" },
626 { 0x00000000, "NULL" },
630 static const value_string dcom_dualstringarray_authz[] = {
631 { 0x0000, "RPC_C_AUTHZ_NONE" },
632 { 0x0001, "RPC_C_AUTHZ_NAME"},
633 { 0x0002, "RPC_C_AUTHZ_DCE"},
634 { 0xffff, "Default"},
638 static const value_string dcom_dualstringarray_authn[] = {
639 { 00, "RPC_C_AUTHN_NONE" },
640 { 1, "RPC_C_AUTHN_DCE_PRIVATE"},
641 { 2, "RPC_C_AUTHN_DCE_PUBLIC"},
642 { 4, "RPC_C_AUTHN_DEC_PUBLIC"},
643 { 9, "RPC_C_AUTHN_GSS_NEGOTIATE"},
644 { 10, "RPC_C_AUTH_WINNT"},
645 { 14, "RPC_C_AUTHN_GSS_SCHANNEL"},
646 { 16, "RPC_C_AUTHN_GSS_KERBEROS"},
647 { 17, "RPC_C_AUTHN_MSN"},
648 { 18, "RPC_C_AUTHN_DPA"},
649 { 100, "RPC_C_AUTHN_MQ"},
650 { 0xffff, "RPC_C_AUTHN_DEFAULT"},
654 const value_string dcom_protseq_vals[] = {
655 { 0x04, "NCACN_DNET_NSP" },
656 { 0x07, "NCACN_IP_TCP" },
657 { 0x08, "NCADG_IP_UDP" },
658 { 0x09, "NCACN_IP" },
659 { 0x0C, "NCACN_SPX" },
660 { 0x0D, "NCACN_NB_IPX" },
661 { 0x0E, "NCADG_IPX" },
662 { 0x12, "NCACN_NB_NB" },
663 { 0x1F, "NCACN_HTTP" },
667 static const value_string dcom_vt_bool_vals[] = {
675 /* dissect extension to DCOM "this" and "that" */
677 dissect_dcom_extent(tvbuff_t *tvb, int offset,
678 packet_info *pinfo, proto_tree *tree, guint8 *drep)
680 guint32 u32ArraySize;
681 guint32 u32ArraySize2;
683 guint32 u32VariableOffset;
686 proto_item *sub_item;
687 proto_tree *sub_tree;
689 guint32 u32ArrayCount;
692 guint32 u32ExtentSize;
694 const char *uuid_name;
697 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer);
699 if (u32Pointer == 0) {
703 offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
704 hf_dcom_extent_array_count, &u32ArrayCount);
705 offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
706 hf_dcom_extent_array_res, &u32ArrayRes);
708 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer);
710 if (u32Pointer == 0) {
714 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
717 u32VariableOffset = offset + u32ArraySize*4;
720 while (u32ArraySize--) {
721 sub_item = proto_tree_add_item(tree, hf_dcom_extent, tvb, offset, 0, FALSE);
722 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_extent);
723 u32SubStart = offset;
725 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
727 if(u32Pointer != 0) {
728 u32VariableOffset = dissect_dcom_DWORD(tvb, u32VariableOffset, pinfo, sub_tree, drep,
729 hf_dcom_extent_size, &u32ExtentSize);
731 dissect_dcom_UUID(tvb, u32VariableOffset, pinfo, NULL, drep,
732 hf_dcom_extent_id, &uuidExtend);
734 /* look for a registered uuid name */
735 if((uuid_name = guids_get_uuid_name(&uuidExtend)) != NULL) {
736 proto_tree_add_guid_format_value(sub_tree, hf_dcom_extent_id, tvb,
737 offset, sizeof(e_uuid_t), (e_guid_t *) &uuidExtend,
738 "%s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
740 uuidExtend.Data1, uuidExtend.Data2, uuidExtend.Data3,
741 uuidExtend.Data4[0], uuidExtend.Data4[1],
742 uuidExtend.Data4[2], uuidExtend.Data4[3],
743 uuidExtend.Data4[4], uuidExtend.Data4[5],
744 uuidExtend.Data4[6], uuidExtend.Data4[7]);
745 u32VariableOffset += 16;
747 u32VariableOffset = dissect_dcom_UUID(tvb, u32VariableOffset, pinfo, sub_tree, drep,
748 hf_dcom_extent_id, &uuidExtend);
752 u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, drep,
754 u32VariableOffset = dissect_dcom_nospec_data(tvb, u32VariableOffset, pinfo, sub_tree, drep, u32ArraySize2);
756 /* update subtree header */
757 if(uuid_name != NULL) {
758 proto_item_append_text(sub_item, "[%u]: %s, Bytes=%u",
759 u32Idx, uuid_name, u32ArraySize2);
761 proto_item_append_text(sub_item, "[%u]: Bytes=%u",
762 u32Idx, u32ArraySize2);
764 proto_item_set_len(sub_item, offset - u32SubStart);
766 /* update subtree header */
767 proto_item_append_text(sub_item, "[%u]: NULL", u32Idx);
768 proto_item_set_len(sub_item, offset - u32SubStart);
774 return u32VariableOffset;
778 /* dissect DCOM "this" (start of every DCOM request) */
780 dissect_dcom_this(tvbuff_t *tvb, int offset,
781 packet_info *pinfo, proto_tree *tree, guint8 *drep)
783 guint16 u16VersionMajor;
784 guint16 u16VersionMinor;
787 e_uuid_t uuidCausality;
788 proto_item *sub_item;
789 proto_tree *sub_tree;
792 dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
795 sub_item = proto_tree_add_protocol_format(tree, proto_dcom, tvb, offset, 0,
797 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_this);
799 offset = dissect_dcom_COMVERSION(tvb, offset, pinfo, sub_tree, drep,
800 &u16VersionMajor, &u16VersionMinor);
801 u32SubStart = offset - 4;
803 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
804 hf_dcom_this_flags, &u32Flags);
805 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
806 hf_dcom_this_res, &u32Res);
808 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
809 hf_dcom_this_cid, &uuidCausality);
811 offset = dissect_dcom_extent(tvb, offset, pinfo, sub_tree, drep);
813 /* update subtree header */
814 proto_item_append_text(sub_item, ", V%u.%u, Causality ID: %s",
815 u16VersionMajor, u16VersionMinor, guids_resolve_uuid_to_str(&uuidCausality));
816 proto_item_set_len(sub_item, offset - u32SubStart);
818 if(memcmp(&info->call_data->object_uuid, &uuid_null, sizeof(uuid_null)) != 0) {
819 pi = proto_tree_add_guid_format(tree, hf_dcom_ipid, tvb, offset, 0,
820 (e_guid_t *) &info->call_data->object_uuid,
821 "Object UUID/IPID: %s", guids_resolve_uuid_to_str(&info->call_data->object_uuid));
822 PROTO_ITEM_SET_GENERATED(pi);
829 /* dissect DCOM "that" (start of every DCOM response) */
831 dissect_dcom_that(tvbuff_t *tvb, int offset,
832 packet_info *pinfo, proto_tree *tree, guint8 *drep) {
834 proto_item *sub_item;
835 proto_tree *sub_tree;
838 dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
841 sub_item = proto_tree_add_protocol_format(tree, proto_dcom, tvb, offset, 0,
843 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_that);
845 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
846 hf_dcom_that_flags, &u32Flags);
847 u32SubStart = offset - 4;
849 offset = dissect_dcom_extent(tvb, offset, pinfo, sub_tree, drep);
851 /* update subtree header */
852 proto_item_set_len(sub_item, offset - u32SubStart);
854 if(memcmp(&info->call_data->object_uuid, &uuid_null, sizeof(uuid_null)) != 0) {
855 pi = proto_tree_add_guid_format(tree, hf_dcom_ipid, tvb, offset, 0,
856 (e_guid_t *) &info->call_data->object_uuid,
857 "Object UUID/IPID: %s", guids_resolve_uuid_to_str(&info->call_data->object_uuid));
858 PROTO_ITEM_SET_GENERATED(pi);
865 /* dissect simple dcom request, DCOM "this" only */
867 dissect_dcom_simple_rqst(tvbuff_t *tvb, int offset,
868 packet_info *pinfo, proto_tree *tree, guint8 *drep)
871 offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
877 /* dissect simple dcom response, DCOM "that" and returned HRESULT only */
879 dissect_dcom_simple_resp(tvbuff_t *tvb, int offset,
880 packet_info *pinfo, proto_tree *tree, guint8 *drep)
885 offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
887 offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
890 if (check_col(pinfo->cinfo, COL_INFO)) {
891 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
892 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
899 /* dissect a dcerpc array size */
901 dissect_dcom_dcerpc_array_size(tvbuff_t *tvb, gint offset, packet_info *pinfo,
902 proto_tree *tree, guint8 *drep, guint32 *pu32ArraySize)
906 /* en-/disable this by preference setting */
907 if (!dcom_prefs_display_unmarshalling_details) {
908 /* this will read in the data, but prevent output to tree */
912 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
913 hf_dcom_array_size, pu32ArraySize);
919 /* dissect a dcerpc pointer value */
921 dissect_dcom_dcerpc_pointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
922 proto_tree *tree, guint8 *drep, guint32 *pu32Pointer)
925 /* en-/disable this by preference setting */
926 if (!dcom_prefs_display_unmarshalling_details) {
927 /* this will read in the data, but prevent output to tree */
931 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
932 hf_dcom_pointer_val, pu32Pointer);
938 /* mark data as "ToBeDone" */
939 /* XXX: handout data to generic "unkown data" dissector? */
941 dissect_dcom_tobedone_data(tvbuff_t *tvb, int offset,
942 packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int length)
947 item = proto_tree_add_bytes(tree, hf_dcom_tobedone, tvb, offset, length,
948 tvb_get_ptr(tvb, offset, length));
949 PROTO_ITEM_SET_GENERATED(item);
950 expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Dissection incomplete");
958 /* mark data as "No Specification Available" */
959 /* XXX: handout data to generic "unkown data" dissector? */
961 dissect_dcom_nospec_data(tvbuff_t *tvb, int offset,
962 packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int length)
967 item = proto_tree_add_bytes(tree, hf_dcom_nospec, tvb, offset, length,
968 tvb_get_ptr(tvb, offset, length));
969 PROTO_ITEM_SET_GENERATED(item);
970 expert_add_info_format(pinfo, item, PI_UNDECODED, PI_NOTE, "No specification available, dissection not possible");
978 /* dissect an indexed WORD, something like: "FieldName[1]: 0x1234" */
980 dissect_dcom_indexed_WORD(tvbuff_t *tvb, int offset, packet_info *pinfo,
981 proto_tree *tree, guint8 *drep,
982 int hfindex, guint16 * pu16WORD, int field_index)
987 /* dissect the WORD, but don't add to tree */
988 dissect_dcom_WORD(tvb, offset, pinfo, NULL /*tree*/, drep,
992 /* special formatted output of indexed value */
993 proto_tree_add_uint_format(tree, hfindex, tvb, offset, 2, (drep[0] & 0x10),
995 proto_registrar_get_name(hfindex),
996 field_index, u16WORD);
1002 *pu16WORD = u16WORD;
1008 /* dissect an indexed DWORD, something like: "FieldName[1]: 0x12345678" */
1010 dissect_dcom_indexed_DWORD(tvbuff_t *tvb, int offset, packet_info *pinfo,
1011 proto_tree *tree, guint8 *drep,
1012 int hfindex, guint32 * pu32DWORD, int field_index)
1017 /* dissect the DWORD, but don't add to tree */
1018 dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, drep,
1019 hfindex, &u32DWORD);
1022 /* special formatted output of indexed value */
1023 proto_tree_add_uint_format(tree, hfindex, tvb, offset, 4, (drep[0] & 0x10),
1025 proto_registrar_get_name(hfindex),
1026 field_index, u32DWORD);
1032 *pu32DWORD = u32DWORD;
1038 /* dissect hresult field of a usual DCOM call (create "raw" item) */
1040 dissect_dcom_HRESULT_item(tvbuff_t *tvb, int offset, packet_info *pinfo,
1041 proto_tree *tree, guint8 *drep,
1042 guint32 * pu32HResult, int field_index, proto_item **item)
1046 /* dissect the DWORD, but don't add to tree */
1047 offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, drep,
1048 field_index, &u32HResult);
1051 /* special formatted output of indexed value */
1052 *item = proto_tree_add_item (tree, field_index, tvb, offset-4, 4, (drep[0] & 0x10));
1056 *pu32HResult = u32HResult;
1062 /* dissect hresult field of a usual DCOM call (seperate method, because often used) */
1064 dissect_dcom_HRESULT(tvbuff_t *tvb, int offset, packet_info *pinfo,
1065 proto_tree *tree, guint8 *drep,
1066 guint32 * pu32HResult)
1069 proto_item *item = NULL;
1071 /* dissect the DWORD, but don't add to tree */
1072 offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, drep,
1073 hf_dcom_hresult, &u32HResult);
1076 /* special formatted output of indexed value */
1077 item = proto_tree_add_item (tree, hf_dcom_hresult, tvb, offset-4, 4, (drep[0] & 0x10));
1080 /* expert info only if severity is set */
1081 /* XXX - move this to the callers of this function, to provide a more detailed error output */
1082 if(u32HResult & 0x80000000) {
1083 expert_add_info_format(pinfo, item, PI_RESPONSE_CODE, PI_NOTE, "Hresult: %s",
1084 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%x)"));
1087 *pu32HResult = u32HResult;
1093 /* partial results of indexed DCOM subcalls (e.g.: from a kind of array) */
1095 dissect_dcom_indexed_HRESULT(tvbuff_t *tvb, int offset, packet_info *pinfo,
1096 proto_tree *tree, guint8 *drep,
1097 guint32 * pu32HResult, int field_index)
1100 proto_item *item = NULL;
1103 /* dissect the DWORD, but don't add to tree */
1104 offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, drep,
1105 hf_dcom_hresult, &u32HResult);
1108 /* special formatted output of indexed value */
1109 item = proto_tree_add_uint_format(tree, hf_dcom_hresult, tvb, offset-4, 4, u32HResult,
1110 "HResult[%u]: %s (0x%08x)", field_index,
1111 val_to_str(u32HResult, dcom_hresult_vals, "Unknown"),
1114 /* expert info only if severity flag is set */
1115 /* XXX - move this to the callers of this function, to provide a more detailed error output */
1116 if(u32HResult & 0x80000000) {
1117 expert_add_info_format(pinfo, item, PI_RESPONSE_CODE, PI_NOTE, "Hresult: %s",
1118 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%x)"));
1121 *pu32HResult = u32HResult;
1129 dissect_dcom_COMVERSION(tvbuff_t *tvb, int offset, packet_info *pinfo,
1130 proto_tree *tree, guint8 *drep,
1131 guint16 * pu16VersionMajor, guint16 * pu16VersionMinor)
1134 offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
1135 hf_dcom_version_major, pu16VersionMajor);
1136 offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
1137 hf_dcom_version_minor, pu16VersionMinor);
1144 dissect_dcom_SAFEARRAY(tvbuff_t *tvb, int offset, packet_info *pinfo,
1145 proto_tree *tree, guint8 *drep, int hfindex _U_, sa_callback_t sacb)
1149 guint16 u16Features;
1150 guint32 u32ElementSize;
1152 guint32 u32Elements;
1154 guint32 u32BoundElements;
1155 guint32 u32LowBound;
1157 guint32 u32ArraySize;
1159 guint32 u32VariableOffset;
1165 proto_item *sub_item;
1166 proto_tree *sub_tree;
1167 guint32 u32SubStart;
1168 guint32 u32TmpOffset;
1170 proto_item *feature_item;
1171 proto_tree *feature_tree;
1174 /* XXX: which alignment do we need here? */
1176 sub_item = proto_tree_add_item(tree, hf_dcom_safearray, tvb, offset, 0, FALSE);
1177 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_safearray);
1178 u32SubStart = offset;
1180 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1181 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1183 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1184 hf_dcom_sa_dims32, &u32Dims);
1185 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1186 hf_dcom_sa_dims16, &u16Dims);
1189 u32TmpOffset = dissect_dcom_WORD(tvb, offset, pinfo, NULL, drep,
1190 hf_dcom_sa_features, &u16Features);
1191 feature_item = proto_tree_add_uint (sub_tree, hf_dcom_sa_features, tvb, offset, 2, u16Features);
1192 feature_tree = proto_item_add_subtree (feature_item, ett_dcom_sa_features);
1194 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_variant, tvb, offset, 2, u16Features);
1195 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_dispatch, tvb, offset, 2, u16Features);
1196 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_unknown, tvb, offset, 2, u16Features);
1197 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_bstr, tvb, offset, 2, u16Features);
1198 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_have_vartype, tvb, offset, 2, u16Features);
1199 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_have_iid, tvb, offset, 2, u16Features);
1200 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_record, tvb, offset, 2, u16Features);
1201 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_fixedsize, tvb, offset, 2, u16Features);
1202 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_embedded, tvb, offset, 2, u16Features);
1203 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_static, tvb, offset, 2, u16Features);
1204 proto_tree_add_boolean (feature_tree, hf_dcom_sa_features_auto, tvb, offset, 2, u16Features);
1206 offset = u32TmpOffset;
1208 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1209 hf_dcom_sa_element_size, &u32ElementSize);
1210 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1211 hf_dcom_sa_locks, &u16Locks);
1212 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1213 hf_dcom_sa_vartype16, &u16VarType);
1214 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1215 hf_dcom_sa_vartype32, &u32VarType);
1216 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1217 hf_dcom_sa_elements, &u32Elements);
1218 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1221 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1222 hf_dcom_sa_bound_elements, &u32BoundElements);
1223 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1224 hf_dcom_sa_low_bound, &u32LowBound);
1227 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, drep, &u32ArraySize);
1229 tvb_ensure_bytes_exist(tvb, offset, u32ArraySize * u32ElementSize);
1230 u32VariableOffset = offset + u32ArraySize * u32ElementSize;
1233 sacb(tvb, offset, pinfo, tree, drep, u32VarType, u32ArraySize);
1236 u32Tmp = u32ArraySize;
1237 while(u32ArraySize--) {
1238 switch(u32VarType) {
1239 case(WIRESHARK_VT_ERROR):
1240 offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, drep,
1243 case(WIRESHARK_VT_I1):
1244 offset = dissect_dcom_BYTE(tvb, offset, pinfo, sub_tree, drep,
1245 hf_dcom_vt_i1, &u8Data);
1247 case(WIRESHARK_VT_I2):
1248 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1249 hf_dcom_vt_i2, &u16Data);
1251 case(WIRESHARK_VT_I4):
1252 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1253 hf_dcom_vt_i4, &u32Data);
1255 case(WIRESHARK_VT_I8):
1256 offset = dissect_dcom_I8(tvb, offset, pinfo, sub_tree, drep,
1257 hf_dcom_vt_i8, NULL);
1258 /* take care of the 8 byte alignment */
1259 u32VariableOffset = offset;
1261 case(WIRESHARK_VT_BSTR):
1262 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1264 u32VariableOffset = dissect_dcom_BSTR(tvb, u32VariableOffset, pinfo, sub_tree, drep,
1265 hf_dcom_vt_bstr, cData, sizeof(cData) );
1269 /* XXX: other types possible, but still not implemented:
1274 VT_UNKNOWN|VT_RESERVED
1276 u32VariableOffset = dissect_dcom_tobedone_data(tvb, u32VariableOffset, pinfo, sub_tree, drep,
1281 /* update subtree header */
1282 proto_item_append_text(sub_item, ": Elements: %u/%u VarType: %s",
1283 u32Elements, u32BoundElements,
1284 val_to_str(u32VarType, dcom_variant_type_vals, "Unknown (0x%08x)") );
1286 proto_item_set_len(sub_item, u32VariableOffset - u32SubStart);
1288 return u32VariableOffset;
1294 dissect_dcom_VARTYPE(tvbuff_t *tvb, int offset, packet_info *pinfo,
1295 proto_tree *tree, guint8 *drep,
1296 guint16 *pu16VarType)
1299 offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
1300 hf_dcom_variant_type, pu16VarType);
1307 dissect_dcom_VARIANT(tvbuff_t *tvb, int offset, packet_info *pinfo,
1308 proto_tree *tree, guint8 *drep, int hfindex)
1313 guint32 u32SubStart;
1314 proto_item *sub_item;
1315 proto_tree *sub_tree;
1328 /* alignment of 8 needed for a VARIANT */
1330 offset += 8 - (offset % 8);
1333 sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, FALSE);
1334 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_variant);
1335 u32SubStart = offset;
1337 /* the following size can be VERY confusing:
1338 * It is NOT the maximum size of the variant, as one could expect,
1339 * but the current size of the variant padded to 8 bytes.
1340 * BUT: The following data does not start AFTER this padding,
1341 * it starts just after the variant-data (without padding)!!! */
1342 /* Conclusion: the size given here can be LONGER than the actual size */
1343 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1344 hf_dcom_variant_size, &u32Size);
1345 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1346 hf_dcom_variant_rpc_res, &u32RPCRes);
1347 offset = dissect_dcom_VARTYPE(tvb, offset, pinfo, sub_tree, drep,
1349 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1350 hf_dcom_variant_wres, &u16Res);
1351 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1352 hf_dcom_variant_wres, &u16Res);
1353 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1354 hf_dcom_variant_wres, &u16Res);
1356 /* 32 bit VarType (slightly different to the 16 bit one) */
1357 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1358 hf_dcom_variant_type32, &u32VarType);
1360 if (u32VarType & WIRESHARK_VT_BYREF) {
1361 u32VarType &=~WIRESHARK_VT_BYREF;
1362 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1365 switch (u32VarType) {
1366 case(WIRESHARK_VT_EMPTY):
1368 case(WIRESHARK_VT_BOOL):
1369 offset = dissect_dcom_VARIANT_BOOL(tvb, offset, pinfo, sub_tree, drep,
1370 hf_dcom_vt_bool, &u16Data);
1372 case(WIRESHARK_VT_I1):
1373 offset = dissect_dcom_BYTE(tvb, offset, pinfo, sub_tree, drep,
1374 hf_dcom_vt_i1, &u8Data);
1376 case(WIRESHARK_VT_UI1):
1377 offset = dissect_dcom_BYTE(tvb, offset, pinfo, sub_tree, drep,
1378 hf_dcom_vt_ui1, &u8Data);
1380 case(WIRESHARK_VT_I2):
1381 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1382 hf_dcom_vt_i2, &u16Data);
1384 case(WIRESHARK_VT_UI2):
1385 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1386 hf_dcom_vt_ui2, &u16Data);
1388 case(WIRESHARK_VT_I4):
1389 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1390 hf_dcom_vt_i4, &u32Data);
1392 case(WIRESHARK_VT_UI4):
1393 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1394 hf_dcom_vt_ui4, &u32Data);
1396 case(WIRESHARK_VT_R4):
1397 offset = dissect_dcom_FLOAT(tvb, offset, pinfo, sub_tree, drep,
1398 hf_dcom_vt_r4, &f32Data);
1400 case(WIRESHARK_VT_R8):
1401 offset = dissect_dcom_DOUBLE(tvb, offset, pinfo, sub_tree, drep,
1402 hf_dcom_vt_r8, &f64Data);
1404 case(WIRESHARK_VT_DATE):
1405 offset = dissect_dcom_DATE(tvb, offset, pinfo, sub_tree, drep,
1406 hf_dcom_vt_date, &f64Data);
1408 case(WIRESHARK_VT_BSTR):
1409 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1411 offset = dissect_dcom_BSTR(tvb, offset, pinfo, sub_tree, drep,
1412 hf_dcom_vt_bstr, cData, sizeof(cData) );
1415 case(WIRESHARK_VT_DISPATCH):
1416 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1418 offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, sub_tree, drep,
1419 hf_dcom_vt_dispatch, NULL); /* XXX - how to handle this? */
1422 case(WIRESHARK_VT_ARRAY):
1423 offset = dissect_dcom_SAFEARRAY(tvb, offset, pinfo, sub_tree, drep,
1426 case(WIRESHARK_VT_ERROR):
1427 offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, drep,
1430 case(WIRESHARK_VT_VARIANT):
1431 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1433 offset = dissect_dcom_VARIANT(tvb, offset, pinfo, sub_tree, drep,
1434 hf_dcom_vt_byref /* must be BYREF */);
1437 case(WIRESHARK_VT_UNKNOWN):
1438 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
1441 /* XXX: add more types here! */
1442 offset = dissect_dcom_tobedone_data(tvb, offset, pinfo, sub_tree, drep,
1446 /* update subtree header */
1447 proto_item_append_text(sub_item, ": %s",
1448 val_to_str(u16VarType, dcom_variant_type_vals, "Unknown (0x%08x)") );
1450 proto_item_set_len(sub_item, offset - u32SubStart);
1457 dissect_dcom_UUID(tvbuff_t *tvb, int offset,
1458 packet_info *pinfo, proto_tree *tree, guint8 *drep,
1459 int hfindex, e_uuid_t *pdata)
1461 const gchar *uuid_name;
1462 header_field_info *hfi;
1466 /* get the UUID, but don't put it into the tree */
1467 offset = dissect_ndr_uuid_t(tvb, offset, pinfo, NULL, drep,
1470 /* add to the tree */
1471 hfi = proto_registrar_get_nth(hfindex);
1472 uuid_name = guids_get_uuid_name(&uuid);
1474 proto_tree_add_guid_format(tree, hfindex, tvb, offset-16, 16, (e_guid_t *) &uuid,
1475 "%s: %s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
1476 hfi->name, uuid_name,
1477 uuid.Data1, uuid.Data2, uuid.Data3,
1478 uuid.Data4[0], uuid.Data4[1],
1479 uuid.Data4[2], uuid.Data4[3],
1480 uuid.Data4[4], uuid.Data4[5],
1481 uuid.Data4[6], uuid.Data4[7]);
1483 proto_tree_add_guid_format(tree, hfindex, tvb, offset-16, 16, (e_guid_t *) &uuid,
1484 "%s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1486 uuid.Data1, uuid.Data2, uuid.Data3,
1487 uuid.Data4[0], uuid.Data4[1],
1488 uuid.Data4[2], uuid.Data4[3],
1489 uuid.Data4[4], uuid.Data4[5],
1490 uuid.Data4[6], uuid.Data4[7]);
1502 dissect_dcom_append_UUID(tvbuff_t *tvb, int offset,
1503 packet_info *pinfo, proto_tree *tree, guint8 *drep,
1504 int hfindex, int field_index, e_uuid_t *uuid)
1506 const gchar *uuid_name;
1508 header_field_info *hfi;
1511 /* XXX - this is far from being performance optimized! */
1513 /* get the UUID, but don't put it into the tree */
1514 offset = dissect_ndr_uuid_t(tvb, offset, pinfo, NULL, drep,
1517 /* look for a registered uuid name */
1518 uuid_name = guids_get_uuid_name(uuid);
1520 /* add to the tree */
1521 hfi = proto_registrar_get_nth(hfindex);
1522 pi = proto_tree_add_guid_format(tree, hfindex, tvb, offset-16, 16, (e_guid_t *) uuid, "%s", hfi->name);
1524 if (field_index != -1) {
1525 proto_item_append_text(pi, "[%u]: ", field_index);
1527 proto_item_append_text(pi, ": ");
1531 proto_item_append_text(pi, "%s (", uuid_name);
1534 proto_item_append_text(pi, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1535 uuid->Data1, uuid->Data2, uuid->Data3,
1536 uuid->Data4[0], uuid->Data4[1],
1537 uuid->Data4[2], uuid->Data4[3],
1538 uuid->Data4[4], uuid->Data4[5],
1539 uuid->Data4[6], uuid->Data4[7]);
1542 proto_item_append_text(pi, ")");
1545 /* update column info now */
1546 if (check_col(pinfo->cinfo, COL_INFO)) {
1547 if (field_index != -1) {
1548 col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%u]=%s",
1549 hfi->name, field_index, (uuid_name) ? uuid_name : "???");
1551 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%s",
1552 hfi->name, (uuid_name) ? uuid_name : "???");
1560 /* get a wide character string from tvb (zero terminated or limited through inLength) */
1561 /* the string will be converted to ASCII if possible or simple hexdump otherwise */
1562 /* outLength is in output bytes including zero termination output */
1564 dcom_tvb_get_nwstringz0(tvbuff_t *tvb, gint offset, guint32 inLength, gchar *pszStr, guint32 outLength, gboolean *isPrintable)
1574 *isPrintable = TRUE;
1576 /* we must have at least the space for the zero termination */
1577 DISSECTOR_ASSERT(outLength >= 1);
1579 /* determine length and printablility of the string */
1580 for(u32Idx = 0; u32Idx < inLength-1; u32Idx+=2) {
1581 /* the marshalling direction of a WCHAR is fixed! */
1582 u8Tmp1 = tvb_get_guint8(tvb, offset+u32Idx);
1583 u8Tmp2 = tvb_get_guint8(tvb, offset+u32Idx+1);
1585 /* is this the zero termination? */
1586 if (u8Tmp1 == 0 && u8Tmp2 == 0) {
1591 /* is this character printable? */
1592 /* XXX - there are probably more printable chars than isprint() */
1593 if(!isprint(u8Tmp1) || u8Tmp2 != 0) {
1594 *isPrintable = FALSE;
1598 /* u32Idx now contains the string length in bytes */
1599 /* (including optional zero termination) */
1601 /* if this is a printable string? */
1602 if(*isPrintable == TRUE) {
1603 /* convert to ascii (every "2nd char") */
1604 /* XXX - is it possible to convert to UTF8, so the output functions work with it? */
1605 for(u32IdxA = 0, u32IdxW = 0;
1606 u32IdxW < u32Idx && u32IdxA < outLength-2;
1607 u32IdxW+=2, u32IdxA++) {
1608 pszStr[u32IdxA] = tvb_get_guint8(tvb, offset+u32IdxW);
1611 /* convert to hexdump */
1612 for(u32IdxA = 0, u32IdxW = 0;
1613 u32IdxW < u32Idx && u32IdxA < outLength-2;
1614 u32IdxW++, u32IdxA+=2) {
1615 g_snprintf(&pszStr[u32IdxA], 3, "%02X", tvb_get_guint8(tvb, offset+u32IdxW));
1619 /* zero terminate the string, space must be available */
1620 DISSECTOR_ASSERT(u32IdxA < outLength);
1621 pszStr[u32IdxA] = 0;
1623 return offset + u32Idx;
1627 /* dissect a LPWSTR into a given buffer */
1628 /* use FT_STRING for hfindex */
1629 /* u32MaxStr is maximum length of string (including trailing zero) */
1631 dissect_dcom_indexed_LPWSTR(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1632 proto_tree *tree, guint8 *drep, int hfindex,
1633 gchar *pszStr, guint32 u32MaxStr, int field_index)
1635 guint32 u32MaxCount;
1637 guint32 u32ArraySize;
1638 guint32 u32StrStart;
1639 proto_item *sub_item;
1640 proto_tree *sub_tree;
1641 guint32 u32SubStart;
1642 gboolean isPrintable;
1645 /* alignment of 4 needed */
1647 offset += 4 - (offset % 4);
1650 /* add subtree item */
1651 sub_item = proto_tree_add_string(tree, hfindex, tvb, offset, 0, "");
1652 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_lpwstr);
1653 u32SubStart = offset;
1655 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1656 hf_dcom_max_count, &u32MaxCount);
1657 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1658 hf_dcom_offset, &u32Offset);
1659 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, drep,
1662 u32StrStart = offset;
1663 offset = dcom_tvb_get_nwstringz0(tvb, offset, u32ArraySize*2, pszStr, u32MaxStr, &isPrintable);
1665 proto_tree_add_string(sub_tree, hfindex, tvb, u32StrStart, offset - u32StrStart, pszStr);
1667 /* update subtree header */
1668 if (field_index != -1) {
1669 proto_item_set_text(sub_item, "%s[%u]: %s%s%s",
1670 proto_registrar_get_name(hfindex),
1672 isPrintable ? "\"" : "", pszStr, isPrintable ? "\"" : "");
1674 proto_item_append_text(sub_item, "%s%s%s",
1675 isPrintable ? "\"" : "", pszStr, isPrintable ? "\"" : "");
1677 proto_item_set_len(sub_item, offset - u32SubStart);
1684 dissect_dcom_LPWSTR(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1685 proto_tree *tree, guint8 *drep, int hfindex,
1686 gchar *pszStr, guint32 u32MaxStr)
1690 return dissect_dcom_indexed_LPWSTR(tvb, offset, pinfo, tree, drep,
1691 hfindex, pszStr, u32MaxStr, -1);
1695 /* dissect a BSTR to tree and into a given buffer (use FT_STRING for hfindex) */
1696 /* u32MaxStr is maximum length of string (including trailing zero) */
1697 /* (Hint: the BSTR space is always as long as the maximum size) */
1699 dissect_dcom_BSTR(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1700 proto_tree *tree, guint8 *drep, int hfindex,
1701 gchar *pszStr, guint32 u32MaxStr)
1703 guint32 u32MaxCount;
1704 guint32 u32ArraySize;
1705 guint32 u32StrStart;
1706 proto_item *sub_item;
1707 proto_tree *sub_tree;
1708 guint32 u32SubStart;
1709 guint32 u32ByteLength;
1710 guint32 u32RealOffset;
1711 gboolean isPrintable;
1713 /* alignment of 4 needed */
1715 offset += 4 - (offset % 4);
1718 /* add subtree item */
1719 sub_item = proto_tree_add_string(tree, hfindex, tvb, offset, 0, "");
1720 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_lpwstr);
1721 u32SubStart = offset;
1723 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1724 hf_dcom_max_count, &u32MaxCount);
1725 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1726 hf_dcom_byte_length, &u32ByteLength);
1727 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, drep,
1730 u32RealOffset = offset + u32ArraySize*2;
1732 u32StrStart = offset;
1733 offset = dcom_tvb_get_nwstringz0(tvb, offset, u32ArraySize*2, pszStr, u32MaxStr, &isPrintable);
1735 proto_tree_add_string(sub_tree, hfindex, tvb, u32StrStart, offset - u32StrStart, pszStr);
1737 /* update subtree header */
1738 proto_item_append_text(sub_item, "%s%s%s",
1739 isPrintable ? "\"" : "", pszStr, isPrintable ? "\"" : "");
1740 if ((int) (u32RealOffset - u32SubStart) <= 0)
1741 THROW(ReportedBoundsError);
1742 proto_item_set_len(sub_item, u32RealOffset - u32SubStart);
1744 return u32RealOffset;
1748 /* dissect an DUALSTRINGARRAY */
1750 dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1751 proto_tree *tree, guint8 *drep, int hfindex, gchar *ip)
1753 guint16 u16NumEntries;
1754 guint16 u16SecurityOffset;
1756 guint32 u32MaxStr = sizeof(szStr);
1759 guint16 u16SecurityAuthnSvc;
1760 guint16 u16SecurityAuthzSvc;
1761 proto_item *sub_item;
1762 proto_tree *sub_tree;
1763 guint32 u32SubStart;
1764 guint32 u32StringBindings = 0;
1765 guint32 u32SecurityBindings = 0;
1766 proto_item *subsub_item;
1767 proto_tree *subsub_tree;
1768 guint32 u32SubSubStart;
1769 gboolean isPrintable;
1770 guint32 first_ip = 0;
1771 guint32 curr_ip = 0;
1772 struct in_addr ipaddr;
1776 /* add subtree header */
1777 sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, FALSE);
1778 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_dualstringarray);
1780 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1781 hf_dcom_dualstringarray_num_entries, &u16NumEntries);
1782 /* from here, alignment is ok */
1783 u32SubStart = offset - 2;
1784 offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
1785 hf_dcom_dualstringarray_security_offset, &u16SecurityOffset);
1787 /* STRINGBINDINGs until first wchar zero */
1788 while ( tvb_get_ntohs(tvb, offset) ) {
1789 u32StringBindings++;
1791 subsub_item = proto_tree_add_item(sub_tree, hf_dcom_dualstringarray_string, tvb, offset, 0, FALSE);
1792 subsub_tree = proto_item_add_subtree(subsub_item, ett_dcom_dualstringarray_binding);
1793 u32SubSubStart = offset;
1795 offset = dissect_dcom_WORD(tvb, offset, pinfo, subsub_tree, drep,
1796 hf_dcom_dualstringarray_string_tower_id, &u16TowerId);
1798 /* we don't know the (zero terminated) input length, use the buffer length instead */
1799 offset = dcom_tvb_get_nwstringz0(tvb, offset, u32MaxStr, szStr, u32MaxStr, &isPrintable);
1800 pi = proto_tree_add_string(subsub_tree, hf_dcom_dualstringarray_string_network_addr,
1801 tvb, u32Start, offset - u32Start, szStr);
1803 /* convert ip address (if it is dotted decimal) */
1804 /* XXX - this conversion is ugly */
1805 if (inet_aton(szStr, &ipaddr)) {
1806 if(get_host_ipaddr(szStr, &curr_ip)) {
1807 curr_ip = g_ntohl(curr_ip);
1809 /*expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "DUALSTRINGARRAY: IP:%s",
1810 ip_to_str( (guint8 *) &curr_ip));*/
1814 memcpy(ip, &curr_ip, sizeof(curr_ip));
1818 if(first_ip != curr_ip) {
1819 expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE,
1820 "DUALSTRINGARRAY: multiple IP's %s %s",
1821 ip_to_str( (guint8 *) &first_ip), ip_to_str( (guint8 *) &curr_ip));
1827 proto_item_append_text(subsub_item, "[%u]: TowerId=%s, NetworkAddr=\"%s\"",
1829 val_to_str(u16TowerId, dcom_protseq_vals, "Unknown (0x%04x"),
1831 proto_item_set_len(subsub_item, offset - u32SubSubStart);
1835 /* SECURITYBINDINGs until first wchar zero */
1836 while ( tvb_get_ntohs(tvb, offset) ) {
1837 u32SecurityBindings++;
1839 subsub_item = proto_tree_add_item(sub_tree, hf_dcom_dualstringarray_security, tvb, offset, 0, FALSE);
1840 subsub_tree = proto_item_add_subtree(subsub_item, ett_dcom_dualstringarray_binding);
1841 u32SubSubStart = offset;
1843 offset = dissect_dcom_WORD(tvb, offset, pinfo, subsub_tree, drep,
1844 hf_dcom_dualstringarray_security_authn_svc,
1845 &u16SecurityAuthnSvc);
1846 offset = dissect_dcom_WORD(tvb, offset, pinfo, subsub_tree, drep,
1847 hf_dcom_dualstringarray_security_authz_svc,
1848 &u16SecurityAuthzSvc);
1851 /* we don't know the (zero terminated) input length, use the buffer length instead */
1852 offset = dcom_tvb_get_nwstringz0(tvb, offset, u32MaxStr, szStr, u32MaxStr, &isPrintable);
1853 proto_tree_add_string(subsub_tree, hf_dcom_dualstringarray_security_princ_name,
1854 tvb, u32Start, offset - u32Start, szStr);
1856 proto_item_append_text(subsub_item, "[%u]: AuthnSvc=0x%04x, AuthzSvc=0x%04x, PrincName=\"%s\"",
1857 u32SecurityBindings, u16SecurityAuthnSvc, u16SecurityAuthzSvc, szStr);
1858 proto_item_set_len(subsub_item, offset - u32SubSubStart);
1862 /* append info to subtree header */
1863 proto_item_append_text(sub_item, ": STRINGBINDINGs=%u, SECURITYBINDINGs=%u",
1864 u32StringBindings, u32SecurityBindings);
1865 proto_item_set_len(sub_item, offset - u32SubStart);
1871 /* dissect an STDOBJREF */
1873 dissect_dcom_STDOBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1874 proto_tree *tree, guint8 *drep, int hfindex _U_,
1875 guint64 *oxid, guint64 *oid, e_uuid_t *ipid)
1878 guint32 u32PublicRefs;
1879 proto_item *sub_item;
1880 proto_tree *sub_tree;
1881 guint32 u32SubStart;
1884 /* add subtree header */
1885 sub_item = proto_tree_add_item(tree, hf_dcom_stdobjref, tvb, offset, 0, FALSE);
1886 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_stdobjref);
1888 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1889 hf_dcom_stdobjref_flags, &u32Flags);
1890 /* from here, alignment is ok */
1891 u32SubStart = offset - 4;
1892 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1893 hf_dcom_stdobjref_public_refs, &u32PublicRefs);
1894 offset = dissect_dcom_ID(tvb, offset, pinfo, sub_tree, drep,
1895 hf_dcom_oxid, oxid);
1896 offset = dissect_dcom_ID(tvb, offset, pinfo, sub_tree, drep,
1898 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
1899 hf_dcom_ipid, ipid);
1901 /* append info to subtree header */
1902 proto_item_append_text(sub_item, ": PublicRefs=%u IPID=%s",
1903 u32PublicRefs, guids_resolve_uuid_to_str(ipid));
1904 proto_item_set_len(sub_item, offset - u32SubStart);
1910 /* dissect an OBJREF */
1912 dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1913 proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
1915 guint32 u32Signature;
1919 proto_item *sub_item;
1920 proto_tree *sub_tree;
1921 guint32 u32SubStart;
1922 guint32 u32CBExtension;
1927 dcom_interface_t *dcom_if = NULL;
1931 /* add subtree header */
1932 sub_item = proto_tree_add_item(tree, hf_dcom_objref, tvb, offset, 0, FALSE);
1933 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_objref);
1935 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1936 hf_dcom_objref_signature, &u32Signature);
1937 /* from here, alignment is ok */
1938 u32SubStart = offset - 4;
1939 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1940 hf_dcom_objref_flags, &u32Flags);
1941 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
1945 case(0x1): /* standard */
1946 offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex,
1947 &oxid, &oid, &ipid);
1948 offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, sub_tree, drep,
1949 hf_dcom_objref_resolver_address, ip);
1951 case(0x2): /* handler (untested) */
1952 offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex,
1954 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
1955 hf_dcom_clsid, &clsid);
1956 offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, sub_tree, drep,
1957 hf_dcom_objref_resolver_address, ip);
1959 case(0x4): /* custom */
1960 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
1961 hf_dcom_clsid, &clsid);
1962 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1963 hf_dcom_objref_cbextension, &u32CBExtension);
1964 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
1965 hf_dcom_objref_size, &u32Size);
1966 /* the following data depends on the CLSID, no docs available on this */
1967 offset = dissect_dcom_nospec_data(tvb, offset, pinfo, sub_tree, drep, u32Size);
1971 if(u32Flags == 0x1 || u32Flags == 0x2) {
1972 /* add interface instance to database (we currently only handle IPv4) */
1973 if(pinfo->net_src.type == AT_IPv4) {
1974 dcom_if = dcom_interface_new(pinfo,
1976 &iid, oxid, oid, &ipid);
1980 if(interf != NULL) {
1984 /* append info to subtree header */
1985 proto_item_set_len(sub_item, offset - u32SubStart);
1992 /* dissect an MInterfacePointer */
1994 dissect_dcom_MInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1995 proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
1998 guint32 u32ArraySize;
1999 proto_item *sub_item;
2000 proto_tree *sub_tree;
2001 guint32 u32SubStart;
2005 hfindex = hf_dcom_interface_pointer;
2008 /* add subtree header */
2009 sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, FALSE);
2010 sub_tree = proto_item_add_subtree(sub_item, ett_dcom_interface_pointer);
2012 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
2013 hf_dcom_ip_cnt_data, &u32CntData);
2014 u32SubStart = offset - 4;
2016 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, drep, &u32ArraySize);
2018 offset = dissect_dcom_OBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex, interf);
2020 /* append info to subtree header */
2021 proto_item_set_len(sub_item, offset - u32SubStart);
2027 /* dissect a pointer to a MInterfacePointer */
2029 dissect_dcom_PMInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
2030 proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
2035 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer);
2038 offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, hfindex, interf);
2040 if(interf != NULL) {
2049 static void dcom_reinit( void) {
2050 dcom_machines = NULL;
2051 dcom_interfaces = NULL;
2056 proto_register_dcom (void)
2059 static hf_register_info hf_dcom_this_array[] = {
2060 { &hf_dcom_this_version_major,
2061 { "VersionMajor", "dcom.this.version_major", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2062 { &hf_dcom_this_version_minor,
2063 { "VersionMinor", "dcom.this.version_minor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2064 { &hf_dcom_this_flags,
2065 { "Flags", "dcom.this.flags", FT_UINT32, BASE_HEX, VALS(dcom_thisthat_flag_vals), 0x0, "", HFILL }},
2066 { &hf_dcom_this_res,
2067 { "Reserved", "dcom.this.res", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2068 { &hf_dcom_this_cid,
2069 { "Causality ID", "dcom.this.uuid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }}
2072 static hf_register_info hf_dcom_that_array[] = {
2073 { &hf_dcom_that_flags,
2074 { "Flags", "dcom.that.flags", FT_UINT32, BASE_HEX, VALS(dcom_thisthat_flag_vals), 0x0, "", HFILL }}
2077 static hf_register_info hf_dcom_extent_array[] = {
2079 { "Extension", "dcom.extent", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2080 { &hf_dcom_extent_array_count,
2081 { "Extension Count", "dcom.extent.array_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2082 { &hf_dcom_extent_array_res,
2083 { "Reserved", "dcom.extent.array_res", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2084 { &hf_dcom_extent_size,
2085 { "Extension Size", "dcom.extent.size", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2086 { &hf_dcom_extent_id,
2087 { "Extension Id", "dcom.extent.id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }}
2090 static hf_register_info hf_dcom_array[] = {
2091 { &hf_dcom_version_major,
2092 { "VersionMajor", "dcom.version_major", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2093 { &hf_dcom_version_minor,
2094 { "VersionMinor", "dcom.version_minor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2096 { "HResult", "dcom.hresult", FT_UINT32, BASE_HEX, VALS(dcom_hresult_vals), 0x0, "", HFILL }},
2097 { &hf_dcom_max_count,
2098 { "MaxCount", "dcom.max_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2100 { "Offset", "dcom.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2101 { &hf_dcom_byte_length,
2102 { "ByteLength", "dcom.byte_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2103 { &hf_dcom_actual_count,
2104 { "ActualCount", "dcom.actual_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2105 { &hf_dcom_tobedone,
2106 { "To Be Done", "dcom.tobedone", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2108 { "No Specification Available", "dcom.nospec", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2110 { "Variant", "dcom.variant", FT_NONE, BASE_HEX, NULL, 0x0, "", HFILL }},
2111 { &hf_dcom_variant_type,
2112 { "VarType", "dcom.variant_type", FT_UINT16, BASE_HEX, VALS(dcom_variant_type_vals), 0x0, "", HFILL }},
2113 { &hf_dcom_variant_type32,
2114 { "VarType32", "dcom.variant_type32", FT_UINT32, BASE_HEX, VALS(dcom_variant_type_vals), 0x0, "", HFILL }},
2115 { &hf_dcom_variant_size,
2116 { "Size", "dcom.variant_size", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2117 { &hf_dcom_variant_rpc_res,
2118 { "RPC-Reserved", "dcom.variant_rpc_res", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2119 { &hf_dcom_variant_wres,
2120 { "Reserved", "dcom.variant_wres", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2121 { &hf_dcom_array_size,
2122 { "(ArraySize)", "dcom.array_size", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2123 { &hf_dcom_pointer_val,
2124 { "(PointerVal)", "dcom.pointer_val", FT_UINT32, BASE_HEX, VALS(dcom_dcerpc_pointer_vals), 0x0, "", HFILL }}
2127 static hf_register_info hf_dcom_interface_pointer_array[] = {
2128 { &hf_dcom_interface_pointer,
2129 { "InterfacePointer", "dcom.ifp", FT_NONE, BASE_HEX, NULL, 0x0, "", HFILL }},
2130 { &hf_dcom_ip_cnt_data,
2131 { "CntData", "dcom.ip_cnt_data", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
2134 static hf_register_info hf_dcom_objref_array[] = {
2136 { "OBJREF", "dcom.objref", FT_NONE, BASE_HEX, NULL, 0x0, "", HFILL }},
2137 { &hf_dcom_objref_signature,
2138 { "Signature", "dcom.objref.signature", FT_UINT32, BASE_HEX, VALS(dcom_objref_signature_vals), 0x0, "", HFILL }},
2139 { &hf_dcom_objref_flags,
2140 { "Flags", "dcom.objref.flags", FT_UINT32, BASE_HEX, VALS(dcom_objref_flag_vals), 0x0, "", HFILL }},
2142 { "IID", "dcom.iid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
2144 { "CLSID", "dcom.clsid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
2145 { &hf_dcom_objref_resolver_address,
2146 { "ResolverAddress", "dcom.objref.resolver_address", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2147 { &hf_dcom_objref_cbextension,
2148 { "CBExtension", "dcom.objref.cbextension", FT_UINT32, BASE_DEC, NULL, 0x0, "Size of extension data", HFILL }},
2149 { &hf_dcom_objref_size,
2150 { "Size", "dcom.objref.size", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
2153 static hf_register_info hf_dcom_stdobjref_array[] = {
2154 { &hf_dcom_stdobjref,
2155 { "STDOBJREF", "dcom.stdobjref", FT_NONE, BASE_HEX, NULL, 0x0, "", HFILL }},
2156 { &hf_dcom_stdobjref_flags,
2157 { "Flags", "dcom.stdobjref.flags", FT_UINT32, BASE_HEX, VALS(dcom_stdobjref_flag_vals), 0x0, "", HFILL }},
2158 { &hf_dcom_stdobjref_public_refs,
2159 { "PublicRefs", "dcom.stdobjref.public_refs", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2161 { "OXID", "dcom.oxid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
2163 { "OID", "dcom.oid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
2165 { "IPID", "dcom.ipid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }}
2168 static hf_register_info hf_dcom_dualstringarray_array[] = {
2169 { &hf_dcom_dualstringarray_num_entries,
2170 { "NumEntries", "dcom.dualstringarray.num_entries", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2171 { &hf_dcom_dualstringarray_security_offset,
2172 { "SecurityOffset", "dcom.dualstringarray.security_offset", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2173 { &hf_dcom_dualstringarray_string,
2174 { "StringBinding", "dcom.dualstringarray.string", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2175 { &hf_dcom_dualstringarray_string_tower_id,
2176 { "TowerId", "dcom.dualstringarray.tower_id", FT_UINT16, BASE_HEX, VALS(dcom_protseq_vals), 0x0, "", HFILL }},
2177 { &hf_dcom_dualstringarray_string_network_addr,
2178 { "NetworkAddr", "dcom.dualstringarray.network_addr", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
2179 { &hf_dcom_dualstringarray_security,
2180 { "SecurityBinding", "dcom.dualstringarray.security", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2181 { &hf_dcom_dualstringarray_security_authn_svc,
2182 { "AuthnSvc", "dcom.dualstringarray.security_authn_svc", FT_UINT16, BASE_HEX, VALS(dcom_dualstringarray_authn), 0x0, "", HFILL }},
2183 { &hf_dcom_dualstringarray_security_authz_svc,
2184 { "AuthzSvc", "dcom.dualstringarray.security_authz_svc", FT_UINT16, BASE_HEX, VALS(dcom_dualstringarray_authz), 0x0, "", HFILL }},
2185 { &hf_dcom_dualstringarray_security_princ_name,
2186 { "PrincName", "dcom.dualstringarray.security_princ_name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
2189 static hf_register_info hf_dcom_vt_array[] = {
2191 { "VT_BOOL", "dcom.vt.bool", FT_UINT16, BASE_HEX, VALS(dcom_vt_bool_vals), 0x0, "", HFILL }},
2193 { "VT_I1", "dcom.vt.i1", FT_INT8, BASE_DEC, NULL, 0x0, "", HFILL }},
2195 { "VT_I2", "dcom.vt.i2", FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2197 { "VT_I4", "dcom.vt.i4", FT_INT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2199 { "VT_I8", "dcom.vt.i8", FT_INT64, BASE_DEC, NULL, 0x0, "", HFILL }},
2201 { "VT_UI1", "dcom.vt.ui1", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
2203 { "VT_UI2", "dcom.vt.ui2", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2205 { "VT_UI4", "dcom.vt.ui4", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2207 { "VT_R4", "dcom.vt.r4", FT_FLOAT, BASE_NONE, NULL, 0x0, "", HFILL }},
2209 { "VT_R8", "dcom.vt.r8", FT_DOUBLE, BASE_NONE, NULL, 0x0, "", HFILL }},
2211 { "VT_DATE", "dcom.vt.date", FT_DOUBLE, BASE_NONE, NULL, 0x0, "", HFILL }},
2213 { "VT_BSTR", "dcom.vt.bstr", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
2214 { &hf_dcom_vt_byref,
2215 { "BYREF", "dcom.vt.byref", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2216 { &hf_dcom_vt_dispatch,
2217 { "VT_DISPATCH", "dcom.vt.dispatch", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}
2220 static hf_register_info hf_dcom_sa_array[] = {
2221 { &hf_dcom_safearray,
2222 { "SAFEARRAY", "dcom.sa", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2223 { &hf_dcom_sa_dims32,
2224 { "Dims32", "dcom.sa.dims32", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2225 { &hf_dcom_sa_dims16,
2226 { "Dims16", "dcom.sa.dims16", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2227 { &hf_dcom_sa_features,
2228 { "Features", "dcom.sa.features", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2229 { &hf_dcom_sa_element_size,
2230 { "ElementSize", "dcom.sa.element_size", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2231 { &hf_dcom_sa_locks,
2232 { "Locks", "dcom.sa.locks", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2233 { &hf_dcom_sa_vartype32,
2234 { "VarType32", "dcom.sa.vartype", FT_UINT32, BASE_DEC, VALS(dcom_variant_type_vals), 0x0, "", HFILL }},
2235 { &hf_dcom_sa_vartype16,
2236 { "VarType16", "dcom.sa.vartype", FT_UINT16, BASE_DEC, VALS(dcom_variant_type_vals), 0x0, "", HFILL }},
2237 { &hf_dcom_sa_elements,
2238 { "Elements", "dcom.sa.elements", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2239 { &hf_dcom_sa_bound_elements,
2240 { "BoundElements", "dcom.sa.bound_elements", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2241 { &hf_dcom_sa_low_bound,
2242 { "LowBound", "dcom.sa.low_bound", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2244 { &hf_dcom_sa_features_auto,
2245 { "AUTO", "dcom.sa.features_auto", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_AUTO, "", HFILL }},
2246 { &hf_dcom_sa_features_static,
2247 { "STATIC", "dcom.sa.features_static", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_STATIC, "", HFILL }},
2248 { &hf_dcom_sa_features_embedded,
2249 { "EMBEDDED", "dcom.sa.features_embedded", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_EMBEDDED, "", HFILL }},
2250 { &hf_dcom_sa_features_fixedsize,
2251 { "FIXEDSIZE", "dcom.sa.features_fixedsize", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_FIXEDSIZE, "", HFILL }},
2252 { &hf_dcom_sa_features_record,
2253 { "RECORD", "dcom.sa.features_record", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_RECORD, "", HFILL }},
2254 { &hf_dcom_sa_features_have_iid,
2255 { "HAVEIID", "dcom.sa.features_have_iid", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_HAVEIID, "", HFILL }},
2256 { &hf_dcom_sa_features_have_vartype,
2257 { "HAVEVARTYPE", "dcom.sa.features_have_vartype", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_HAVEVARTYPE, "", HFILL }},
2258 { &hf_dcom_sa_features_bstr,
2259 { "BSTR", "dcom.sa.features_bstr", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_BSTR, "", HFILL }},
2260 { &hf_dcom_sa_features_unknown,
2261 { "UNKNOWN", "dcom.sa.features_unknown", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_UNKNOWN, "", HFILL }},
2262 { &hf_dcom_sa_features_dispatch,
2263 { "DISPATCH", "dcom.sa.features_dispatch", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_DISPATCH, "", HFILL }},
2264 { &hf_dcom_sa_features_variant,
2265 { "VARIANT", "dcom.sa.features_variant", FT_BOOLEAN, 16, TFS (&flags_set_truth), WIRESHARK_FADF_VARIANT, "", HFILL }}
2268 static gint *ett_dcom[] = {
2273 &ett_dcom_interface_pointer,
2275 &ett_dcom_stdobjref,
2276 &ett_dcom_dualstringarray,
2277 &ett_dcom_dualstringarray_binding,
2279 &ett_dcom_safearray,
2280 &ett_dcom_sa_features
2283 module_t *dcom_module;
2285 /* currently, the DCOM protocol "itself" has no real protocol dissector */
2286 /* we only need this, to register some generic elements */
2287 proto_dcom = proto_register_protocol ("DCOM", "DCOM", "dcom");
2288 proto_register_field_array(proto_dcom, hf_dcom_this_array, array_length(hf_dcom_this_array));
2289 proto_register_field_array(proto_dcom, hf_dcom_that_array, array_length(hf_dcom_that_array));
2290 proto_register_field_array(proto_dcom, hf_dcom_extent_array, array_length(hf_dcom_extent_array));
2291 proto_register_field_array(proto_dcom, hf_dcom_array, array_length(hf_dcom_array));
2292 proto_register_field_array(proto_dcom, hf_dcom_objref_array, array_length(hf_dcom_objref_array));
2293 proto_register_field_array(proto_dcom, hf_dcom_stdobjref_array, array_length(hf_dcom_stdobjref_array));
2294 proto_register_field_array(proto_dcom, hf_dcom_dualstringarray_array, array_length(hf_dcom_dualstringarray_array));
2295 proto_register_field_array(proto_dcom, hf_dcom_interface_pointer_array, array_length(hf_dcom_interface_pointer_array));
2296 proto_register_field_array(proto_dcom, hf_dcom_vt_array, array_length(hf_dcom_vt_array));
2297 proto_register_field_array(proto_dcom, hf_dcom_sa_array, array_length(hf_dcom_sa_array));
2298 proto_register_subtree_array (ett_dcom, array_length (ett_dcom));
2301 dcom_module = prefs_register_protocol(proto_dcom, NULL);
2303 prefs_register_bool_preference(dcom_module, "display_unmarshalling_details",
2304 "Display DCOM unmarshalling details",
2305 "Display some DCOM unmarshalled fields "
2307 &dcom_prefs_display_unmarshalling_details);
2309 register_init_routine(dcom_reinit);
2314 proto_reg_handoff_dcom (void)
2316 /* register some "well known" UUID's */
2317 guids_add_uuid(&uuid_debug_ext, "Debug Information Body Extension");
2318 guids_add_uuid(&uuid_ext_error_ext, "Extended Error Info Body Extension");
2319 guids_add_uuid(&ipid_rem_unknown, "IRemUnknown");
2320 guids_add_uuid(&iid_unknown, "IUnknown");
2321 guids_add_uuid(&uuid_null, "NULL");
2322 guids_add_uuid(&iid_class_factory, "IClassFactory");
2324 /* Currently, we have nothing to register for DCOM */