Document the new Copy Profile button.
[obnox/wireshark/wip.git] / epan / dissectors / packet-dcom-oxid.c
1 /* packet-dcom-oxid.c
2  * Routines for DCOM OXID Resolver
3  * Copyright 2001, Todd Sabin <tas@webspan.net>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 /* see packet-dcom.c for details about DCOM */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <string.h>
33
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include "packet-dcerpc.h"
37 #include "packet-dcom.h"
38
39 static int proto_oxid = -1;
40
41 static int hf_oxid_opnum = -1;
42 static int hf_oxid_setid = -1;
43 static int hf_oxid_seqnum = -1;
44 static int hf_oxid_addtoset = -1;
45 static int hf_oxid_delfromset = -1;
46 static int hf_oxid_oid = -1;
47 static int hf_oxid_ping_backoff_factor = -1;
48 static int hf_oxid_oxid = -1;
49 static int hf_oxid_requested_protseqs = -1;
50 static int hf_oxid_protseqs = -1;
51 static int hf_oxid_bindings = -1;
52 static int hf_oxid_ipid = -1;
53 static int hf_oxid_authn_hint = -1;
54
55 static int hf_oxid_Unknown1 = -1;
56 static int hf_oxid_Unknown2 = -1;
57 static int hf_oxid_ds_array = -1;
58
59
60 static gint ett_oxid = -1;
61
62 static e_uuid_t uuid_oxid = { 0x99fcfec4, 0x5260, 0x101b, { 0xbb, 0xcb, 0x00, 0xaa, 0x00, 0x21, 0x34, 0x7a } };
63 static guint16  ver_oxid = 0;
64
65
66 static int
67 dissect_oxid_simple_ping_rqst(tvbuff_t *tvb, int offset,
68         packet_info *pinfo, proto_tree *tree, guint8 *drep)
69 {
70         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
71                                                 hf_oxid_setid, NULL);
72
73         return offset;
74 }
75
76
77 static int
78 dissect_oxid_simple_ping_resp(tvbuff_t *tvb, int offset,
79         packet_info *pinfo, proto_tree *tree, guint8 *drep)
80 {
81         guint32 u32HResult;
82
83
84         offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, 
85                                                 &u32HResult);
86
87         if (check_col(pinfo->cinfo, COL_INFO)) {
88           col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", 
89                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
90         }
91
92         return offset;
93 }
94
95
96 static int
97 dissect_oxid_server_alive_resp(tvbuff_t *tvb, int offset,
98         packet_info *pinfo, proto_tree *tree, guint8 *drep)
99 {
100         guint32 u32HResult;
101
102
103         offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, 
104                                                 &u32HResult);
105
106         if (check_col(pinfo->cinfo, COL_INFO)) {
107           col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", 
108                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
109         }
110
111         return offset;
112 }
113
114
115 static int
116 dissect_oxid_complex_ping_rqst(tvbuff_t *tvb, int offset,
117         packet_info *pinfo, proto_tree *tree, guint8 *drep)
118 {
119         guint16 u16SeqNum;
120         guint16 u16AddToSet;
121         guint16 u16DelFromSet;
122         guint32 u32Pointer;
123         guint32 u32ArraySize;
124
125         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
126                                                 hf_oxid_setid, NULL);
127
128         offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep, 
129                                                 hf_oxid_seqnum, &u16SeqNum);
130         offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep, 
131                                                 hf_oxid_addtoset, &u16AddToSet);
132         offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep, 
133                                                 hf_oxid_delfromset, &u16DelFromSet);
134
135         if (check_col(pinfo->cinfo, COL_INFO)) {
136                 col_append_fstr(pinfo->cinfo, COL_INFO, " AddToSet=%u DelFromSet=%u", 
137                         u16AddToSet, u16DelFromSet);
138         }
139
140         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
141                                                 &u32Pointer);
142         if (u32Pointer) {
143                 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, 
144                                                         &u32ArraySize);
145
146                 while (u16AddToSet--) {
147                         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
148                                                         hf_oxid_oid, NULL);
149                 }
150         }
151
152         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
153                                                 &u32Pointer);
154     if (u32Pointer) {
155                 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, 
156                                                         &u32ArraySize);
157
158                 while (u16DelFromSet--) {
159                         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
160                                                         hf_oxid_oid, NULL);
161                 }
162         }
163
164         return offset;
165 }
166
167
168 static int
169 dissect_oxid_complex_ping_resp(tvbuff_t *tvb, int offset,
170         packet_info *pinfo, proto_tree *tree, guint8 *drep)
171 {
172         guint16 u16PingBackoffFactor;
173         guint32 u32HResult;
174
175
176         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
177                                                 hf_oxid_setid, NULL);
178         offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
179                                                 hf_oxid_ping_backoff_factor, &u16PingBackoffFactor);
180
181         offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, 
182                                                 &u32HResult);
183
184         if (check_col(pinfo->cinfo, COL_INFO)) {
185           col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", 
186                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
187         }
188
189         return offset;
190 }
191
192
193 static int
194 dissect_oxid_resolve_oxid2_rqst(tvbuff_t *tvb, int offset,
195         packet_info *pinfo, proto_tree *tree, guint8 *drep)
196 {
197         guint16 u16ProtSeqs;
198         guint32 u32ArraySize;
199         guint32 u32ItemIdx;
200
201
202         offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep, 
203                                                 hf_oxid_oxid, NULL);
204
205         offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep, 
206                         hf_oxid_requested_protseqs, &u16ProtSeqs);
207
208         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, 
209                                                 &u32ArraySize);
210
211         u32ItemIdx = 1;
212         while (u32ArraySize--) {
213                 offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep, 
214                                                         hf_oxid_protseqs, &u16ProtSeqs);
215                 u32ItemIdx++;
216         }
217
218         return offset;
219 }
220
221
222 static int
223 dissect_oxid_resolve_oxid2_resp(tvbuff_t *tvb, int offset,
224         packet_info *pinfo, proto_tree *tree, guint8 *drep)
225 {
226         guint32 u32Pointer;
227         guint32 u32ArraySize;
228         e_uuid_t ipid;
229         guint32 u32AuthnHint;
230         guint16 u16VersionMajor;
231         guint16 u16VersionMinor;
232         guint32 u32HResult;
233
234
235         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, 
236                                                 &u32Pointer);
237         if (u32Pointer) {
238                 offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, 
239                                                         &u32ArraySize);
240
241                 offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep, 
242                                                         hf_oxid_bindings, NULL);
243                 
244                 offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep, 
245                                                         hf_oxid_ipid, &ipid);
246
247                 offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, 
248                                                         hf_oxid_authn_hint, &u32AuthnHint);
249
250                 offset = dissect_dcom_COMVERSION(tvb, offset, pinfo, tree, drep,
251                                         &u16VersionMajor, &u16VersionMinor);
252         }
253
254         offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, 
255                                                 &u32HResult);
256
257         if (check_col(pinfo->cinfo, COL_INFO)) {
258           col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", 
259                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
260         }
261
262         return offset;
263 }
264
265
266 static int
267 dissect_oxid_server_alive2_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, 
268                                 proto_tree *tree, guint8 *drep) {
269     guint16     u16VersionMajor;
270     guint16 u16VersionMinor;
271
272     offset = dissect_dcom_COMVERSION(tvb, offset, pinfo, tree, drep, &u16VersionMajor, &u16VersionMinor);
273
274     /* XXX - understand what those 8 bytes mean! don't skip'em!*/
275     dissect_dcerpc_uint64(tvb , offset, pinfo, tree, drep, hf_oxid_Unknown1, NULL);
276     offset += 8;
277
278     offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep, hf_oxid_ds_array, NULL);
279
280     /* unknown field 2 */
281     dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep, hf_oxid_Unknown2, NULL);
282     offset += 8;
283     return offset;
284 }
285
286
287 /* XXX - some dissectors still need to be done */
288 static dcerpc_sub_dissector oxid_dissectors[] = {
289     { 0, "ResolveOxid", NULL, NULL },
290     { 1, "SimplePing", dissect_oxid_simple_ping_rqst, dissect_oxid_simple_ping_resp },
291     { 2, "ComplexPing", dissect_oxid_complex_ping_rqst, dissect_oxid_complex_ping_resp },
292     { 3, "ServerAlive", NULL /* no input parameters */, dissect_oxid_server_alive_resp },
293     { 4, "ResolveOxid2", dissect_oxid_resolve_oxid2_rqst, dissect_oxid_resolve_oxid2_resp },
294     { 5, "ServerAlive2", NULL, dissect_oxid_server_alive2_resp },
295     { 0, NULL, NULL, NULL },
296 };
297
298
299 void
300 proto_register_oxid (void)
301 {
302         static hf_register_info hf[] = {
303                 { &hf_oxid_opnum,
304                   { "Operation", "oxid.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
305
306                 { &hf_oxid_setid,
307                 { "SetId", "oxid_setid",  FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
308                 { &hf_oxid_seqnum,
309                 { "SeqNum", "oxid_seqnum",  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
310                 { &hf_oxid_addtoset,
311                 { "AddToSet", "oxid_addtoset",  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
312                 { &hf_oxid_delfromset,
313                 { "DelFromSet", "oxid_delfromset",  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
314                 { &hf_oxid_oid,
315                 { "OID", "oxid_oid",  FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
316                 { &hf_oxid_ping_backoff_factor,
317                 { "PingBackoffFactor", "oxid_ping_backoff_factor", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
318                 { &hf_oxid_oxid,
319                 { "OXID", "oxid_oxid",  FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
320
321                 { &hf_oxid_requested_protseqs,
322                 { "RequestedProtSeq", "oxid_requested_protseqs",  FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
323                 { &hf_oxid_protseqs,
324                 { "ProtSeq", "oxid_protseqs",  FT_UINT16, BASE_DEC, VALS(dcom_protseq_vals), 0x0, NULL, HFILL }},
325
326                 { &hf_oxid_bindings,
327                 { "OxidBindings", "oxid_bindings", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
328         { &hf_oxid_ipid,
329         { "IPID", "oxid_ipid", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
330                 { &hf_oxid_authn_hint,
331                 { "AuthnHint", "oxid_authn_hint", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
332
333                 { &hf_oxid_ds_array,
334                   { "Address", "dcom.oxid.address", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
335                 { &hf_oxid_Unknown1,
336                   { "unknown 8 bytes 1", "oxid5.unknown1", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
337                 { &hf_oxid_Unknown2,
338                   { "unknown 8 bytes 2", "oxid5.unknown2", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}
339         };
340         static gint *ett[] = {
341                 &ett_oxid
342         };
343         proto_oxid = proto_register_protocol ("DCOM OXID Resolver", "IOXIDResolver", "oxid");
344         proto_register_field_array (proto_oxid, hf, array_length (hf));
345         proto_register_subtree_array (ett, array_length (ett));
346 }
347
348 void
349 proto_reg_handoff_oxid (void)
350 {
351         /* Register the protocol as dcerpc */
352         dcerpc_init_uuid (proto_oxid, ett_oxid, &uuid_oxid, ver_oxid, oxid_dissectors, hf_oxid_opnum);
353 }