Dissection of some functions and structure for dcerpc browser protocol.
[metze/wireshark/wip.git] / packet-dcerpc-browser.c
1 /* packet-dcerpc-browser.c
2  * Routines for DCERPC Browser packet disassembly
3  * Copyright 2001, Ronnie Sahlberg
4  *
5  * $Id: packet-dcerpc-browser.c,v 1.2 2002/05/28 13:08:07 sahlberg Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
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 /* The IDL file for this interface can be extracted by grepping for idl 
27  * in capitals.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include "packet-dcerpc.h"
37 #include "packet-dcerpc-browser.h"
38 #include "packet-dcerpc-nt.h"
39 #include "smb.h"
40
41 static int proto_dcerpc_browser = -1;
42 static int hf_browser_rc = -1;
43 static int hf_browser_unknown_long = -1;
44 static int hf_browser_unknown_bytes = -1;
45 static int hf_browser_unknown_string = -1;
46
47
48 static gint ett_dcerpc_browser = -1;
49
50
51 static int
52 dissect_browser_long_pointer(tvbuff_t *tvb, int offset, 
53                              packet_info *pinfo, proto_tree *tree, 
54                              char *drep)
55 {
56         dcerpc_info *di;
57
58         di=pinfo->private_data;
59         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
60                                      di->hf_index, NULL);
61         return offset;
62 }
63
64
65
66 /*
67  IDL [ uuid(6bffd098-a112-3610-9833-012892020162),
68  IDL   version(0.0),
69  IDL   implicit_handle(handle_t rpc_binding)
70  IDL ] interface browser
71  IDL {
72 */
73
74 static e_uuid_t uuid_dcerpc_browser = {
75         0x6bffd098, 0xa112, 0x3610,
76         { 0x98, 0x33, 0x01, 0x28, 0x92, 0x02, 0x01, 0x62 }
77 };
78
79 static guint16 ver_dcerpc_browser = 0;
80
81
82 /*
83   IDL typedef struct {
84   IDL   long element_7;
85   IDL   [size_is(element_7)] [unique] byte *element_8;
86   IDL } TYPE_4;
87 */
88 static int
89 dissect_browser_TYPE_4_data(tvbuff_t *tvb, int offset,
90                         packet_info *pinfo, proto_tree *tree,
91                         char *drep)
92 {
93         guint32 len;
94         dcerpc_info *di;
95
96         di=pinfo->private_data;
97         if(di->conformant_run){
98                 /*just a run to handle conformant arrays, nothing to dissect */
99                 return offset;
100         }
101
102         /* this is really the length of the encoded data */
103         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
104                 hf_browser_unknown_long, &len);
105         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
106                 FALSE);
107         offset += len;
108
109         return len;
110 }
111 static int
112 dissect_browser_TYPE_4(tvbuff_t *tvb, int offset,
113                         packet_info *pinfo, proto_tree *tree,
114                         char *drep)
115 {
116         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
117                 hf_browser_unknown_long, NULL);
118
119         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
120                 dissect_browser_TYPE_4_data, NDR_POINTER_UNIQUE,
121                 "unknown TYPE_4", -1, -1);
122
123         return offset;
124 }
125
126
127 /*
128   IDL typedef struct {
129   IDL   long element_5;
130   IDL   [size_is(element_5)] [unique] byte *element_6;
131   IDL } TYPE_3;
132 */
133 static int
134 dissect_browser_TYPE_3_data(tvbuff_t *tvb, int offset,
135                         packet_info *pinfo, proto_tree *tree,
136                         char *drep)
137 {
138         guint32 len;
139         dcerpc_info *di;
140
141         di=pinfo->private_data;
142         if(di->conformant_run){
143                 /*just a run to handle conformant arrays, nothing to dissect */
144                 return offset;
145         }
146
147         /* this is really the length of the encoded data */
148         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
149                 hf_browser_unknown_long, &len);
150         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
151                 FALSE);
152         offset += len;
153
154         return len;
155 }
156 static int
157 dissect_browser_TYPE_3(tvbuff_t *tvb, int offset,
158                         packet_info *pinfo, proto_tree *tree,
159                         char *drep)
160 {
161         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
162                 hf_browser_unknown_long, NULL);
163
164         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
165                 dissect_browser_TYPE_3_data, NDR_POINTER_UNIQUE,
166                 "unknown TYPE_3", -1, -1);
167
168         return offset;
169 }
170
171
172
173 /*
174   IDL typedef [switch_type(long)] union {
175   IDL   [case(100)] [unique] TYPE_3 *element_3;
176   IDL   [case(101)] [unique] TYPE_4 *element_4;
177   IDL } TYPE_2;
178 */
179 static int
180 dissect_browser_TYPE_2(tvbuff_t *tvb, int offset,
181                         packet_info *pinfo, proto_tree *tree,
182                         char *drep)
183 {
184         guint32 level;
185
186         /* this is really the union switch arm */
187         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
188                 hf_browser_unknown_long, &level);
189         ALIGN_TO_4_BYTES;
190
191         switch(level){
192         case 100:       
193                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
194                         dissect_browser_TYPE_3, NDR_POINTER_UNIQUE,
195                         "unknown TYPE_3", -1, -1);
196                 break;
197         case 101:       
198                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
199                         dissect_browser_TYPE_4, NDR_POINTER_UNIQUE,
200                         "unknown TYPE_4", -1, -1);
201                 break;
202         }
203
204         return offset;
205 }
206
207
208 /*
209   IDL typedef struct {
210   IDL   long element_1;
211   IDL   TYPE_2 element_2;
212   IDL } TYPE_1;
213 */
214 static int
215 dissect_browser_TYPE_1(tvbuff_t *tvb, int offset,
216                         packet_info *pinfo, proto_tree *tree,
217                         char *drep)
218 {
219         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
220                 hf_browser_unknown_long, NULL);
221
222         offset = dissect_browser_TYPE_2(tvb, offset, pinfo, tree, drep);
223
224         return offset;
225 }
226
227
228
229 /*
230  IDL  long Function_00(
231  IDL        [in] [unique] [string] wchar_t *element_9,
232  IDL        [in] [unique] [string] wchar_t *element_10,
233  IDL        [in] [unique] [string] wchar_t *element_11,
234  IDL        [in,out] [ref] TYPE_1 element_12,
235  IDL        [in] long element_13,
236  IDL        [out] long element_14,
237  IDL        [in] long element_15,
238  IDL        [in] [unique] [string] wchar_t *element_16,
239  IDL        [in,out] [unique] long *element_17
240  IDL  );
241 */
242 static int
243 dissect_browser_UNKNOWN_00_rqst(tvbuff_t *tvb, int offset,
244                         packet_info *pinfo, proto_tree *tree,
245                         char *drep)
246 {
247         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
248                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
249                         "unknown string", hf_browser_unknown_string, 0);
250
251         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
252                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
253                         "unknown string", hf_browser_unknown_string, 0);
254
255         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
256                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
257                         "unknown string", hf_browser_unknown_string, 0);
258
259         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
260                         dissect_browser_TYPE_1, NDR_POINTER_REF,
261                         "unknown TYPE_1", -1, 0);
262
263         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
264                 hf_browser_unknown_long, NULL);
265
266         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
267                 hf_browser_unknown_long, NULL);
268
269         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
270                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
271                         "unknown string", hf_browser_unknown_string, 0);
272
273         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
274                         dissect_browser_long_pointer, NDR_POINTER_UNIQUE,
275                         "unknown long", hf_browser_unknown_long, 0);
276
277         return offset;
278 }
279 static int
280 dissect_browser_UNKNOWN_00_reply(tvbuff_t *tvb, int offset,
281                         packet_info *pinfo, proto_tree *tree,
282                         char *drep)
283 {
284         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
285                         dissect_browser_TYPE_1, NDR_POINTER_REF,
286                         "unknown TYPE_1", -1, 0);
287
288         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
289                 hf_browser_unknown_long, NULL);
290
291         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
292                         dissect_browser_long_pointer, NDR_POINTER_UNIQUE,
293                         "unknown long", hf_browser_unknown_long, 0);
294
295         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
296                 hf_browser_rc, NULL);
297
298         return offset;
299 }
300
301 /*
302   IDL long Function_01(
303   IDL       [in] [unique] [string] wchar_t *element_18,
304   IDL       [in] long element_19,
305   IDL       [in] long element_20
306   IDL );
307 */
308 static int
309 dissect_browser_UNKNOWN_01_rqst(tvbuff_t *tvb, int offset,
310                         packet_info *pinfo, proto_tree *tree,
311                         char *drep)
312 {
313         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
314                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
315                         "unknown string", hf_browser_unknown_string, 0);
316
317         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
318                 hf_browser_unknown_long, NULL);
319
320         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
321                 hf_browser_unknown_long, NULL);
322
323         return offset;
324 }
325 static int
326 dissect_browser_UNKNOWN_01_reply(tvbuff_t *tvb, int offset,
327                         packet_info *pinfo, proto_tree *tree,
328                         char *drep)
329 {
330         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
331                 hf_browser_rc, NULL);
332
333         return offset;
334 }
335
336
337 /*
338   IDL long Function_02(
339   IDL       [in] [unique] [string] wchar_t *element_21,
340   IDL       [in,out] [ref] TYPE_1 element_22,
341   IDL       [out] long element_23
342   IDL );
343 */
344 static int
345 dissect_browser_UNKNOWN_02_rqst(tvbuff_t *tvb, int offset,
346                         packet_info *pinfo, proto_tree *tree,
347                         char *drep)
348 {
349         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
350                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
351                         "unknown string", hf_browser_unknown_string, 0);
352
353         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
354                         dissect_browser_TYPE_1, NDR_POINTER_REF,
355                         "unknown TYPE_1", -1, 0);
356
357         return offset;
358 }
359 static int
360 dissect_browser_UNKNOWN_02_reply(tvbuff_t *tvb, int offset,
361                         packet_info *pinfo, proto_tree *tree,
362                         char *drep)
363 {
364         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
365                 hf_browser_unknown_long, NULL);
366
367         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
368                 hf_browser_rc, NULL);
369
370         return offset;
371 }
372
373
374 /*
375   IDL long Function_03(
376   IDL       [in] [unique] [string] wchar_t *element_24
377   IDL );
378 */
379 static int
380 dissect_browser_UNKNOWN_03_rqst(tvbuff_t *tvb, int offset,
381                         packet_info *pinfo, proto_tree *tree,
382                         char *drep)
383 {
384         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
385                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
386                         "unknown string", hf_browser_unknown_string, 0);
387
388         return offset;
389 }
390 static int
391 dissect_browser_UNKNOWN_03_reply(tvbuff_t *tvb, int offset,
392                         packet_info *pinfo, proto_tree *tree,
393                         char *drep)
394 {
395         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
396                 hf_browser_rc, NULL);
397
398         return offset;
399 }
400
401
402 /*
403   IDL long Function_04(
404   IDL       [in] [unique] [string] wchar_t *element_25,
405   IDL       [in] [string] char element_26
406   IDL );
407 */
408 static int
409 dissect_browser_UNKNOWN_04_rqst(tvbuff_t *tvb, int offset,
410                         packet_info *pinfo, proto_tree *tree,
411                         char *drep)
412 {
413         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
414                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
415                         "unknown string", hf_browser_unknown_string, 0);
416
417         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
418                         dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_REF,
419                         "unknown string", hf_browser_unknown_string, 0);
420
421         return offset;
422 }
423 static int
424 dissect_browser_UNKNOWN_04_reply(tvbuff_t *tvb, int offset,
425                         packet_info *pinfo, proto_tree *tree,
426                         char *drep)
427 {
428         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
429                 hf_browser_rc, NULL);
430
431         return offset;
432 }
433
434
435 static dcerpc_sub_dissector dcerpc_browser_dissectors[] = {
436         { BROWSER_UNKNOWN_00, "BROWSER_UNKNOWN_00", 
437                 dissect_browser_UNKNOWN_00_rqst,
438                 dissect_browser_UNKNOWN_00_reply },
439         { BROWSER_UNKNOWN_01, "BROWSER_UNKNOWN_01",
440                 dissect_browser_UNKNOWN_01_rqst,
441                 dissect_browser_UNKNOWN_01_reply },
442         { BROWSER_UNKNOWN_02, "BROWSER_UNKNOWN_02",
443                 dissect_browser_UNKNOWN_02_rqst,
444                 dissect_browser_UNKNOWN_02_reply },
445         { BROWSER_UNKNOWN_03, "BROWSER_UNKNOWN_03",
446                 dissect_browser_UNKNOWN_03_rqst,
447                 dissect_browser_UNKNOWN_03_reply },
448         { BROWSER_UNKNOWN_04, "BROWSER_UNKNOWN_04",
449                 dissect_browser_UNKNOWN_04_rqst,
450                 dissect_browser_UNKNOWN_04_reply },
451         { BROWSER_UNKNOWN_05, "BROWSER_UNKNOWN_05", NULL, NULL },
452         { BROWSER_UNKNOWN_06, "BROWSER_UNKNOWN_06", NULL, NULL },
453         { BROWSER_UNKNOWN_07, "BROWSER_UNKNOWN_07", NULL, NULL },
454         { BROWSER_UNKNOWN_08, "BROWSER_UNKNOWN_08", NULL, NULL },
455         { BROWSER_UNKNOWN_09, "BROWSER_UNKNOWN_09", NULL, NULL },
456         { BROWSER_UNKNOWN_0a, "BROWSER_UNKNOWN_0a", NULL, NULL },
457         { BROWSER_UNKNOWN_0b, "BROWSER_UNKNOWN_0b", NULL, NULL },
458
459         {0, NULL, NULL,  NULL },
460 };
461
462 void 
463 proto_register_dcerpc_browser(void)
464 {
465 static hf_register_info hf[] = {
466         { &hf_browser_rc, { 
467                 "Return code", "rpc_browser.rc", FT_UINT32, BASE_HEX, 
468                 VALS(NT_errors), 0x0, "Browser return code", HFILL }},
469
470         { &hf_browser_unknown_long, { 
471                 "Unknown long", "rpc_browser.unknown.long", FT_UINT32, BASE_HEX, 
472                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
473         
474         { &hf_browser_unknown_bytes, { 
475                 "Unknown bytes", "rpc_browser.unknown.bytes", FT_BYTES, BASE_HEX, 
476                 NULL, 0x0, "Unknown bytes. If you know what this is, contact ethereal developers.", HFILL }},
477
478         { &hf_browser_unknown_string, { 
479                 "Unknown string", "rpc_browser.unknown.string", FT_STRING, BASE_HEX, 
480                 NULL, 0x0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
481
482         };
483         static gint *ett[] = {
484                 &ett_dcerpc_browser,
485         };
486
487         proto_dcerpc_browser = proto_register_protocol(
488                 "RPC Browser", "RPC_BROWSER", "rpc_browser");
489
490         proto_register_field_array(proto_dcerpc_browser, hf, 
491                                    array_length(hf));
492         proto_register_subtree_array(ett, array_length(ett));
493 }
494
495 void
496 proto_reg_handoff_dcerpc_browser(void)
497 {
498         /* Register protocol as dcerpc */
499
500         dcerpc_init_uuid(proto_dcerpc_browser, ett_dcerpc_browser, 
501                          &uuid_dcerpc_browser, ver_dcerpc_browser, 
502                          dcerpc_browser_dissectors);
503 }