Guy suggested that the dcerpc opnum value_string code could be simplified
[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.27 2003/08/04 02:48:59 tpot 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] *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] *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_NetWkstaGetInfo, "NetWkstaGetInfo", 
1027           wkssvc_dissect_netwkstagetinfo_rqst, 
1028           wkssvc_dissect_netwkstagetinfo_reply},
1029         { WKS_NetWkstaSetInfo, "NetWkstaSetInfo",
1030           wkssvc_dissect_netwkstasetinfo_rqst,
1031           wkssvc_dissect_netwkstasetinfo_reply},
1032         { WKS_NetWkstaEnumUsers, "NetWkstaUserEnum",
1033           wkssvc_dissect_netwkstaenumusers_rqst,
1034           wkssvc_dissect_netwkstaenumusers_reply},
1035         { WKS_NetWkstaUnkn_003, "NetWkstaUnknown_003",
1036           NULL,
1037           NULL,},
1038         { WKS_NetWkstaUnkn_004, "NetWkstaUnknown_004",
1039           NULL,
1040           NULL},
1041         { WKS_NetWkstaTransportEnum, "NetWkstaTransportEnum",
1042           wkssvc_dissect_netwkstatransportenum_rqst, 
1043           wkssvc_dissect_netwkstatransportenum_reply},
1044         {0, NULL, NULL,  NULL }
1045 };
1046
1047 void
1048 proto_register_dcerpc_wkssvc(void)
1049 {
1050         static hf_register_info hf[] = { 
1051           { &hf_wkssvc_opnum,
1052             { "Operation", "wkssvc.opnum", FT_UINT16, BASE_DEC,
1053               NULL, 0x0, "", HFILL }},
1054           { &hf_wkssvc_server,
1055             { "Server", "wkssvc.server", FT_STRING, BASE_NONE,
1056               NULL, 0x0, "Server Name", HFILL}},
1057           { &hf_wkssvc_net_group,
1058             { "Net Group", "wkssvc.netgrp", FT_STRING, BASE_NONE,
1059               NULL, 0x0, "Net Group", HFILL}},
1060           { &hf_wkssvc_info_level,
1061             { "Info Level", "wkssvc.info_level", FT_UINT32,
1062               BASE_DEC, NULL, 0x0, "Info Level", HFILL}},
1063           { &hf_wkssvc_platform_id,
1064             { "Platform ID", "wkssvc.info.platform_id", FT_UINT32,
1065               BASE_DEC, VALS(platform_id_vals), 0x0, "Platform ID", HFILL}},
1066           { &hf_wkssvc_ver_major,
1067             { "Major Version", "wkssvc.version.major", FT_UINT32,
1068               BASE_DEC, NULL, 0x0, "Major Version", HFILL}},
1069           { &hf_wkssvc_ver_minor,
1070             { "Minor Version", "wkssvc.version.minor", FT_UINT32,
1071               BASE_DEC, NULL, 0x0, "Minor Version", HFILL}},
1072           { &hf_wkssvc_lan_root,
1073             { "Lan Root", "wkssvc.lan.root", FT_STRING, BASE_NONE,
1074               NULL, 0x0, "Lan Root", HFILL}},
1075           { &hf_wkssvc_logged_on_users,
1076             { "Logged On Users", "wkssvc.logged.on.users", FT_UINT32,
1077               BASE_DEC, NULL, 0x0, "Logged On Users", HFILL}},
1078           { &hf_wkssvc_pref_max, 
1079             { "Preferred Max Len", "wkssvc.pref.max.len", FT_INT32,
1080               BASE_DEC, NULL, 0x0, "Preferred Max Len", HFILL}},
1081           { &hf_wkssvc_junk, 
1082             { "Junk", "wkssvc.junk", FT_UINT32,
1083               BASE_DEC, NULL, 0x0, "Junk", HFILL}},
1084           { &hf_wkssvc_enum_handle,
1085             { "Enumeration handle", "wkssvc.enum_hnd", FT_BYTES,
1086               BASE_HEX, NULL, 0x0, "Enumeration Handle", HFILL}},
1087           { &hf_wkssvc_user_name,
1088             { "User Name", "wkssvc.user.name", FT_STRING, BASE_NONE,
1089               NULL, 0x0, "User Name", HFILL}},
1090           { &hf_wkssvc_logon_domain,
1091             { "Logon Domain", "wkssvc.logon.domain", FT_STRING, BASE_NONE,
1092               NULL, 0x0, "Logon Domain", HFILL}},
1093           { &hf_wkssvc_other_domains,
1094             { "Other Domains", "wkssvc.other.domains", FT_STRING, BASE_NONE,
1095               NULL, 0x0, "Other Domains", HFILL}},
1096           { &hf_wkssvc_logon_server,
1097             { "Logon Server", "wkssvc.logon.server", FT_STRING, BASE_NONE,
1098               NULL, 0x0, "Logon Server", HFILL}},
1099           { &hf_wkssvc_rc,
1100             { "Return code", "srvsvc.rc", FT_UINT32,
1101               BASE_HEX, VALS(DOS_errors), 0x0, "Return Code", HFILL}},
1102           { &hf_wkssvc_num_entries, 
1103             { "Num Entries", "wkssvc.num.entries", FT_INT32,
1104               BASE_DEC, NULL, 0x0, "Num Entries", HFILL}},
1105           { &hf_wkssvc_entries_read, 
1106             { "Entries Read", "wkssvc.entries.read", FT_INT32,
1107               BASE_DEC, NULL, 0x0, "Entries Read", HFILL}},
1108           { &hf_wkssvc_total_entries, 
1109             { "Total Entries", "wkssvc.total.entries", FT_INT32,
1110               BASE_DEC, NULL, 0x0, "Total Entries", HFILL}},
1111           { &hf_wkssvc_char_wait, 
1112             { "Char Wait", "wkssvc.char.wait", FT_INT32,
1113               BASE_DEC, NULL, 0x0, "Char Wait", HFILL}},
1114           { &hf_wkssvc_collection_time, 
1115             { "Collection Time", "wkssvc.collection.time", FT_INT32,
1116               BASE_DEC, NULL, 0x0, "Collection Time", HFILL}},
1117           { &hf_wkssvc_maximum_collection_count, 
1118             { "Maximum Collection Count", "wkssvc.maximum.collection.count", 
1119               FT_INT32,
1120               BASE_DEC, NULL, 0x0, "Maximum Collection Count", HFILL}},
1121           { &hf_wkssvc_keep_conn, 
1122             { "Keep Connection", "wkssvc.keep.connection", FT_INT32,
1123               BASE_DEC, NULL, 0x0, "Keep Connection", HFILL}},
1124           { &hf_wkssvc_max_cmds, 
1125             { "Maximum Commands", "wkssvc.maximum.commands", FT_INT32,
1126               BASE_DEC, NULL, 0x0, "Maximum Commands", HFILL}},
1127           { &hf_wkssvc_sess_timeout, 
1128             { "Session Timeout", "wkssvc.session.timeout", FT_INT32,
1129               BASE_DEC, NULL, 0x0, "Session Timeout", HFILL}},
1130           { &hf_wkssvc_siz_char_buf, 
1131             { "Character Buffer Size", "wkssvc.size.char.buff", FT_INT32,
1132               BASE_DEC, NULL, 0x0, "Character Buffer Size", HFILL}},
1133           { &hf_wkssvc_max_threads, 
1134             { "Maximum Threads", "wkssvc.maximum.threads", FT_INT32,
1135               BASE_DEC, NULL, 0x0, "Maximum Threads", HFILL}},
1136           { &hf_wkssvc_lock_quota, 
1137             { "Lock Quota", "wkssvc.lock.quota", FT_INT32,
1138               BASE_DEC, NULL, 0x0, "Lock Quota", HFILL}},
1139           { &hf_wkssvc_lock_increment, 
1140             { "Lock Increment", "wkssvc.lock.increment", FT_INT32,
1141               BASE_DEC, NULL, 0x0, "Lock Increment", HFILL}},
1142           { &hf_wkssvc_lock_maximum, 
1143             { "Lock Maximum", "wkssvc.lock.maximum", FT_INT32,
1144               BASE_DEC, NULL, 0x0, "Lock Maximum", HFILL}},
1145           { &hf_wkssvc_pipe_increment, 
1146             { "Pipe Increment", "wkssvc.pipe.increment", FT_INT32,
1147               BASE_DEC, NULL, 0x0, "Pipe Increment", HFILL}},
1148           { &hf_wkssvc_pipe_maximum, 
1149             { "Pipe Maximum", "wkssvc.pipe.maximum", FT_INT32,
1150               BASE_DEC, NULL, 0x0, "Pipe Maximum", HFILL}},
1151           { &hf_wkssvc_cache_file_timeout, 
1152             { "Cache File Timeout", "wkssvc.cache.file.timeout", FT_INT32,
1153               BASE_DEC, NULL, 0x0, "Cache File Timeout", HFILL}},
1154           { &hf_wkssvc_dormant_file_limit, 
1155             { "Dormant File Limit", "wkssvc.dormant.file.limit", FT_INT32,
1156               BASE_DEC, NULL, 0x0, "Dormant File Limit", HFILL}},
1157           { &hf_wkssvc_read_ahead_throughput, 
1158             { "Read Ahead Throughput", "wkssvc.read.ahead.throughput", FT_INT32,
1159               BASE_DEC, NULL, 0x0, "Read Ahead Throughput", HFILL}},
1160           { &hf_wkssvc_num_mailslot_buffers, 
1161             { "Num Mailslot Buffers", "wkssvc.num.mailslot.buffers", FT_INT32,
1162               BASE_DEC, NULL, 0x0, "Num Mailslot Buffers", HFILL}},
1163           { &hf_wkssvc_num_srv_announce_buffers, 
1164             { "Num Srv Announce Buffers", "wkssvc.num.srv.announce.buffers", FT_INT32,
1165               BASE_DEC, NULL, 0x0, "Num Srv Announce Buffers", HFILL}},
1166           { &hf_wkssvc_max_illegal_datagram_events, 
1167             { "Max Illegal Datagram Events", "wkssvc.max.illegal.datagram.events", FT_INT32,
1168               BASE_DEC, NULL, 0x0, "Max Illegal Datagram Events", HFILL}},
1169           { &hf_wkssvc_illegal_datagram_event_reset_frequency, 
1170             { "Illegal Datagram Event Reset Frequency", "wkssvc.illegal.datagram.reset.frequency", FT_INT32,
1171               BASE_DEC, NULL, 0x0, "Illegal Datagram Event Reset Frequency", HFILL}},
1172           { &hf_wkssvc_log_election_packets, 
1173             { "Log Election Packets", "wkssvc.log.election.packets", FT_INT32,
1174               BASE_DEC, NULL, 0x0, "Log Election Packets", HFILL}},
1175           { &hf_wkssvc_use_opportunistic_locking, 
1176             { "Use Opportunistic Locking", "wkssvc.use.oplocks", FT_INT32,
1177               BASE_DEC, NULL, 0x0, "Use OpLocks", HFILL}},
1178           { &hf_wkssvc_use_unlock_behind, 
1179             { "Use Lock Behind", "wkssvc.use.lock.behind", FT_INT32,
1180               BASE_DEC, NULL, 0x0, "Use Lock Behind", HFILL}},
1181           { &hf_wkssvc_use_close_behind, 
1182             { "Use Close Behind", "wkssvc.use.close.behind", FT_INT32,
1183               BASE_DEC, NULL, 0x0, "Use Close Behind", HFILL}},
1184           { &hf_wkssvc_buf_named_pipes, 
1185             { "Buffer Named Pipes", "wkssvc.buffer.named.pipes", FT_INT32,
1186               BASE_DEC, NULL, 0x0, "Buffer Named Pipes", HFILL}},
1187           { &hf_wkssvc_use_lock_read_unlock, 
1188             { "Use Lock Read Unlock", "wkssvc.use.lock.read.unlock", FT_INT32,
1189               BASE_DEC, NULL, 0x0, "Use Lock Read Unlock", HFILL}},
1190           { &hf_wkssvc_utilize_nt_caching, 
1191             { "Utilize NT Caching", "wkssvc.utilize.nt.caching", FT_INT32,
1192               BASE_DEC, NULL, 0x0, "Utilize NT Caching", HFILL}},
1193           { &hf_wkssvc_use_raw_read, 
1194             { "Use Raw Read", "wkssvc.use.raw.read", FT_INT32,
1195               BASE_DEC, NULL, 0x0, "Use Raw Read", HFILL}},
1196           { &hf_wkssvc_use_raw_write, 
1197             { "Use Raw Write", "wkssvc.use.raw.write", FT_INT32,
1198               BASE_DEC, NULL, 0x0, "Use Raw Write", HFILL}},
1199           { &hf_wkssvc_use_write_raw_data, 
1200             { "Use Write Raw Data", "wkssvc.use.write.raw.data", FT_INT32,
1201               BASE_DEC, NULL, 0x0, "Use Write Raw Data", HFILL}},
1202           { &hf_wkssvc_use_encryption, 
1203             { "Use Encryption", "wkssvc.use.encryption", FT_INT32,
1204               BASE_DEC, NULL, 0x0, "Use Encryption", HFILL}},
1205           { &hf_wkssvc_buf_files_deny_write, 
1206             { "Buffer Files Deny Write", "wkssvc.buf.files.deny.write", FT_INT32,
1207               BASE_DEC, NULL, 0x0, "Buffer Files Deny Write", HFILL}},
1208           { &hf_wkssvc_buf_read_only_files, 
1209             { "Buffer Files Read Only", "wkssvc.buf.files.read.only", FT_INT32,
1210               BASE_DEC, NULL, 0x0, "Buffer Files Read Only", HFILL}},
1211           { &hf_wkssvc_force_core_create_mode, 
1212             { "Force Core Create Mode", "wkssvc.force.core.create.mode", FT_INT32,
1213               BASE_DEC, NULL, 0x0, "Force Core Create Mode", HFILL}},
1214           { &hf_wkssvc_use_512_byte_max_transfer, 
1215             { "Use 512 Byte Max Transfer", "wkssvc.use.512.byte.max.transfer", FT_INT32,
1216               BASE_DEC, NULL, 0x0, "Use 512 Byte Maximum Transfer", HFILL}},
1217           { &hf_wkssvc_parm_err, 
1218             { "Parameter Error Offset", "wkssvc.parm.err", FT_INT32,
1219               BASE_DEC, NULL, 0x0, "Parameter Error Offset", HFILL}},
1220           { &hf_wkssvc_errlog_sz, 
1221             { "Error Log Size", "wkssvc.errlog.sz", FT_INT32,
1222               BASE_DEC, NULL, 0x0, "Error Log Size", HFILL}},
1223           { &hf_wkssvc_print_buf_time, 
1224             { "Print Buf Time", "wkssvc.print.buf.time", FT_INT32,
1225               BASE_DEC, NULL, 0x0, "Print Buff Time", HFILL}},
1226           { &hf_wkssvc_wrk_heuristics, 
1227             { "Wrk Heuristics", "wkssvc.wrk.heuristics", FT_INT32,
1228               BASE_DEC, NULL, 0x0, "Wrk Heuristics", HFILL}},
1229           { &hf_wkssvc_quality_of_service, 
1230             { "Quality Of Service", "wkssvc.qos", FT_INT32,
1231               BASE_DEC, NULL, 0x0, "Quality Of Service", HFILL}},
1232           { &hf_wkssvc_number_of_vcs, 
1233             { "Number Of VCs", "wkssvc.number.of.vcs", FT_INT32,
1234               BASE_DEC, NULL, 0x0, "Number of VSs", HFILL}},
1235           { &hf_wkssvc_transport_name,
1236             { "Transport Name", "wkssvc.transport.name", FT_STRING, BASE_NONE,
1237               NULL, 0x0, "Transport Name", HFILL}},
1238           { &hf_wkssvc_transport_address,
1239             { "Transport Address", "wkssvc.transport.address", FT_STRING, 
1240               BASE_NONE,
1241               NULL, 0x0, "Transport Address", HFILL}},
1242           { &hf_wkssvc_wan_ish, 
1243             { "WAN ish", "wkssvc.wan.ish", FT_INT32,
1244               BASE_DEC, NULL, 0x0, "WAN ish", HFILL}},
1245         };
1246         static gint *ett[] = {
1247                 &ett_dcerpc_wkssvc
1248         };
1249
1250         proto_dcerpc_wkssvc = proto_register_protocol(
1251                 "Microsoft Workstation Service", "WKSSVC", "wkssvc");
1252
1253         proto_register_field_array(proto_dcerpc_wkssvc, hf, array_length(hf));
1254         proto_register_subtree_array(ett, array_length(ett));
1255 }
1256
1257 void
1258 proto_reg_handoff_dcerpc_wkssvc(void)
1259 {
1260         /* Register protocol as dcerpc */
1261
1262         dcerpc_init_uuid(proto_dcerpc_wkssvc, ett_dcerpc_wkssvc,
1263                          &uuid_dcerpc_wkssvc, ver_dcerpc_wkssvc,
1264                          dcerpc_wkssvc_dissectors, hf_wkssvc_opnum);
1265 }