"hex_str_to_bytes()" modifies the GByteArray supplied to it, so don't
[obnox/wireshark/wip.git] / packet-dcerpc-wkssvc.c
1 /* packet-dcerpc-wkssvc.c
2  * Routines for SMB \\PIPE\\wkssvc packet disassembly
3  * Copyright 2001, Tim Potter <tpot@samba.org>
4  * Copyright 2003, Richard Sharpe <rsharpe@richardsharpe.com>
5  *
6  * $Id: packet-dcerpc-wkssvc.c,v 1.29 2003/11/19 07:13:01 sharpe Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include "packet-dcerpc.h"
34 #include "packet-dcerpc-wkssvc.h"
35 #include "packet-dcerpc-nt.h"
36 #include "smb.h"
37
38 static int proto_dcerpc_wkssvc = -1;
39 static int hf_wkssvc_opnum = -1;
40 static int hf_wkssvc_server = -1;
41 static int hf_wkssvc_info_level = -1;
42 static int hf_wkssvc_platform_id = -1; 
43 static int hf_wkssvc_net_group = -1;
44 static int hf_wkssvc_ver_major = -1;
45 static int hf_wkssvc_ver_minor = -1;
46 static int hf_wkssvc_lan_root = -1;
47 static int hf_wkssvc_rc = -1;
48 static int hf_wkssvc_logged_on_users = -1;
49 static int hf_wkssvc_pref_max = -1;
50 static int hf_wkssvc_enum_handle = -1;
51 static int hf_wkssvc_junk = -1;
52 static int hf_wkssvc_user_name = -1;
53 static int hf_wkssvc_num_entries = -1;
54 static int hf_wkssvc_logon_domain = -1;
55 static int hf_wkssvc_other_domains = -1;
56 static int hf_wkssvc_logon_server = -1;
57 static int hf_wkssvc_entries_read = -1;
58 static int hf_wkssvc_total_entries = -1;
59 static int hf_wkssvc_char_wait = -1;
60 static int hf_wkssvc_collection_time = -1;
61 static int hf_wkssvc_maximum_collection_count = -1;
62 static int hf_wkssvc_keep_conn = -1;
63 static int hf_wkssvc_max_cmds = -1;
64 static int hf_wkssvc_sess_timeout = -1;
65 static int hf_wkssvc_siz_char_buf = -1;
66 static int hf_wkssvc_max_threads = -1;
67 static int hf_wkssvc_lock_quota = -1;
68 static int hf_wkssvc_lock_increment = -1;
69 static int hf_wkssvc_lock_maximum = -1;
70 static int hf_wkssvc_pipe_increment = -1;
71 static int hf_wkssvc_pipe_maximum = -1;
72 static int hf_wkssvc_cache_file_timeout = -1;
73 static int hf_wkssvc_dormant_file_limit = -1;
74 static int hf_wkssvc_read_ahead_throughput = -1;
75 static int hf_wkssvc_num_mailslot_buffers = -1;
76 static int hf_wkssvc_num_srv_announce_buffers = -1;
77 static int hf_wkssvc_max_illegal_datagram_events = -1;
78 static int hf_wkssvc_illegal_datagram_event_reset_frequency = -1;
79 static int hf_wkssvc_log_election_packets = -1;
80 static int hf_wkssvc_use_opportunistic_locking = -1; 
81 static int hf_wkssvc_use_unlock_behind = -1; 
82 static int hf_wkssvc_use_close_behind = -1; 
83 static int hf_wkssvc_buf_named_pipes = -1;
84 static int hf_wkssvc_use_lock_read_unlock = -1;
85 static int hf_wkssvc_utilize_nt_caching = -1;
86 static int hf_wkssvc_use_raw_read = -1;
87 static int hf_wkssvc_use_raw_write = -1;
88 static int hf_wkssvc_use_write_raw_data = -1;
89 static int hf_wkssvc_use_encryption = -1; 
90 static int hf_wkssvc_buf_files_deny_write = -1;
91 static int hf_wkssvc_buf_read_only_files = -1;
92 static int hf_wkssvc_force_core_create_mode = -1;
93 static int hf_wkssvc_use_512_byte_max_transfer = -1;
94 static int hf_wkssvc_parm_err = -1;
95 static int hf_wkssvc_errlog_sz = -1;
96 static int hf_wkssvc_print_buf_time = -1;
97 static int hf_wkssvc_wrk_heuristics = -1;
98 static int hf_wkssvc_quality_of_service = -1;
99 static int hf_wkssvc_number_of_vcs = -1;
100 static int hf_wkssvc_transport_name = -1;
101 static int hf_wkssvc_transport_address = -1;
102 static int hf_wkssvc_wan_ish = -1;
103 static gint ett_dcerpc_wkssvc = -1;
104
105 static e_uuid_t uuid_dcerpc_wkssvc = {
106         0x6bffd098, 0xa112, 0x3610,
107         { 0x98, 0x33, 0x46, 0xc3, 0xf8, 0x7e, 0x34, 0x5a }
108 };
109
110 static int
111 wkssvc_dissect_ENUM_HANDLE(tvbuff_t *tvb, int offset,
112                            packet_info *pinfo, proto_tree *tree,
113                            char *drep)
114 {
115
116   offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
117                               hf_wkssvc_enum_handle, 0);
118   return offset;
119
120 }
121
122 static guint16 ver_dcerpc_wkssvc = 1;
123
124 /*
125  * IDL typedef struct {
126  * IDL   long platform_id;
127  * IDL   [string] [unique] wchar_t *server;
128  * IDL   [string] [unique] wchar_t *lan_grp;
129  * IDL   long ver_major;
130  * IDL   long ver_minor;
131  * IDL } WKS_INFO_100;
132  */
133 static int
134 wkssvc_dissect_WKS_INFO_100(tvbuff_t *tvb, int offset,
135                             packet_info *pinfo, proto_tree *tree,
136                             char *drep)
137 {
138         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
139                         hf_wkssvc_platform_id, NULL);
140
141         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
142                         NDR_POINTER_UNIQUE, "Server", hf_wkssvc_server, 0);
143
144         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
145                         NDR_POINTER_UNIQUE, "Net Group", hf_wkssvc_net_group, 0);
146
147         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
148                         hf_wkssvc_ver_major, NULL);
149
150         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
151                         hf_wkssvc_ver_minor, NULL);
152
153         return offset;
154 }
155
156 /*
157  * IDL typedef struct {
158  * IDL   long platform_id;
159  * IDL   [string] [unique] wchar_t *server;
160  * IDL   [string] [unique] wchar_t *lan_grp;
161  * IDL   long ver_major;
162  * IDL   long ver_minor;
163  * IDL   [string] [unique] wchar_t *lan_root;
164  * IDL } WKS_INFO_101;
165  */
166 static int
167 wkssvc_dissect_WKS_INFO_101(tvbuff_t *tvb, int offset,
168                             packet_info *pinfo, proto_tree *tree,
169                             char *drep)
170 {
171         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
172                         hf_wkssvc_platform_id, NULL);
173
174         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
175                         NDR_POINTER_UNIQUE, "Server", hf_wkssvc_server, 0);
176
177         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
178                         NDR_POINTER_UNIQUE, "Net Group", hf_wkssvc_net_group, 0);
179
180         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
181                         hf_wkssvc_ver_major, NULL);
182
183         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
184                         hf_wkssvc_ver_minor, NULL);
185
186         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
187                         NDR_POINTER_UNIQUE, "Lan Root", hf_wkssvc_lan_root, 0);
188
189         return offset;
190 }
191
192 /*
193  * IDL typedef struct {
194  * IDL   long platform_id;
195  * IDL   [string] [unique] wchar_t *server;
196  * IDL   [string] [unique] wchar_t *lan_grp;
197  * IDL   long ver_major;
198  * IDL   long ver_minor;
199  * IDL   [string] [unique] wchar_t *lan_root;
200  * IDL   long logged_on_users;
201  * IDL } WKS_INFO_102;
202  */
203 static int
204 wkssvc_dissect_WKS_INFO_102(tvbuff_t *tvb, int offset,
205                             packet_info *pinfo, proto_tree *tree,
206                             char *drep)
207 {
208         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
209                         hf_wkssvc_platform_id, NULL);
210
211         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
212                         NDR_POINTER_UNIQUE, "Server", hf_wkssvc_server, 0);
213
214         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
215                         NDR_POINTER_UNIQUE, "Net Group", hf_wkssvc_net_group, 0);
216
217         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
218                         hf_wkssvc_ver_major, NULL);
219
220         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
221                         hf_wkssvc_ver_minor, NULL);
222
223         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
224                         NDR_POINTER_UNIQUE, "Lan Root", hf_wkssvc_lan_root, 0);
225
226         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
227                         hf_wkssvc_logged_on_users, NULL);
228
229         return offset;
230 }
231 /*
232  * IDL typedef struct {
233  * IDL   long wki502_sess_timeout;
234  * IDL } WKS_INFO_502;
235  */
236 static int
237 wkssvc_dissect_WKS_INFO_502(tvbuff_t *tvb, int offset,
238                             packet_info *pinfo, proto_tree *tree,
239                             char *drep)
240 {
241         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
242                         hf_wkssvc_char_wait, NULL);
243
244         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
245                         hf_wkssvc_collection_time, NULL);
246
247         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
248                         hf_wkssvc_maximum_collection_count, NULL);
249
250         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
251                         hf_wkssvc_keep_conn, NULL);
252
253         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
254                         hf_wkssvc_max_cmds, NULL);
255
256         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
257                         hf_wkssvc_sess_timeout, NULL);
258
259         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
260                         hf_wkssvc_siz_char_buf, NULL);
261
262         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
263                         hf_wkssvc_max_threads, NULL);   
264
265         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
266                         hf_wkssvc_lock_quota, NULL);    
267
268         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
269                         hf_wkssvc_lock_increment, NULL);        
270
271         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
272                         hf_wkssvc_lock_maximum, NULL);  
273
274         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
275                         hf_wkssvc_pipe_increment, NULL);        
276
277         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
278                         hf_wkssvc_pipe_maximum, NULL);  
279
280         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
281                         hf_wkssvc_cache_file_timeout, NULL);    
282
283         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
284                         hf_wkssvc_dormant_file_limit, NULL);    
285
286         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
287                         hf_wkssvc_read_ahead_throughput, NULL); 
288
289         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
290                         hf_wkssvc_num_mailslot_buffers, NULL);  
291
292         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
293                         hf_wkssvc_num_srv_announce_buffers, NULL);      
294
295         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
296                         hf_wkssvc_max_illegal_datagram_events, NULL);   
297
298         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
299                             hf_wkssvc_illegal_datagram_event_reset_frequency, 
300                                     NULL);
301
302         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
303                         hf_wkssvc_log_election_packets, NULL);  
304
305         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
306                         hf_wkssvc_use_opportunistic_locking, NULL);
307
308         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
309                         hf_wkssvc_use_unlock_behind, NULL);
310
311         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
312                         hf_wkssvc_use_close_behind, NULL);
313
314         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
315                         hf_wkssvc_buf_named_pipes, NULL);                       
316         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
317                         hf_wkssvc_use_lock_read_unlock, NULL);  
318
319         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
320                         hf_wkssvc_utilize_nt_caching, NULL);    
321
322         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
323                         hf_wkssvc_use_raw_read, NULL);  
324
325         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
326                         hf_wkssvc_use_raw_write, NULL); 
327
328         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
329                         hf_wkssvc_use_write_raw_data, NULL);    
330
331         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
332                         hf_wkssvc_use_encryption, NULL);        
333
334         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
335                         hf_wkssvc_buf_files_deny_write, NULL);  
336
337         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
338                         hf_wkssvc_buf_read_only_files, NULL);   
339
340         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
341                         hf_wkssvc_force_core_create_mode, NULL);        
342
343         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
344                         hf_wkssvc_use_512_byte_max_transfer, NULL);     
345
346         return offset;
347 }
348
349 static int
350 wkssvc_dissect_WKS_INFO_1010(tvbuff_t *tvb, int offset,
351                              packet_info *pinfo, proto_tree *tree,
352                              char *drep)
353 {
354         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
355                         hf_wkssvc_char_wait, NULL);
356
357         return offset;
358 }
359
360 static int
361 wkssvc_dissect_WKS_INFO_1011(tvbuff_t *tvb, int offset,
362                              packet_info *pinfo, proto_tree *tree,
363                              char *drep)
364 {
365         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
366                         hf_wkssvc_collection_time, NULL);
367
368         return offset;
369 }
370
371 static int
372 wkssvc_dissect_WKS_INFO_1012(tvbuff_t *tvb, int offset,
373                              packet_info *pinfo, proto_tree *tree,
374                              char *drep)
375 {
376         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
377                         hf_wkssvc_maximum_collection_count, NULL);
378
379         return offset;
380 }
381
382 static int
383 wkssvc_dissect_WKS_INFO_1013(tvbuff_t *tvb, int offset,
384                              packet_info *pinfo, proto_tree *tree,
385                              char *drep)
386 {
387         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
388                         hf_wkssvc_keep_conn, NULL);
389
390         return offset;
391 }
392
393 static int
394 wkssvc_dissect_WKS_INFO_1018(tvbuff_t *tvb, int offset,
395                              packet_info *pinfo, proto_tree *tree,
396                              char *drep)
397 {
398         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
399                         hf_wkssvc_sess_timeout, NULL);
400
401         return offset;
402 }
403
404 static int
405 wkssvc_dissect_WKS_INFO_1023(tvbuff_t *tvb, int offset,
406                              packet_info *pinfo, proto_tree *tree,
407                              char *drep)
408 {
409         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
410                         hf_wkssvc_siz_char_buf, NULL);
411
412         return offset;
413 }
414
415 static int
416 wkssvc_dissect_WKS_INFO_1027(tvbuff_t *tvb, int offset,
417                              packet_info *pinfo, proto_tree *tree,
418                              char *drep)
419 {
420         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
421                         hf_wkssvc_errlog_sz, NULL);
422
423         return offset;
424 }
425
426 static int
427 wkssvc_dissect_WKS_INFO_1033(tvbuff_t *tvb, int offset,
428                              packet_info *pinfo, proto_tree *tree,
429                              char *drep)
430 {
431         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
432                         hf_wkssvc_max_threads, NULL);
433
434         return offset;
435 }
436
437 /*
438  * IDL long NetWkstaGetInfo(
439  * IDL      [in] [string] [unique] wchar_t *ServerName,
440  * IDL      [in] long level,
441  * IDL      [out] [ref] WKS_INFO_UNION *wks
442  * IDL );
443  */
444 static int
445 wkssvc_dissect_netwkstagetinfo_rqst(tvbuff_t *tvb, int offset, 
446                                     packet_info *pinfo, proto_tree *tree,
447                                     char *drep)
448 {
449         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
450                                               NDR_POINTER_UNIQUE, "Server", 
451                                               hf_wkssvc_server, 0);
452
453         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
454                                     hf_wkssvc_info_level, 0);
455
456         return offset;
457
458 }
459
460 /*
461  * IDL typedef [switch_type(long)] union {
462  * IDL   [case(100)] [unique] WKS_INFO_100 *wks100;
463  * IDL   [case(101)] [unique] WKS_INFO_101 *wks101;
464  * IDL   [case(102)] [unique] WKS_INFO_102 *wks102;
465  * IDL   [case(502)] [unique] WKS_INFO_502 *wks502;
466  * IDL   [case(1010)] [unique] WKS_INFO_1010 *wks1010;
467  * IDL   [case(1011)] [unique] WKS_INFO_1011 *wks1011;
468  * IDL   [case(1012)] [unique] WKS_INFO_1012 *wks1012;
469  * IDL   [case(1013)] [unique] WKS_INFO_1013 *wks1013;
470  * IDL   [case(1018)] [unique] WKS_INFO_1018 *wks1018;
471  * IDL   [case(1023)] [unique] WKS_INFO_1023 *wks1023;
472  * IDL   [case(1027)] [unique] WKS_INFO_1027 *wks1027;
473  * IDL   [case(1033)] [unique] WKS_INFO_1033 *wks1033;
474  * IDL } WKS_INFO_UNION;
475  */
476 static int
477 wkssvc_dissect_WKS_GETINFO_UNION(tvbuff_t *tvb, int offset,
478                                  packet_info *pinfo, proto_tree *tree,
479                                  char *drep)
480 {
481         guint32 level;
482
483         ALIGN_TO_4_BYTES;
484
485         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_wkssvc_info_level, &level);
486
487         switch(level){
488         case 100:
489                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
490                         wkssvc_dissect_WKS_INFO_100,
491                         NDR_POINTER_UNIQUE, "WKS_INFO_100:", -1);
492                 break;
493
494         case 101:
495                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
496                         wkssvc_dissect_WKS_INFO_101,
497                         NDR_POINTER_UNIQUE, "WKS_INFO_101:", -1);
498                 break;
499
500         case 102:
501                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
502                         wkssvc_dissect_WKS_INFO_102,
503                         NDR_POINTER_UNIQUE, "WKS_INFO_102:", -1);
504                 break;
505
506                 /* There is a 302 and 402 level, but I am too lazy today */
507
508         case 502:
509                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
510                                              wkssvc_dissect_WKS_INFO_502,
511                                              NDR_POINTER_UNIQUE, 
512                                              "WKS_INFO_502:", -1);
513                 break;
514
515         case 1010:
516                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
517                                              wkssvc_dissect_WKS_INFO_1010,
518                                              NDR_POINTER_UNIQUE, 
519                                              "WKS_INFO_1010:", -1);
520                 break;
521
522         case 1011:
523                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
524                                              wkssvc_dissect_WKS_INFO_1011,
525                                              NDR_POINTER_UNIQUE, 
526                                              "WKS_INFO_1011:", -1);
527                 break;
528
529         case 1012:
530                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
531                                              wkssvc_dissect_WKS_INFO_1012,
532                                              NDR_POINTER_UNIQUE, 
533                                              "WKS_INFO_1012:", -1);
534                 break;
535
536         case 1013:
537                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
538                                              wkssvc_dissect_WKS_INFO_1013,
539                                              NDR_POINTER_UNIQUE, 
540                                              "WKS_INFO_1013:", -1);
541                 break;
542
543         case 1018:
544                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
545                                              wkssvc_dissect_WKS_INFO_1018,
546                                              NDR_POINTER_UNIQUE, 
547                                              "WKS_INFO_1018:", -1);
548                 break;
549
550         case 1023:
551                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
552                                              wkssvc_dissect_WKS_INFO_1023,
553                                              NDR_POINTER_UNIQUE, 
554                                              "WKS_INFO_1023:", -1);
555                 break;
556
557         case 1027:
558                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
559                                              wkssvc_dissect_WKS_INFO_1027,
560                                              NDR_POINTER_UNIQUE, 
561                                              "WKS_INFO_1027:", -1);
562                 break;
563
564         case 1033:
565                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
566                                              wkssvc_dissect_WKS_INFO_1033,
567                                              NDR_POINTER_UNIQUE, 
568                                              "WKS_INFO_1033:", -1);
569                 break;
570
571                 /*      case 1018:
572                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
573                                              wkssvc_dissect_WKS_INFO_1018,
574                                              NDR_POINTER_UNIQUE, 
575                                              "WKS_INFO_1018:", -1);
576                                              break; */
577
578         }
579
580         return offset;
581
582 }
583
584 static int wkssvc_dissect_netwkstagetinfo_reply(tvbuff_t *tvb, int offset,
585                                                 packet_info *pinfo, 
586                                                 proto_tree *tree,
587                                                 char *drep)
588 {
589         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
590                         wkssvc_dissect_WKS_GETINFO_UNION,
591                         NDR_POINTER_REF, "Server Info", -1);
592
593         offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
594                         hf_wkssvc_rc, NULL);
595
596         return offset;
597 }
598
599 /*
600  * IDL long NetWkstaSetInfo(
601  * IDL      [in] [string] [unique] wchar_t *ServerName,
602  * IDL      [in] long level,
603  * IDL      [in] [ref] WKS_INFO_UNION *wks,
604  * IDL      [out] long parm_err
605  * IDL );
606  */
607 static int wkssvc_dissect_netwkstasetinfo_rqst(tvbuff_t *tvb, int offset,
608                                                packet_info *pinfo, 
609                                                proto_tree *tree,
610                                                char *drep)
611 {
612         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
613                                               NDR_POINTER_UNIQUE, "Server", 
614                                               hf_wkssvc_server, 0);
615
616         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
617                                     hf_wkssvc_info_level, 0);
618
619         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
620                         wkssvc_dissect_WKS_GETINFO_UNION,
621                         NDR_POINTER_REF, "Server Info", -1);
622
623         return offset;
624
625 }
626
627 static int wkssvc_dissect_netwkstasetinfo_reply(tvbuff_t *tvb, int offset,
628                                                 packet_info *pinfo, 
629                                                 proto_tree *tree,
630                                                 char *drep)
631 {
632         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
633                                     hf_wkssvc_parm_err, 0);
634
635         offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
636         hf_wkssvc_rc, NULL);
637
638         return offset;
639
640 }
641
642 /*
643  * IDL typedef struct {
644  * IDL   [string] [unique] wchar_t *dev;
645  * IDL } USER_INFO_0;
646  */
647 static int
648 wkssvc_dissect_USER_INFO_0(tvbuff_t *tvb, int offset,
649                                      packet_info *pinfo, proto_tree *tree,
650                                      char *drep)
651 {
652         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
653                         NDR_POINTER_UNIQUE, "User Name", 
654                         hf_wkssvc_user_name, 0);
655
656         return offset;
657 }
658
659 static int
660 wkssvc_dissect_USER_INFO_0_array(tvbuff_t *tvb, int offset,
661                                      packet_info *pinfo, proto_tree *tree,
662                                      char *drep)
663 {
664         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
665                         wkssvc_dissect_USER_INFO_0);
666
667         return offset;
668 }
669
670 /*
671  * IDL typedef struct {
672  * IDL   long EntriesRead;
673  * IDL   [size_is(EntriesRead)] [unique] USER_INFO_0 *devs;
674  * IDL } USER_INFO_0_CONTAINER;
675  */
676 static int
677 wkssvc_dissect_USER_INFO_0_CONTAINER(tvbuff_t *tvb, int offset,
678                                      packet_info *pinfo, proto_tree *tree,
679                                      char *drep)
680 {
681         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
682                 hf_wkssvc_num_entries, NULL);
683
684         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
685                 wkssvc_dissect_USER_INFO_0_array, NDR_POINTER_UNIQUE,
686                 "USER_INFO_0 array:", -1);
687
688         return offset;
689 }
690
691 /*
692  * IDL typedef struct {
693  * IDL   [string] [unique] wchar_t *user_name;
694  * IDL   [string] [unique] wchar_t *logon_domain;
695  * IDL   [string] [unique] wchar_t *other_domains;
696  * IDL   [string] [unique] wchar_t *logon_server;
697  * IDL } USER_INFO_1;
698  */
699 static int
700 wkssvc_dissect_USER_INFO_1(tvbuff_t *tvb, int offset,
701                                      packet_info *pinfo, proto_tree *tree,
702                                      char *drep)
703 {
704         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
705                                               NDR_POINTER_UNIQUE, "User Name", 
706                                               hf_wkssvc_user_name, 0);
707
708         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
709                         NDR_POINTER_UNIQUE, "Logon Domain", 
710                                               hf_wkssvc_logon_domain, 0);
711
712         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
713                         NDR_POINTER_UNIQUE, "Other Domains", 
714                                               hf_wkssvc_other_domains, 0);
715
716         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
717                         NDR_POINTER_UNIQUE, "Logon Server", 
718                                               hf_wkssvc_logon_server, 0);
719
720
721         return offset;
722 }
723 static int
724 wkssvc_dissect_USER_INFO_1_array(tvbuff_t *tvb, int offset,
725                                      packet_info *pinfo, proto_tree *tree,
726                                      char *drep)
727 {
728         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
729                         wkssvc_dissect_USER_INFO_1);
730
731         return offset;
732 }
733
734 /*
735  * IDL typedef struct {
736  * IDL   long EntriesRead;
737  * IDL   [size_is(EntriesRead)] [unique] USER_INFO_1 *devs;
738  * IDL } USER_INFO_1_CONTAINER;
739  */
740 static int
741 wkssvc_dissect_USER_INFO_1_CONTAINER(tvbuff_t *tvb, int offset,
742                                      packet_info *pinfo, proto_tree *tree,
743                                      char *drep)
744 {
745         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
746                 hf_wkssvc_num_entries, NULL);
747
748         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
749                 wkssvc_dissect_USER_INFO_1_array, NDR_POINTER_UNIQUE,
750                 "USER_INFO_1 array:", -1);
751
752         return offset;
753 }
754
755 /*
756  * IDL typedef [switch_type(long)] union {
757  * IDL   [case(0)] [unique] USER_INFO_0_CONTAINER *dev0;
758  * IDL   [case(1)] [unique] USER_INFO_1_CONTAINER *dev1;
759  * IDL } CHARDEV_ENUM_UNION;
760  */
761 static int
762 wkssvc_dissect_USER_ENUM_UNION(tvbuff_t *tvb, int offset,
763                                      packet_info *pinfo, proto_tree *tree,
764                                      char *drep)
765 {
766         guint32 level;
767
768         ALIGN_TO_4_BYTES;
769
770         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_wkssvc_info_level, &level);
771
772         switch(level){
773         case 0:
774                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
775                         wkssvc_dissect_USER_INFO_0_CONTAINER,
776                         NDR_POINTER_UNIQUE, "USER_INFO_0_CONTAINER:", -1);
777                 break;
778         case 1:
779                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
780                         wkssvc_dissect_USER_INFO_1_CONTAINER,
781                         NDR_POINTER_UNIQUE, "USER_INFO_1_CONTAINER:", -1);
782                 break;
783         }
784
785         return offset;
786 }
787
788 /*
789  * IDL long NetWkstaEnumUsers(
790  * IDL      [in] [string] [unique] wchar_t *ServerName,
791  * IDL      [in] long level,
792  * IDL      [in] [out] [ref] WKS_USER_ENUM_STRUCT *users,
793  * IDL      [in] long prefmaxlen,
794  * IDL      [out] long *entriesread,
795  * IDL      [out] long *totalentries,
796  * IDL      [in] [out] [ref] long *resumehandle
797  * IDL );
798  */
799 static int
800 wkssvc_dissect_netwkstaenumusers_rqst(tvbuff_t *tvb, int offset, 
801                                       packet_info *pinfo, proto_tree *tree,
802                                       char *drep)
803 {
804         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
805                                               NDR_POINTER_UNIQUE, "Server", 
806                                               hf_wkssvc_server, 0);
807
808         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
809                                     hf_wkssvc_info_level, 0);
810
811         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
812                         wkssvc_dissect_USER_ENUM_UNION,
813                         NDR_POINTER_REF, "User Info", -1);
814         /* Seems to be junk here ... */
815         /*      offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, 
816                                     hf_wkssvc_junk, 0);
817
818         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, 
819                                      wkssvc_dissect_ENUM_HANDLE,
820                                      NDR_POINTER_UNIQUE, "Junk Handle", -1);
821
822         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, 
823         hf_wkssvc_junk, 0); */
824
825         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
826                                     hf_wkssvc_pref_max, 0);
827
828         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, 
829                                      wkssvc_dissect_ENUM_HANDLE,
830                                      NDR_POINTER_UNIQUE, "Enum Handle", -1);
831
832         return offset;
833
834 }
835
836 static int wkssvc_dissect_netwkstaenumusers_reply(tvbuff_t *tvb, int offset,
837                                                   packet_info *pinfo, 
838                                                   proto_tree *tree,
839                                                   char *drep)
840 {
841         /* There seems to be an info level there first */
842         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
843                                     hf_wkssvc_info_level, 0);
844
845         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
846                         wkssvc_dissect_USER_ENUM_UNION,
847                         NDR_POINTER_REF, "User Info", -1);
848
849         /* Entries read seems to be in the enum array ... */
850
851         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
852                                     hf_wkssvc_total_entries, 0);
853
854         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, 
855                                      wkssvc_dissect_ENUM_HANDLE,
856                                      NDR_POINTER_UNIQUE, "Enum Handle", -1);
857
858         offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
859         hf_wkssvc_rc, NULL);
860
861         return offset;
862 }
863
864 /*
865  * IDL typedef struct {
866  * IDL   long quality_of_service;
867  * IDL   long number_of_vcs;
868  * IDL   [string] [unique] wchar_t *transport_name;
869  * IDL   [string] [unique] wchar_t *transport_address; 
870  * IDL   BOOL wan_ish;
871  * IDL } TRANSPORT_INFO_0;
872  */
873 static int
874 wkssvc_dissect_TRANSPORT_INFO_0(tvbuff_t *tvb, int offset,
875                                      packet_info *pinfo, proto_tree *tree,
876                                      char *drep)
877 {
878         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
879                                     hf_wkssvc_quality_of_service, 0);
880
881         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
882                                     hf_wkssvc_number_of_vcs, 0);
883
884         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
885                         NDR_POINTER_UNIQUE, "Transport Name", 
886                         hf_wkssvc_transport_name, 0);
887
888         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
889                         NDR_POINTER_UNIQUE, "Transport Address", 
890                         hf_wkssvc_transport_address, 0);
891
892         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
893                                     hf_wkssvc_wan_ish, 0);
894
895         return offset;
896 }
897
898 static int
899 wkssvc_dissect_TRANSPORT_INFO_0_array(tvbuff_t *tvb, int offset,
900                                      packet_info *pinfo, proto_tree *tree,
901                                      char *drep)
902 {
903         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
904                         wkssvc_dissect_TRANSPORT_INFO_0);
905
906         return offset;
907 }
908
909 /*
910  * IDL typedef struct {
911  * IDL   long EntriesRead;
912  * IDL   [size_is(EntriesRead)] [unique] TRANSPORT_INFO_0 *devs;
913  * IDL } TRANSPORT_INFO_0_CONTAINER;
914  */
915 static int
916 wkssvc_dissect_TRANSPORT_INFO_0_CONTAINER(tvbuff_t *tvb, int offset,
917                                      packet_info *pinfo, proto_tree *tree,
918                                      char *drep)
919 {
920         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
921                 hf_wkssvc_num_entries, NULL);
922
923         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
924                 wkssvc_dissect_TRANSPORT_INFO_0_array, NDR_POINTER_UNIQUE,
925                 "TRANSPORT_INFO_0 array:", -1);
926
927         return offset;
928 }
929
930 /*
931  * IDL typedef [switch_type(long)] union {
932  * IDL   [case(0)] [unique] TRANSPORT_INFO_0_CONTAINER *dev0;
933  * IDL } TRANSPORT_ENUM_UNION;
934  */
935 static int
936 wkssvc_dissect_TRANSPORT_ENUM_UNION(tvbuff_t *tvb, int offset,
937                                      packet_info *pinfo, proto_tree *tree,
938                                      char *drep)
939 {
940         guint32 level;
941
942         ALIGN_TO_4_BYTES;
943
944         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_wkssvc_info_level, &level);
945
946         switch(level){
947         case 0:
948                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
949                         wkssvc_dissect_TRANSPORT_INFO_0_CONTAINER,
950                         NDR_POINTER_UNIQUE, "TRANSPORT_INFO_0_CONTAINER:", -1);
951                 break;
952
953         }
954
955         return offset;
956 }
957
958 /*
959  * IDL long NetWkstaTransportEnum(
960  * IDL      [in] [string] [unique] wchar_t *ServerName,
961  * IDL      [in] long level,
962  * IDL      [in] [out] [ref] WKS_TRANSPORT_ENUM_STRUCT *users,
963  * IDL      [in] long prefmaxlen,
964  * IDL      [out] long *entriesread,
965  * IDL      [out] long *totalentries,
966  * IDL      [in] [out] [ref] long *resumehandle
967  * IDL );
968  */
969 static int
970 wkssvc_dissect_netwkstatransportenum_rqst(tvbuff_t *tvb, int offset, 
971                                       packet_info *pinfo, proto_tree *tree,
972                                       char *drep)
973 {
974         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
975                                               NDR_POINTER_UNIQUE, "Server", 
976                                               hf_wkssvc_server, 0);
977
978         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
979                                     hf_wkssvc_info_level, 0);
980
981         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
982                         wkssvc_dissect_TRANSPORT_ENUM_UNION,
983                         NDR_POINTER_REF, "Transport Info", -1);
984
985         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
986                                     hf_wkssvc_pref_max, 0);
987
988         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, 
989                                      wkssvc_dissect_ENUM_HANDLE,
990                                      NDR_POINTER_UNIQUE, "Enum Handle", -1);
991
992         return offset;
993
994 }
995
996 static int wkssvc_dissect_netwkstatransportenum_reply(tvbuff_t *tvb, 
997                                                       int offset,
998                                                       packet_info *pinfo, 
999                                                       proto_tree *tree,
1000                                                       char *drep)
1001 {
1002         /* There seems to be an info level there first */
1003         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1004                                     hf_wkssvc_info_level, 0);
1005
1006         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1007                         wkssvc_dissect_TRANSPORT_ENUM_UNION,
1008                         NDR_POINTER_REF, "Transport Info", -1);
1009
1010         /* Entries read seems to be in the enum array ... */
1011
1012         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1013                                     hf_wkssvc_total_entries, 0);
1014
1015         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, 
1016                                      wkssvc_dissect_ENUM_HANDLE,
1017                                      NDR_POINTER_UNIQUE, "Enum Handle", -1);
1018
1019         offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
1020         hf_wkssvc_rc, NULL);
1021
1022         return offset;
1023 }
1024
1025 static dcerpc_sub_dissector dcerpc_wkssvc_dissectors[] = {
1026         { WKS_NETRWKSTAGETINFO, "NetrWkstaGetInfo", 
1027           wkssvc_dissect_netwkstagetinfo_rqst, 
1028           wkssvc_dissect_netwkstagetinfo_reply},
1029         { WKS_NETRWKSTASETINFO, "NetrWkstaSetInfo",
1030           wkssvc_dissect_netwkstasetinfo_rqst,
1031           wkssvc_dissect_netwkstasetinfo_reply},
1032         { WKS_NETRWKSTAUSERENUM, "NetrWkstaUserEnum",
1033           wkssvc_dissect_netwkstaenumusers_rqst,
1034           wkssvc_dissect_netwkstaenumusers_reply},
1035         { WKS_NETRWKSTAUSERGETINFO, "NetrWkstaUserGetInfo", NULL, NULL },
1036         { WKS_NETRWKSTAUSERSETINFO, "NetrWkstaUserSetInfo", NULL, NULL },
1037         { WKS_NETRWKSTATRANSPORTENUM, "NetrWkstaTransportEnum",
1038           wkssvc_dissect_netwkstatransportenum_rqst, 
1039           wkssvc_dissect_netwkstatransportenum_reply},
1040         { WKS_NETRWKSTATRANSPORTADD, "NetrWkstaTransportAdd", NULL, NULL },
1041         { WKS_NETRWKSTATRANSPORTDEL, "NetrWkstaTransportDel", NULL, NULL },
1042         { WKS_NETRUSEADD, "NetrUseAdd", NULL, NULL },
1043         { WKS_NETRUSEGETINFO, "NetrUseGetInfo", NULL, NULL },
1044         { WKS_NETRUSEDEL, "NetrUseDel", NULL, NULL },
1045         { WKS_NETRUSEENUM, "NetrUseEnum", NULL, NULL },
1046         { WKS_NETRMESSAGEBUFFERSEND, "NetrMessageBufferSend", NULL, NULL },
1047         { WKS_NETRWORKSTATIONSTATISTICSGET, "NetrWorkstationStatisticsGet", 
1048           NULL, NULL },
1049         { WKS_NETRLOGONDOMAINNAMEADD, "NetrLogonDomainNameAdd", NULL, NULL },
1050         { WKS_NETRLOGONDOMAINNAMEDEL, "NetrLogonDomainNameDel", NULL, NULL },
1051         { WKS_NETRJOINDOMAIN, "NetrJoinDomain", NULL, NULL },
1052         { WKS_NETRUNJOINDOMAIN, "NetrUnjoinDomain", NULL, NULL },
1053         { WKS_NETRRENAMEMACHINEINDOMAIN, "NetrRenameMachineInDomain", 
1054           NULL, NULL },
1055         { WKS_NETRVALIDATENAME, "NetrValidateName", NULL, NULL },
1056         { WKS_NETRGETJOININFORMATION, "NetrGetJoinInformation", NULL, NULL },
1057         { WKS_NETRGETJOINABLEOUS, "NetrGetJoinableOUs", NULL, NULL },
1058         { WKS_NETRJOINDOMAIN2, "NetrJoinDomain2", NULL, NULL },
1059         { WKS_NETRUNJOINDOMAIN2, "NetrUnjoinDomain2", NULL, NULL },
1060         { WKS_NETRRENAMEMACHINEINDOMAIN2, "NetrRenameMachineInDomain2", 
1061           NULL, NULL },
1062         { WKS_NETRVALIDATENAME2, "NetrValidateName2", NULL, NULL },
1063         { WKS_NETRGETJOINABLEOUS2, "NetrGetJoinableOUs2", NULL, NULL },
1064         { WKS_NETRADDALTERNATECOMPUTERNAME, "NetrAddAlternateComputerName", 
1065           NULL, NULL },
1066         { WKS_NETRREMOVEALTERNATECOMPUTERNAME,
1067           "NetrRemoveAlternateComputerName", NULL, NULL },
1068         { WKS_NETRSETPRIMARYCOMPUTERNAME, "NetrSetPrimaryComputerName", 
1069           NULL, NULL },
1070         { WKS_NETRENUMERATECOMPUTERNAMES, "NetrEnumerateComputerNames", 
1071           NULL, NULL },
1072         {0, NULL, NULL,  NULL }
1073 };
1074
1075 void
1076 proto_register_dcerpc_wkssvc(void)
1077 {
1078         static hf_register_info hf[] = { 
1079           { &hf_wkssvc_opnum,
1080             { "Operation", "wkssvc.opnum", FT_UINT16, BASE_DEC,
1081               NULL, 0x0, "", HFILL }},
1082           { &hf_wkssvc_server,
1083             { "Server", "wkssvc.server", FT_STRING, BASE_NONE,
1084               NULL, 0x0, "Server Name", HFILL}},
1085           { &hf_wkssvc_net_group,
1086             { "Net Group", "wkssvc.netgrp", FT_STRING, BASE_NONE,
1087               NULL, 0x0, "Net Group", HFILL}},
1088           { &hf_wkssvc_info_level,
1089             { "Info Level", "wkssvc.info_level", FT_UINT32,
1090               BASE_DEC, NULL, 0x0, "Info Level", HFILL}},
1091           { &hf_wkssvc_platform_id,
1092             { "Platform ID", "wkssvc.info.platform_id", FT_UINT32,
1093               BASE_DEC, VALS(platform_id_vals), 0x0, "Platform ID", HFILL}},
1094           { &hf_wkssvc_ver_major,
1095             { "Major Version", "wkssvc.version.major", FT_UINT32,
1096               BASE_DEC, NULL, 0x0, "Major Version", HFILL}},
1097           { &hf_wkssvc_ver_minor,
1098             { "Minor Version", "wkssvc.version.minor", FT_UINT32,
1099               BASE_DEC, NULL, 0x0, "Minor Version", HFILL}},
1100           { &hf_wkssvc_lan_root,
1101             { "Lan Root", "wkssvc.lan.root", FT_STRING, BASE_NONE,
1102               NULL, 0x0, "Lan Root", HFILL}},
1103           { &hf_wkssvc_logged_on_users,
1104             { "Logged On Users", "wkssvc.logged.on.users", FT_UINT32,
1105               BASE_DEC, NULL, 0x0, "Logged On Users", HFILL}},
1106           { &hf_wkssvc_pref_max, 
1107             { "Preferred Max Len", "wkssvc.pref.max.len", FT_INT32,
1108               BASE_DEC, NULL, 0x0, "Preferred Max Len", HFILL}},
1109           { &hf_wkssvc_junk, 
1110             { "Junk", "wkssvc.junk", FT_UINT32,
1111               BASE_DEC, NULL, 0x0, "Junk", HFILL}},
1112           { &hf_wkssvc_enum_handle,
1113             { "Enumeration handle", "wkssvc.enum_hnd", FT_BYTES,
1114               BASE_HEX, NULL, 0x0, "Enumeration Handle", HFILL}},
1115           { &hf_wkssvc_user_name,
1116             { "User Name", "wkssvc.user.name", FT_STRING, BASE_NONE,
1117               NULL, 0x0, "User Name", HFILL}},
1118           { &hf_wkssvc_logon_domain,
1119             { "Logon Domain", "wkssvc.logon.domain", FT_STRING, BASE_NONE,
1120               NULL, 0x0, "Logon Domain", HFILL}},
1121           { &hf_wkssvc_other_domains,
1122             { "Other Domains", "wkssvc.other.domains", FT_STRING, BASE_NONE,
1123               NULL, 0x0, "Other Domains", HFILL}},
1124           { &hf_wkssvc_logon_server,
1125             { "Logon Server", "wkssvc.logon.server", FT_STRING, BASE_NONE,
1126               NULL, 0x0, "Logon Server", HFILL}},
1127           { &hf_wkssvc_rc,
1128             { "Return code", "srvsvc.rc", FT_UINT32,
1129               BASE_HEX, VALS(DOS_errors), 0x0, "Return Code", HFILL}},
1130           { &hf_wkssvc_num_entries, 
1131             { "Num Entries", "wkssvc.num.entries", FT_INT32,
1132               BASE_DEC, NULL, 0x0, "Num Entries", HFILL}},
1133           { &hf_wkssvc_entries_read, 
1134             { "Entries Read", "wkssvc.entries.read", FT_INT32,
1135               BASE_DEC, NULL, 0x0, "Entries Read", HFILL}},
1136           { &hf_wkssvc_total_entries, 
1137             { "Total Entries", "wkssvc.total.entries", FT_INT32,
1138               BASE_DEC, NULL, 0x0, "Total Entries", HFILL}},
1139           { &hf_wkssvc_char_wait, 
1140             { "Char Wait", "wkssvc.char.wait", FT_INT32,
1141               BASE_DEC, NULL, 0x0, "Char Wait", HFILL}},
1142           { &hf_wkssvc_collection_time, 
1143             { "Collection Time", "wkssvc.collection.time", FT_INT32,
1144               BASE_DEC, NULL, 0x0, "Collection Time", HFILL}},
1145           { &hf_wkssvc_maximum_collection_count, 
1146             { "Maximum Collection Count", "wkssvc.maximum.collection.count", 
1147               FT_INT32,
1148               BASE_DEC, NULL, 0x0, "Maximum Collection Count", HFILL}},
1149           { &hf_wkssvc_keep_conn, 
1150             { "Keep Connection", "wkssvc.keep.connection", FT_INT32,
1151               BASE_DEC, NULL, 0x0, "Keep Connection", HFILL}},
1152           { &hf_wkssvc_max_cmds, 
1153             { "Maximum Commands", "wkssvc.maximum.commands", FT_INT32,
1154               BASE_DEC, NULL, 0x0, "Maximum Commands", HFILL}},
1155           { &hf_wkssvc_sess_timeout, 
1156             { "Session Timeout", "wkssvc.session.timeout", FT_INT32,
1157               BASE_DEC, NULL, 0x0, "Session Timeout", HFILL}},
1158           { &hf_wkssvc_siz_char_buf, 
1159             { "Character Buffer Size", "wkssvc.size.char.buff", FT_INT32,
1160               BASE_DEC, NULL, 0x0, "Character Buffer Size", HFILL}},
1161           { &hf_wkssvc_max_threads, 
1162             { "Maximum Threads", "wkssvc.maximum.threads", FT_INT32,
1163               BASE_DEC, NULL, 0x0, "Maximum Threads", HFILL}},
1164           { &hf_wkssvc_lock_quota, 
1165             { "Lock Quota", "wkssvc.lock.quota", FT_INT32,
1166               BASE_DEC, NULL, 0x0, "Lock Quota", HFILL}},
1167           { &hf_wkssvc_lock_increment, 
1168             { "Lock Increment", "wkssvc.lock.increment", FT_INT32,
1169               BASE_DEC, NULL, 0x0, "Lock Increment", HFILL}},
1170           { &hf_wkssvc_lock_maximum, 
1171             { "Lock Maximum", "wkssvc.lock.maximum", FT_INT32,
1172               BASE_DEC, NULL, 0x0, "Lock Maximum", HFILL}},
1173           { &hf_wkssvc_pipe_increment, 
1174             { "Pipe Increment", "wkssvc.pipe.increment", FT_INT32,
1175               BASE_DEC, NULL, 0x0, "Pipe Increment", HFILL}},
1176           { &hf_wkssvc_pipe_maximum, 
1177             { "Pipe Maximum", "wkssvc.pipe.maximum", FT_INT32,
1178               BASE_DEC, NULL, 0x0, "Pipe Maximum", HFILL}},
1179           { &hf_wkssvc_cache_file_timeout, 
1180             { "Cache File Timeout", "wkssvc.cache.file.timeout", FT_INT32,
1181               BASE_DEC, NULL, 0x0, "Cache File Timeout", HFILL}},
1182           { &hf_wkssvc_dormant_file_limit, 
1183             { "Dormant File Limit", "wkssvc.dormant.file.limit", FT_INT32,
1184               BASE_DEC, NULL, 0x0, "Dormant File Limit", HFILL}},
1185           { &hf_wkssvc_read_ahead_throughput, 
1186             { "Read Ahead Throughput", "wkssvc.read.ahead.throughput", FT_INT32,
1187               BASE_DEC, NULL, 0x0, "Read Ahead Throughput", HFILL}},
1188           { &hf_wkssvc_num_mailslot_buffers, 
1189             { "Num Mailslot Buffers", "wkssvc.num.mailslot.buffers", FT_INT32,
1190               BASE_DEC, NULL, 0x0, "Num Mailslot Buffers", HFILL}},
1191           { &hf_wkssvc_num_srv_announce_buffers, 
1192             { "Num Srv Announce Buffers", "wkssvc.num.srv.announce.buffers", FT_INT32,
1193               BASE_DEC, NULL, 0x0, "Num Srv Announce Buffers", HFILL}},
1194           { &hf_wkssvc_max_illegal_datagram_events, 
1195             { "Max Illegal Datagram Events", "wkssvc.max.illegal.datagram.events", FT_INT32,
1196               BASE_DEC, NULL, 0x0, "Max Illegal Datagram Events", HFILL}},
1197           { &hf_wkssvc_illegal_datagram_event_reset_frequency, 
1198             { "Illegal Datagram Event Reset Frequency", "wkssvc.illegal.datagram.reset.frequency", FT_INT32,
1199               BASE_DEC, NULL, 0x0, "Illegal Datagram Event Reset Frequency", HFILL}},
1200           { &hf_wkssvc_log_election_packets, 
1201             { "Log Election Packets", "wkssvc.log.election.packets", FT_INT32,
1202               BASE_DEC, NULL, 0x0, "Log Election Packets", HFILL}},
1203           { &hf_wkssvc_use_opportunistic_locking, 
1204             { "Use Opportunistic Locking", "wkssvc.use.oplocks", FT_INT32,
1205               BASE_DEC, NULL, 0x0, "Use OpLocks", HFILL}},
1206           { &hf_wkssvc_use_unlock_behind, 
1207             { "Use Lock Behind", "wkssvc.use.lock.behind", FT_INT32,
1208               BASE_DEC, NULL, 0x0, "Use Lock Behind", HFILL}},
1209           { &hf_wkssvc_use_close_behind, 
1210             { "Use Close Behind", "wkssvc.use.close.behind", FT_INT32,
1211               BASE_DEC, NULL, 0x0, "Use Close Behind", HFILL}},
1212           { &hf_wkssvc_buf_named_pipes, 
1213             { "Buffer Named Pipes", "wkssvc.buffer.named.pipes", FT_INT32,
1214               BASE_DEC, NULL, 0x0, "Buffer Named Pipes", HFILL}},
1215           { &hf_wkssvc_use_lock_read_unlock, 
1216             { "Use Lock Read Unlock", "wkssvc.use.lock.read.unlock", FT_INT32,
1217               BASE_DEC, NULL, 0x0, "Use Lock Read Unlock", HFILL}},
1218           { &hf_wkssvc_utilize_nt_caching, 
1219             { "Utilize NT Caching", "wkssvc.utilize.nt.caching", FT_INT32,
1220               BASE_DEC, NULL, 0x0, "Utilize NT Caching", HFILL}},
1221           { &hf_wkssvc_use_raw_read, 
1222             { "Use Raw Read", "wkssvc.use.raw.read", FT_INT32,
1223               BASE_DEC, NULL, 0x0, "Use Raw Read", HFILL}},
1224           { &hf_wkssvc_use_raw_write, 
1225             { "Use Raw Write", "wkssvc.use.raw.write", FT_INT32,
1226               BASE_DEC, NULL, 0x0, "Use Raw Write", HFILL}},
1227           { &hf_wkssvc_use_write_raw_data, 
1228             { "Use Write Raw Data", "wkssvc.use.write.raw.data", FT_INT32,
1229               BASE_DEC, NULL, 0x0, "Use Write Raw Data", HFILL}},
1230           { &hf_wkssvc_use_encryption, 
1231             { "Use Encryption", "wkssvc.use.encryption", FT_INT32,
1232               BASE_DEC, NULL, 0x0, "Use Encryption", HFILL}},
1233           { &hf_wkssvc_buf_files_deny_write, 
1234             { "Buffer Files Deny Write", "wkssvc.buf.files.deny.write", FT_INT32,
1235               BASE_DEC, NULL, 0x0, "Buffer Files Deny Write", HFILL}},
1236           { &hf_wkssvc_buf_read_only_files, 
1237             { "Buffer Files Read Only", "wkssvc.buf.files.read.only", FT_INT32,
1238               BASE_DEC, NULL, 0x0, "Buffer Files Read Only", HFILL}},
1239           { &hf_wkssvc_force_core_create_mode, 
1240             { "Force Core Create Mode", "wkssvc.force.core.create.mode", FT_INT32,
1241               BASE_DEC, NULL, 0x0, "Force Core Create Mode", HFILL}},
1242           { &hf_wkssvc_use_512_byte_max_transfer, 
1243             { "Use 512 Byte Max Transfer", "wkssvc.use.512.byte.max.transfer", FT_INT32,
1244               BASE_DEC, NULL, 0x0, "Use 512 Byte Maximum Transfer", HFILL}},
1245           { &hf_wkssvc_parm_err, 
1246             { "Parameter Error Offset", "wkssvc.parm.err", FT_INT32,
1247               BASE_DEC, NULL, 0x0, "Parameter Error Offset", HFILL}},
1248           { &hf_wkssvc_errlog_sz, 
1249             { "Error Log Size", "wkssvc.errlog.sz", FT_INT32,
1250               BASE_DEC, NULL, 0x0, "Error Log Size", HFILL}},
1251           { &hf_wkssvc_print_buf_time, 
1252             { "Print Buf Time", "wkssvc.print.buf.time", FT_INT32,
1253               BASE_DEC, NULL, 0x0, "Print Buff Time", HFILL}},
1254           { &hf_wkssvc_wrk_heuristics, 
1255             { "Wrk Heuristics", "wkssvc.wrk.heuristics", FT_INT32,
1256               BASE_DEC, NULL, 0x0, "Wrk Heuristics", HFILL}},
1257           { &hf_wkssvc_quality_of_service, 
1258             { "Quality Of Service", "wkssvc.qos", FT_INT32,
1259               BASE_DEC, NULL, 0x0, "Quality Of Service", HFILL}},
1260           { &hf_wkssvc_number_of_vcs, 
1261             { "Number Of VCs", "wkssvc.number.of.vcs", FT_INT32,
1262               BASE_DEC, NULL, 0x0, "Number of VSs", HFILL}},
1263           { &hf_wkssvc_transport_name,
1264             { "Transport Name", "wkssvc.transport.name", FT_STRING, BASE_NONE,
1265               NULL, 0x0, "Transport Name", HFILL}},
1266           { &hf_wkssvc_transport_address,
1267             { "Transport Address", "wkssvc.transport.address", FT_STRING, 
1268               BASE_NONE,
1269               NULL, 0x0, "Transport Address", HFILL}},
1270           { &hf_wkssvc_wan_ish, 
1271             { "WAN ish", "wkssvc.wan.ish", FT_INT32,
1272               BASE_DEC, NULL, 0x0, "WAN ish", HFILL}},
1273         };
1274         static gint *ett[] = {
1275                 &ett_dcerpc_wkssvc
1276         };
1277
1278         proto_dcerpc_wkssvc = proto_register_protocol(
1279                 "Microsoft Workstation Service", "WKSSVC", "wkssvc");
1280
1281         proto_register_field_array(proto_dcerpc_wkssvc, hf, array_length(hf));
1282         proto_register_subtree_array(ett, array_length(ett));
1283 }
1284
1285 void
1286 proto_reg_handoff_dcerpc_wkssvc(void)
1287 {
1288         /* Register protocol as dcerpc */
1289
1290         dcerpc_init_uuid(proto_dcerpc_wkssvc, ett_dcerpc_wkssvc,
1291                          &uuid_dcerpc_wkssvc, ver_dcerpc_wkssvc,
1292                          dcerpc_wkssvc_dissectors, hf_wkssvc_opnum);
1293 }