Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-dcom-remunkn.c
blobddce90c34d29293db00a78e7a9f5ff3edcd1ebd9
1 /* packet-dcom-remunkn.c
2 * Routines for the IRemUnknown interface
3 * Copyright 2004, Jelmer Vernooij <jelmer@samba.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* see packet-dcom.c for details about DCOM */
14 #include "config.h"
16 #include <epan/packet.h>
17 #include "packet-dcerpc.h"
18 #include "packet-dcom.h"
20 void proto_register_remunk(void);
21 void proto_reg_handoff_remunk(void);
23 static int hf_remunk_opnum;
26 static int hf_remunk_refs;
27 static int hf_remunk_iids;
29 /* static int hf_remunk_flags; */
30 static int hf_remunk_qiresult;
32 static int ett_remunk_reminterfaceref;
33 static int hf_remunk_reminterfaceref;
34 static int hf_remunk_interface_refs;
35 static int hf_remunk_public_refs;
36 static int hf_remunk_private_refs;
39 static int ett_remunk_rqi_result;
42 static int ett_remunk;
43 static e_guid_t uuid_remunk = { 0x00000131, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
44 static uint16_t ver_remunk;
45 static int proto_remunk;
47 static e_guid_t ipid_remunk = { 0x00000131, 0x1234, 0x5678, { 0xCA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
49 /* There is a little bit confusion about the IRemUnknown2 interface UUIDs */
50 /* DCOM documentation tells us: 0x00000142 (7 methods) */
51 /* win2000 registry tells us: 0x00000142 IRemoteQI (4 methods) */
52 /* win2000 registry tells us: 0x00000143 IRemUnknown2 (7 methods) */
53 /* There is some evidence, that the DCOM documentation is wrong, so using 143 for IRemUnknown2 now. */
55 static int ett_remunk2;
56 static e_guid_t uuid_remunk2 = { 0x00000143, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
57 static uint16_t ver_remunk2;
58 static int proto_remunk2;
61 typedef struct remunk_remqueryinterface_call_s {
62 unsigned iid_count;
63 e_guid_t *iids;
64 } remunk_remqueryinterface_call_t;
67 static int
68 dissect_remunk_remqueryinterface_rqst(tvbuff_t *tvb, int offset,
69 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)
71 e_guid_t ipid;
72 uint32_t u32Refs;
73 uint16_t u16IIDs;
74 uint32_t u32ArraySize;
75 uint32_t u32ItemIdx;
76 e_guid_t iid;
77 remunk_remqueryinterface_call_t *call;
80 offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
82 offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, di, drep,
83 hf_dcom_ipid, &ipid);
85 offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
86 hf_remunk_refs, &u32Refs);
88 offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
89 hf_remunk_iids, &u16IIDs);
91 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
92 &u32ArraySize);
94 /* limit the allocation to a reasonable size */
95 if(u32ArraySize < 100) {
96 call = (remunk_remqueryinterface_call_t *)wmem_alloc0(wmem_file_scope(), sizeof(remunk_remqueryinterface_call_t) + u32ArraySize * sizeof(e_guid_t));
97 call->iid_count = u32ArraySize;
98 call->iids = (e_guid_t *) (call+1);
99 di->call_data->private_data = call;
100 } else {
101 call = NULL;
104 for (u32ItemIdx = 0; u32ArraySize--; u32ItemIdx++) {
105 offset = dissect_dcom_append_UUID(tvb, offset, pinfo, tree, di, drep,
106 hf_dcom_iid, u32ItemIdx+1, &iid);
107 if(call != NULL) {
108 call->iids[u32ItemIdx] = iid;
112 return offset;
116 static int
117 dissect_remunk_remqueryinterface_resp(tvbuff_t *tvb, int offset,
118 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)
120 uint32_t u32Pointer;
121 uint32_t u32ArraySize;
122 uint32_t u32ItemIdx;
123 proto_item *sub_item;
124 proto_tree *sub_tree;
125 uint32_t u32HResult;
126 uint32_t u32SubStart;
127 e_guid_t iid;
128 e_guid_t iid_null = DCERPC_UUID_NULL;
129 remunk_remqueryinterface_call_t *call = (remunk_remqueryinterface_call_t *)di->call_data->private_data;
130 uint64_t oxid;
131 uint64_t oid;
132 e_guid_t ipid;
135 offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
137 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
138 &u32Pointer);
139 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
140 &u32ArraySize);
142 u32ItemIdx = 1;
143 while (u32ArraySize--) {
144 /* add subtree */
145 sub_item = proto_tree_add_item(tree, hf_remunk_qiresult, tvb, offset, 0, ENC_NA);
146 sub_tree = proto_item_add_subtree(sub_item, ett_remunk_rqi_result);
148 /* REMQIRESULT */
149 offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
150 &u32HResult);
151 u32SubStart = offset - 4;
152 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
153 &u32Pointer);
155 /* try to read the iid from the request */
156 if(call != NULL && u32ItemIdx <= call->iid_count) {
157 iid = call->iids[u32ItemIdx-1];
158 } else {
159 iid = iid_null;
162 /* XXX - this doesn't seem to be dependent on the pointer above?!? */
163 /*if (u32Pointer) {*/
164 offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, di, drep, 0 /* hfindex */,
165 &oxid, &oid, &ipid);
166 /*}*/
168 /* add interface instance to database (we currently only handle IPv4) */
169 if(pinfo->net_src.type == AT_IPv4) {
170 dcom_interface_new(pinfo,
171 &pinfo->net_src,
172 &iid, oxid, oid, &ipid);
175 /* update subtree */
176 proto_item_append_text(sub_item, "[%u]: %s",
177 u32ItemIdx,
178 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
179 proto_item_set_len(sub_item, offset - u32SubStart);
181 /* update column info now */
182 col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%u]",
183 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)"),
184 u32ItemIdx);
185 u32ItemIdx++;
188 /* HRESULT of call */
189 offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
190 &u32HResult);
192 /* update column info now */
193 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
194 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)"));
196 return offset;
200 static int
201 dissect_remunk_remrelease_rqst(tvbuff_t *tvb, int offset,
202 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)
204 uint32_t u32Pointer;
205 uint32_t u32IntRefs;
206 uint32_t u32ItemIdx;
207 e_guid_t ipid;
208 uint32_t u32PublicRefs;
209 uint32_t u32PrivateRefs;
210 const char *pszFormat;
211 proto_item *sub_item;
212 proto_tree *sub_tree;
213 uint32_t u32SubStart;
216 offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
218 offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
219 &u32Pointer);
221 offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
222 hf_remunk_interface_refs, &u32IntRefs);
224 /* update column info now */
225 if (u32IntRefs) {
226 col_append_fstr(pinfo->cinfo, COL_INFO, " Cnt=%u Refs=", u32IntRefs);
227 } else {
228 col_append_str(pinfo->cinfo, COL_INFO, " Cnt=0");
232 u32ItemIdx = 1;
233 while (u32IntRefs--) {
234 /* add subtree */
235 sub_item = proto_tree_add_item(tree, hf_remunk_reminterfaceref, tvb, offset, 0, ENC_NA);
236 sub_tree = proto_item_add_subtree(sub_item, ett_remunk_reminterfaceref);
237 u32SubStart = offset;
239 offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, di, drep,
240 hf_dcom_ipid, &ipid);
242 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
243 hf_remunk_public_refs, &u32PublicRefs);
245 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
246 hf_remunk_private_refs, &u32PrivateRefs);
248 /* update subtree */
249 proto_item_append_text(sub_item, "[%u]: IPID=%s, PublicRefs=%u, PrivateRefs=%u",
250 u32ItemIdx,
251 guids_resolve_guid_to_str(&ipid, pinfo->pool),
252 u32PublicRefs, u32PrivateRefs);
253 proto_item_set_len(sub_item, offset - u32SubStart);
255 /* update column info now */
256 pszFormat = "";
257 if (u32ItemIdx == 1) {
258 pszFormat = "%u-%u";
259 } else if (u32ItemIdx < 10) {
260 pszFormat = ",%u-%u";
261 } else if (u32ItemIdx == 10) {
262 pszFormat = ",...";
264 col_append_fstr(pinfo->cinfo, COL_INFO, pszFormat, u32PublicRefs, u32PrivateRefs);
266 u32ItemIdx++;
269 return offset;
273 /* sub dissector table of IRemUnknown interface */
274 static const dcerpc_sub_dissector remunk_dissectors[] = {
275 { 0, "QueryInterface", NULL, NULL },
276 { 1, "AddRef", NULL, NULL },
277 { 2, "Release", NULL, NULL },
279 { 3, "RemQueryInterface", dissect_remunk_remqueryinterface_rqst, dissect_remunk_remqueryinterface_resp },
280 { 4, "RemAddRef", NULL, NULL },
281 { 5, "RemRelease", dissect_remunk_remrelease_rqst, dissect_dcom_simple_resp },
282 { 0, NULL, NULL, NULL }
285 /* sub dissector table of IRemUnknown2 interface */
286 static const dcerpc_sub_dissector remunk2_dissectors[] = {
287 { 0, "QueryInterface", NULL, NULL },
288 { 1, "AddRef", NULL, NULL },
289 { 2, "Release", NULL, NULL },
291 { 3, "RemQueryInterface", dissect_remunk_remqueryinterface_rqst, dissect_remunk_remqueryinterface_resp },
292 { 4, "RemAddRef", NULL, NULL },
293 { 5, "RemRelease", dissect_remunk_remrelease_rqst, dissect_dcom_simple_resp },
295 { 6, "RemQueryInterface2", NULL, NULL },
296 { 0, NULL, NULL, NULL }
301 void
302 proto_register_remunk (void)
304 static hf_register_info hf_remunk_rqi_array[] = {
305 { &hf_remunk_opnum,
306 { "Operation", "remunk.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
308 { &hf_remunk_refs,
309 { "Refs", "remunk.refs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
310 { &hf_remunk_iids,
311 { "IIDs", "remunk.iids", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
312 { &hf_remunk_qiresult,
313 { "QIResult", "remunk.qiresult", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
314 #if 0
315 { &hf_remunk_flags,
316 { "Flags", "remunk.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
317 #endif
318 { &hf_remunk_public_refs,
319 { "PublicRefs", "remunk.public_refs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
320 { &hf_remunk_reminterfaceref,
321 { "RemInterfaceRef", "remunk.reminterfaceref", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
322 { &hf_remunk_interface_refs,
323 { "InterfaceRefs", "remunk.int_refs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
324 { &hf_remunk_private_refs,
325 { "PrivateRefs", "remunk.private_refs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}
328 static int *ett_remunk_array[] = {
329 &ett_remunk,
330 &ett_remunk_rqi_result,
331 &ett_remunk2,
332 &ett_remunk_reminterfaceref
335 proto_remunk = proto_register_protocol ("IRemUnknown", "IRemUnknown", "remunk");
336 proto_register_field_array (proto_remunk, hf_remunk_rqi_array, array_length (hf_remunk_rqi_array));
338 proto_remunk2 = proto_register_protocol ("IRemUnknown2", "IRemUnknown2", "remunk2");
340 proto_register_subtree_array (ett_remunk_array, array_length (ett_remunk_array));
343 void
344 proto_reg_handoff_remunk (void)
347 /* Register the IPID */
348 guids_add_uuid(&ipid_remunk, "IPID-IRemUnknown");
350 /* Register the interfaces */
351 dcerpc_init_uuid(proto_remunk, ett_remunk,
352 &uuid_remunk, ver_remunk,
353 remunk_dissectors, hf_remunk_opnum);
355 dcerpc_init_uuid(proto_remunk2, ett_remunk2,
356 &uuid_remunk2, ver_remunk2,
357 remunk2_dissectors, hf_remunk_opnum);
361 * Editor modelines - https://www.wireshark.org/tools/modelines.html
363 * Local variables:
364 * c-basic-offset: 4
365 * tab-width: 8
366 * indent-tabs-mode: nil
367 * End:
369 * vi: set shiftwidth=4 tabstop=8 expandtab:
370 * :indentSize=4:tabSize=8:noTabs=true: