From Jesper Peterson:
[obnox/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.12 2003/08/04 02:49:03 tpot 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_opnum = -1;
43 static int hf_browser_rc = -1;
44 static int hf_browser_unknown_long = -1;
45 static int hf_browser_unknown_hyper = -1;
46 static int hf_browser_unknown_bytes = -1;
47 static int hf_browser_unknown_string = -1;
48
49
50 static gint ett_dcerpc_browser = -1;
51
52
53 static int
54 dissect_browser_long_pointer(tvbuff_t *tvb, int offset,
55                              packet_info *pinfo, proto_tree *tree,
56                              char *drep)
57 {
58         dcerpc_info *di;
59
60         di=pinfo->private_data;
61         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
62                                      di->hf_index, NULL);
63         return offset;
64 }
65
66
67
68 /*
69  IDL [ uuid(6bffd098-a112-3610-9833-012892020162),
70  IDL   version(0.0),
71  IDL   implicit_handle(handle_t rpc_binding)
72  IDL ] interface browser
73  IDL {
74 */
75
76 static e_uuid_t uuid_dcerpc_browser = {
77         0x6bffd098, 0xa112, 0x3610,
78         { 0x98, 0x33, 0x01, 0x28, 0x92, 0x02, 0x01, 0x62 }
79 };
80
81 static guint16 ver_dcerpc_browser = 0;
82
83
84 /*
85   IDL typedef struct {
86   IDL   long element_7;
87   IDL   [size_is(element_7)] [unique] byte *element_8;
88   IDL } TYPE_4;
89 */
90 static int
91 dissect_browser_TYPE_4_data(tvbuff_t *tvb, int offset,
92                         packet_info *pinfo, proto_tree *tree,
93                         char *drep)
94 {
95         guint32 len;
96         dcerpc_info *di;
97
98         di=pinfo->private_data;
99         if(di->conformant_run){
100                 /* this call is to make ethereal eat the array header for the conformant run */
101                 offset =dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, NULL);
102
103                 return offset;
104         }
105         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
106                 hf_browser_unknown_long, &len);
107
108         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
109                 FALSE);
110         offset += len;
111
112         return len;
113 }
114 static int
115 dissect_browser_TYPE_4(tvbuff_t *tvb, int offset,
116                         packet_info *pinfo, proto_tree *tree,
117                         char *drep)
118 {
119         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
120                 hf_browser_unknown_long, NULL);
121
122         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
123                 dissect_browser_TYPE_4_data, NDR_POINTER_UNIQUE,
124                 "unknown TYPE_4", -1);
125
126         return offset;
127 }
128
129
130 /*
131   IDL typedef struct {
132   IDL   long element_5;
133   IDL   [size_is(element_5)] [unique] byte *element_6;
134   IDL } TYPE_3;
135 */
136 static int
137 dissect_browser_TYPE_3_data(tvbuff_t *tvb, int offset,
138                         packet_info *pinfo, proto_tree *tree,
139                         char *drep)
140 {
141         guint32 len;
142         dcerpc_info *di;
143
144         di=pinfo->private_data;
145         if(di->conformant_run){
146                 /* this call is to make ethereal eat the array header for the conformant run */
147                 offset =dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, NULL);
148
149                 return offset;
150         }
151
152         /* this is really the length of the encoded data */
153         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
154                 hf_browser_unknown_long, &len);
155         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
156                 FALSE);
157         offset += len;
158
159         return len;
160 }
161 static int
162 dissect_browser_TYPE_3(tvbuff_t *tvb, int offset,
163                         packet_info *pinfo, proto_tree *tree,
164                         char *drep)
165 {
166         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
167                 hf_browser_unknown_long, NULL);
168
169         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
170                 dissect_browser_TYPE_3_data, NDR_POINTER_UNIQUE,
171                 "unknown TYPE_3", -1);
172
173         return offset;
174 }
175
176
177
178 /*
179   IDL typedef [switch_type(long)] union {
180   IDL   [case(100)] [unique] TYPE_3 *element_3;
181   IDL   [case(101)] [unique] TYPE_4 *element_4;
182   IDL } TYPE_2;
183 */
184 static int
185 dissect_browser_TYPE_2(tvbuff_t *tvb, int offset,
186                         packet_info *pinfo, proto_tree *tree,
187                         char *drep)
188 {
189         guint32 level;
190
191         /* this is really the union switch arm */
192         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
193                 hf_browser_unknown_long, &level);
194
195         ALIGN_TO_4_BYTES;
196
197         switch(level){
198         case 100:
199                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
200                         dissect_browser_TYPE_3, NDR_POINTER_UNIQUE,
201                         "unknown TYPE_3", -1);
202                 break;
203         case 101:
204                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
205                         dissect_browser_TYPE_4, NDR_POINTER_UNIQUE,
206                         "unknown TYPE_4", -1);
207                 break;
208         }
209
210         return offset;
211 }
212
213
214 /*
215   IDL typedef struct {
216   IDL   long element_1;
217   IDL   TYPE_2 element_2;
218   IDL } TYPE_1;
219 */
220 static int
221 dissect_browser_TYPE_1(tvbuff_t *tvb, int offset,
222                         packet_info *pinfo, proto_tree *tree,
223                         char *drep)
224 {
225         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
226                 hf_browser_unknown_long, NULL);
227
228         offset = dissect_browser_TYPE_2(tvb, offset, pinfo, tree, drep);
229
230         return offset;
231 }
232
233
234
235 /*
236  IDL  long Function_00(
237  IDL        [in] [unique] [string] wchar_t *element_9,
238  IDL        [in] [unique] [string] wchar_t *element_10,
239  IDL        [in] [unique] [string] wchar_t *element_11,
240  IDL        [in,out] [ref] TYPE_1 *element_12,
241  IDL        [in] long element_13,
242  IDL        [out] long element_14,
243  IDL        [in] long element_15,
244  IDL        [in] [unique] [string] wchar_t *element_16,
245  IDL        [in,out] [unique] long *element_17
246  IDL  );
247 */
248 static int
249 dissect_browser_UNKNOWN_00_rqst(tvbuff_t *tvb, int offset,
250                         packet_info *pinfo, proto_tree *tree,
251                         char *drep)
252 {
253         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
254                         NDR_POINTER_UNIQUE, "unknown string", 
255                         hf_browser_unknown_string, 0);
256
257         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
258                         NDR_POINTER_UNIQUE, "unknown string", 
259                         hf_browser_unknown_string, 0);
260
261         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
262                         NDR_POINTER_UNIQUE, "unknown string", 
263                         hf_browser_unknown_string, 0);
264
265         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
266                         dissect_browser_TYPE_1, NDR_POINTER_REF,
267                         "unknown TYPE_1", -1);
268
269         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
270                 hf_browser_unknown_long, NULL);
271
272         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
273                 hf_browser_unknown_long, NULL);
274
275         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
276                         NDR_POINTER_UNIQUE, "unknown string", 
277                         hf_browser_unknown_string, 0);
278
279         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
280                         dissect_browser_long_pointer, NDR_POINTER_UNIQUE, 
281                         "unknown long", hf_browser_unknown_long);
282
283         return offset;
284 }
285 static int
286 dissect_browser_UNKNOWN_00_reply(tvbuff_t *tvb, int offset,
287                         packet_info *pinfo, proto_tree *tree,
288                         char *drep)
289 {
290         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
291                         dissect_browser_TYPE_1, NDR_POINTER_REF,
292                         "unknown TYPE_1", -1);
293
294         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
295                 hf_browser_unknown_long, NULL);
296
297         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
298                         dissect_browser_long_pointer, NDR_POINTER_UNIQUE,
299                         "unknown long", hf_browser_unknown_long);
300
301         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
302                 hf_browser_rc, NULL);
303
304         return offset;
305 }
306
307 /*
308   IDL long Function_01(
309   IDL       [in] [unique] [string] wchar_t *element_18,
310   IDL       [in] long element_19,
311   IDL       [in] long element_20
312   IDL );
313 */
314 static int
315 dissect_browser_UNKNOWN_01_rqst(tvbuff_t *tvb, int offset,
316                         packet_info *pinfo, proto_tree *tree,
317                         char *drep)
318 {
319         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
320                         NDR_POINTER_UNIQUE, "unknown string", 
321                         hf_browser_unknown_string, 0);
322
323         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
324                 hf_browser_unknown_long, NULL);
325
326         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
327                 hf_browser_unknown_long, NULL);
328
329         return offset;
330 }
331 static int
332 dissect_browser_UNKNOWN_01_reply(tvbuff_t *tvb, int offset,
333                         packet_info *pinfo, proto_tree *tree,
334                         char *drep)
335 {
336         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
337                 hf_browser_rc, NULL);
338
339         return offset;
340 }
341
342
343 /*
344   IDL long Function_02(
345   IDL       [in] [unique] [string] wchar_t *element_21,
346   IDL       [in,out] [ref] TYPE_1 *element_22,
347   IDL       [out] long element_23
348   IDL );
349 */
350 static int
351 dissect_browser_UNKNOWN_02_rqst(tvbuff_t *tvb, int offset,
352                         packet_info *pinfo, proto_tree *tree,
353                         char *drep)
354 {
355         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
356                         NDR_POINTER_UNIQUE, "unknown string", 
357                         hf_browser_unknown_string, 0);
358
359         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
360                         dissect_browser_TYPE_1, NDR_POINTER_REF,
361                         "unknown TYPE_1", -1);
362
363         return offset;
364 }
365 static int
366 dissect_browser_UNKNOWN_02_reply(tvbuff_t *tvb, int offset,
367                         packet_info *pinfo, proto_tree *tree,
368                         char *drep)
369 {
370         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
371                 hf_browser_unknown_long, NULL);
372
373         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
374                 hf_browser_rc, NULL);
375
376         return offset;
377 }
378
379
380 /*
381   IDL long Function_03(
382   IDL       [in] [unique] [string] wchar_t *element_24
383   IDL );
384 */
385 static int
386 dissect_browser_UNKNOWN_03_rqst(tvbuff_t *tvb, int offset,
387                         packet_info *pinfo, proto_tree *tree,
388                         char *drep)
389 {
390         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
391                         NDR_POINTER_UNIQUE, "unknown string", 
392                         hf_browser_unknown_string, 0);
393
394         return offset;
395 }
396 static int
397 dissect_browser_UNKNOWN_03_reply(tvbuff_t *tvb, int offset,
398                         packet_info *pinfo, proto_tree *tree,
399                         char *drep)
400 {
401         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
402                 hf_browser_rc, NULL);
403
404         return offset;
405 }
406
407
408 /*
409   IDL long Function_04(
410   IDL       [in] [unique] [string] wchar_t *element_25,
411   IDL       [in] [string] char element_26
412   IDL );
413 */
414 static int
415 dissect_browser_UNKNOWN_04_rqst(tvbuff_t *tvb, int offset,
416                         packet_info *pinfo, proto_tree *tree,
417                         char *drep)
418 {
419         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
420                         NDR_POINTER_UNIQUE, "unknown string", 
421                         hf_browser_unknown_string, 0);
422
423         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
424                         NDR_POINTER_REF, "unknown string", 
425                         hf_browser_unknown_string, 0);
426
427         return offset;
428 }
429 static int
430 dissect_browser_UNKNOWN_04_reply(tvbuff_t *tvb, int offset,
431                         packet_info *pinfo, proto_tree *tree,
432                         char *drep)
433 {
434         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
435                 hf_browser_rc, NULL);
436
437         return offset;
438 }
439
440
441
442 /*
443   IDL typedef struct {
444   IDL   TYPE_6 element_27;
445   IDL   TYPE_6 element_28;
446   IDL   TYPE_6 element_29;
447   IDL   long element_30;
448   IDL   long element_31;
449   IDL   long element_32;
450   IDL   long element_33;
451   IDL   long element_34;
452   IDL   long element_35;
453   IDL   long element_36;
454   IDL   long element_37;
455   IDL   long element_38;
456   IDL   long element_39;
457   IDL   long element_40;
458   IDL   long element_41;
459   IDL   long element_42;
460   IDL   long element_43;
461   IDL   long element_44;
462   IDL   TYPE_6 element_45;
463   IDL } TYPE_5;
464   IDL
465   IDL typedef struct {
466   IDL   hyper element_46;
467   IDL } TYPE_6;
468 */
469 static int
470 dissect_browser_TYPE_5(tvbuff_t *tvb, int offset,
471                         packet_info *pinfo, proto_tree *tree,
472                         char *drep)
473 {
474         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
475                 hf_browser_unknown_hyper, NULL);
476
477         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
478                 hf_browser_unknown_hyper, NULL);
479
480         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
481                 hf_browser_unknown_hyper, NULL);
482
483         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
484                 hf_browser_unknown_long, NULL);
485
486         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
487                 hf_browser_unknown_long, NULL);
488
489         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
490                 hf_browser_unknown_long, NULL);
491
492         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
493                 hf_browser_unknown_long, NULL);
494
495         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
496                 hf_browser_unknown_long, NULL);
497
498         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
499                 hf_browser_unknown_long, NULL);
500
501         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
502                 hf_browser_unknown_long, NULL);
503
504         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
505                 hf_browser_unknown_long, NULL);
506
507         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
508                 hf_browser_unknown_long, NULL);
509
510         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
511                 hf_browser_unknown_long, NULL);
512
513         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
514                 hf_browser_unknown_long, NULL);
515
516         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
517                 hf_browser_unknown_long, NULL);
518
519         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
520                 hf_browser_unknown_long, NULL);
521
522         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
523                 hf_browser_unknown_long, NULL);
524
525         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
526                 hf_browser_unknown_long, NULL);
527
528         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
529                 hf_browser_unknown_hyper, NULL);
530
531         return offset;
532 }
533
534
535 /*
536   IDL long Function_05(
537   IDL       [in] [unique] [string] wchar_t *element_47,
538   IDL       [out] [ref] TYPE_5 **element_48
539   IDL );
540 */
541 static int
542 dissect_browser_UNKNOWN_05_rqst(tvbuff_t *tvb, int offset,
543                         packet_info *pinfo, proto_tree *tree,
544                         char *drep)
545 {
546         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
547                         NDR_POINTER_UNIQUE, "unknown string", 
548                         hf_browser_unknown_string, 0);
549
550         return offset;
551 }
552 static int
553 dissect_browser_UNKNOWN_05_reply(tvbuff_t *tvb, int offset,
554                         packet_info *pinfo, proto_tree *tree,
555                         char *drep)
556 {
557         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
558                         dissect_browser_TYPE_5, NDR_POINTER_UNIQUE,
559                         "unknown TYPE_5", -1);
560
561         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
562                 hf_browser_rc, NULL);
563
564         return offset;
565 }
566
567
568 /*
569   IDL long Function_06(
570   IDL       [in] [unique] [string] wchar_t *element_49
571   IDL );
572 */
573 static int
574 dissect_browser_UNKNOWN_06_rqst(tvbuff_t *tvb, int offset,
575                         packet_info *pinfo, proto_tree *tree,
576                         char *drep)
577 {
578         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
579                         NDR_POINTER_UNIQUE, "unknown string", 
580                         hf_browser_unknown_string, 0);
581
582         return offset;
583 }
584 static int
585 dissect_browser_UNKNOWN_06_reply(tvbuff_t *tvb, int offset,
586                         packet_info *pinfo, proto_tree *tree,
587                         char *drep)
588 {
589         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
590                 hf_browser_rc, NULL);
591
592         return offset;
593 }
594
595
596 /*
597   IDL long Function_07(
598   IDL       [in] [unique] [string] wchar_t *element_49
599   IDL );
600 */
601 static int
602 dissect_browser_UNKNOWN_07_rqst(tvbuff_t *tvb, int offset,
603                         packet_info *pinfo, proto_tree *tree,
604                         char *drep)
605 {
606         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
607                         NDR_POINTER_UNIQUE, "unknown string", 
608                         hf_browser_unknown_string, 0);
609
610         return offset;
611 }
612 static int
613 dissect_browser_UNKNOWN_07_reply(tvbuff_t *tvb, int offset,
614                         packet_info *pinfo, proto_tree *tree,
615                         char *drep)
616 {
617         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
618                 hf_browser_rc, NULL);
619
620         return offset;
621 }
622
623
624 /*
625   IDL typedef struct {
626   IDL   TYPE_6 element_59;
627   IDL   TYPE_6 element_60;
628   IDL   TYPE_6 element_61;
629   IDL   long element_62;
630   IDL   long element_63;
631   IDL   long element_64;
632   IDL   TYPE_6 element_65;
633   IDL   long element_66;
634   IDL   long element_67;
635   IDL   long element_68;
636   IDL   long element_69;
637   IDL   long element_70;
638   IDL   long element_71;
639   IDL   long element_72;
640   IDL   long element_73;
641   IDL   long element_74;
642   IDL } TYPE_11;
643 */
644 static int
645 dissect_browser_TYPE_11(tvbuff_t *tvb, int offset,
646                         packet_info *pinfo, proto_tree *tree,
647                         char *drep)
648 {
649         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
650                 hf_browser_unknown_hyper, NULL);
651
652         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
653                 hf_browser_unknown_hyper, NULL);
654
655         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
656                 hf_browser_unknown_hyper, NULL);
657
658         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
659                 hf_browser_unknown_long, NULL);
660
661         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
662                 hf_browser_unknown_long, NULL);
663
664         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
665                 hf_browser_unknown_long, NULL);
666
667         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
668                 hf_browser_unknown_hyper, NULL);
669
670         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
671                 hf_browser_unknown_long, NULL);
672
673         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
674                 hf_browser_unknown_long, NULL);
675
676         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
677                 hf_browser_unknown_long, NULL);
678
679         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
680                 hf_browser_unknown_long, NULL);
681
682         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
683                 hf_browser_unknown_long, NULL);
684
685         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
686                 hf_browser_unknown_long, NULL);
687
688         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
689                 hf_browser_unknown_long, NULL);
690
691         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
692                 hf_browser_unknown_long, NULL);
693
694         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
695                 hf_browser_unknown_long, NULL);
696
697         return offset;
698 }
699
700 /*
701   IDL typedef struct {
702   IDL   long element_57;
703   IDL   [size_is(element_57)] [unique] TYPE_11 *element_58;
704   IDL } TYPE_10;
705 */
706 static int
707 dissect_browser_TYPE_11_array(tvbuff_t *tvb, int offset,
708                         packet_info *pinfo, proto_tree *tree,
709                         char *drep)
710 {
711         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
712                 dissect_browser_TYPE_11);
713
714         return offset;
715 }
716
717 static int
718 dissect_browser_TYPE_10(tvbuff_t *tvb, int offset,
719                         packet_info *pinfo, proto_tree *tree,
720                         char *drep)
721 {
722         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
723                 hf_browser_unknown_long, NULL);
724
725         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
726                 dissect_browser_TYPE_11_array, NDR_POINTER_UNIQUE,
727                 "unknown TYPE_11_ARRAY", -1);
728
729         return offset;
730 }
731
732
733 /*
734   IDL typedef struct {
735   IDL   long element_55;
736   IDL   [size_is(element_55)] [unique] byte *element_56;
737   IDL } TYPE_9;
738 */
739 static int
740 dissect_browser_TYPE_9_data(tvbuff_t *tvb, int offset,
741                         packet_info *pinfo, proto_tree *tree,
742                         char *drep)
743 {
744         guint32 len;
745         dcerpc_info *di;
746
747         di=pinfo->private_data;
748         if(di->conformant_run){
749                 /* this call is to make ethereal eat the array header for the conformant run */
750                 offset =dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, NULL);
751
752                 return offset;
753         }
754
755         /* this is really the length of the encoded data */
756         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
757                 hf_browser_unknown_long, &len);
758
759         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
760                 FALSE);
761         offset += len;
762
763         return len;
764 }
765 static int
766 dissect_browser_TYPE_9(tvbuff_t *tvb, int offset,
767                         packet_info *pinfo, proto_tree *tree,
768                         char *drep)
769 {
770         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
771                 hf_browser_unknown_long, NULL);
772
773         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
774                 dissect_browser_TYPE_9_data, NDR_POINTER_UNIQUE,
775                 "unknown TYPE_9", -1);
776
777         return offset;
778 }
779
780
781 /*
782   IDL typedef [switch_type(long)] union {
783   IDL   [case(100)] [unique] TYPE_9 *element_53;
784   IDL   [case(101)] [unique] TYPE_10 *element_54;
785   IDL } TYPE_8;
786 */
787 static int
788 dissect_browser_TYPE_8(tvbuff_t *tvb, int offset,
789                         packet_info *pinfo, proto_tree *tree,
790                         char *drep)
791 {
792         guint32 level;
793
794         /* this is really the union switch arm */
795         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
796                 hf_browser_unknown_long, &level);
797
798         ALIGN_TO_4_BYTES;
799
800         switch(level){
801         case 100:
802                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
803                         dissect_browser_TYPE_9, NDR_POINTER_UNIQUE,
804                         "unknown TYPE_9", -1);
805                 break;
806         case 101:
807                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
808                         dissect_browser_TYPE_10, NDR_POINTER_UNIQUE,
809                         "unknown TYPE_10", -1);
810                 break;
811         }
812
813         return offset;
814 }
815
816
817 /*
818   IDL typedef struct {
819   IDL   long element_51;
820   IDL   TYPE_8 element_52;
821   IDL } TYPE_7;
822 */
823 static int
824 dissect_browser_TYPE_7(tvbuff_t *tvb, int offset,
825                         packet_info *pinfo, proto_tree *tree,
826                         char *drep)
827 {
828         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
829                 hf_browser_unknown_long, NULL);
830
831         offset = dissect_browser_TYPE_8(tvb, offset, pinfo, tree, drep);
832
833         return offset;
834 }
835
836
837 /*
838   IDL long Function_08(
839   IDL       [in] [unique] [string] wchar_t *element_75,
840   IDL       [in] long element_76,
841   IDL   [in,out] [ref] TYPE_7 *element_77
842   IDL );
843 */
844 static int
845 dissect_browser_UNKNOWN_08_rqst(tvbuff_t *tvb, int offset,
846                         packet_info *pinfo, proto_tree *tree,
847                         char *drep)
848 {
849         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
850                         NDR_POINTER_UNIQUE, "unknown string", 
851                         hf_browser_unknown_string, 0);
852
853         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
854                 hf_browser_unknown_long, NULL);
855
856         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
857                         dissect_browser_TYPE_7, NDR_POINTER_REF,
858                         "unknown TYPE_7", -1);
859
860         return offset;
861 }
862 static int
863 dissect_browser_UNKNOWN_08_reply(tvbuff_t *tvb, int offset,
864                         packet_info *pinfo, proto_tree *tree,
865                         char *drep)
866 {
867         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
868                         dissect_browser_TYPE_7, NDR_POINTER_REF,
869                         "unknown TYPE_7", -1);
870
871         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
872                 hf_browser_rc, NULL);
873
874         return offset;
875 }
876
877
878 /*
879   IDL long Function_09(
880   IDL       [in] [unique] [string] wchar_t *element_78,
881   IDL       [in] [ref] [string] wchar_t *element_79,
882   IDL       [in] [unique] [string] wchar_t *element_80,
883   IDL       [in] long element_81
884   IDL );
885 */
886 static int
887 dissect_browser_UNKNOWN_09_rqst(tvbuff_t *tvb, int offset,
888                         packet_info *pinfo, proto_tree *tree,
889                         char *drep)
890 {
891         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
892                         NDR_POINTER_UNIQUE, "unknown string", 
893                         hf_browser_unknown_string, 0);
894
895         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
896                         NDR_POINTER_REF, "unknown string", 
897                         hf_browser_unknown_string, 0);
898
899         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
900                         NDR_POINTER_UNIQUE, "unknown string", 
901                         hf_browser_unknown_string, 0);
902
903         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
904                 hf_browser_unknown_long, NULL);
905
906         return offset;
907 }
908 static int
909 dissect_browser_UNKNOWN_09_reply(tvbuff_t *tvb, int offset,
910                         packet_info *pinfo, proto_tree *tree,
911                         char *drep)
912 {
913         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
914                 hf_browser_rc, NULL);
915
916         return offset;
917 }
918
919
920
921
922 /*
923   IDL typedef struct {
924   IDL   long element_82;
925   IDL   [size_is(element_82)] [unique] byte *element_83;
926   IDL } TYPE_12;
927 */
928 static int
929 dissect_browser_TYPE_12_data(tvbuff_t *tvb, int offset,
930                         packet_info *pinfo, proto_tree *tree,
931                         char *drep)
932 {
933         guint32 len;
934         dcerpc_info *di;
935
936         di=pinfo->private_data;
937         if(di->conformant_run){
938                 /* this call is to make ethereal eat the array header for the conformant run */
939                 offset =dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, NULL);
940
941                 return offset;
942         }
943
944         /* this is really the length of the encoded data */
945         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
946                 hf_browser_unknown_long, &len);
947
948         proto_tree_add_item(tree, hf_browser_unknown_bytes, tvb, offset, len,
949                 FALSE);
950         offset += len;
951
952         return len;
953 }
954 static int
955 dissect_browser_TYPE_12(tvbuff_t *tvb, int offset,
956                         packet_info *pinfo, proto_tree *tree,
957                         char *drep)
958 {
959         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
960                 hf_browser_unknown_long, NULL);
961
962         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
963                 dissect_browser_TYPE_12_data, NDR_POINTER_UNIQUE,
964                 "unknown TYPE_12", -1);
965
966         return offset;
967 }
968
969
970 /*
971   IDL long Function_0a(
972   IDL       [in] [unique] [string] wchar_t *element_84,
973   IDL       [in,out] [ref] TYPE_12 *element_85
974   );
975 */
976 static int
977 dissect_browser_UNKNOWN_0a_rqst(tvbuff_t *tvb, int offset,
978                         packet_info *pinfo, proto_tree *tree,
979                         char *drep)
980 {
981         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
982                         NDR_POINTER_UNIQUE, "unknown string", 
983                         hf_browser_unknown_string, 0);
984
985         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
986                         dissect_browser_TYPE_12, NDR_POINTER_REF,
987                         "unknown TYPE_12", -1);
988
989         return offset;
990 }
991 static int
992 dissect_browser_UNKNOWN_0a_reply(tvbuff_t *tvb, int offset,
993                         packet_info *pinfo, proto_tree *tree,
994                         char *drep)
995 {
996         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
997                         dissect_browser_TYPE_12, NDR_POINTER_REF,
998                         "unknown TYPE_12", -1);
999
1000         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1001                 hf_browser_rc, NULL);
1002
1003         return offset;
1004 }
1005
1006
1007 /*
1008   IDL long Function_0b(
1009   IDL       [in] [unique] [string] wchar_t *element_86,
1010   IDL       [in] [unique] [string] wchar_t *element_87,
1011   IDL       [in] [unique] [string] wchar_t *element_88,
1012   IDL       [in,out] [ref] TYPE_1 *element_89,
1013   IDL       [in] long element_90,
1014   IDL       [out] long element_91,
1015   IDL       [in] long element_92,
1016   IDL       [in] [unique] [string] wchar_t *element_93,
1017   IDL       [in] [unique] [string] wchar_t *element_94
1018   IDL );
1019 */
1020 static int
1021 dissect_browser_UNKNOWN_0b_rqst(tvbuff_t *tvb, int offset,
1022                         packet_info *pinfo, proto_tree *tree,
1023                         char *drep)
1024 {
1025         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1026                         NDR_POINTER_UNIQUE, "unknown string", 
1027                         hf_browser_unknown_string, 0);
1028
1029         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1030                         NDR_POINTER_UNIQUE, "unknown string", 
1031                         hf_browser_unknown_string, 0);
1032
1033         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1034                         NDR_POINTER_UNIQUE, "unknown string", 
1035                         hf_browser_unknown_string, 0);
1036
1037         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1038                         dissect_browser_TYPE_1, NDR_POINTER_REF,
1039                         "unknown TYPE_1", -1);
1040
1041         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1042                 hf_browser_unknown_long, NULL);
1043
1044         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1045                 hf_browser_unknown_long, NULL);
1046
1047         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1048                         NDR_POINTER_UNIQUE, "unknown string", 
1049                         hf_browser_unknown_string, 0);
1050
1051         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1052                         NDR_POINTER_UNIQUE, "unknown string", 
1053                         hf_browser_unknown_string, 0);
1054
1055         return offset;
1056 }
1057 static int
1058 dissect_browser_UNKNOWN_0b_reply(tvbuff_t *tvb, int offset,
1059                         packet_info *pinfo, proto_tree *tree,
1060                         char *drep)
1061 {
1062         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1063                         dissect_browser_TYPE_1, NDR_POINTER_REF,
1064                         "unknown TYPE_1", -1);
1065
1066         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1067                 hf_browser_unknown_long, NULL);
1068
1069         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1070                 hf_browser_rc, NULL);
1071
1072         return offset;
1073 }
1074
1075
1076
1077 /*
1078   IDL }
1079 */
1080 static dcerpc_sub_dissector dcerpc_browser_dissectors[] = {
1081         { BROWSER_UNKNOWN_00, "BROWSER_UNKNOWN_00",
1082                 dissect_browser_UNKNOWN_00_rqst,
1083                 dissect_browser_UNKNOWN_00_reply },
1084         { BROWSER_UNKNOWN_01, "BROWSER_UNKNOWN_01",
1085                 dissect_browser_UNKNOWN_01_rqst,
1086                 dissect_browser_UNKNOWN_01_reply },
1087         { BROWSER_UNKNOWN_02, "BROWSER_UNKNOWN_02",
1088                 dissect_browser_UNKNOWN_02_rqst,
1089                 dissect_browser_UNKNOWN_02_reply },
1090         { BROWSER_UNKNOWN_03, "BROWSER_UNKNOWN_03",
1091                 dissect_browser_UNKNOWN_03_rqst,
1092                 dissect_browser_UNKNOWN_03_reply },
1093         { BROWSER_UNKNOWN_04, "BROWSER_UNKNOWN_04",
1094                 dissect_browser_UNKNOWN_04_rqst,
1095                 dissect_browser_UNKNOWN_04_reply },
1096         { BROWSER_UNKNOWN_05, "BROWSER_UNKNOWN_05",
1097                 dissect_browser_UNKNOWN_05_rqst,
1098                 dissect_browser_UNKNOWN_05_reply },
1099         { BROWSER_UNKNOWN_06, "BROWSER_UNKNOWN_06",
1100                 dissect_browser_UNKNOWN_06_rqst,
1101                 dissect_browser_UNKNOWN_06_reply },
1102         { BROWSER_UNKNOWN_07, "BROWSER_UNKNOWN_07",
1103                 dissect_browser_UNKNOWN_07_rqst,
1104                 dissect_browser_UNKNOWN_07_reply },
1105         { BROWSER_UNKNOWN_08, "BROWSER_UNKNOWN_08",
1106                 dissect_browser_UNKNOWN_08_rqst,
1107                 dissect_browser_UNKNOWN_08_reply },
1108         { BROWSER_UNKNOWN_09, "BROWSER_UNKNOWN_09",
1109                 dissect_browser_UNKNOWN_09_rqst,
1110                 dissect_browser_UNKNOWN_09_reply },
1111         { BROWSER_UNKNOWN_0a, "BROWSER_UNKNOWN_0a",
1112                 dissect_browser_UNKNOWN_0a_rqst,
1113                 dissect_browser_UNKNOWN_0a_reply },
1114         { BROWSER_UNKNOWN_0b, "BROWSER_UNKNOWN_0b",
1115                 dissect_browser_UNKNOWN_0b_rqst,
1116                 dissect_browser_UNKNOWN_0b_reply },
1117
1118         {0, NULL, NULL,  NULL }
1119 };
1120
1121 void
1122 proto_register_dcerpc_browser(void)
1123 {
1124 static hf_register_info hf[] = {
1125
1126         { &hf_browser_opnum, { 
1127                 "Operation", "rpc_browser.opnum", FT_UINT16, BASE_DEC,
1128                 NULL, 0x0, "Operation", HFILL }},
1129
1130         { &hf_browser_rc, {
1131                 "Return code", "rpc_browser.rc", FT_UINT32, BASE_HEX,
1132                 VALS(NT_errors), 0x0, "Browser return code", HFILL }},
1133
1134         { &hf_browser_unknown_long, {
1135                 "Unknown long", "rpc_browser.unknown.long", FT_UINT32, BASE_HEX,
1136                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
1137
1138         { &hf_browser_unknown_hyper, {
1139                 "Unknown hyper", "rpc_browser.unknown.hyper", FT_UINT64, BASE_HEX,
1140                 NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
1141
1142         { &hf_browser_unknown_bytes, {
1143                 "Unknown bytes", "rpc_browser.unknown.bytes", FT_BYTES, BASE_HEX,
1144                 NULL, 0x0, "Unknown bytes. If you know what this is, contact ethereal developers.", HFILL }},
1145
1146         { &hf_browser_unknown_string, {
1147                 "Unknown string", "rpc_browser.unknown.string", FT_STRING, BASE_HEX,
1148                 NULL, 0x0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }}
1149
1150         };
1151         static gint *ett[] = {
1152                 &ett_dcerpc_browser
1153         };
1154
1155         proto_dcerpc_browser = proto_register_protocol(
1156                 "RPC Browser", "RPC_BROWSER", "rpc_browser");
1157
1158         proto_register_field_array(proto_dcerpc_browser, hf,
1159                                    array_length(hf));
1160         proto_register_subtree_array(ett, array_length(ett));
1161 }
1162
1163 void
1164 proto_reg_handoff_dcerpc_browser(void)
1165 {
1166         /* Register protocol as dcerpc */
1167
1168         dcerpc_init_uuid(proto_dcerpc_browser, ett_dcerpc_browser,
1169                          &uuid_dcerpc_browser, ver_dcerpc_browser,
1170                          dcerpc_browser_dissectors, hf_browser_opnum);
1171 }