Clarify which filter expressions on the command line are capture filters
[metze/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  *
5  * $Id: packet-smb.c,v 1.78 2001/01/03 16:41:07 gram Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
40 #endif
41
42 #include <time.h>
43 #include <string.h>
44 #include <glib.h>
45 #include <ctype.h>
46 #include "packet.h"
47 #include "conversation.h"
48 #include "smb.h"
49 #include "alignment.h"
50 #include "strutil.h"
51
52 guint32 dissect_mailslot_smb(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int, const u_char *, int, int, int, int);
53
54 guint32 dissect_pipe_smb(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int, const u_char *, int, int, int, int);
55
56
57 static int proto_smb = -1;
58
59 static int hf_smb_cmd = -1;
60
61 static gint ett_smb = -1;
62 static gint ett_smb_fileattributes = -1;
63 static gint ett_smb_capabilities = -1;
64 static gint ett_smb_aflags = -1;
65 static gint ett_smb_dialects = -1;
66 static gint ett_smb_mode = -1;
67 static gint ett_smb_rawmode = -1;
68 static gint ett_smb_flags = -1;
69 static gint ett_smb_flags2 = -1;
70 static gint ett_smb_desiredaccess = -1;
71 static gint ett_smb_search = -1;
72 static gint ett_smb_file = -1;
73 static gint ett_smb_openfunction = -1;
74 static gint ett_smb_filetype = -1;
75 static gint ett_smb_action = -1;
76 static gint ett_smb_writemode = -1;
77 static gint ett_smb_lock_type = -1;
78
79
80
81 /*
82  * Struct passed to each SMB decode routine of info it may need
83  */
84
85 char *decode_smb_name(unsigned char);
86
87 int smb_packet_init_count = 200;
88
89 struct smb_request_key {
90   guint32 conversation;
91   guint16 mid;
92 };
93
94
95 GHashTable *smb_request_hash = NULL;
96 GMemChunk *smb_request_keys = NULL;
97 GMemChunk *smb_request_vals = NULL;
98
99 /* Hash Functions */
100 gint
101 smb_equal(gconstpointer v, gconstpointer w)
102 {
103   struct smb_request_key *v1 = (struct smb_request_key *)v;
104   struct smb_request_key *v2 = (struct smb_request_key *)w;
105
106 #if defined(DEBUG_SMB_HASH)
107   printf("Comparing %08X:%u\n      and %08X:%u\n",
108          v1 -> conversation, v1 -> mid,
109          v2 -> conversation, v2 -> mid);
110 #endif
111
112   if (v1 -> conversation == v2 -> conversation &&
113       v1 -> mid          == v2 -> mid) {
114
115     return 1;
116
117   }
118
119   return 0;
120 }
121
122 guint 
123 smb_hash (gconstpointer v)
124 {
125   struct smb_request_key *key = (struct smb_request_key *)v;
126   guint val;
127
128   val = key -> conversation + key -> mid;
129
130 #if defined(DEBUG_SMB_HASH)
131   printf("SMB Hash calculated as %u\n", val);
132 #endif
133
134   return val;
135
136 }
137
138 /*
139  * Free up any state information we've saved, and re-initialize the
140  * tables of state information.
141  */
142 static void
143 smb_init_protocol(void)
144 {
145 #if defined(DEBUG_SMB_HASH)
146   printf("Initializing SMB hashtable area\n");
147 #endif
148
149   if (smb_request_hash)
150     g_hash_table_destroy(smb_request_hash);
151   if (smb_request_keys)
152     g_mem_chunk_destroy(smb_request_keys);
153   if (smb_request_vals)
154     g_mem_chunk_destroy(smb_request_vals);
155
156   smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
157   smb_request_keys = g_mem_chunk_new("smb_request_keys",
158                                      sizeof(struct smb_request_key),
159                                      smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
160   smb_request_vals = g_mem_chunk_new("smb_request_vals",
161                                      sizeof(struct smb_request_val),
162                                      smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
163 }
164
165 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int, int, int);
166
167 static const value_string smb_cmd_vals[] = {
168   { 0x00, "SMBcreatedirectory" },
169   { 0x01, "SMBdeletedirectory" },
170   { 0x02, "SMBopen" },
171   { 0x03, "SMBcreate" },
172   { 0x04, "SMBclose" },
173   { 0x05, "SMBflush" },
174   { 0x06, "SMBunlink" },
175   { 0x07, "SMBmv" },
176   { 0x08, "SMBgetatr" },
177   { 0x09, "SMBsetatr" },
178   { 0x0A, "SMBread" },
179   { 0x0B, "SMBwrite" },
180   { 0x0C, "SMBlock" },
181   { 0x0D, "SMBunlock" },
182   { 0x0E, "SMBctemp" },
183   { 0x0F, "SMBmknew" },
184   { 0x10, "SMBchkpth" },
185   { 0x11, "SMBexit" },
186   { 0x12, "SMBlseek" },
187   { 0x13, "SMBlockread" },
188   { 0x14, "SMBwriteunlock" },
189   { 0x15, "unknown-0x15" },
190   { 0x16, "unknown-0x16" },
191   { 0x17, "unknown-0x17" },
192   { 0x18, "unknown-0x18" },
193   { 0x19, "unknown-0x19" },
194   { 0x1A, "SMBreadBraw" },
195   { 0x1B, "SMBreadBmpx" },
196   { 0x1C, "SMBreadBs" },
197   { 0x1D, "SMBwriteBraw" },
198   { 0x1E, "SMBwriteBmpx" },
199   { 0x1F, "SMBwriteBs" },
200   { 0x20, "SMBwriteC" },
201   { 0x21, "unknown-0x21" },
202   { 0x22, "SMBsetattrE" },
203   { 0x23, "SMBgetattrE" },
204   { 0x24, "SMBlockingX" },
205   { 0x25, "SMBtrans" },
206   { 0x26, "SMBtranss" },
207   { 0x27, "SMBioctl" },
208   { 0x28, "SMBioctls" },
209   { 0x29, "SMBcopy" },
210   { 0x2A, "SMBmove" },
211   { 0x2B, "SMBecho" },
212   { 0x2C, "SMBwriteclose" },
213   { 0x2D, "SMBopenX" },
214   { 0x2E, "SMBreadX" },
215   { 0x2F, "SMBwriteX" },
216   { 0x30, "unknown-0x30" },
217   { 0x31, "SMBcloseandtreedisc" },
218   { 0x32, "SMBtrans2" },
219   { 0x33, "SMBtrans2secondary" },
220   { 0x34, "SMBfindclose2" },
221   { 0x35, "SMBfindnotifyclose" },
222   { 0x36, "unknown-0x36" },
223   { 0x37, "unknown-0x37" },
224   { 0x38, "unknown-0x38" },
225   { 0x39, "unknown-0x39" },
226   { 0x3A, "unknown-0x3A" },
227   { 0x3B, "unknown-0x3B" },
228   { 0x3C, "unknown-0x3C" },
229   { 0x3D, "unknown-0x3D" },
230   { 0x3E, "unknown-0x3E" },
231   { 0x3F, "unknown-0x3F" },
232   { 0x40, "unknown-0x40" },
233   { 0x41, "unknown-0x41" },
234   { 0x42, "unknown-0x42" },
235   { 0x43, "unknown-0x43" },
236   { 0x44, "unknown-0x44" },
237   { 0x45, "unknown-0x45" },
238   { 0x46, "unknown-0x46" },
239   { 0x47, "unknown-0x47" },
240   { 0x48, "unknown-0x48" },
241   { 0x49, "unknown-0x49" },
242   { 0x4A, "unknown-0x4A" },
243   { 0x4B, "unknown-0x4B" },
244   { 0x4C, "unknown-0x4C" },
245   { 0x4D, "unknown-0x4D" },
246   { 0x4E, "unknown-0x4E" },
247   { 0x4F, "unknown-0x4F" },
248   { 0x50, "unknown-0x50" },
249   { 0x51, "unknown-0x51" },
250   { 0x52, "unknown-0x52" },
251   { 0x53, "unknown-0x53" },
252   { 0x54, "unknown-0x54" },
253   { 0x55, "unknown-0x55" },
254   { 0x56, "unknown-0x56" },
255   { 0x57, "unknown-0x57" },
256   { 0x58, "unknown-0x58" },
257   { 0x59, "unknown-0x59" },
258   { 0x5A, "unknown-0x5A" },
259   { 0x5B, "unknown-0x5B" },
260   { 0x5C, "unknown-0x5C" },
261   { 0x5D, "unknown-0x5D" },
262   { 0x5E, "unknown-0x5E" },
263   { 0x5F, "unknown-0x5F" },
264   { 0x60, "unknown-0x60" },
265   { 0x61, "unknown-0x61" },
266   { 0x62, "unknown-0x62" },
267   { 0x63, "unknown-0x63" },
268   { 0x64, "unknown-0x64" },
269   { 0x65, "unknown-0x65" },
270   { 0x66, "unknown-0x66" },
271   { 0x67, "unknown-0x67" },
272   { 0x68, "unknown-0x68" },
273   { 0x69, "unknown-0x69" },
274   { 0x6A, "unknown-0x6A" },
275   { 0x6B, "unknown-0x6B" },
276   { 0x6C, "unknown-0x6C" },
277   { 0x6D, "unknown-0x6D" },
278   { 0x6E, "unknown-0x6E" },
279   { 0x6F, "unknown-0x6F" },
280   { 0x70, "SMBtcon" },
281   { 0x71, "SMBtdis" },
282   { 0x72, "SMBnegprot" },
283   { 0x73, "SMBsesssetupX" },
284   { 0x74, "SMBlogoffX" },
285   { 0x75, "SMBtconX" },
286   { 0x76, "unknown-0x76" },
287   { 0x77, "unknown-0x77" },
288   { 0x78, "unknown-0x78" },
289   { 0x79, "unknown-0x79" },
290   { 0x7A, "unknown-0x7A" },
291   { 0x7B, "unknown-0x7B" },
292   { 0x7C, "unknown-0x7C" },
293   { 0x7D, "unknown-0x7D" },
294   { 0x7E, "unknown-0x7E" },
295   { 0x7F, "unknown-0x7F" },
296   { 0x80, "SMBdskattr" },
297   { 0x81, "SMBsearch" },
298   { 0x82, "SMBffirst" },
299   { 0x83, "SMBfunique" },
300   { 0x84, "SMBfclose" },
301   { 0x85, "unknown-0x85" },
302   { 0x86, "unknown-0x86" },
303   { 0x87, "unknown-0x87" },
304   { 0x88, "unknown-0x88" },
305   { 0x89, "unknown-0x89" },
306   { 0x8A, "unknown-0x8A" },
307   { 0x8B, "unknown-0x8B" },
308   { 0x8C, "unknown-0x8C" },
309   { 0x8D, "unknown-0x8D" },
310   { 0x8E, "unknown-0x8E" },
311   { 0x8F, "unknown-0x8F" },
312   { 0x90, "unknown-0x90" },
313   { 0x91, "unknown-0x91" },
314   { 0x92, "unknown-0x92" },
315   { 0x93, "unknown-0x93" },
316   { 0x94, "unknown-0x94" },
317   { 0x95, "unknown-0x95" },
318   { 0x96, "unknown-0x96" },
319   { 0x97, "unknown-0x97" },
320   { 0x98, "unknown-0x98" },
321   { 0x99, "unknown-0x99" },
322   { 0x9A, "unknown-0x9A" },
323   { 0x9B, "unknown-0x9B" },
324   { 0x9C, "unknown-0x9C" },
325   { 0x9D, "unknown-0x9D" },
326   { 0x9E, "unknown-0x9E" },
327   { 0x9F, "unknown-0x9F" },
328   { 0xA0, "SMBnttransact" },
329   { 0xA1, "SMBnttransactsecondary" },
330   { 0xA2, "SMBntcreateX" },
331   { 0xA3, "unknown-0xA3" },
332   { 0xA4, "SMBntcancel" },
333   { 0xA5, "unknown-0xA5" },
334   { 0xA6, "unknown-0xA6" },
335   { 0xA7, "unknown-0xA7" },
336   { 0xA8, "unknown-0xA8" },
337   { 0xA9, "unknown-0xA9" },
338   { 0xAA, "unknown-0xAA" },
339   { 0xAB, "unknown-0xAB" },
340   { 0xAC, "unknown-0xAC" },
341   { 0xAD, "unknown-0xAD" },
342   { 0xAE, "unknown-0xAE" },
343   { 0xAF, "unknown-0xAF" },
344   { 0xB0, "unknown-0xB0" },
345   { 0xB1, "unknown-0xB1" },
346   { 0xB2, "unknown-0xB2" },
347   { 0xB3, "unknown-0xB3" },
348   { 0xB4, "unknown-0xB4" },
349   { 0xB5, "unknown-0xB5" },
350   { 0xB6, "unknown-0xB6" },
351   { 0xB7, "unknown-0xB7" },
352   { 0xB8, "unknown-0xB8" },
353   { 0xB9, "unknown-0xB9" },
354   { 0xBA, "unknown-0xBA" },
355   { 0xBB, "unknown-0xBB" },
356   { 0xBC, "unknown-0xBC" },
357   { 0xBD, "unknown-0xBD" },
358   { 0xBE, "unknown-0xBE" },
359   { 0xBF, "unknown-0xBF" },
360   { 0xC0, "SMBsplopen" },
361   { 0xC1, "SMBsplwr" },
362   { 0xC2, "SMBsplclose" },
363   { 0xC3, "SMBsplretq" },
364   { 0xC4, "unknown-0xC4" },
365   { 0xC5, "unknown-0xC5" },
366   { 0xC6, "unknown-0xC6" },
367   { 0xC7, "unknown-0xC7" },
368   { 0xC8, "unknown-0xC8" },
369   { 0xC9, "unknown-0xC9" },
370   { 0xCA, "unknown-0xCA" },
371   { 0xCB, "unknown-0xCB" },
372   { 0xCC, "unknown-0xCC" },
373   { 0xCD, "unknown-0xCD" },
374   { 0xCE, "unknown-0xCE" },
375   { 0xCF, "unknown-0xCF" },
376   { 0xD0, "SMBsends" },
377   { 0xD1, "SMBsendb" },
378   { 0xD2, "SMBfwdname" },
379   { 0xD3, "SMBcancelf" },
380   { 0xD4, "SMBgetmac" },
381   { 0xD5, "SMBsendstrt" },
382   { 0xD6, "SMBsendend" },
383   { 0xD7, "SMBsendtxt" },
384   { 0xD8, "SMBreadbulk" },
385   { 0xD9, "SMBwritebulk" },
386   { 0xDA, "SMBwritebulkdata" },
387   { 0xDB, "unknown-0xDB" },
388   { 0xDC, "unknown-0xDC" },
389   { 0xDD, "unknown-0xDD" },
390   { 0xDE, "unknown-0xDE" },
391   { 0xDF, "unknown-0xDF" },
392   { 0xE0, "unknown-0xE0" },
393   { 0xE1, "unknown-0xE1" },
394   { 0xE2, "unknown-0xE2" },
395   { 0xE3, "unknown-0xE3" },
396   { 0xE4, "unknown-0xE4" },
397   { 0xE5, "unknown-0xE5" },
398   { 0xE6, "unknown-0xE6" },
399   { 0xE7, "unknown-0xE7" },
400   { 0xE8, "unknown-0xE8" },
401   { 0xE9, "unknown-0xE9" },
402   { 0xEA, "unknown-0xEA" },
403   { 0xEB, "unknown-0xEB" },
404   { 0xEC, "unknown-0xEC" },
405   { 0xED, "unknown-0xED" },
406   { 0xEE, "unknown-0xEE" },
407   { 0xEF, "unknown-0xEF" },
408   { 0xF0, "unknown-0xF0" },
409   { 0xF1, "unknown-0xF1" },
410   { 0xF2, "unknown-0xF2" },
411   { 0xF3, "unknown-0xF3" },
412   { 0xF4, "unknown-0xF4" },
413   { 0xF5, "unknown-0xF5" },
414   { 0xF6, "unknown-0xF6" },
415   { 0xF7, "unknown-0xF7" },
416   { 0xF8, "unknown-0xF8" },
417   { 0xF9, "unknown-0xF9" },
418   { 0xFA, "unknown-0xFA" },
419   { 0xFB, "unknown-0xFB" },
420   { 0xFC, "unknown-0xFC" },
421   { 0xFD, "unknown-0xFD" },
422   { 0xFE, "SMBinvalid" },
423   { 0xFF, "unknown-0xFF" },
424   { 0x00, NULL },
425 };
426
427 char *SMB_names[256] = {
428   "SMBcreatedirectory",
429   "SMBdeletedirectory",
430   "SMBopen",
431   "SMBcreate",
432   "SMBclose",
433   "SMBflush",
434   "SMBunlink",
435   "SMBmv",
436   "SMBgetatr",
437   "SMBsetatr",
438   "SMBread",
439   "SMBwrite",
440   "SMBlock",
441   "SMBunlock",
442   "SMBctemp",
443   "SMBmknew",
444   "SMBchkpth",
445   "SMBexit",
446   "SMBlseek",
447   "SMBlockread",
448   "SMBwriteunlock",
449   "unknown-0x15",
450   "unknown-0x16",
451   "unknown-0x17",
452   "unknown-0x18",
453   "unknown-0x19",
454   "SMBreadBraw",
455   "SMBreadBmpx",
456   "SMBreadBs",
457   "SMBwriteBraw",
458   "SMBwriteBmpx",
459   "SMBwriteBs",
460   "SMBwriteC",
461   "unknown-0x21",
462   "SMBsetattrE",
463   "SMBgetattrE",
464   "SMBlockingX",
465   "SMBtrans",
466   "SMBtranss",
467   "SMBioctl",
468   "SMBioctls",
469   "SMBcopy",
470   "SMBmove",
471   "SMBecho",
472   "SMBwriteclose",
473   "SMBopenX",
474   "SMBreadX",
475   "SMBwriteX",
476   "unknown-0x30",
477   "SMBcloseandtreedisc",
478   "SMBtrans2",
479   "SMBtrans2secondary",
480   "SMBfindclose2",
481   "SMBfindnotifyclose",
482   "unknown-0x36",
483   "unknown-0x37",
484   "unknown-0x38",
485   "unknown-0x39",
486   "unknown-0x3A",
487   "unknown-0x3B",
488   "unknown-0x3C",
489   "unknown-0x3D",
490   "unknown-0x3E",
491   "unknown-0x3F",
492   "unknown-0x40",
493   "unknown-0x41",
494   "unknown-0x42",
495   "unknown-0x43",
496   "unknown-0x44",
497   "unknown-0x45",
498   "unknown-0x46",
499   "unknown-0x47",
500   "unknown-0x48",
501   "unknown-0x49",
502   "unknown-0x4A",
503   "unknown-0x4B",
504   "unknown-0x4C",
505   "unknown-0x4D",
506   "unknown-0x4E",
507   "unknown-0x4F",
508   "unknown-0x50",
509   "unknown-0x51",
510   "unknown-0x52",
511   "unknown-0x53",
512   "unknown-0x54",
513   "unknown-0x55",
514   "unknown-0x56",
515   "unknown-0x57",
516   "unknown-0x58",
517   "unknown-0x59",
518   "unknown-0x5A",
519   "unknown-0x5B",
520   "unknown-0x5C",
521   "unknown-0x5D",
522   "unknown-0x5E",
523   "unknown-0x5F",
524   "unknown-0x60",
525   "unknown-0x61",
526   "unknown-0x62",
527   "unknown-0x63",
528   "unknown-0x64",
529   "unknown-0x65",
530   "unknown-0x66",
531   "unknown-0x67",
532   "unknown-0x68",
533   "unknown-0x69",
534   "unknown-0x6A",
535   "unknown-0x6B",
536   "unknown-0x6C",
537   "unknown-0x6D",
538   "unknown-0x6E",
539   "unknown-0x6F",
540   "SMBtcon",
541   "SMBtdis",
542   "SMBnegprot",
543   "SMBsesssetupX",
544   "SMBlogoffX",
545   "SMBtconX",
546   "unknown-0x76",
547   "unknown-0x77",
548   "unknown-0x78",
549   "unknown-0x79",
550   "unknown-0x7A",
551   "unknown-0x7B",
552   "unknown-0x7C",
553   "unknown-0x7D",
554   "unknown-0x7E",
555   "unknown-0x7F",
556   "SMBdskattr",
557   "SMBsearch",
558   "SMBffirst",
559   "SMBfunique",
560   "SMBfclose",
561   "unknown-0x85",
562   "unknown-0x86",
563   "unknown-0x87",
564   "unknown-0x88",
565   "unknown-0x89",
566   "unknown-0x8A",
567   "unknown-0x8B",
568   "unknown-0x8C",
569   "unknown-0x8D",
570   "unknown-0x8E",
571   "unknown-0x8F",
572   "unknown-0x90",
573   "unknown-0x91",
574   "unknown-0x92",
575   "unknown-0x93",
576   "unknown-0x94",
577   "unknown-0x95",
578   "unknown-0x96",
579   "unknown-0x97",
580   "unknown-0x98",
581   "unknown-0x99",
582   "unknown-0x9A",
583   "unknown-0x9B",
584   "unknown-0x9C",
585   "unknown-0x9D",
586   "unknown-0x9E",
587   "unknown-0x9F",
588   "SMBnttransact",
589   "SMBnttransactsecondary",
590   "SMBntcreateX",
591   "unknown-0xA3",
592   "SMBntcancel",
593   "unknown-0xA5",
594   "unknown-0xA6",
595   "unknown-0xA7",
596   "unknown-0xA8",
597   "unknown-0xA9",
598   "unknown-0xAA",
599   "unknown-0xAB",
600   "unknown-0xAC",
601   "unknown-0xAD",
602   "unknown-0xAE",
603   "unknown-0xAF",
604   "unknown-0xB0",
605   "unknown-0xB1",
606   "unknown-0xB2",
607   "unknown-0xB3",
608   "unknown-0xB4",
609   "unknown-0xB5",
610   "unknown-0xB6",
611   "unknown-0xB7",
612   "unknown-0xB8",
613   "unknown-0xB9",
614   "unknown-0xBA",
615   "unknown-0xBB",
616   "unknown-0xBC",
617   "unknown-0xBD",
618   "unknown-0xBE",
619   "unknown-0xBF",
620   "SMBsplopen",
621   "SMBsplwr",
622   "SMBsplclose",
623   "SMBsplretq",
624   "unknown-0xC4",
625   "unknown-0xC5",
626   "unknown-0xC6",
627   "unknown-0xC7",
628   "unknown-0xC8",
629   "unknown-0xC9",
630   "unknown-0xCA",
631   "unknown-0xCB",
632   "unknown-0xCC",
633   "unknown-0xCD",
634   "unknown-0xCE",
635   "unknown-0xCF",
636   "SMBsends",
637   "SMBsendb",
638   "SMBfwdname",
639   "SMBcancelf",
640   "SMBgetmac",
641   "SMBsendstrt",
642   "SMBsendend",
643   "SMBsendtxt",
644   "SMBreadbulk",
645   "SMBwritebulk",
646   "SMBwritebulkdata",
647   "unknown-0xDB",
648   "unknown-0xDC",
649   "unknown-0xDD",
650   "unknown-0xDE",
651   "unknown-0xDF",
652   "unknown-0xE0",
653   "unknown-0xE1",
654   "unknown-0xE2",
655   "unknown-0xE3",
656   "unknown-0xE4",
657   "unknown-0xE5",
658   "unknown-0xE6",
659   "unknown-0xE7",
660   "unknown-0xE8",
661   "unknown-0xE9",
662   "unknown-0xEA",
663   "unknown-0xEB",
664   "unknown-0xEC",
665   "unknown-0xED",
666   "unknown-0xEE",
667   "unknown-0xEF",
668   "unknown-0xF0",
669   "unknown-0xF1",
670   "unknown-0xF2",
671   "unknown-0xF3",
672   "unknown-0xF4",
673   "unknown-0xF5",
674   "unknown-0xF6",
675   "unknown-0xF7",
676   "unknown-0xF8",
677   "unknown-0xF9",
678   "unknown-0xFA",
679   "unknown-0xFB",
680   "unknown-0xFC",
681   "unknown-0xFD",
682   "SMBinvalid",
683   "unknown-0xFF"
684 };
685
686 void 
687 dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
688 {
689
690   if (tree) {
691
692     proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)", 
693                         END_OF_FRAME); 
694
695   }
696
697 }
698
699 /* 
700  * Dissect a UNIX like date ...
701  */
702
703 struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
704                       conflict with /usr/include/time.h on some NetBSD
705                       systems */
706
707 static char *
708 dissect_smbu_date(guint16 date, guint16 time)
709
710 {
711   static char         datebuf[4+2+2+2+1+10];
712   time_t              ltime = (date << 16) + time;
713
714   _gtime = gmtime(&ltime);
715
716   if (_gtime)
717     sprintf(datebuf, "%04d-%02d-%02d",
718             1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
719   else 
720     sprintf(datebuf, "Bad date format");
721
722   return datebuf;
723
724 }
725
726 /*
727  * Relies on time
728  */
729 static char *
730 dissect_smbu_time(guint16 date, guint16 time)
731
732 {
733   static char timebuf[2+2+2+2+1+10];
734
735   if (_gtime)
736     sprintf(timebuf, "%02d:%02d:%02d",
737             _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
738   else
739     sprintf(timebuf, "Bad time format");
740
741   return timebuf;
742
743 }
744
745 /*
746  * Dissect a DOS-format date.
747  */
748 static char *
749 dissect_dos_date(guint16 date)
750 {
751         static char datebuf[4+2+2+1];
752
753         sprintf(datebuf, "%04d-%02d-%02d",
754             ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
755         return datebuf;
756 }
757
758 /*
759  * Dissect a DOS-format time.
760  */
761 static char *
762 dissect_dos_time(guint16 time)
763 {
764         static char timebuf[2+2+2+1];
765
766         sprintf(timebuf, "%02d:%02d:%02d",
767             (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
768         return timebuf;
769 }
770
771 /* Max string length for displaying Unicode strings.  */
772 #define MAX_UNICODE_STR_LEN     256
773
774 /* Turn a little-endian Unicode '\0'-terminated string into a string we
775    can display.
776    XXX - for now, we just handle the ISO 8859-1 characters. */
777 static gchar *
778 unicode_to_str(const guint8 *us, int *us_lenp) {
779   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
780   static gchar *cur;
781   gchar        *p;
782   int           len;
783   int           us_len;
784   int           overflow = 0;
785
786   if (cur == &str[0][0]) {
787     cur = &str[1][0];
788   } else if (cur == &str[1][0]) {  
789     cur = &str[2][0];
790   } else {  
791     cur = &str[0][0];
792   }
793   p = cur;
794   len = MAX_UNICODE_STR_LEN;
795   us_len = 0;
796   while (*us != 0 || *(us + 1) != 0) {
797     if (len > 0) {
798       *p++ = *us;
799       len--;
800     } else
801       overflow = 1;
802     us += 2;
803     us_len += 2;
804   }
805   if (overflow) {
806     /* Note that we're not showing the full string.  */
807     *p++ = '.';
808     *p++ = '.';
809     *p++ = '.';
810   }
811   *p = '\0';
812   *us_lenp = us_len;
813   return cur;
814 }
815
816 /*
817  * Each dissect routine is passed an offset to wct and works from there 
818  */
819
820 void
821 dissect_flush_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
822
823 {
824   guint8        WordCount;
825   guint16       FID;
826   guint16       ByteCount;
827
828   if (dirn == 1) { /* Request(s) dissect code */
829
830     /* Build display for: Word Count (WCT) */
831
832     WordCount = GBYTE(pd, offset);
833
834     if (tree) {
835
836       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
837
838     }
839
840     offset += 1; /* Skip Word Count (WCT) */
841
842     /* Build display for: FID */
843
844     FID = GSHORT(pd, offset);
845
846     if (tree) {
847
848       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
849
850     }
851
852     offset += 2; /* Skip FID */
853
854     /* Build display for: Byte Count */
855
856     ByteCount = GSHORT(pd, offset);
857
858     if (tree) {
859
860       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
861
862     }
863
864     offset += 2; /* Skip Byte Count */
865
866   }
867
868   if (dirn == 0) { /* Response(s) dissect code */
869
870     /* Build display for: Word Count (WCT) */
871
872     WordCount = GBYTE(pd, offset);
873
874     if (tree) {
875
876       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
877
878     }
879
880     offset += 1; /* Skip Word Count (WCT) */
881
882     /* Build display for: Byte Count (BCC) */
883
884     ByteCount = GSHORT(pd, offset);
885
886     if (tree) {
887
888       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
889
890     }
891
892     offset += 2; /* Skip Byte Count (BCC) */
893
894   }
895
896 }
897
898 void
899 dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
900
901 {
902   guint8        WordCount;
903   guint16       TotalUnits;
904   guint16       Reserved;
905   guint16       FreeUnits;
906   guint16       ByteCount;
907   guint16       BlocksPerUnit;
908   guint16       BlockSize;
909
910   if (dirn == 1) { /* Request(s) dissect code */
911
912     /* Build display for: Word Count (WCT) */
913
914     WordCount = GBYTE(pd, offset);
915
916     if (tree) {
917
918       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
919
920     }
921
922     offset += 1; /* Skip Word Count (WCT) */
923
924     /* Build display for: Byte Count (BCC) */
925
926     ByteCount = GSHORT(pd, offset);
927
928     if (tree) {
929
930       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
931
932     }
933
934     offset += 2; /* Skip Byte Count (BCC) */
935
936   }
937
938   if (dirn == 0) { /* Response(s) dissect code */
939
940     /* Build display for: Word Count (WCT) */
941
942     WordCount = GBYTE(pd, offset);
943
944     if (tree) {
945
946       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
947
948     }
949
950     offset += 1; /* Skip Word Count (WCT) */
951
952     if (WordCount > 0) {
953
954       /* Build display for: Total Units */
955
956       TotalUnits = GSHORT(pd, offset);
957
958       if (tree) {
959
960         proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
961
962       }
963
964       offset += 2; /* Skip Total Units */
965
966       /* Build display for: Blocks Per Unit */
967
968       BlocksPerUnit = GSHORT(pd, offset);
969
970       if (tree) {
971
972         proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
973
974       }
975
976       offset += 2; /* Skip Blocks Per Unit */
977
978       /* Build display for: Block Size */
979
980       BlockSize = GSHORT(pd, offset);
981
982       if (tree) {
983
984         proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
985
986       }
987
988       offset += 2; /* Skip Block Size */
989
990       /* Build display for: Free Units */
991
992       FreeUnits = GSHORT(pd, offset);
993
994       if (tree) {
995
996         proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
997
998       }
999
1000       offset += 2; /* Skip Free Units */
1001
1002       /* Build display for: Reserved */
1003
1004       Reserved = GSHORT(pd, offset);
1005
1006       if (tree) {
1007
1008         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1009
1010       }
1011
1012       offset += 2; /* Skip Reserved */
1013
1014     }
1015
1016     /* Build display for: Byte Count (BCC) */
1017
1018     ByteCount = GSHORT(pd, offset);
1019
1020     if (tree) {
1021
1022       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1023
1024     }
1025
1026     offset += 2; /* Skip Byte Count (BCC) */
1027
1028   }
1029
1030 }
1031
1032 void
1033 dissect_set_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1034
1035 {
1036   proto_tree    *Attributes_tree;
1037   proto_item    *ti;
1038   guint8        WordCount;
1039   guint8        ByteCount;
1040   guint8        BufferFormat;
1041   guint16       Reserved5;
1042   guint16       Reserved4;
1043   guint16       Reserved3;
1044   guint16       Reserved2;
1045   guint16       Reserved1;
1046   guint16       LastWriteTime;
1047   guint16       LastWriteDate;
1048   guint16       Attributes;
1049   const char    *FileName;
1050
1051   if (dirn == 1) { /* Request(s) dissect code */
1052
1053     /* Build display for: Word Count (WCT) */
1054
1055     WordCount = GBYTE(pd, offset);
1056
1057     if (tree) {
1058
1059       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1060
1061     }
1062
1063     offset += 1; /* Skip Word Count (WCT) */
1064
1065     if (WordCount > 0) {
1066
1067       /* Build display for: Attributes */
1068
1069       Attributes = GSHORT(pd, offset);
1070
1071       if (tree) {
1072
1073         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
1074         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
1075         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1076                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
1077         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1078                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
1079         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1080                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
1081         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1082                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
1083         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1084                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
1085         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1086                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
1087         
1088       }
1089
1090       offset += 2; /* Skip Attributes */
1091
1092       /* Build display for: Last Write Time */
1093
1094       LastWriteTime = GSHORT(pd, offset);
1095
1096       if (tree) {
1097
1098         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
1099
1100       }
1101
1102       offset += 2; /* Skip Last Write Time */
1103
1104       /* Build display for: Last Write Date */
1105
1106       LastWriteDate = GSHORT(pd, offset);
1107
1108       if (tree) {
1109
1110         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
1111
1112       }
1113
1114       offset += 2; /* Skip Last Write Date */
1115
1116       /* Build display for: Reserved 1 */
1117
1118       Reserved1 = GSHORT(pd, offset);
1119
1120       if (tree) {
1121
1122         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
1123
1124       }
1125
1126       offset += 2; /* Skip Reserved 1 */
1127
1128       /* Build display for: Reserved 2 */
1129
1130       Reserved2 = GSHORT(pd, offset);
1131
1132       if (tree) {
1133
1134         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
1135
1136       }
1137
1138       offset += 2; /* Skip Reserved 2 */
1139
1140       /* Build display for: Reserved 3 */
1141
1142       Reserved3 = GSHORT(pd, offset);
1143
1144       if (tree) {
1145
1146         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
1147
1148       }
1149
1150       offset += 2; /* Skip Reserved 3 */
1151
1152       /* Build display for: Reserved 4 */
1153
1154       Reserved4 = GSHORT(pd, offset);
1155
1156       if (tree) {
1157
1158         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
1159
1160       }
1161
1162       offset += 2; /* Skip Reserved 4 */
1163
1164       /* Build display for: Reserved 5 */
1165
1166       Reserved5 = GSHORT(pd, offset);
1167
1168       if (tree) {
1169
1170         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
1171
1172       }
1173
1174       offset += 2; /* Skip Reserved 5 */
1175
1176     }
1177
1178     /* Build display for: Byte Count (BCC) */
1179
1180     ByteCount = GSHORT(pd, offset);
1181
1182     if (tree) {
1183
1184       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1185
1186     }
1187
1188     offset += 2; /* Skip Byte Count (BCC) */
1189
1190     /* Build display for: Buffer Format */
1191
1192     BufferFormat = GBYTE(pd, offset);
1193
1194     if (tree) {
1195
1196       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
1197
1198     }
1199
1200     offset += 1; /* Skip Buffer Format */
1201
1202     /* Build display for: File Name */
1203
1204     FileName = pd + offset;
1205
1206     if (tree) {
1207
1208       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
1209
1210     }
1211
1212     offset += strlen(FileName) + 1; /* Skip File Name */
1213
1214   }
1215
1216   if (dirn == 0) { /* Response(s) dissect code */
1217
1218     /* Build display for: Word Count (WCT) */
1219
1220     WordCount = GBYTE(pd, offset);
1221
1222     if (tree) {
1223
1224       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1225
1226     }
1227
1228     offset += 1; /* Skip Word Count (WCT) */
1229
1230     /* Build display for: Byte Count (BCC) */
1231
1232     ByteCount = GBYTE(pd, offset);
1233
1234     if (tree) {
1235
1236       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
1237
1238     }
1239
1240     offset += 1; /* Skip Byte Count (BCC) */
1241
1242   }
1243
1244 }
1245
1246 void
1247 dissect_write_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1248
1249 {
1250   guint8        WordCount;
1251   guint8        BufferFormat;
1252   guint32       Offset;
1253   guint16       Remaining;
1254   guint16       FID;
1255   guint16       DataLength;
1256   guint16       Count;
1257   guint16       ByteCount;
1258
1259   if (dirn == 1) { /* Request(s) dissect code */
1260
1261     /* Build display for: Word Count (WCT) */
1262
1263     WordCount = GBYTE(pd, offset);
1264
1265     if (tree) {
1266
1267       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1268
1269     }
1270
1271     offset += 1; /* Skip Word Count (WCT) */
1272
1273     /* Build display for: FID */
1274
1275     FID = GSHORT(pd, offset);
1276
1277     if (tree) {
1278
1279       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1280
1281     }
1282
1283     offset += 2; /* Skip FID */
1284
1285     /* Build display for: Count */
1286
1287     Count = GSHORT(pd, offset);
1288
1289     if (tree) {
1290
1291       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1292
1293     }
1294
1295     offset += 2; /* Skip Count */
1296
1297     /* Build display for: Offset */
1298
1299     Offset = GWORD(pd, offset);
1300
1301     if (tree) {
1302
1303       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1304
1305     }
1306
1307     offset += 4; /* Skip Offset */
1308
1309     /* Build display for: Remaining */
1310
1311     Remaining = GSHORT(pd, offset);
1312
1313     if (tree) {
1314
1315       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
1316
1317     }
1318
1319     offset += 2; /* Skip Remaining */
1320
1321     /* Build display for: Byte Count (BCC) */
1322
1323     ByteCount = GSHORT(pd, offset);
1324
1325     if (tree) {
1326
1327       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1328
1329     }
1330
1331     offset += 2; /* Skip Byte Count (BCC) */
1332
1333     /* Build display for: Buffer Format */
1334
1335     BufferFormat = GBYTE(pd, offset);
1336
1337     if (tree) {
1338
1339       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
1340
1341     }
1342
1343     offset += 1; /* Skip Buffer Format */
1344
1345     /* Build display for: Data Length */
1346
1347     DataLength = GSHORT(pd, offset);
1348
1349     if (tree) {
1350
1351       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1352
1353     }
1354
1355     offset += 2; /* Skip Data Length */
1356
1357     if (ByteCount > 0 && tree) {
1358
1359         if(END_OF_FRAME >= ByteCount)
1360             proto_tree_add_text(tree, NullTVB, offset, ByteCount, "Data (%u bytes)", ByteCount);
1361         else
1362             proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
1363
1364     }
1365
1366   }
1367
1368   if (dirn == 0) { /* Response(s) dissect code */
1369
1370     /* Build display for: Word Count (WCT) */
1371
1372     WordCount = GBYTE(pd, offset);
1373
1374     if (tree) {
1375
1376       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1377
1378     }
1379
1380     offset += 1; /* Skip Word Count (WCT) */
1381
1382     /* Build display for: Count */
1383
1384     Count = GSHORT(pd, offset);
1385
1386     if (tree) {
1387
1388       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1389
1390     }
1391
1392     offset += 2; /* Skip Count */
1393
1394     /* Build display for: Byte Count (BCC) */
1395
1396     ByteCount = GSHORT(pd, offset);
1397
1398     if (tree) {
1399
1400       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1401
1402     }
1403
1404     offset += 2; /* Skip Byte Count (BCC) */
1405
1406   }
1407
1408 }
1409
1410 void
1411 dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1412
1413 {
1414   guint8        WordCount;
1415   guint8        Pad;
1416   guint32       Reserved1;
1417   guint32       Offset;
1418   guint16       Reserved2;
1419   guint16       Reserved;
1420   guint16       MinCount;
1421   guint16       MaxCount;
1422   guint16       FID;
1423   guint16       DataOffset;
1424   guint16       DataLength;
1425   guint16       DataCompactionMode;
1426   guint16       Count;
1427   guint16       ByteCount;
1428
1429   if (dirn == 1) { /* Request(s) dissect code */
1430
1431     /* Build display for: Word Count (WCT) */
1432
1433     WordCount = GBYTE(pd, offset);
1434
1435     if (tree) {
1436
1437       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1438
1439     }
1440
1441     offset += 1; /* Skip Word Count (WCT) */
1442
1443     /* Build display for: FID */
1444
1445     FID = GSHORT(pd, offset);
1446
1447     if (tree) {
1448
1449       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1450
1451     }
1452
1453     offset += 2; /* Skip FID */
1454
1455     /* Build display for: Offset */
1456
1457     Offset = GWORD(pd, offset);
1458
1459     if (tree) {
1460
1461       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1462
1463     }
1464
1465     offset += 4; /* Skip Offset */
1466
1467     /* Build display for: Max Count */
1468
1469     MaxCount = GSHORT(pd, offset);
1470
1471     if (tree) {
1472
1473       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
1474
1475     }
1476
1477     offset += 2; /* Skip Max Count */
1478
1479     /* Build display for: Min Count */
1480
1481     MinCount = GSHORT(pd, offset);
1482
1483     if (tree) {
1484
1485       proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
1486
1487     }
1488
1489     offset += 2; /* Skip Min Count */
1490
1491     /* Build display for: Reserved 1 */
1492
1493     Reserved1 = GWORD(pd, offset);
1494
1495     if (tree) {
1496
1497       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 1: %u", Reserved1);
1498
1499     }
1500
1501     offset += 4; /* Skip Reserved 1 */
1502
1503     /* Build display for: Reserved 2 */
1504
1505     Reserved2 = GSHORT(pd, offset);
1506
1507     if (tree) {
1508
1509       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
1510
1511     }
1512
1513     offset += 2; /* Skip Reserved 2 */
1514
1515     /* Build display for: Byte Count (BCC) */
1516
1517     ByteCount = GSHORT(pd, offset);
1518
1519     if (tree) {
1520
1521       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1522
1523     }
1524
1525     offset += 2; /* Skip Byte Count (BCC) */
1526
1527   }
1528
1529   if (dirn == 0) { /* Response(s) dissect code */
1530
1531     /* Build display for: Word Count */
1532
1533     WordCount = GBYTE(pd, offset);
1534
1535     if (tree) {
1536
1537       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
1538
1539     }
1540
1541     offset += 1; /* Skip Word Count */
1542
1543     if (WordCount > 0) {
1544
1545       /* Build display for: Offset */
1546
1547       Offset = GWORD(pd, offset);
1548
1549       if (tree) {
1550
1551         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1552
1553       }
1554
1555       offset += 4; /* Skip Offset */
1556
1557       /* Build display for: Count */
1558
1559       Count = GSHORT(pd, offset);
1560
1561       if (tree) {
1562
1563         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1564
1565       }
1566
1567       offset += 2; /* Skip Count */
1568
1569       /* Build display for: Reserved */
1570
1571       Reserved = GSHORT(pd, offset);
1572
1573       if (tree) {
1574
1575         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1576
1577       }
1578
1579       offset += 2; /* Skip Reserved */
1580
1581       /* Build display for: Data Compaction Mode */
1582
1583       DataCompactionMode = GSHORT(pd, offset);
1584
1585       if (tree) {
1586
1587         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
1588
1589       }
1590
1591       offset += 2; /* Skip Data Compaction Mode */
1592
1593       /* Build display for: Reserved */
1594
1595       Reserved = GSHORT(pd, offset);
1596
1597       if (tree) {
1598
1599         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1600
1601       }
1602
1603       offset += 2; /* Skip Reserved */
1604
1605       /* Build display for: Data Length */
1606
1607       DataLength = GSHORT(pd, offset);
1608
1609       if (tree) {
1610
1611         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1612
1613       }
1614
1615       offset += 2; /* Skip Data Length */
1616
1617       /* Build display for: Data Offset */
1618
1619       DataOffset = GSHORT(pd, offset);
1620
1621       if (tree) {
1622
1623         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
1624
1625       }
1626
1627       offset += 2; /* Skip Data Offset */
1628
1629     }
1630
1631     /* Build display for: Byte Count (BCC) */
1632
1633     ByteCount = GSHORT(pd, offset);
1634
1635     if (tree) {
1636
1637       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1638
1639     }
1640
1641     offset += 2; /* Skip Byte Count (BCC) */
1642
1643     /* Build display for: Pad */
1644
1645     Pad = GBYTE(pd, offset);
1646
1647     if (tree) {
1648
1649       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
1650
1651     }
1652
1653     offset += 1; /* Skip Pad */
1654
1655   }
1656
1657 }
1658
1659 void
1660 dissect_delete_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *paernt, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1661
1662 {
1663   guint8        WordCount;
1664   guint8        BufferFormat;
1665   guint16       SearchAttributes;
1666   guint16       ByteCount;
1667   const char    *FileName;
1668
1669   if (dirn == 1) { /* Request(s) dissect code */
1670
1671     /* Build display for: Word Count (WCT) */
1672
1673     WordCount = GBYTE(pd, offset);
1674
1675     if (tree) {
1676
1677       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1678
1679     }
1680
1681     offset += 1; /* Skip Word Count (WCT) */
1682
1683     /* Build display for: SearchAttributes */
1684
1685     SearchAttributes = GSHORT(pd, offset);
1686
1687     if (tree) {
1688
1689         proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
1690     }
1691
1692     offset += 2; /* Skip SearchAttributes */
1693
1694     /* Build display for: Byte Count (BCC) */
1695
1696     ByteCount = GSHORT(pd, offset);
1697
1698     if (tree) {
1699
1700       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1701
1702     }
1703
1704     offset += 2; /* Skip Byte Count (BCC) */
1705
1706     /* Build display for: Buffer Format */
1707
1708     BufferFormat = GBYTE(pd, offset);
1709
1710     if (tree) {
1711
1712       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
1713
1714     }
1715
1716     offset += 1; /* Skip Buffer Format */
1717
1718     /* Build display for: File Name */
1719
1720     FileName = pd + offset;
1721
1722     if (tree) {
1723
1724       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
1725
1726     }
1727
1728     offset += strlen(FileName) + 1; /* Skip File Name */
1729
1730   }
1731
1732   if (dirn == 0) { /* Response(s) dissect code */
1733
1734     /* Build display for: Word Count (WCT) */
1735
1736     WordCount = GBYTE(pd, offset);
1737
1738     if (tree) {
1739
1740       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1741
1742     }
1743
1744     offset += 1; /* Skip Word Count (WCT) */
1745
1746     /* Build display for: Byte Count (BCC) */
1747
1748     ByteCount = GSHORT(pd, offset);
1749
1750     if (tree) {
1751
1752       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1753
1754     }
1755
1756     offset += 2; /* Skip Byte Count (BCC) */
1757
1758   }
1759
1760 }
1761
1762 void
1763 dissect_query_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1764
1765 {
1766   proto_tree    *Attributes_tree;
1767   proto_item    *ti;
1768   guint8        WordCount;
1769   guint32       FileDataSize;
1770   guint32       FileAllocationSize;
1771   guint16       LastWriteTime;
1772   guint16       LastWriteDate;
1773   guint16       LastAccessTime;
1774   guint16       LastAccessDate;
1775   guint16       FID;
1776   guint16       CreationTime;
1777   guint16       CreationDate;
1778   guint16       ByteCount;
1779   guint16       Attributes;
1780
1781   if (dirn == 1) { /* Request(s) dissect code */
1782
1783     /* Build display for: Word Count (WCT) */
1784
1785     WordCount = GBYTE(pd, offset);
1786
1787     if (tree) {
1788
1789       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1790
1791     }
1792
1793     offset += 1; /* Skip Word Count (WCT) */
1794
1795     /* Build display for: FID */
1796
1797     FID = GSHORT(pd, offset);
1798
1799     if (tree) {
1800
1801       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1802
1803     }
1804
1805     offset += 2; /* Skip FID */
1806
1807     /* Build display for: Byte Count */
1808
1809     ByteCount = GSHORT(pd, offset);
1810
1811     if (tree) {
1812
1813       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
1814
1815     }
1816
1817     offset += 2; /* Skip Byte Count */
1818
1819   }
1820
1821   if (dirn == 0) { /* Response(s) dissect code */
1822
1823     /* Build display for: Word Count (WCT) */
1824
1825     WordCount = GBYTE(pd, offset);
1826
1827     if (tree) {
1828
1829       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1830
1831     }
1832
1833     offset += 1; /* Skip Word Count (WCT) */
1834
1835     if (WordCount > 0) {
1836
1837       /* Build display for: Creation Date */
1838
1839       CreationDate = GSHORT(pd, offset);
1840
1841       if (tree) {
1842
1843         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
1844
1845       }
1846
1847       offset += 2; /* Skip Creation Date */
1848
1849       /* Build display for: Creation Time */
1850
1851       CreationTime = GSHORT(pd, offset);
1852
1853       if (tree) {
1854
1855         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
1856
1857       }
1858
1859       offset += 2; /* Skip Creation Time */
1860
1861       /* Build display for: Last Access Date */
1862
1863       LastAccessDate = GSHORT(pd, offset);
1864
1865       if (tree) {
1866
1867         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
1868
1869       }
1870
1871       offset += 2; /* Skip Last Access Date */
1872
1873       /* Build display for: Last Access Time */
1874
1875       LastAccessTime = GSHORT(pd, offset);
1876
1877       if (tree) {
1878
1879         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
1880
1881       }
1882
1883       offset += 2; /* Skip Last Access Time */
1884
1885       /* Build display for: Last Write Date */
1886
1887       LastWriteDate = GSHORT(pd, offset);
1888
1889       if (tree) {
1890
1891         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
1892
1893       }
1894
1895       offset += 2; /* Skip Last Write Date */
1896
1897       /* Build display for: Last Write Time */
1898
1899       LastWriteTime = GSHORT(pd, offset);
1900
1901       if (tree) {
1902
1903         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
1904
1905       }
1906
1907       offset += 2; /* Skip Last Write Time */
1908
1909       /* Build display for: File Data Size */
1910
1911       FileDataSize = GWORD(pd, offset);
1912
1913       if (tree) {
1914         
1915         proto_tree_add_text(tree, NullTVB, offset, 4, "File Data Size: %u", FileDataSize);
1916
1917       }
1918
1919       offset += 4; /* Skip File Data Size */
1920
1921       /* Build display for: File Allocation Size */
1922
1923       FileAllocationSize = GWORD(pd, offset);
1924
1925       if (tree) {
1926
1927         proto_tree_add_text(tree, NullTVB, offset, 4, "File Allocation Size: %u", FileAllocationSize);
1928
1929       }
1930
1931       offset += 4; /* Skip File Allocation Size */
1932
1933       /* Build display for: Attributes */
1934
1935       Attributes = GSHORT(pd, offset);
1936       
1937       if (tree) {
1938
1939         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
1940         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
1941         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1942                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
1943         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1944                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
1945         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1946                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
1947         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1948                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
1949         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1950                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
1951         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1952                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
1953     
1954       }
1955
1956       offset += 2; /* Skip Attributes */
1957
1958     }
1959
1960     /* Build display for: Byte Count */
1961
1962     ByteCount = GSHORT(pd, offset);
1963
1964     if (tree) {
1965
1966       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
1967
1968     }
1969
1970     offset += 2; /* Skip Byte Count */
1971
1972   }
1973
1974 }
1975
1976 void
1977 dissect_treecon_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1978
1979 {
1980   guint8        WordCount;
1981   guint8        BufferFormat3;
1982   guint8        BufferFormat2;
1983   guint8        BufferFormat1;
1984   guint16       TID;
1985   guint16       MaxBufferSize;
1986   guint16       ByteCount;
1987   const char    *SharePath;
1988   const char    *Service;
1989   const char    *Password;
1990
1991   if (dirn == 1) { /* Request(s) dissect code */
1992
1993     /* Build display for: Word Count (WCT) */
1994
1995     WordCount = GBYTE(pd, offset);
1996
1997     if (tree) {
1998
1999       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2000
2001     }
2002
2003     offset += 1; /* Skip Word Count (WCT) */
2004
2005     /* Build display for: Byte Count (BCC) */
2006
2007     ByteCount = GSHORT(pd, offset);
2008
2009     if (tree) {
2010
2011       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2012
2013     }
2014
2015     offset += 2; /* Skip Byte Count (BCC) */
2016
2017     /* Build display for: BufferFormat1 */
2018
2019     BufferFormat1 = GBYTE(pd, offset);
2020
2021     if (tree) {
2022
2023       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat1: %u", BufferFormat1);
2024
2025     }
2026
2027     offset += 1; /* Skip BufferFormat1 */
2028
2029     /* Build display for: Share Path */
2030
2031     SharePath = pd + offset;
2032
2033     if (tree) {
2034
2035       proto_tree_add_text(tree, NullTVB, offset, strlen(SharePath) + 1, "Share Path: %s", SharePath);
2036
2037     }
2038
2039     offset += strlen(SharePath) + 1; /* Skip Share Path */
2040
2041     /* Build display for: BufferFormat2 */
2042
2043     BufferFormat2 = GBYTE(pd, offset);
2044
2045     if (tree) {
2046
2047       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat2: %u", BufferFormat2);
2048
2049     }
2050
2051     offset += 1; /* Skip BufferFormat2 */
2052
2053     /* Build display for: Password */
2054
2055     Password = pd + offset;
2056
2057     if (tree) {
2058
2059       proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
2060
2061     }
2062
2063     offset += strlen(Password) + 1; /* Skip Password */
2064
2065     /* Build display for: BufferFormat3 */
2066
2067     BufferFormat3 = GBYTE(pd, offset);
2068
2069     if (tree) {
2070
2071       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat3: %u", BufferFormat3);
2072
2073     }
2074
2075     offset += 1; /* Skip BufferFormat3 */
2076
2077     /* Build display for: Service */
2078
2079     Service = pd + offset;
2080
2081     if (tree) {
2082
2083       proto_tree_add_text(tree, NullTVB, offset, strlen(Service) + 1, "Service: %s", Service);
2084
2085     }
2086
2087     offset += strlen(Service) + 1; /* Skip Service */
2088
2089   }
2090
2091   if (dirn == 0) { /* Response(s) dissect code */
2092
2093     /* Build display for: Word Count (WCT) */
2094
2095     WordCount = GBYTE(pd, offset);
2096
2097     if (tree) {
2098
2099       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2100
2101     }
2102
2103     if (errcode != 0) return;
2104
2105     offset += 1; /* Skip Word Count (WCT) */
2106
2107     /* Build display for: Max Buffer Size */
2108
2109     MaxBufferSize = GSHORT(pd, offset);
2110
2111     if (tree) {
2112
2113       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Buffer Size: %u", MaxBufferSize);
2114
2115     }
2116
2117     offset += 2; /* Skip Max Buffer Size */
2118
2119     /* Build display for: TID */
2120
2121     TID = GSHORT(pd, offset);
2122
2123     if (tree) {
2124
2125       proto_tree_add_text(tree, NullTVB, offset, 2, "TID: %u", TID);
2126
2127     }
2128
2129     offset += 2; /* Skip TID */
2130
2131     /* Build display for: Byte Count (BCC) */
2132
2133     ByteCount = GSHORT(pd, offset);
2134
2135     if (tree) {
2136
2137       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2138
2139     }
2140
2141     offset += 2; /* Skip Byte Count (BCC) */
2142
2143   }
2144
2145 }
2146
2147 /* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
2148 void
2149 dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
2150
2151 {
2152   proto_tree    *Capabilities_tree;
2153   proto_item    *ti;
2154   guint8        WordCount;
2155   guint8        AndXReserved;
2156   guint8        AndXCommand = 0xFF;
2157   guint32       SessionKey;
2158   guint32       Reserved;
2159   guint32       Capabilities;
2160   guint16       VcNumber;
2161   guint16       UNICODEAccountPasswordLength;
2162   guint16       PasswordLen;
2163   guint16       MaxMpxCount;
2164   guint16       MaxBufferSize;
2165   guint16       ByteCount;
2166   guint16       AndXOffset = 0;
2167   guint16       Action;
2168   guint16       ANSIAccountPasswordLength;
2169   const char    *UNICODEPassword;
2170   const char    *Password;
2171   const char    *PrimaryDomain;
2172   const char    *NativeOS;
2173   const char    *NativeLanManType;
2174   const char    *NativeLanMan;
2175   const char    *AccountName;
2176   const char    *ANSIPassword;
2177
2178   if (dirn == 1) { /* Request(s) dissect code */
2179
2180     WordCount = GBYTE(pd, offset);
2181
2182     switch (WordCount) {
2183
2184     case 10:
2185
2186       /* Build display for: Word Count (WCT) */
2187
2188       WordCount = GBYTE(pd, offset);
2189
2190       if (tree) {
2191
2192         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2193
2194       }
2195
2196       offset += 1; /* Skip Word Count (WCT) */
2197
2198       /* Build display for: AndXCommand */
2199
2200       AndXCommand = GBYTE(pd, offset);
2201
2202       if (tree) {
2203
2204         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2205                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2206
2207       }
2208
2209       offset += 1; /* Skip AndXCommand */
2210
2211       /* Build display for: AndXReserved */
2212
2213       AndXReserved = GBYTE(pd, offset);
2214
2215       if (tree) {
2216
2217         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2218
2219       }
2220
2221       offset += 1; /* Skip AndXReserved */
2222
2223       /* Build display for: AndXOffset */
2224
2225       AndXOffset = GSHORT(pd, offset);
2226
2227       if (tree) {
2228
2229         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2230
2231       }
2232
2233       offset += 2; /* Skip AndXOffset */
2234
2235       /* Build display for: MaxBufferSize */
2236
2237       MaxBufferSize = GSHORT(pd, offset);
2238
2239       if (tree) {
2240
2241         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2242
2243       }
2244
2245       offset += 2; /* Skip MaxBufferSize */
2246
2247       /* Build display for: MaxMpxCount */
2248
2249       MaxMpxCount = GSHORT(pd, offset);
2250
2251       if (tree) {
2252
2253         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2254
2255       }
2256
2257       offset += 2; /* Skip MaxMpxCount */
2258
2259       /* Build display for: VcNumber */
2260
2261       VcNumber = GSHORT(pd, offset);
2262
2263       if (tree) {
2264
2265         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2266
2267       }
2268
2269       offset += 2; /* Skip VcNumber */
2270
2271       /* Build display for: SessionKey */
2272
2273       SessionKey = GWORD(pd, offset);
2274
2275       if (tree) {
2276
2277         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2278
2279       }
2280
2281       offset += 4; /* Skip SessionKey */
2282
2283       /* Build display for: PasswordLen */
2284
2285       PasswordLen = GSHORT(pd, offset);
2286
2287       if (tree) {
2288
2289         proto_tree_add_text(tree, NullTVB, offset, 2, "PasswordLen: %u", PasswordLen);
2290
2291       }
2292
2293       offset += 2; /* Skip PasswordLen */
2294
2295       /* Build display for: Reserved */
2296
2297       Reserved = GWORD(pd, offset);
2298
2299       if (tree) {
2300
2301         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2302
2303       }
2304
2305       offset += 4; /* Skip Reserved */
2306
2307       /* Build display for: Byte Count (BCC) */
2308
2309       ByteCount = GSHORT(pd, offset);
2310
2311       if (tree) {
2312
2313         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2314
2315       }
2316
2317       offset += 2; /* Skip Byte Count (BCC) */
2318
2319       if (ByteCount > 0) {
2320
2321         /* Build displat for: Password */
2322
2323         Password = pd + offset;
2324
2325         if (tree) {
2326
2327           proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
2328
2329         }
2330
2331         offset += PasswordLen;
2332
2333         /* Build display for: AccountName */
2334
2335         AccountName = pd + offset;
2336
2337         if (tree) {
2338
2339           proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
2340
2341         }
2342
2343         offset += strlen(AccountName) + 1; /* Skip AccountName */
2344
2345         /* Build display for: PrimaryDomain */
2346
2347         PrimaryDomain = pd + offset;
2348
2349         if (tree) {
2350
2351           proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
2352
2353         }
2354
2355         offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
2356
2357         /* Build display for: NativeOS */
2358
2359         NativeOS = pd + offset;
2360
2361         if (tree) {
2362
2363           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
2364
2365         }
2366
2367         offset += strlen(NativeOS) + 1; /* Skip NativeOS */
2368
2369         /* Build display for: NativeLanMan */
2370
2371         NativeLanMan = pd + offset;
2372
2373         if (tree) {
2374
2375           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "Native Lan Manager: %s", NativeLanMan);
2376
2377         }
2378
2379         offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
2380
2381       }
2382
2383     break;
2384
2385     case 13:
2386
2387       /* Build display for: Word Count (WCT) */
2388
2389       WordCount = GBYTE(pd, offset);
2390
2391       if (tree) {
2392
2393         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2394
2395       }
2396
2397       offset += 1; /* Skip Word Count (WCT) */
2398
2399       /* Build display for: AndXCommand */
2400
2401       AndXCommand = GBYTE(pd, offset);
2402
2403       if (tree) {
2404
2405         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2406                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2407
2408       }
2409
2410       offset += 1; /* Skip AndXCommand */
2411
2412       /* Build display for: AndXReserved */
2413
2414       AndXReserved = GBYTE(pd, offset);
2415
2416       if (tree) {
2417
2418         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2419
2420       }
2421
2422       offset += 1; /* Skip AndXReserved */
2423
2424       /* Build display for: AndXOffset */
2425
2426       AndXOffset = GSHORT(pd, offset);
2427
2428       if (tree) {
2429
2430         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2431
2432       }
2433
2434       offset += 2; /* Skip AndXOffset */
2435
2436       /* Build display for: MaxBufferSize */
2437
2438       MaxBufferSize = GSHORT(pd, offset);
2439
2440       if (tree) {
2441
2442         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2443
2444       }
2445
2446       offset += 2; /* Skip MaxBufferSize */
2447
2448       /* Build display for: MaxMpxCount */
2449
2450       MaxMpxCount = GSHORT(pd, offset);
2451
2452       if (tree) {
2453
2454         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2455
2456       }
2457
2458       offset += 2; /* Skip MaxMpxCount */
2459
2460       /* Build display for: VcNumber */
2461
2462       VcNumber = GSHORT(pd, offset);
2463
2464       if (tree) {
2465
2466         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2467
2468       }
2469
2470       offset += 2; /* Skip VcNumber */
2471
2472       /* Build display for: SessionKey */
2473
2474       SessionKey = GWORD(pd, offset);
2475
2476       if (tree) {
2477
2478         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2479
2480       }
2481
2482       offset += 4; /* Skip SessionKey */
2483
2484       /* Build display for: ANSI Account Password Length */
2485
2486       ANSIAccountPasswordLength = GSHORT(pd, offset);
2487
2488       if (tree) {
2489
2490         proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
2491
2492       }
2493
2494       offset += 2; /* Skip ANSI Account Password Length */
2495
2496       /* Build display for: UNICODE Account Password Length */
2497
2498       UNICODEAccountPasswordLength = GSHORT(pd, offset);
2499
2500       if (tree) {
2501
2502         proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
2503
2504       }
2505
2506       offset += 2; /* Skip UNICODE Account Password Length */
2507
2508       /* Build display for: Reserved */
2509
2510       Reserved = GWORD(pd, offset);
2511
2512       if (tree) {
2513
2514         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2515
2516       }
2517
2518       offset += 4; /* Skip Reserved */
2519
2520       /* Build display for: Capabilities */
2521
2522       Capabilities = GWORD(pd, offset);
2523
2524       if (tree) {
2525
2526         ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", Capabilities);
2527         Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
2528         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2529                             decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
2530         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2531                             decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
2532         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2533                             decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
2534         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2535                             decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
2536         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2537                             decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
2538         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2539                             decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
2540         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2541                             decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
2542         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2543                             decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
2544         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2545                             decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
2546         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2547                             decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
2548         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2549                             decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
2550         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2551                             decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
2552         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2553                             decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
2554         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2555                             decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
2556       
2557 }
2558
2559       offset += 4; /* Skip Capabilities */
2560
2561       /* Build display for: Byte Count */
2562
2563       ByteCount = GSHORT(pd, offset);
2564
2565       if (tree) {
2566
2567         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
2568
2569       }
2570
2571       offset += 2; /* Skip Byte Count */
2572
2573       if (ByteCount > 0) {
2574
2575           /* Build display for: ANSI Password */
2576
2577           ANSIPassword = pd + offset;
2578
2579           if (ANSIAccountPasswordLength > 0) {
2580
2581               if (tree) {
2582
2583                   proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
2584
2585               }
2586
2587               offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
2588           }
2589
2590         /* Build display for: UNICODE Password */
2591
2592         UNICODEPassword = pd + offset;
2593
2594         if (UNICODEAccountPasswordLength > 0) {
2595
2596           if (tree) {
2597
2598             proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
2599
2600           }
2601
2602           offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
2603
2604         }
2605
2606         /* Build display for: Account Name */
2607
2608         AccountName = pd + offset;
2609
2610         if (tree) {
2611
2612           proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "Account Name: %s", AccountName);
2613
2614         }
2615
2616         offset += strlen(AccountName) + 1; /* Skip Account Name */
2617
2618         /* Build display for: Primary Domain */
2619
2620         PrimaryDomain = pd + offset;
2621
2622         if (tree) {
2623
2624           proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "Primary Domain: %s", PrimaryDomain);
2625
2626         }
2627
2628         offset += strlen(PrimaryDomain) + 1; /* Skip Primary Domain */
2629
2630         /* Build display for: Native OS */
2631
2632         NativeOS = pd + offset;
2633
2634         if (tree) {
2635
2636           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
2637
2638         }
2639
2640         offset += strlen(NativeOS) + 1; /* Skip Native OS */
2641
2642         /* Build display for: Native LanMan Type */
2643
2644         NativeLanManType = pd + offset;
2645
2646         if (tree) {
2647
2648           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanManType) + 1, "Native LanMan Type: %s", NativeLanManType);
2649
2650         }
2651
2652         offset += strlen(NativeLanManType) + 1; /* Skip Native LanMan Type */
2653
2654       }
2655
2656       break;
2657
2658     }
2659
2660
2661     if (AndXCommand != 0xFF) {
2662
2663       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
2664
2665     }
2666
2667   }
2668
2669   if (dirn == 0) { /* Response(s) dissect code */
2670
2671     /* Build display for: Word Count (WCT) */
2672
2673     WordCount = GBYTE(pd, offset);
2674
2675     if (tree) {
2676
2677       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2678
2679     }
2680
2681     offset += 1; /* Skip Word Count (WCT) */
2682
2683     if (WordCount > 0) {
2684
2685       /* Build display for: AndXCommand */
2686
2687       AndXCommand = GBYTE(pd, offset);
2688
2689       if (tree) {
2690
2691         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
2692                             (AndXCommand == 0xFF ? "No futher commands" : decode_smb_name(AndXCommand)));
2693
2694       }
2695
2696       offset += 1; /* Skip AndXCommand */
2697
2698       /* Build display for: AndXReserved */
2699
2700       AndXReserved = GBYTE(pd, offset);
2701
2702       if (tree) {
2703
2704         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2705
2706       }
2707
2708       offset += 1; /* Skip AndXReserved */
2709
2710       /* Build display for: AndXOffset */
2711
2712       AndXOffset = GSHORT(pd, offset);
2713
2714       if (tree) {
2715
2716         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2717
2718       }
2719
2720
2721       offset += 2; /* Skip AndXOffset */
2722
2723       /* Build display for: Action */
2724
2725       Action = GSHORT(pd, offset);
2726
2727       if (tree) {
2728
2729         proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
2730
2731       }
2732
2733       offset += 2; /* Skip Action */
2734
2735     }
2736
2737     /* Build display for: Byte Count (BCC) */
2738
2739     ByteCount = GSHORT(pd, offset);
2740
2741     if (tree) {
2742
2743       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2744
2745     }
2746
2747     if (errcode != 0 && WordCount == 0xFF) return;  /* No more here ... */
2748
2749     offset += 2; /* Skip Byte Count (BCC) */
2750
2751     if (ByteCount > 0) {
2752
2753       /* Build display for: NativeOS */
2754
2755       NativeOS = pd + offset;
2756
2757       if (tree) {
2758
2759         proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);
2760
2761       }
2762
2763       offset += strlen(NativeOS) + 1; /* Skip NativeOS */
2764
2765       /* Build display for: NativeLanMan */
2766
2767       NativeLanMan = pd + offset;
2768
2769       if (tree) {
2770
2771         proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "NativeLanMan: %s", NativeLanMan);
2772
2773       }
2774
2775       offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
2776
2777       /* Build display for: PrimaryDomain */
2778
2779       PrimaryDomain = pd + offset;
2780
2781       if (tree) {
2782
2783         proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
2784
2785       }
2786
2787       offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
2788
2789     }
2790
2791     if (AndXCommand != 0xFF) {
2792
2793       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
2794
2795     }
2796
2797   }
2798
2799 }
2800
2801 void
2802 dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
2803
2804 {
2805   guint8      wct, andxcmd = 0xFF;
2806   guint16     andxoffs = 0, flags, passwdlen, bcc, optionsup;
2807   const char  *str;
2808   proto_tree  *flags_tree;
2809   proto_item  *ti;
2810
2811   wct = pd[offset];
2812
2813   /* Now figure out what format we are talking about, 2, 3, or 4 response
2814    * words ...
2815    */
2816
2817   if (!((dirn == 1) && (wct == 4)) && !((dirn == 0) && (wct == 2)) &&
2818       !((dirn == 0) && (wct == 3)) && !(wct == 0)) {
2819
2820     if (tree) {
2821
2822       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
2823
2824       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
2825
2826       return;
2827
2828     }
2829     
2830   }
2831
2832   if (tree) {
2833
2834     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
2835
2836   }
2837
2838   offset += 1;
2839
2840   if (wct > 0) {
2841
2842     andxcmd = pd[offset];
2843
2844     if (tree) {
2845
2846       proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
2847                           (andxcmd == 0xFF) ? "No further commands":
2848                           decode_smb_name(andxcmd));
2849                 
2850       proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
2851
2852     }
2853
2854     offset += 2;
2855
2856     andxoffs = GSHORT(pd, offset);
2857
2858     if (tree) {
2859
2860       proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
2861
2862     }
2863
2864     offset += 2;
2865
2866   }
2867
2868   switch (wct) {
2869
2870   case 0:
2871
2872     bcc = GSHORT(pd, offset);
2873
2874     if (tree) {
2875
2876       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2877
2878     }
2879
2880     break;
2881
2882   case 4:
2883
2884     flags = GSHORT(pd, offset);
2885
2886     if (tree) {
2887
2888       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%02x", flags);
2889       flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
2890       proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s", 
2891                           decode_boolean_bitfield(flags, 0x01, 16,
2892                                                   "Disconnect TID",
2893                                                   "Don't disconnect TID"));
2894
2895     }
2896
2897     offset += 2;
2898
2899     passwdlen = GSHORT(pd, offset);
2900
2901     if (tree) {
2902
2903       proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
2904
2905     }
2906
2907     offset += 2;
2908
2909     bcc = GSHORT(pd, offset);
2910
2911     if (tree) {
2912
2913       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2914
2915     }
2916
2917     offset += 2;
2918
2919     str = pd + offset;
2920
2921     if (tree) {
2922
2923       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
2924
2925     }
2926
2927     offset += passwdlen;
2928
2929     str = pd + offset;
2930
2931     if (tree) {
2932
2933       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Path: %s", str);
2934
2935     }
2936
2937     offset += strlen(str) + 1;
2938
2939     str = pd + offset;
2940
2941     if (tree) {
2942
2943       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
2944
2945     }
2946
2947     break;
2948
2949   case 2:
2950
2951     bcc = GSHORT(pd, offset);
2952
2953     if (tree) {
2954
2955       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2956
2957     }
2958
2959     offset += 2;
2960
2961     str = pd + offset;
2962
2963     if (tree) {
2964
2965       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
2966                           str);
2967
2968     }
2969
2970     offset += strlen(str) + 1;
2971
2972     break;
2973
2974   case 3:
2975
2976     optionsup = GSHORT(pd, offset);
2977
2978     if (tree) {  /* Should break out the bits */
2979
2980       proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x", 
2981                           optionsup);
2982
2983     }
2984
2985     offset += 2;
2986
2987     bcc = GSHORT(pd, offset);
2988
2989     if (tree) {
2990
2991       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2992
2993     }
2994
2995     offset += 2;
2996
2997     str = pd + offset;
2998
2999     if (tree) {
3000
3001       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
3002
3003     }
3004
3005     offset += strlen(str) + 1;
3006
3007     str = pd + offset;
3008
3009     if (tree) {
3010
3011       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Native File System: %s", str);
3012
3013     }
3014
3015     offset += strlen(str) + 1;
3016
3017     
3018     break;
3019
3020   default:
3021         ; /* nothing */
3022         break;
3023   }
3024
3025   if (andxcmd != 0xFF) /* Process that next command ... ??? */
3026
3027     (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset, errcode, dirn);
3028
3029 }
3030
3031 void 
3032 dissect_negprot_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3033 {
3034   guint8        wct, enckeylen;
3035   guint16       bcc, mode, rawmode, dialect;
3036   guint32       caps;
3037   proto_tree    *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree;
3038   proto_item    *ti;
3039   const char    *str;
3040   char          *ustr;
3041   int           ustr_len;
3042
3043   wct = pd[offset];    /* Should be 0, 1 or 13 or 17, I think */
3044
3045   if (!((wct == 0) && (dirn == 1)) && !((wct == 1) && (dirn == 0)) &&
3046       !((wct == 13) && (dirn == 0)) && !((wct == 17) && (dirn == 0))) {
3047     if (tree) {
3048
3049       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., not %u", wct);
3050
3051       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
3052
3053       return;
3054     }
3055   }
3056
3057   if (tree) {
3058
3059     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %d", wct);
3060
3061   }
3062
3063   if (dirn == 0 && errcode != 0) return;  /* No more info ... */
3064
3065   offset += 1; 
3066
3067   /* Now decode the various formats ... */
3068
3069   switch (wct) {
3070
3071   case 0:     /* A request */
3072
3073     bcc = GSHORT(pd, offset);
3074
3075     if (tree) {
3076
3077       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3078
3079     }
3080
3081     offset += 2;
3082
3083     if (tree) {
3084
3085       ti = proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Dialects");
3086       dialects = proto_item_add_subtree(ti, ett_smb_dialects);
3087
3088     }
3089
3090     while (IS_DATA_IN_FRAME(offset)) {
3091       const char *str;
3092
3093       if (tree) {
3094
3095         proto_tree_add_text(dialects, NullTVB, offset, 1, "Dialect Marker: %d", pd[offset]);
3096
3097       }
3098
3099       offset += 1;
3100
3101       str = pd + offset;
3102
3103       if (tree) {
3104
3105         proto_tree_add_text(dialects, NullTVB, offset, strlen(str)+1, "Dialect: %s", str);
3106
3107       }
3108
3109       offset += strlen(str) + 1;
3110
3111     }
3112     break;
3113
3114   case 1:     /* PC NETWORK PROGRAM 1.0 */
3115
3116     dialect = GSHORT(pd, offset);
3117
3118     if (tree) {  /* Hmmmm, what if none of the dialects is recognized */
3119
3120       if (dialect == 0xFFFF) { /* Server didn't like them dialects */
3121
3122         proto_tree_add_text(tree, NullTVB, offset, 2, "Supplied dialects not recognized");
3123
3124       }
3125       else {
3126
3127         proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, PC NETWORK PROTGRAM 1.0", dialect);
3128
3129       }
3130
3131     }
3132
3133     offset += 2;
3134
3135     bcc = GSHORT(pd, offset);
3136
3137     if (tree) {
3138
3139       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3140
3141     }
3142
3143     break;
3144
3145   case 13:    /* Greater than Core and up to and incl LANMAN2.1  */
3146
3147     if (tree) {
3148
3149       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
3150
3151     }
3152
3153     /* Much of this is similar to response 17 below */
3154
3155     offset += 2;
3156
3157     mode = GSHORT(pd, offset);
3158
3159     if (tree) {
3160
3161       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Security Mode: 0x%04x", mode);
3162       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
3163       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
3164                           decode_boolean_bitfield(mode, 0x0001, 16,
3165                                                   "Security  = User",
3166                                                   "Security  = Share"));
3167       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
3168                           decode_boolean_bitfield(mode, 0x0002, 16,
3169                                                   "Passwords = Encrypted",
3170                                                   "Passwords = Plaintext"));
3171
3172     }
3173
3174     offset += 2;
3175
3176     if (tree) {
3177
3178       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GSHORT(pd, offset));
3179
3180     }
3181
3182     offset += 2;
3183
3184     if (tree) {
3185
3186       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
3187
3188     }
3189     
3190     offset += 2;
3191
3192     if (tree) {
3193
3194       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
3195
3196     }
3197
3198     offset += 2;
3199
3200     rawmode = GSHORT(pd, offset);
3201
3202     if (tree) {
3203
3204       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Raw Mode: 0x%04x", rawmode);
3205       rawmode_tree = proto_item_add_subtree(ti, ett_smb_rawmode);
3206       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
3207                           decode_boolean_bitfield(rawmode, 0x01, 16,
3208                                                   "Read Raw supported",
3209                                                   "Read Raw not supported"));
3210       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
3211                           decode_boolean_bitfield(rawmode, 0x02, 16,
3212                                                   "Write Raw supported",
3213                                                   "Write Raw not supported"));
3214
3215     }
3216
3217     offset += 2;
3218
3219     if (tree) {
3220
3221       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
3222
3223     }
3224
3225     offset += 4;
3226
3227     /* Now the server time, two short parameters ... */
3228
3229     if (tree) {
3230
3231       proto_tree_add_text(tree, NullTVB, offset, 2, "Server Time: %s",
3232                         dissect_dos_time(GSHORT(pd, offset)));
3233       proto_tree_add_text(tree, NullTVB, offset + 2, 2, "Server Date: %s",
3234                         dissect_dos_date(GSHORT(pd, offset + 2)));
3235
3236     }
3237
3238     offset += 4;
3239
3240     /* Server Time Zone, SHORT */
3241
3242     if (tree) {
3243
3244       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
3245                           (signed)GSSHORT(pd, offset));
3246
3247     }
3248
3249     offset += 2;
3250
3251     /* Challenge Length */
3252
3253     enckeylen = GSHORT(pd, offset);
3254
3255     if (tree) {
3256
3257       proto_tree_add_text(tree, NullTVB, offset, 2, "Challenge Length: %u", enckeylen);
3258
3259     }
3260
3261     offset += 2;
3262
3263     if (tree) {
3264
3265       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u (MBZ)", GSHORT(pd, offset));
3266
3267     }
3268
3269     offset += 2;
3270
3271     bcc = GSHORT(pd, offset);
3272
3273     if (tree) {
3274
3275       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3276
3277     }
3278
3279     offset += 2;
3280
3281     if (enckeylen) { /* only if non-zero key len */
3282
3283       str = pd + offset;
3284
3285       if (tree) {
3286
3287         proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge: %s",
3288                                 bytes_to_str(str, enckeylen));
3289       }
3290
3291       offset += enckeylen;
3292
3293     }
3294
3295     /* Primary Domain ... */
3296
3297     str = pd + offset;
3298
3299     if (tree) {
3300
3301       proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "Primary Domain: %s", str);
3302
3303     }
3304
3305     break;
3306
3307   case 17:    /* Greater than LANMAN2.1 */
3308
3309     if (tree) {
3310
3311       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than LANMAN2.1", GSHORT(pd, offset));
3312
3313     }
3314
3315     offset += 2;
3316
3317     mode = GBYTE(pd, offset);
3318
3319     if (tree) {
3320
3321       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Security Mode: 0x%02x", mode);
3322       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
3323       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3324                           decode_boolean_bitfield(mode, 0x01, 8,
3325                                                   "Security  = User",
3326                                                   "Security  = Share"));
3327       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3328                           decode_boolean_bitfield(mode, 0x02, 8,
3329                                                   "Passwords = Encrypted",
3330                                                   "Passwords = Plaintext"));
3331       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3332                           decode_boolean_bitfield(mode, 0x04, 8,
3333                                                   "Security signatures enabled",
3334                                                   "Security signatures not enabled"));
3335       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3336                           decode_boolean_bitfield(mode, 0x08, 8,
3337                                                   "Security signatures required",
3338                                                   "Security signatures not required"));
3339
3340     }
3341
3342     offset += 1;
3343
3344     if (tree) {
3345
3346       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
3347
3348     }
3349     
3350     offset += 2;
3351
3352     if (tree) {
3353
3354       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
3355
3356     }
3357
3358     offset += 2;
3359
3360     if (tree) {
3361
3362       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GWORD(pd, offset));
3363
3364     }
3365
3366     offset += 4;
3367
3368     if (tree) {
3369
3370       proto_tree_add_text(tree, NullTVB, offset, 4, "Max raw size:        %u", GWORD(pd, offset));
3371
3372     }
3373
3374     offset += 4;
3375
3376     if (tree) {
3377
3378       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
3379
3380     }
3381
3382     offset += 4;
3383
3384     caps = GWORD(pd, offset);
3385
3386     if (tree) {
3387
3388       ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", caps);
3389       caps_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
3390       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3391                           decode_boolean_bitfield(caps, 0x0001, 32,
3392                                                   "Raw Mode supported",
3393                                                   "Raw Mode not supported"));
3394       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3395                           decode_boolean_bitfield(caps, 0x0002, 32,
3396                                                   "MPX Mode supported",
3397                                                   "MPX Mode not supported"));
3398       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3399                           decode_boolean_bitfield(caps, 0x0004, 32,
3400                                                   "Unicode supported",
3401                                                   "Unicode not supported"));
3402       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3403                           decode_boolean_bitfield(caps, 0x0008, 32,
3404                                                   "Large files supported",
3405                                                   "Large files not supported"));
3406       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3407                           decode_boolean_bitfield(caps, 0x0010, 32, 
3408                                                   "NT LM 0.12 SMBs supported",
3409                                                   "NT LM 0.12 SMBs not supported"));
3410       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3411                           decode_boolean_bitfield(caps, 0x0020, 32,
3412                                                   "RPC remote APIs supported",
3413                                                   "RPC remote APIs not supported"));
3414       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3415                           decode_boolean_bitfield(caps, 0x0040, 32,
3416                                                   "NT status codes supported",
3417                                                   "NT status codes  not supported"));
3418       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3419                           decode_boolean_bitfield(caps, 0x0080, 32,
3420                                                   "Level 2 OpLocks supported",
3421                                                   "Level 2 OpLocks not supported"));
3422       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3423                           decode_boolean_bitfield(caps, 0x0100, 32,
3424                                                   "Lock&Read supported",
3425                                                   "Lock&Read not supported"));
3426       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3427                           decode_boolean_bitfield(caps, 0x0200, 32,
3428                                                   "NT Find supported",
3429                                                   "NT Find not supported"));
3430       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3431                           decode_boolean_bitfield(caps, 0x1000, 32,
3432                                                   "DFS supported",
3433                                                   "DFS not supported"));
3434       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3435                           decode_boolean_bitfield(caps, 0x4000, 32,
3436                                                   "Large READX supported",
3437                                                   "Large READX not supported"));
3438       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3439                           decode_boolean_bitfield(caps, 0x8000, 32,
3440                                                   "Large WRITEX supported",
3441                                                   "Large WRITEX not supported"));
3442       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3443                           decode_boolean_bitfield(caps, 0x80000000, 32,
3444                                                   "Extended security exchanges supported",
3445                                                   "Extended security exchanges not supported"));
3446     }
3447
3448     offset += 4;
3449
3450     /* Server time, 2 WORDS */
3451
3452     if (tree) {
3453
3454       proto_tree_add_text(tree, NullTVB, offset, 4, "System Time Low: 0x%08x", GWORD(pd, offset));
3455       proto_tree_add_text(tree, NullTVB, offset + 4, 4, "System Time High: 0x%08x", GWORD(pd, offset + 4)); 
3456
3457     }
3458
3459     offset += 8;
3460
3461     /* Server Time Zone, SHORT */
3462
3463     if (tree) {
3464
3465       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
3466                           (signed)GSSHORT(pd, offset));
3467
3468     }
3469
3470     offset += 2;
3471
3472     /* Encryption key len */
3473
3474     enckeylen = pd[offset];
3475
3476     if (tree) {
3477
3478       proto_tree_add_text(tree, NullTVB, offset, 1, "Encryption key len: %u", enckeylen);
3479
3480     }
3481
3482     offset += 1;
3483
3484     bcc = GSHORT(pd, offset);
3485
3486     if (tree) {
3487
3488       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte count (BCC): %u", bcc);
3489
3490     }
3491
3492     offset += 2;
3493
3494     if (enckeylen) { /* only if non-zero key len */
3495
3496       /* Encryption challenge key */
3497
3498       str = pd + offset;
3499
3500       if (tree) {
3501
3502         proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge encryption key: %s",
3503                                 bytes_to_str(str, enckeylen));
3504
3505       }
3506
3507       offset += enckeylen;
3508
3509     }
3510
3511     /* The domain, a null terminated string; Unicode if "caps" has
3512        the 0x0004 bit set, ASCII (OEM character set) otherwise.
3513        XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
3514
3515     str = pd + offset;
3516
3517     if (tree) {
3518
3519       if (caps & 0x0004) {
3520         ustr = unicode_to_str(str, &ustr_len);
3521         proto_tree_add_text(tree, NullTVB, offset, ustr_len+2, "OEM domain name: %s", ustr);
3522       } else {
3523         proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "OEM domain name: %s", str);
3524       }
3525
3526     }
3527
3528     break;
3529
3530   default:    /* Baddd */
3531
3532     if (tree)
3533       proto_tree_add_text(tree, NullTVB, offset, 1, "Bad format, should never get here");
3534     return;
3535
3536   }
3537
3538 }
3539
3540 void
3541 dissect_deletedir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3542
3543 {
3544   guint8        WordCount;
3545   guint8        BufferFormat;
3546   guint16       ByteCount;
3547   const char    *DirectoryName;
3548
3549   if (dirn == 1) { /* Request(s) dissect code */
3550
3551     /* Build display for: Word Count (WCT) */
3552
3553     WordCount = GBYTE(pd, offset);
3554
3555     if (tree) {
3556
3557       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3558
3559     }
3560
3561     offset += 1; /* Skip Word Count (WCT) */
3562
3563     /* Build display for: Byte Count (BCC) */
3564
3565     ByteCount = GSHORT(pd, offset);
3566
3567     if (tree) {
3568
3569       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3570
3571     }
3572
3573     offset += 2; /* Skip Byte Count (BCC) */
3574
3575     /* Build display for: Buffer Format */
3576
3577     BufferFormat = GBYTE(pd, offset);
3578
3579     if (tree) {
3580
3581       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3582
3583     }
3584
3585     offset += 1; /* Skip Buffer Format */
3586
3587     /* Build display for: Directory Name */
3588
3589     DirectoryName = pd + offset;
3590
3591     if (tree) {
3592
3593       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3594
3595     }
3596
3597     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3598
3599   }
3600
3601   if (dirn == 0) { /* Response(s) dissect code */
3602
3603     /* Build display for: Word Count (WCT) */
3604
3605     WordCount = GBYTE(pd, offset);
3606
3607     if (tree) {
3608
3609       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3610
3611     }
3612
3613     offset += 1; /* Skip Word Count (WCT) */
3614
3615     /* Build display for: Byte Count (BCC) */
3616
3617     ByteCount = GSHORT(pd, offset);
3618
3619     if (tree) {
3620
3621       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3622
3623     }
3624
3625     offset += 2; /* Skip Byte Count (BCC) */
3626
3627   }
3628
3629 }
3630
3631 void
3632 dissect_createdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3633
3634 {
3635   guint8        WordCount;
3636   guint8        BufferFormat;
3637   guint16       ByteCount;
3638   const char    *DirectoryName;
3639
3640   if (dirn == 1) { /* Request(s) dissect code */
3641
3642     /* Build display for: Word Count (WCT) */
3643
3644     WordCount = GBYTE(pd, offset);
3645
3646     if (tree) {
3647
3648       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3649
3650     }
3651
3652     offset += 1; /* Skip Word Count (WCT) */
3653
3654     /* Build display for: Byte Count (BCC) */
3655
3656     ByteCount = GSHORT(pd, offset);
3657
3658     if (tree) {
3659
3660       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3661
3662     }
3663
3664     offset += 2; /* Skip Byte Count (BCC) */
3665
3666     /* Build display for: Buffer Format */
3667
3668     BufferFormat = GBYTE(pd, offset);
3669
3670     if (tree) {
3671
3672       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3673
3674     }
3675
3676     offset += 1; /* Skip Buffer Format */
3677
3678     /* Build display for: Directory Name */
3679
3680     DirectoryName = pd + offset;
3681
3682     if (tree) {
3683
3684       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3685
3686     }
3687
3688     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3689
3690   }
3691
3692   if (dirn == 0) { /* Response(s) dissect code */
3693
3694     /* Build display for: Word Count (WCT) */
3695
3696     WordCount = GBYTE(pd, offset);
3697
3698     if (tree) {
3699
3700       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3701
3702     }
3703
3704     offset += 1; /* Skip Word Count (WCT) */
3705
3706     /* Build display for: Byte Count (BCC) */
3707
3708     ByteCount = GSHORT(pd, offset);
3709
3710     if (tree) {
3711
3712       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3713
3714     }
3715
3716     offset += 2; /* Skip Byte Count (BCC) */
3717
3718   }
3719
3720 }
3721
3722
3723 void
3724 dissect_checkdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3725
3726 {
3727   guint8        WordCount;
3728   guint8        BufferFormat;
3729   guint16       ByteCount;
3730   const char    *DirectoryName;
3731
3732   if (dirn == 1) { /* Request(s) dissect code */
3733
3734     /* Build display for: Word Count (WCT) */
3735
3736     WordCount = GBYTE(pd, offset);
3737
3738     if (tree) {
3739
3740       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3741
3742     }
3743
3744     offset += 1; /* Skip Word Count (WCT) */
3745
3746     /* Build display for: Byte Count (BCC) */
3747
3748     ByteCount = GSHORT(pd, offset);
3749
3750     if (tree) {
3751
3752       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3753
3754     }
3755
3756     offset += 2; /* Skip Byte Count (BCC) */
3757
3758     /* Build display for: Buffer Format */
3759
3760     BufferFormat = GBYTE(pd, offset);
3761
3762     if (tree) {
3763
3764       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3765
3766     }
3767
3768     offset += 1; /* Skip Buffer Format */
3769
3770     /* Build display for: Directory Name */
3771
3772     DirectoryName = pd + offset;
3773
3774     if (tree) {
3775
3776       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3777
3778     }
3779
3780     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3781
3782   }
3783
3784   if (dirn == 0) { /* Response(s) dissect code */
3785
3786     /* Build display for: Word Count (WCT) */
3787
3788     WordCount = GBYTE(pd, offset);
3789
3790     if (tree) {
3791
3792       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3793
3794     }
3795
3796     offset += 1; /* Skip Word Count (WCT) */
3797
3798     /* Build display for: Byte Count (BCC) */
3799
3800     ByteCount = GSHORT(pd, offset);
3801
3802     if (tree) {
3803
3804       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3805
3806     }
3807
3808     offset += 2; /* Skip Byte Count (BCC) */
3809
3810   }
3811
3812 }
3813
3814 void
3815 dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3816
3817 {
3818   static const value_string OpenFunction_0x10[] = {
3819         { 0, "Fail if file does not exist"},
3820         { 16, "Create file if it does not exist"},
3821         { 0, NULL}
3822   };
3823   static const value_string OpenFunction_0x03[] = {
3824         { 0, "Fail if file exists"},
3825         { 1, "Open file if it exists"},
3826         { 2, "Truncate File if it exists"},
3827         { 0, NULL}
3828   };
3829   static const value_string FileType_0xFFFF[] = {
3830         { 0, "Disk file or directory"},
3831         { 1, "Named pipe in byte mode"},
3832         { 2, "Named pipe in message mode"},
3833         { 3, "Spooled printer"},
3834         { 0, NULL}
3835   };
3836   static const value_string DesiredAccess_0x70[] = {
3837         { 00, "Compatibility mode"},
3838         { 16, "Deny read/write/execute (exclusive)"},
3839         { 32, "Deny write"},
3840         { 48, "Deny read/execute"},
3841         { 64, "Deny none"},
3842         { 0, NULL}
3843   };
3844   static const value_string DesiredAccess_0x700[] = {
3845         { 0, "Locality of reference unknown"},
3846         { 256, "Mainly sequential access"},
3847         { 512, "Mainly random access"},
3848         { 768, "Random access with some locality"},
3849         {0, NULL}
3850   };
3851   static const value_string DesiredAccess_0x4000[] = {
3852         { 0, "Write through mode disabled"},
3853         { 16384, "Write through mode enabled"},
3854         {0, NULL}
3855   };
3856   static const value_string DesiredAccess_0x1000[] = {
3857         { 0, "Normal file (caching permitted)"},
3858         { 4096, "Do not cache this file"},
3859         {0, NULL}
3860   };
3861   static const value_string DesiredAccess_0x07[] = {
3862         { 0, "Open for reading"},
3863         { 1, "Open for writing"},
3864         { 2, "Open for reading and writing"},
3865         { 3, "Open for execute"},
3866         {0, NULL}
3867   };
3868   static const value_string Action_0x8000[] = {
3869         { 0, "File opened by another user (or mode not supported by server)"},
3870         { 32768, "File is opened only by this user at present"},
3871         {0, NULL}
3872   };
3873   static const value_string Action_0x0003[] = {
3874         { 0, "No action taken?"},
3875         { 1, "The file existed and was opened"},
3876         { 2, "The file did not exist but was created"},
3877         { 3, "The file existed and was truncated"},
3878         {0, NULL}
3879   };
3880   proto_tree    *Search_tree;
3881   proto_tree    *OpenFunction_tree;
3882   proto_tree    *Flags_tree;
3883   proto_tree    *File_tree;
3884   proto_tree    *FileType_tree;
3885   proto_tree    *FileAttributes_tree;
3886   proto_tree    *DesiredAccess_tree;
3887   proto_tree    *Action_tree;
3888   proto_item    *ti;
3889   guint8        WordCount;
3890   guint8        AndXReserved;
3891   guint8        AndXCommand = 0xFF;
3892   guint32       ServerFID;
3893   guint32       Reserved2;
3894   guint32       Reserved1;
3895   guint32       DataSize;
3896   guint32       AllocatedSize;
3897   guint16       Search;
3898   guint16       Reserved;
3899   guint16       OpenFunction;
3900   guint16       LastWriteTime;
3901   guint16       LastWriteDate;
3902   guint16       GrantedAccess;
3903   guint16       Flags;
3904   guint16       FileType;
3905   guint16       FileAttributes;
3906   guint16       File;
3907   guint16       FID;
3908   guint16       DeviceState;
3909   guint16       DesiredAccess;
3910   guint16       CreationTime;
3911   guint16       CreationDate;
3912   guint16       ByteCount;
3913   guint16       AndXOffset = 0;
3914   guint16       Action;
3915   const char    *FileName;
3916
3917   if (dirn == 1) { /* Request(s) dissect code */
3918
3919     /* Build display for: Word Count (WCT) */
3920
3921     WordCount = GBYTE(pd, offset);
3922
3923     if (tree) {
3924
3925       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3926
3927     }
3928
3929     offset += 1; /* Skip Word Count (WCT) */
3930
3931     /* Build display for: AndXCommand */
3932
3933     AndXCommand = GBYTE(pd, offset);
3934
3935     if (tree) {
3936
3937       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
3938                           (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
3939
3940     }
3941
3942     offset += 1; /* Skip AndXCommand */
3943
3944     /* Build display for: AndXReserved */
3945
3946     AndXReserved = GBYTE(pd, offset);
3947
3948     if (tree) {
3949
3950       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
3951
3952     }
3953
3954     offset += 1; /* Skip AndXReserved */
3955
3956     /* Build display for: AndXOffset */
3957
3958     AndXOffset = GSHORT(pd, offset);
3959
3960     if (tree) {
3961
3962       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
3963
3964     }
3965
3966     offset += 2; /* Skip AndXOffset */
3967
3968     /* Build display for: Flags */
3969
3970     Flags = GSHORT(pd, offset);
3971
3972     if (tree) {
3973
3974       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
3975       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
3976       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3977                           decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
3978       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3979                           decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
3980       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3981                           decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
3982     
3983 }
3984
3985     offset += 2; /* Skip Flags */
3986
3987     /* Build display for: Desired Access */
3988
3989     DesiredAccess = GSHORT(pd, offset);
3990
3991     if (tree) {
3992
3993       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
3994       DesiredAccess_tree = proto_item_add_subtree(ti, ett_smb_desiredaccess);
3995       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3996                           decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
3997       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3998                           decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
3999       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4000                           decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
4001       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4002                           decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
4003       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4004                           decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
4005     
4006 }
4007
4008     offset += 2; /* Skip Desired Access */
4009
4010     /* Build display for: Search */
4011
4012     Search = GSHORT(pd, offset);
4013
4014     if (tree) {
4015
4016       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Search: 0x%02x", Search);
4017       Search_tree = proto_item_add_subtree(ti, ett_smb_search);
4018       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4019                           decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
4020       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4021                           decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
4022       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4023                           decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
4024       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4025                           decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
4026       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4027                           decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
4028       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4029                           decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
4030     
4031 }
4032
4033     offset += 2; /* Skip Search */
4034
4035     /* Build display for: File */
4036
4037     File = GSHORT(pd, offset);
4038
4039     if (tree) {
4040
4041       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File: 0x%02x", File);
4042       File_tree = proto_item_add_subtree(ti, ett_smb_file);
4043       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4044                           decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
4045       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4046                           decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
4047       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4048                           decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
4049       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4050                           decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
4051       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4052                           decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
4053       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4054                           decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
4055     
4056 }
4057
4058     offset += 2; /* Skip File */
4059
4060     /* Build display for: Creation Time */
4061
4062     CreationTime = GSHORT(pd, offset);
4063
4064     if (tree) {
4065
4066
4067     }
4068
4069     offset += 2; /* Skip Creation Time */
4070
4071     /* Build display for: Creation Date */
4072
4073     CreationDate = GSHORT(pd, offset);
4074
4075     if (tree) {
4076
4077       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_smbu_date(CreationDate, CreationTime));
4078       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_smbu_time(CreationDate, CreationTime));
4079
4080     }
4081
4082     offset += 2; /* Skip Creation Date */
4083
4084     /* Build display for: Open Function */
4085
4086     OpenFunction = GSHORT(pd, offset);
4087
4088     if (tree) {
4089
4090       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: 0x%02x", OpenFunction);
4091       OpenFunction_tree = proto_item_add_subtree(ti, ett_smb_openfunction);
4092       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
4093                           decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
4094       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
4095                           decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
4096     
4097 }
4098
4099     offset += 2; /* Skip Open Function */
4100
4101     /* Build display for: Allocated Size */
4102
4103     AllocatedSize = GWORD(pd, offset);
4104
4105     if (tree) {
4106
4107       proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
4108
4109     }
4110
4111     offset += 4; /* Skip Allocated Size */
4112
4113     /* Build display for: Reserved1 */
4114
4115     Reserved1 = GWORD(pd, offset);
4116
4117     if (tree) {
4118
4119       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
4120
4121     }
4122
4123     offset += 4; /* Skip Reserved1 */
4124
4125     /* Build display for: Reserved2 */
4126
4127     Reserved2 = GWORD(pd, offset);
4128
4129     if (tree) {
4130
4131       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
4132
4133     }
4134
4135     offset += 4; /* Skip Reserved2 */
4136
4137     /* Build display for: Byte Count */
4138
4139     ByteCount = GSHORT(pd, offset);
4140
4141     if (tree) {
4142
4143       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4144
4145     }
4146
4147     offset += 2; /* Skip Byte Count */
4148
4149     /* Build display for: File Name */
4150
4151     FileName = pd + offset;
4152
4153     if (tree) {
4154
4155       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
4156
4157     }
4158
4159     offset += strlen(FileName) + 1; /* Skip File Name */
4160
4161
4162     if (AndXCommand != 0xFF) {
4163
4164       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
4165
4166     }
4167
4168   }
4169
4170   if (dirn == 0) { /* Response(s) dissect code */
4171
4172     /* Build display for: Word Count (WCT) */
4173
4174     WordCount = GBYTE(pd, offset);
4175
4176     if (tree) {
4177
4178       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4179
4180     }
4181
4182     offset += 1; /* Skip Word Count (WCT) */
4183
4184     if (WordCount > 0) {
4185
4186       /* Build display for: AndXCommand */
4187
4188       AndXCommand = GBYTE(pd, offset);
4189
4190       if (tree) {
4191
4192         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
4193                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
4194
4195       }
4196
4197       offset += 1; /* Skip AndXCommand */
4198
4199       /* Build display for: AndXReserved */
4200
4201       AndXReserved = GBYTE(pd, offset);
4202
4203       if (tree) {
4204
4205         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
4206
4207       }
4208
4209       offset += 1; /* Skip AndXReserved */
4210
4211       /* Build display for: AndXOffset */
4212
4213       AndXOffset = GSHORT(pd, offset);
4214
4215       if (tree) {
4216
4217         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
4218
4219       }
4220
4221       offset += 2; /* Skip AndXOffset */
4222
4223       /* Build display for: FID */
4224
4225       FID = GSHORT(pd, offset);
4226
4227       if (tree) {
4228
4229         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4230
4231       }
4232
4233       offset += 2; /* Skip FID */
4234
4235       /* Build display for: FileAttributes */
4236
4237       FileAttributes = GSHORT(pd, offset);
4238
4239       if (tree) {
4240
4241         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
4242         FileAttributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
4243         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4244                             decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
4245         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4246                             decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
4247         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4248                             decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
4249         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4250                             decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
4251         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4252                             decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
4253         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4254                             decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
4255     
4256       }
4257
4258       offset += 2; /* Skip FileAttributes */
4259
4260       /* Build display for: Last Write Time */
4261
4262       LastWriteTime = GSHORT(pd, offset);
4263
4264       if (tree) {
4265
4266       }
4267
4268       offset += 2; /* Skip Last Write Time */
4269
4270       /* Build display for: Last Write Date */
4271
4272       LastWriteDate = GSHORT(pd, offset);
4273
4274       if (tree) {
4275
4276         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
4277         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
4278
4279
4280       }
4281
4282       offset += 2; /* Skip Last Write Date */
4283
4284       /* Build display for: Data Size */
4285
4286       DataSize = GWORD(pd, offset);
4287
4288       if (tree) {
4289
4290         proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
4291
4292       }
4293
4294       offset += 4; /* Skip Data Size */
4295
4296       /* Build display for: Granted Access */
4297
4298       GrantedAccess = GSHORT(pd, offset);
4299
4300       if (tree) {
4301
4302         proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
4303
4304       }
4305
4306       offset += 2; /* Skip Granted Access */
4307
4308       /* Build display for: File Type */
4309
4310       FileType = GSHORT(pd, offset);
4311
4312       if (tree) {
4313
4314         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File Type: 0x%02x", FileType);
4315         FileType_tree = proto_item_add_subtree(ti, ett_smb_filetype);
4316         proto_tree_add_text(FileType_tree, NullTVB, offset, 2, "%s",
4317                           decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
4318     
4319       }
4320
4321       offset += 2; /* Skip File Type */
4322
4323       /* Build display for: Device State */
4324
4325       DeviceState = GSHORT(pd, offset);
4326
4327       if (tree) {
4328
4329         proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
4330
4331       }
4332
4333       offset += 2; /* Skip Device State */
4334
4335       /* Build display for: Action */
4336
4337       Action = GSHORT(pd, offset);
4338
4339       if (tree) {
4340
4341         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: 0x%02x", Action);
4342         Action_tree = proto_item_add_subtree(ti, ett_smb_action);
4343         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
4344                             decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
4345         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
4346                             decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
4347         
4348       }
4349       
4350       offset += 2; /* Skip Action */
4351
4352       /* Build display for: Server FID */
4353       
4354       ServerFID = GWORD(pd, offset);
4355
4356       if (tree) {
4357
4358         proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: %u", ServerFID);
4359
4360       }
4361
4362       offset += 4; /* Skip Server FID */
4363
4364       /* Build display for: Reserved */
4365
4366       Reserved = GSHORT(pd, offset);
4367
4368       if (tree) {
4369         
4370         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
4371
4372       }
4373
4374       offset += 2; /* Skip Reserved */
4375
4376     }
4377
4378     /* Build display for: Byte Count */
4379
4380     ByteCount = GSHORT(pd, offset);
4381
4382     if (tree) {
4383
4384       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4385
4386     }
4387
4388     offset += 2; /* Skip Byte Count */
4389
4390
4391     if (AndXCommand != 0xFF) {
4392
4393       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
4394
4395     }
4396
4397   }
4398
4399 }
4400
4401 void
4402 dissect_write_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4403
4404 {
4405   proto_tree    *WriteMode_tree;
4406   proto_item    *ti;
4407   guint8        WordCount;
4408   guint8        Pad;
4409   guint32       Timeout;
4410   guint32       Reserved2;
4411   guint32       Offset;
4412   guint16       WriteMode;
4413   guint16       Reserved1;
4414   guint16       Remaining;
4415   guint16       FID;
4416   guint16       DataOffset;
4417   guint16       DataLength;
4418   guint16       Count;
4419   guint16       ByteCount;
4420
4421   if (dirn == 1) { /* Request(s) dissect code */
4422
4423     WordCount = GBYTE(pd, offset);
4424
4425     switch (WordCount) {
4426
4427     case 12:
4428
4429       /* Build display for: Word Count (WCT) */
4430
4431       WordCount = GBYTE(pd, offset);
4432
4433       if (tree) {
4434
4435         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4436
4437       }
4438
4439       offset += 1; /* Skip Word Count (WCT) */
4440
4441       /* Build display for: FID */
4442
4443       FID = GSHORT(pd, offset);
4444
4445       if (tree) {
4446
4447         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4448
4449       }
4450
4451       offset += 2; /* Skip FID */
4452
4453       /* Build display for: Count */
4454
4455       Count = GSHORT(pd, offset);
4456
4457       if (tree) {
4458
4459         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4460
4461       }
4462
4463       offset += 2; /* Skip Count */
4464
4465       /* Build display for: Reserved 1 */
4466
4467       Reserved1 = GSHORT(pd, offset);
4468
4469       if (tree) {
4470
4471         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
4472
4473       }
4474
4475       offset += 2; /* Skip Reserved 1 */
4476
4477       /* Build display for: Offset */
4478
4479       Offset = GWORD(pd, offset);
4480
4481       if (tree) {
4482
4483         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
4484
4485       }
4486
4487       offset += 4; /* Skip Offset */
4488
4489       /* Build display for: Timeout */
4490
4491       Timeout = GWORD(pd, offset);
4492
4493       if (tree) {
4494
4495         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
4496
4497       }
4498
4499       offset += 4; /* Skip Timeout */
4500
4501       /* Build display for: WriteMode */
4502
4503       WriteMode = GSHORT(pd, offset);
4504
4505       if (tree) {
4506
4507         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
4508         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
4509         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4510                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
4511         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4512                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
4513       
4514 }
4515
4516       offset += 2; /* Skip WriteMode */
4517
4518       /* Build display for: Reserved 2 */
4519
4520       Reserved2 = GWORD(pd, offset);
4521
4522       if (tree) {
4523
4524         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
4525
4526       }
4527
4528       offset += 4; /* Skip Reserved 2 */
4529
4530       /* Build display for: Data Length */
4531
4532       DataLength = GSHORT(pd, offset);
4533
4534       if (tree) {
4535
4536         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
4537
4538       }
4539
4540       offset += 2; /* Skip Data Length */
4541
4542       /* Build display for: Data Offset */
4543
4544       DataOffset = GSHORT(pd, offset);
4545
4546       if (tree) {
4547
4548         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
4549
4550       }
4551
4552       offset += 2; /* Skip Data Offset */
4553
4554       /* Build display for: Byte Count (BCC) */
4555
4556       ByteCount = GSHORT(pd, offset);
4557
4558       if (tree) {
4559
4560         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4561
4562       }
4563
4564       offset += 2; /* Skip Byte Count (BCC) */
4565
4566       /* Build display for: Pad */
4567
4568       Pad = GBYTE(pd, offset);
4569
4570       if (tree) {
4571
4572         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
4573
4574       }
4575
4576       offset += 1; /* Skip Pad */
4577
4578     break;
4579
4580     case 14:
4581
4582       /* Build display for: Word Count (WCT) */
4583
4584       WordCount = GBYTE(pd, offset);
4585
4586       if (tree) {
4587
4588         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4589
4590       }
4591
4592       offset += 1; /* Skip Word Count (WCT) */
4593
4594       /* Build display for: FID */
4595
4596       FID = GSHORT(pd, offset);
4597
4598       if (tree) {
4599
4600         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4601
4602       }
4603
4604       offset += 2; /* Skip FID */
4605
4606       /* Build display for: Count */
4607
4608       Count = GSHORT(pd, offset);
4609
4610       if (tree) {
4611
4612         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4613
4614       }
4615
4616       offset += 2; /* Skip Count */
4617
4618       /* Build display for: Reserved 1 */
4619
4620       Reserved1 = GSHORT(pd, offset);
4621
4622       if (tree) {
4623
4624         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
4625
4626       }
4627
4628       offset += 2; /* Skip Reserved 1 */
4629
4630       /* Build display for: Timeout */
4631
4632       Timeout = GWORD(pd, offset);
4633
4634       if (tree) {
4635
4636         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
4637
4638       }
4639
4640       offset += 4; /* Skip Timeout */
4641
4642       /* Build display for: WriteMode */
4643
4644       WriteMode = GSHORT(pd, offset);
4645
4646       if (tree) {
4647
4648         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
4649         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
4650         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4651                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
4652         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4653                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
4654       
4655 }
4656
4657       offset += 2; /* Skip WriteMode */
4658
4659       /* Build display for: Reserved 2 */
4660
4661       Reserved2 = GWORD(pd, offset);
4662
4663       if (tree) {
4664
4665         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
4666
4667       }
4668
4669       offset += 4; /* Skip Reserved 2 */
4670
4671       /* Build display for: Data Length */
4672
4673       DataLength = GSHORT(pd, offset);
4674
4675       if (tree) {
4676
4677         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
4678
4679       }
4680
4681       offset += 2; /* Skip Data Length */
4682
4683       /* Build display for: Data Offset */
4684
4685       DataOffset = GSHORT(pd, offset);
4686
4687       if (tree) {
4688
4689         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
4690
4691       }
4692
4693       offset += 2; /* Skip Data Offset */
4694
4695       /* Build display for: Byte Count (BCC) */
4696
4697       ByteCount = GSHORT(pd, offset);
4698
4699       if (tree) {
4700
4701         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4702
4703       }
4704
4705       offset += 2; /* Skip Byte Count (BCC) */
4706
4707       /* Build display for: Pad */
4708
4709       Pad = GBYTE(pd, offset);
4710
4711       if (tree) {
4712
4713         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
4714
4715       }
4716
4717       offset += 1; /* Skip Pad */
4718
4719     break;
4720
4721     }
4722
4723   }
4724
4725   if (dirn == 0) { /* Response(s) dissect code */
4726
4727     /* Build display for: Word Count (WCT) */
4728
4729     WordCount = GBYTE(pd, offset);
4730
4731     if (tree) {
4732
4733       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4734
4735     }
4736
4737     offset += 1; /* Skip Word Count (WCT) */
4738
4739     if (WordCount > 0) {
4740
4741       /* Build display for: Remaining */
4742
4743       Remaining = GSHORT(pd, offset);
4744
4745       if (tree) {
4746
4747         proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
4748
4749       }
4750
4751       offset += 2; /* Skip Remaining */
4752
4753     }
4754
4755     /* Build display for: Byte Count */
4756
4757     ByteCount = GSHORT(pd, offset);
4758
4759     if (tree) {
4760
4761       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4762
4763     }
4764
4765     offset += 2; /* Skip Byte Count */
4766
4767   }
4768
4769 }
4770
4771 void
4772 dissect_tdis_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4773
4774 {
4775   guint8        WordCount;
4776   guint16       ByteCount;
4777
4778   if (dirn == 1) { /* Request(s) dissect code */
4779
4780     /* Build display for: Word Count (WCT) */
4781
4782     WordCount = GBYTE(pd, offset);
4783
4784     if (tree) {
4785
4786       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4787
4788     }
4789
4790     offset += 1; /* Skip Word Count (WCT) */
4791
4792     /* Build display for: Byte Count (BCC) */
4793
4794     ByteCount = GSHORT(pd, offset);
4795
4796     if (tree) {
4797
4798       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4799
4800     }
4801
4802     offset += 2; /* Skip Byte Count (BCC) */
4803
4804   }
4805
4806   if (dirn == 0) { /* Response(s) dissect code */
4807
4808     /* Build display for: Word Count (WCT) */
4809
4810     WordCount = GBYTE(pd, offset);
4811
4812     if (tree) {
4813
4814       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4815
4816     }
4817
4818     offset += 1; /* Skip Word Count (WCT) */
4819
4820     /* Build display for: Byte Count (BCC) */
4821
4822     ByteCount = GSHORT(pd, offset);
4823
4824     if (tree) {
4825
4826       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4827
4828     }
4829
4830     offset += 2; /* Skip Byte Count (BCC) */
4831
4832   }
4833
4834 }
4835
4836 void
4837 dissect_move_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4838
4839 {
4840   static const value_string Flags_0x03[] = {
4841         { 0, "Target must be a file"},
4842         { 1, "Target must be a directory"},
4843         { 2, "Reserved"},
4844         { 3, "Reserved"},
4845         { 4, "Verify all writes"},
4846         { 0, NULL}
4847 };
4848   proto_tree    *Flags_tree;
4849   proto_item    *ti;
4850   guint8        WordCount;
4851   guint8        ErrorFileFormat;
4852   guint16       TID2;
4853   guint16       OpenFunction;
4854   guint16       Flags;
4855   guint16       Count;
4856   guint16       ByteCount;
4857   const char    *ErrorFileName;
4858
4859   if (dirn == 1) { /* Request(s) dissect code */
4860
4861     /* Build display for: Word Count (WCT) */
4862
4863     WordCount = GBYTE(pd, offset);
4864
4865     if (tree) {
4866
4867       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4868
4869     }
4870
4871     offset += 1; /* Skip Word Count (WCT) */
4872
4873     /* Build display for: TID2 */
4874
4875     TID2 = GSHORT(pd, offset);
4876
4877     if (tree) {
4878
4879       proto_tree_add_text(tree, NullTVB, offset, 2, "TID2: %u", TID2);
4880
4881     }
4882
4883     offset += 2; /* Skip TID2 */
4884
4885     /* Build display for: Open Function */
4886
4887     OpenFunction = GSHORT(pd, offset);
4888
4889     if (tree) {
4890
4891       proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: %u", OpenFunction);
4892
4893     }
4894
4895     offset += 2; /* Skip Open Function */
4896
4897     /* Build display for: Flags */
4898
4899     Flags = GSHORT(pd, offset);
4900
4901     if (tree) {
4902
4903       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
4904       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
4905       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
4906                           decode_enumerated_bitfield(Flags, 0x03, 16, Flags_0x03, "%s"));
4907     
4908 }
4909
4910     offset += 2; /* Skip Flags */
4911
4912   }
4913
4914   if (dirn == 0) { /* Response(s) dissect code */
4915
4916     /* Build display for: Word Count (WCT) */
4917
4918     WordCount = GBYTE(pd, offset);
4919
4920     if (tree) {
4921
4922       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4923
4924     }
4925
4926     offset += 1; /* Skip Word Count (WCT) */
4927
4928     if (WordCount > 0) {
4929
4930       /* Build display for: Count */
4931
4932       Count = GSHORT(pd, offset);
4933
4934       if (tree) {
4935
4936         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4937
4938       }
4939
4940       offset += 2; /* Skip Count */
4941
4942     }
4943
4944     /* Build display for: Byte Count */
4945
4946     ByteCount = GSHORT(pd, offset);
4947
4948     if (tree) {
4949
4950       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4951
4952     }
4953
4954     offset += 2; /* Skip Byte Count */
4955
4956     /* Build display for: Error File Format */
4957
4958     ErrorFileFormat = GBYTE(pd, offset);
4959
4960     if (tree) {
4961
4962       proto_tree_add_text(tree, NullTVB, offset, 1, "Error File Format: %u", ErrorFileFormat);
4963
4964     }
4965
4966     offset += 1; /* Skip Error File Format */
4967
4968     /* Build display for: Error File Name */
4969
4970     ErrorFileName = pd + offset;
4971
4972     if (tree) {
4973
4974       proto_tree_add_text(tree, NullTVB, offset, strlen(ErrorFileName) + 1, "Error File Name: %s", ErrorFileName);
4975
4976     }
4977
4978     offset += strlen(ErrorFileName) + 1; /* Skip Error File Name */
4979
4980   }
4981
4982 }
4983
4984 void
4985 dissect_rename_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4986
4987 {
4988   guint8        WordCount;
4989   guint8        BufferFormat2;
4990   guint8        BufferFormat1;
4991   guint16       SearchAttributes;
4992   guint16       ByteCount;
4993   const char    *OldFileName;
4994   const char    *NewFileName;
4995
4996   if (dirn == 1) { /* Request(s) dissect code */
4997
4998     /* Build display for: Word Count (WCT) */
4999
5000     WordCount = GBYTE(pd, offset);
5001
5002     if (tree) {
5003
5004       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5005
5006     }
5007
5008     offset += 1; /* Skip Word Count (WCT) */
5009
5010     /* Build display for: Search Attributes */
5011
5012     SearchAttributes = GSHORT(pd, offset);
5013
5014     if (tree) {
5015
5016       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
5017
5018     }
5019
5020     offset += 2; /* Skip Search Attributes */
5021
5022     /* Build display for: Byte Count */
5023
5024     ByteCount = GSHORT(pd, offset);
5025
5026     if (tree) {
5027
5028       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
5029
5030     }
5031
5032     offset += 2; /* Skip Byte Count */
5033
5034     /* Build display for: Buffer Format 1 */
5035
5036     BufferFormat1 = GBYTE(pd, offset);
5037
5038     if (tree) {
5039
5040       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %u", BufferFormat1);
5041
5042     }
5043
5044     offset += 1; /* Skip Buffer Format 1 */
5045
5046     /* Build display for: Old File Name */
5047
5048     OldFileName = pd + offset;
5049
5050     if (tree) {
5051
5052       proto_tree_add_text(tree, NullTVB, offset, strlen(OldFileName) + 1, "Old File Name: %s", OldFileName);
5053
5054     }
5055
5056     offset += strlen(OldFileName) + 1; /* Skip Old File Name */
5057
5058     /* Build display for: Buffer Format 2 */
5059
5060     BufferFormat2 = GBYTE(pd, offset);
5061
5062     if (tree) {
5063
5064       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %u", BufferFormat2);
5065
5066     }
5067
5068     offset += 1; /* Skip Buffer Format 2 */
5069
5070     /* Build display for: New File Name */
5071
5072     NewFileName = pd + offset;
5073
5074     if (tree) {
5075
5076       proto_tree_add_text(tree, NullTVB, offset, strlen(NewFileName) + 1, "New File Name: %s", NewFileName);
5077
5078     }
5079
5080     offset += strlen(NewFileName) + 1; /* Skip New File Name */
5081
5082   }
5083
5084   if (dirn == 0) { /* Response(s) dissect code */
5085
5086     /* Build display for: Word Count (WCT) */
5087
5088     WordCount = GBYTE(pd, offset);
5089
5090     if (tree) {
5091
5092       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5093
5094     }
5095
5096     offset += 1; /* Skip Word Count (WCT) */
5097
5098     /* Build display for: Byte Count (BCC) */
5099
5100     ByteCount = GSHORT(pd, offset);
5101
5102     if (tree) {
5103
5104       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5105
5106     }
5107
5108     offset += 2; /* Skip Byte Count (BCC) */
5109
5110   }
5111
5112 }
5113
5114 void
5115 dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5116
5117 {
5118   static const value_string Mode_0x03[] = {
5119         { 0, "Text mode (DOS expands TABs)"},
5120         { 1, "Graphics mode"},
5121         { 0, NULL}
5122 };
5123   proto_tree    *Mode_tree;
5124   proto_item    *ti;
5125   guint8        WordCount;
5126   guint8        BufferFormat;
5127   guint16       SetupLength;
5128   guint16       Mode;
5129   guint16       FID;
5130   guint16       ByteCount;
5131   const char    *IdentifierString;
5132
5133   if (dirn == 1) { /* Request(s) dissect code */
5134
5135     /* Build display for: Word Count (WCT) */
5136
5137     WordCount = GBYTE(pd, offset);
5138
5139     if (tree) {
5140
5141       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5142
5143     }
5144
5145     offset += 1; /* Skip Word Count (WCT) */
5146
5147     /* Build display for: Setup Length */
5148
5149     SetupLength = GSHORT(pd, offset);
5150
5151     if (tree) {
5152
5153       proto_tree_add_text(tree, NullTVB, offset, 2, "Setup Length: %u", SetupLength);
5154
5155     }
5156
5157     offset += 2; /* Skip Setup Length */
5158
5159     /* Build display for: Mode */
5160
5161     Mode = GSHORT(pd, offset);
5162
5163     if (tree) {
5164
5165       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
5166       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
5167       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
5168                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
5169     
5170 }
5171
5172     offset += 2; /* Skip Mode */
5173
5174     /* Build display for: Byte Count (BCC) */
5175
5176     ByteCount = GSHORT(pd, offset);
5177
5178     if (tree) {
5179
5180       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5181
5182     }
5183
5184     offset += 2; /* Skip Byte Count (BCC) */
5185
5186     /* Build display for: Buffer Format */
5187
5188     BufferFormat = GBYTE(pd, offset);
5189
5190     if (tree) {
5191
5192       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
5193
5194     }
5195
5196     offset += 1; /* Skip Buffer Format */
5197
5198     /* Build display for: Identifier String */
5199
5200     IdentifierString = pd + offset;
5201
5202     if (tree) {
5203
5204       proto_tree_add_text(tree, NullTVB, offset, strlen(IdentifierString) + 1, "Identifier String: %s", IdentifierString);
5205
5206     }
5207
5208     offset += strlen(IdentifierString) + 1; /* Skip Identifier String */
5209
5210   }
5211
5212   if (dirn == 0) { /* Response(s) dissect code */
5213
5214     /* Build display for: Word Count (WCT) */
5215
5216     WordCount = GBYTE(pd, offset);
5217
5218     if (tree) {
5219
5220       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5221
5222     }
5223
5224     offset += 1; /* Skip Word Count (WCT) */
5225
5226     /* Build display for: FID */
5227
5228     FID = GSHORT(pd, offset);
5229
5230     if (tree) {
5231
5232       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5233
5234     }
5235
5236     offset += 2; /* Skip FID */
5237
5238     /* Build display for: Byte Count (BCC) */
5239
5240     ByteCount = GSHORT(pd, offset);
5241
5242     if (tree) {
5243
5244       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5245
5246     }
5247
5248     offset += 2; /* Skip Byte Count (BCC) */
5249
5250   }
5251
5252 }
5253
5254 void
5255 dissect_close_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5256
5257 {
5258   guint8        WordCount;
5259   guint16       FID;
5260   guint16       ByteCount;
5261
5262   if (dirn == 1) { /* Request(s) dissect code */
5263
5264     /* Build display for: Word Count (WCT) */
5265
5266     WordCount = GBYTE(pd, offset);
5267
5268     if (tree) {
5269
5270       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5271
5272     }
5273
5274     offset += 1; /* Skip Word Count (WCT) */
5275
5276     /* Build display for: FID */
5277
5278     FID = GSHORT(pd, offset);
5279
5280     if (tree) {
5281
5282       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5283
5284     }
5285
5286     offset += 2; /* Skip FID */
5287
5288     /* Build display for: Byte Count (BCC) */
5289
5290     ByteCount = GSHORT(pd, offset);
5291
5292     if (tree) {
5293
5294       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5295
5296     }
5297
5298     offset += 2; /* Skip Byte Count (BCC) */
5299
5300   }
5301
5302   if (dirn == 0) { /* Response(s) dissect code */
5303
5304     /* Build display for: Word Count */
5305
5306     WordCount = GBYTE(pd, offset);
5307
5308     if (tree) {
5309
5310       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
5311
5312     }
5313
5314     offset += 1; /* Skip Word Count */
5315
5316     /* Build display for: Byte Count (BCC) */
5317
5318     ByteCount = GSHORT(pd, offset);
5319
5320     if (tree) {
5321
5322       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5323
5324     }
5325
5326     offset += 2; /* Skip Byte Count (BCC) */
5327
5328   }
5329
5330 }
5331
5332 void
5333 dissect_read_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5334
5335 {
5336   guint8        WordCount;
5337   guint32       Timeout;
5338   guint32       OffsetHigh;
5339   guint32       Offset;
5340   guint16       Reserved;
5341   guint16       MinCount;
5342   guint16       MaxCount;
5343   guint16       FID;
5344   guint16       ByteCount;
5345
5346   if (dirn == 1) { /* Request(s) dissect code */
5347
5348     WordCount = GBYTE(pd, offset);
5349
5350     switch (WordCount) {
5351
5352     case 8:
5353
5354       /* Build display for: Word Count (WCT) */
5355
5356       WordCount = GBYTE(pd, offset);
5357
5358       if (tree) {
5359
5360         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5361
5362       }
5363
5364       offset += 1; /* Skip Word Count (WCT) */
5365
5366       /* Build display for: FID */
5367
5368       FID = GSHORT(pd, offset);
5369
5370       if (tree) {
5371
5372         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5373
5374       }
5375
5376       offset += 2; /* Skip FID */
5377
5378       /* Build display for: Offset */
5379
5380       Offset = GWORD(pd, offset);
5381
5382       if (tree) {
5383
5384         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5385
5386       }
5387
5388       offset += 4; /* Skip Offset */
5389
5390       /* Build display for: Max Count */
5391
5392       MaxCount = GSHORT(pd, offset);
5393
5394       if (tree) {
5395
5396         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
5397
5398       }
5399
5400       offset += 2; /* Skip Max Count */
5401
5402       /* Build display for: Min Count */
5403
5404       MinCount = GSHORT(pd, offset);
5405
5406       if (tree) {
5407
5408         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
5409
5410       }
5411
5412       offset += 2; /* Skip Min Count */
5413
5414       /* Build display for: Timeout */
5415
5416       Timeout = GWORD(pd, offset);
5417
5418       if (tree) {
5419
5420         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5421
5422       }
5423
5424       offset += 4; /* Skip Timeout */
5425
5426       /* Build display for: Reserved */
5427
5428       Reserved = GSHORT(pd, offset);
5429
5430       if (tree) {
5431
5432         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5433
5434       }
5435
5436       offset += 2; /* Skip Reserved */
5437
5438       /* Build display for: Byte Count (BCC) */
5439
5440       ByteCount = GSHORT(pd, offset);
5441
5442       if (tree) {
5443
5444         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5445
5446       }
5447
5448       offset += 2; /* Skip Byte Count (BCC) */
5449
5450     break;
5451
5452     case 10:
5453
5454       /* Build display for: Word Count (WCT) */
5455
5456       WordCount = GBYTE(pd, offset);
5457
5458       if (tree) {
5459
5460         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5461
5462       }
5463
5464       offset += 1; /* Skip Word Count (WCT) */
5465
5466       /* Build display for: FID */
5467
5468       FID = GSHORT(pd, offset);
5469
5470       if (tree) {
5471
5472         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5473
5474       }
5475
5476       offset += 2; /* Skip FID */
5477
5478       /* Build display for: Offset */
5479
5480       Offset = GWORD(pd, offset);
5481
5482       if (tree) {
5483
5484         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5485
5486       }
5487
5488       offset += 4; /* Skip Offset */
5489
5490       /* Build display for: Max Count */
5491
5492       MaxCount = GSHORT(pd, offset);
5493
5494       if (tree) {
5495
5496         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
5497
5498       }
5499
5500       offset += 2; /* Skip Max Count */
5501
5502       /* Build display for: Min Count */
5503
5504       MinCount = GSHORT(pd, offset);
5505
5506       if (tree) {
5507
5508         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
5509
5510       }
5511
5512       offset += 2; /* Skip Min Count */
5513
5514       /* Build display for: Timeout */
5515
5516       Timeout = GWORD(pd, offset);
5517
5518       if (tree) {
5519
5520         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5521
5522       }
5523
5524       offset += 4; /* Skip Timeout */
5525
5526       /* Build display for: Reserved */
5527
5528       Reserved = GSHORT(pd, offset);
5529
5530       if (tree) {
5531
5532         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5533
5534       }
5535
5536       offset += 2; /* Skip Reserved */
5537
5538       /* Build display for: Offset High */
5539
5540       OffsetHigh = GWORD(pd, offset);
5541
5542       if (tree) {
5543
5544         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
5545
5546       }
5547
5548       offset += 4; /* Skip Offset High */
5549
5550       /* Build display for: Byte Count (BCC) */
5551
5552       ByteCount = GSHORT(pd, offset);
5553
5554       if (tree) {
5555
5556         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5557
5558       }
5559
5560       offset += 2; /* Skip Byte Count (BCC) */
5561
5562     break;
5563
5564     }
5565
5566   }
5567
5568   if (dirn == 0) { /* Response(s) dissect code */
5569
5570   }
5571
5572 }
5573
5574 void
5575 dissect_read_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5576
5577 {
5578   guint8        WordCount;
5579   guint8        AndXReserved;
5580   guint8        AndXCommand = 0xFF;
5581   guint16       ByteCount;
5582   guint16       AndXOffset = 0;
5583   guint16       FID;
5584   guint16       DataCompactionMode;
5585   guint16       DataLength;
5586   guint16       DataOffset;
5587   guint16       Remaining;
5588   guint16       MaxCount;
5589   guint16       MinCount;
5590   guint16       Reserved;
5591   guint32       Offset;
5592   guint32       OffsetHigh;
5593   int           i;
5594
5595   if (dirn == 1) { /* Request(s) dissect code */
5596
5597     /* Build display for: Word Count (WCT) */
5598
5599     WordCount = GBYTE(pd, offset);
5600
5601     if (tree) {
5602
5603       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5604
5605     }
5606
5607     offset += 1; /* Skip Word Count (WCT) */
5608
5609     /* Build display for: AndXCommand */
5610
5611     AndXCommand = GBYTE(pd, offset);
5612
5613     if (tree) {
5614
5615       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
5616
5617     }
5618
5619     offset += 1; /* Skip AndXCommand */
5620
5621     /* Build display for: AndXReserved */
5622
5623     AndXReserved = GBYTE(pd, offset);
5624
5625     if (tree) {
5626
5627       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
5628
5629     }
5630
5631     offset += 1; /* Skip AndXReserved */
5632
5633     /* Build display for: AndXOffset */
5634
5635     AndXOffset = GSHORT(pd, offset);
5636
5637     if (tree) {
5638
5639       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
5640
5641     }
5642
5643     offset += 2; /* Skip AndXOffset */
5644
5645     /* Build display for: FID */
5646
5647     FID = GSHORT(pd, offset);
5648
5649     if (tree) {
5650         
5651       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5652         
5653     }
5654
5655     offset += 2; /* Skip FID */
5656
5657     /* Build display for: Offset */
5658
5659     Offset = GWORD(pd, offset);
5660
5661     if (tree) {
5662
5663       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5664
5665     }
5666
5667     offset += 4; /* Skip Offset */
5668
5669     /* Build display for: Max Count */
5670
5671     MaxCount = GSHORT(pd, offset);
5672
5673     if (tree) {
5674
5675         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
5676
5677     }
5678
5679     offset += 2; /* Skip Max Count */
5680
5681     /* Build display for: Min Count */
5682
5683     MinCount = GSHORT(pd, offset);
5684
5685     if (tree) {
5686
5687         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
5688
5689     }
5690
5691     offset += 2; /* Skip Min Count */
5692
5693     /* Build display for: Reserved */
5694
5695     Reserved = GWORD(pd, offset);
5696
5697     if (tree) {
5698
5699       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
5700
5701     }
5702
5703     offset += 4; /* Skip Reserved */
5704
5705     /* Build display for: Remaining */
5706
5707     Remaining = GSHORT(pd, offset);
5708
5709     if (tree) {
5710
5711       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
5712
5713     }
5714
5715     offset += 2; /* Skip Remaining */
5716
5717     if (WordCount == 12) {
5718
5719         /* Build display for: Offset High */
5720
5721         OffsetHigh = GWORD(pd, offset);
5722
5723         if (tree) {
5724
5725             proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
5726
5727         }
5728
5729         offset += 4; /* Skip Offset High */
5730     }
5731
5732     /* Build display for: Byte Count (BCC) */
5733
5734     ByteCount = GSHORT(pd, offset);
5735
5736     if (tree) {
5737
5738       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5739
5740     }
5741
5742     offset += 2; /* Skip Byte Count (BCC) */
5743
5744
5745     if (AndXCommand != 0xFF) {
5746
5747       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
5748
5749     }
5750
5751   }
5752
5753   if (dirn == 0) { /* Response(s) dissect code */
5754
5755     /* Build display for: Word Count (WCT) */
5756
5757     WordCount = GBYTE(pd, offset);
5758
5759     if (tree) {
5760
5761       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5762
5763     }
5764
5765     offset += 1; /* Skip Word Count (WCT) */
5766
5767     /* Build display for: AndXCommand */
5768
5769     AndXCommand = GBYTE(pd, offset);
5770
5771     if (tree) {
5772
5773       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
5774
5775     }
5776
5777     offset += 1; /* Skip AndXCommand */
5778
5779     /* Build display for: AndXReserved */
5780
5781     AndXReserved = GBYTE(pd, offset);
5782
5783     if (tree) {
5784
5785       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
5786
5787     }
5788
5789     offset += 1; /* Skip AndXReserved */
5790
5791     /* Build display for: AndXOffset */
5792
5793     AndXOffset = GSHORT(pd, offset);
5794
5795     if (tree) {
5796
5797       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
5798
5799     }
5800
5801     offset += 2; /* Skip AndXOffset */
5802
5803     /* Build display for: Remaining */
5804
5805     Remaining = GSHORT(pd, offset);
5806
5807     if (tree) {
5808
5809       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
5810
5811     }
5812
5813     offset += 2; /* Skip Remaining */
5814
5815     /* Build display for: Data Compaction Mode */
5816
5817     DataCompactionMode = GSHORT(pd, offset);
5818
5819     if (tree) {
5820
5821         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
5822
5823     }
5824
5825     offset += 2; /* Skip Data Compaction Mode */
5826
5827     /* Build display for: Reserved */
5828
5829     Reserved = GSHORT(pd, offset);
5830
5831     if (tree) {
5832
5833         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5834
5835     }
5836
5837     offset += 2; /* Skip Reserved */
5838
5839     /* Build display for: Data Length */
5840
5841     DataLength = GSHORT(pd, offset);
5842
5843     if (tree) {
5844
5845         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
5846
5847     }
5848
5849     offset += 2; /* Skip Data Length */
5850
5851     /* Build display for: Data Offset */
5852
5853     DataOffset = GSHORT(pd, offset);
5854
5855     if (tree) {
5856
5857         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
5858
5859     }
5860
5861     offset += 2; /* Skip Data Offset */
5862
5863     /* Build display for: Reserved[5] */
5864  
5865     for(i = 1; i <= 5; ++i) {
5866
5867         Reserved = GSHORT(pd, offset);
5868
5869         if (tree) {
5870
5871             proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);
5872
5873         }
5874         offset += 2;
5875     }
5876
5877     /* Build display for: Byte Count (BCC) */
5878
5879     ByteCount = GSHORT(pd, offset);
5880
5881     if (tree) {
5882
5883       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5884
5885     }
5886
5887     offset += 2; /* Skip Byte Count (BCC) */
5888
5889     /* Build display for data */
5890
5891     if (tree) {
5892
5893         offset = SMB_offset + DataOffset;
5894         if(END_OF_FRAME >= DataLength)
5895             proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
5896         else
5897             proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
5898
5899     }
5900
5901     if (AndXCommand != 0xFF) {
5902
5903       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
5904
5905     }
5906
5907   }
5908
5909 }
5910
5911 void
5912 dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5913
5914 {
5915   guint8        WordCount;
5916   guint8        AndXReserved;
5917   guint8        AndXCommand = 0xFF;
5918   guint16       ByteCount;
5919   guint16       AndXOffset = 0;
5920
5921   if (dirn == 1) { /* Request(s) dissect code */
5922
5923     /* Build display for: Word Count (WCT) */
5924
5925     WordCount = GBYTE(pd, offset);
5926
5927     if (tree) {
5928
5929       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5930
5931     }
5932
5933     offset += 1; /* Skip Word Count (WCT) */
5934
5935     /* Build display for: AndXCommand */
5936
5937     AndXCommand = GBYTE(pd, offset);
5938
5939     if (tree) {
5940
5941       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
5942
5943     }
5944
5945     offset += 1; /* Skip AndXCommand */
5946
5947     /* Build display for: AndXReserved */
5948
5949     AndXReserved = GBYTE(pd, offset);
5950
5951     if (tree) {
5952
5953       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
5954
5955     }
5956
5957     offset += 1; /* Skip AndXReserved */
5958
5959     /* Build display for: AndXOffset */
5960
5961     AndXOffset = GSHORT(pd, offset);
5962
5963     if (tree) {
5964
5965       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
5966
5967     }
5968
5969     offset += 2; /* Skip AndXOffset */
5970
5971     /* Build display for: Byte Count (BCC) */
5972
5973     ByteCount = GSHORT(pd, offset);
5974
5975     if (tree) {
5976
5977       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5978
5979     }
5980
5981     offset += 2; /* Skip Byte Count (BCC) */
5982
5983
5984     if (AndXCommand != 0xFF) {
5985
5986       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
5987
5988     }
5989
5990   }
5991
5992   if (dirn == 0) { /* Response(s) dissect code */
5993
5994     /* Build display for: Word Count (WCT) */
5995
5996     WordCount = GBYTE(pd, offset);
5997
5998     if (tree) {
5999
6000       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6001
6002     }
6003
6004     offset += 1; /* Skip Word Count (WCT) */
6005
6006     /* Build display for: AndXCommand */
6007
6008     AndXCommand = GBYTE(pd, offset);
6009
6010     if (tree) {
6011
6012       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6013
6014     }
6015
6016     offset += 1; /* Skip AndXCommand */
6017
6018     /* Build display for: AndXReserved */
6019
6020     AndXReserved = GBYTE(pd, offset);
6021
6022     if (tree) {
6023
6024       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6025
6026     }
6027
6028     offset += 1; /* Skip AndXReserved */
6029
6030     /* Build display for: AndXOffset */
6031
6032     AndXOffset = GSHORT(pd, offset);
6033
6034     if (tree) {
6035
6036       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6037
6038     }
6039
6040     offset += 2; /* Skip AndXOffset */
6041
6042     /* Build display for: Byte Count (BCC) */
6043
6044     ByteCount = GSHORT(pd, offset);
6045
6046     if (tree) {
6047
6048       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6049
6050     }
6051
6052     offset += 2; /* Skip Byte Count (BCC) */
6053
6054
6055     if (AndXCommand != 0xFF) {
6056
6057       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
6058
6059     }
6060
6061   }
6062
6063 }
6064
6065 void
6066 dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6067
6068 {
6069   static const value_string Mode_0x03[] = {
6070         { 0, "Seek from start of file"},
6071         { 1, "Seek from current position"},
6072         { 2, "Seek from end of file"},
6073         { 0, NULL}
6074 };
6075   proto_tree    *Mode_tree;
6076   proto_item    *ti;
6077   guint8        WordCount;
6078   guint32       Offset;
6079   guint16       Mode;
6080   guint16       FID;
6081   guint16       ByteCount;
6082
6083   if (dirn == 1) { /* Request(s) dissect code */
6084
6085     /* Build display for: Word Count (WCT) */
6086
6087     WordCount = GBYTE(pd, offset);
6088
6089     if (tree) {
6090
6091       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6092
6093     }
6094
6095     offset += 1; /* Skip Word Count (WCT) */
6096
6097     /* Build display for: FID */
6098
6099     FID = GSHORT(pd, offset);
6100
6101     if (tree) {
6102
6103       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6104
6105     }
6106
6107     offset += 2; /* Skip FID */
6108
6109     /* Build display for: Mode */
6110
6111     Mode = GSHORT(pd, offset);
6112
6113     if (tree) {
6114
6115       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
6116       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
6117       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
6118                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
6119     
6120 }
6121
6122     offset += 2; /* Skip Mode */
6123
6124     /* Build display for: Offset */
6125
6126     Offset = GWORD(pd, offset);
6127
6128     if (tree) {
6129
6130       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6131
6132     }
6133
6134     offset += 4; /* Skip Offset */
6135
6136     /* Build display for: Byte Count (BCC) */
6137
6138     ByteCount = GSHORT(pd, offset);
6139
6140     if (tree) {
6141
6142       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6143
6144     }
6145
6146     offset += 2; /* Skip Byte Count (BCC) */
6147
6148   }
6149
6150   if (dirn == 0) { /* Response(s) dissect code */
6151
6152     /* Build display for: Word Count (WCT) */
6153
6154     WordCount = GBYTE(pd, offset);
6155
6156     if (tree) {
6157
6158       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6159
6160     }
6161
6162     offset += 1; /* Skip Word Count (WCT) */
6163
6164     /* Build display for: Offset */
6165
6166     Offset = GWORD(pd, offset);
6167
6168     if (tree) {
6169
6170       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6171
6172     }
6173
6174     offset += 4; /* Skip Offset */
6175
6176     /* Build display for: Byte Count (BCC) */
6177
6178     ByteCount = GSHORT(pd, offset);
6179
6180     if (tree) {
6181
6182       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6183
6184     }
6185
6186     offset += 2; /* Skip Byte Count (BCC) */
6187
6188   }
6189
6190 }
6191
6192 void
6193 dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6194
6195 {
6196   guint8        WordCount;
6197   guint8        BufferFormat;
6198   guint32       Offset;
6199   guint16       Remaining;
6200   guint16       FID;
6201   guint16       DataLength;
6202   guint16       Count;
6203   guint16       ByteCount;
6204
6205   if (dirn == 1) { /* Request(s) dissect code */
6206
6207     /* Build display for: Word Count (WCT) */
6208
6209     WordCount = GBYTE(pd, offset);
6210
6211     if (tree) {
6212
6213       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6214
6215     }
6216
6217     offset += 1; /* Skip Word Count (WCT) */
6218
6219     /* Build display for: FID */
6220
6221     FID = GSHORT(pd, offset);
6222
6223     if (tree) {
6224
6225       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6226
6227     }
6228
6229     offset += 2; /* Skip FID */
6230
6231     /* Build display for: Count */
6232
6233     Count = GSHORT(pd, offset);
6234
6235     if (tree) {
6236
6237       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6238
6239     }
6240
6241     offset += 2; /* Skip Count */
6242
6243     /* Build display for: Offset */
6244
6245     Offset = GWORD(pd, offset);
6246
6247     if (tree) {
6248
6249       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6250
6251     }
6252
6253     offset += 4; /* Skip Offset */
6254
6255     /* Build display for: Remaining */
6256
6257     Remaining = GSHORT(pd, offset);
6258
6259     if (tree) {
6260
6261       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
6262
6263     }
6264
6265     offset += 2; /* Skip Remaining */
6266
6267     /* Build display for: Byte Count (BCC) */
6268
6269     ByteCount = GSHORT(pd, offset);
6270
6271     if (tree) {
6272
6273       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6274
6275     }
6276
6277     offset += 2; /* Skip Byte Count (BCC) */
6278
6279     /* Build display for: Buffer Format */
6280
6281     BufferFormat = GBYTE(pd, offset);
6282
6283     if (tree) {
6284
6285       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6286
6287     }
6288
6289     offset += 1; /* Skip Buffer Format */
6290
6291     /* Build display for: Data Length */
6292
6293     DataLength = GSHORT(pd, offset);
6294
6295     if (tree) {
6296
6297       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
6298
6299     }
6300
6301     offset += 2; /* Skip Data Length */
6302
6303   }
6304
6305   if (dirn == 0) { /* Response(s) dissect code */
6306
6307     /* Build display for: Word Count (WCT) */
6308
6309     WordCount = GBYTE(pd, offset);
6310
6311     if (tree) {
6312
6313       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6314
6315     }
6316
6317     offset += 1; /* Skip Word Count (WCT) */
6318
6319     /* Build display for: Count */
6320
6321     Count = GSHORT(pd, offset);
6322
6323     if (tree) {
6324
6325       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6326
6327     }
6328
6329     offset += 2; /* Skip Count */
6330
6331     /* Build display for: Byte Count (BCC) */
6332
6333     ByteCount = GSHORT(pd, offset);
6334
6335     if (tree) {
6336
6337       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6338
6339     }
6340
6341     offset += 2; /* Skip Byte Count (BCC) */
6342
6343   }
6344
6345 }
6346
6347 void
6348 dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6349
6350 {
6351   guint8        WordCount;
6352   guint16       LastWriteTime;
6353   guint16       LastWriteDate;
6354   guint16       LastAccessTime;
6355   guint16       LastAccessDate;
6356   guint16       FID;
6357   guint16       CreationTime;
6358   guint16       CreationDate;
6359   guint16       ByteCount;
6360
6361   if (dirn == 1) { /* Request(s) dissect code */
6362
6363     /* Build display for: Word Count */
6364
6365     WordCount = GBYTE(pd, offset);
6366
6367     if (tree) {
6368
6369       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
6370
6371     }
6372
6373     offset += 1; /* Skip Word Count */
6374
6375     /* Build display for: FID */
6376
6377     FID = GSHORT(pd, offset);
6378
6379     if (tree) {
6380
6381       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6382
6383     }
6384
6385     offset += 2; /* Skip FID */
6386
6387     /* Build display for: Creation Date */
6388
6389     CreationDate = GSHORT(pd, offset);
6390
6391     if (tree) {
6392
6393       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
6394
6395     }
6396
6397     offset += 2; /* Skip Creation Date */
6398
6399     /* Build display for: Creation Time */
6400
6401     CreationTime = GSHORT(pd, offset);
6402
6403     if (tree) {
6404
6405       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
6406
6407     }
6408
6409     offset += 2; /* Skip Creation Time */
6410
6411     /* Build display for: Last Access Date */
6412
6413     LastAccessDate = GSHORT(pd, offset);
6414
6415     if (tree) {
6416
6417       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
6418
6419     }
6420
6421     offset += 2; /* Skip Last Access Date */
6422
6423     /* Build display for: Last Access Time */
6424
6425     LastAccessTime = GSHORT(pd, offset);
6426
6427     if (tree) {
6428
6429       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
6430
6431     }
6432
6433     offset += 2; /* Skip Last Access Time */
6434
6435     /* Build display for: Last Write Date */
6436
6437     LastWriteDate = GSHORT(pd, offset);
6438
6439     if (tree) {
6440
6441       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
6442
6443     }
6444
6445     offset += 2; /* Skip Last Write Date */
6446
6447     /* Build display for: Last Write Time */
6448
6449     LastWriteTime = GSHORT(pd, offset);
6450
6451     if (tree) {
6452
6453       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
6454
6455     }
6456
6457     offset += 2; /* Skip Last Write Time */
6458
6459     /* Build display for: Byte Count (BCC) */
6460
6461     ByteCount = GSHORT(pd, offset);
6462
6463     if (tree) {
6464
6465       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6466
6467     }
6468
6469     offset += 2; /* Skip Byte Count (BCC) */
6470
6471   }
6472
6473   if (dirn == 0) { /* Response(s) dissect code */
6474
6475     /* Build display for: Word Count (WCC) */
6476
6477     WordCount = GBYTE(pd, offset);
6478
6479     if (tree) {
6480
6481       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
6482
6483     }
6484
6485     offset += 1; /* Skip Word Count (WCC) */
6486
6487     /* Build display for: Byte Count (BCC) */
6488
6489     ByteCount = GSHORT(pd, offset);
6490
6491     if (tree) {
6492
6493       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6494
6495     }
6496
6497     offset += 2; /* Skip Byte Count (BCC) */
6498
6499   }
6500
6501 }
6502
6503 void
6504 dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6505
6506 {
6507   guint8        WordCount;
6508   guint32       Offset;
6509   guint32       Count;
6510   guint16       FID;
6511   guint16       ByteCount;
6512
6513   if (dirn == 1) { /* Request(s) dissect code */
6514
6515     /* Build display for: Word Count (WCT) */
6516
6517     WordCount = GBYTE(pd, offset);
6518
6519     if (tree) {
6520
6521       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6522
6523     }
6524
6525     offset += 1; /* Skip Word Count (WCT) */
6526
6527     /* Build display for: FID */
6528
6529     FID = GSHORT(pd, offset);
6530
6531     if (tree) {
6532
6533       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6534
6535     }
6536
6537     offset += 2; /* Skip FID */
6538
6539     /* Build display for: Count */
6540
6541     Count = GWORD(pd, offset);
6542
6543     if (tree) {
6544
6545       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
6546
6547     }
6548
6549     offset += 4; /* Skip Count */
6550
6551     /* Build display for: Offset */
6552
6553     Offset = GWORD(pd, offset);
6554
6555     if (tree) {
6556
6557       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6558
6559     }
6560
6561     offset += 4; /* Skip Offset */
6562
6563     /* Build display for: Byte Count (BCC) */
6564
6565     ByteCount = GSHORT(pd, offset);
6566
6567     if (tree) {
6568
6569       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6570
6571     }
6572
6573     offset += 2; /* Skip Byte Count (BCC) */
6574
6575   }
6576
6577   if (dirn == 0) { /* Response(s) dissect code */
6578
6579     /* Build display for: Word Count (WCT) */
6580
6581     WordCount = GBYTE(pd, offset);
6582
6583     if (tree) {
6584
6585       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6586
6587     }
6588
6589     offset += 1; /* Skip Word Count (WCT) */
6590
6591     /* Build display for: Byte Count (BCC) */
6592
6593     ByteCount = GSHORT(pd, offset);
6594
6595     if (tree) {
6596
6597       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6598
6599     }
6600
6601     offset += 2; /* Skip Byte Count (BCC) */
6602
6603   }
6604
6605 }
6606
6607 void
6608 dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6609
6610 {
6611   guint8        WordCount;
6612   guint8        BufferFormat;
6613   guint16       StartIndex;
6614   guint16       RestartIndex;
6615   guint16       MaxCount;
6616   guint16       DataLength;
6617   guint16       Count;
6618   guint16       ByteCount;
6619
6620   if (dirn == 1) { /* Request(s) dissect code */
6621
6622     /* Build display for: Word Count */
6623
6624     WordCount = GBYTE(pd, offset);
6625
6626     if (tree) {
6627
6628       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
6629
6630     }
6631
6632     offset += 1; /* Skip Word Count */
6633
6634     /* Build display for: Max Count */
6635
6636     MaxCount = GSHORT(pd, offset);
6637
6638     if (tree) {
6639
6640       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6641
6642     }
6643
6644     offset += 2; /* Skip Max Count */
6645
6646     /* Build display for: Start Index */
6647
6648     StartIndex = GSHORT(pd, offset);
6649
6650     if (tree) {
6651
6652       proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);
6653
6654     }
6655
6656     offset += 2; /* Skip Start Index */
6657
6658     /* Build display for: Byte Count (BCC) */
6659
6660     ByteCount = GSHORT(pd, offset);
6661
6662     if (tree) {
6663
6664       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6665
6666     }
6667
6668     offset += 2; /* Skip Byte Count (BCC) */
6669
6670   }
6671
6672   if (dirn == 0) { /* Response(s) dissect code */
6673
6674     /* Build display for: Word Count (WCT) */
6675
6676     WordCount = GBYTE(pd, offset);
6677
6678     if (tree) {
6679
6680       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6681
6682     }
6683
6684     offset += 1; /* Skip Word Count (WCT) */
6685
6686     if (WordCount > 0) {
6687
6688       /* Build display for: Count */
6689
6690       Count = GSHORT(pd, offset);
6691
6692       if (tree) {
6693
6694         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6695
6696       }
6697
6698       offset += 2; /* Skip Count */
6699
6700       /* Build display for: Restart Index */
6701
6702       RestartIndex = GSHORT(pd, offset);
6703
6704       if (tree) {
6705
6706         proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
6707
6708       }
6709
6710       offset += 2; /* Skip Restart Index */
6711
6712       /* Build display for: Byte Count (BCC) */
6713
6714     }
6715
6716     ByteCount = GSHORT(pd, offset);
6717
6718     if (tree) {
6719
6720       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6721
6722     }
6723
6724     offset += 2; /* Skip Byte Count (BCC) */
6725
6726     /* Build display for: Buffer Format */
6727
6728     BufferFormat = GBYTE(pd, offset);
6729
6730     if (tree) {
6731
6732       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6733
6734     }
6735
6736     offset += 1; /* Skip Buffer Format */
6737
6738     /* Build display for: Data Length */
6739
6740     DataLength = GSHORT(pd, offset);
6741
6742     if (tree) {
6743
6744       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
6745
6746     }
6747
6748     offset += 2; /* Skip Data Length */
6749
6750   }
6751
6752 }
6753
6754 void
6755 dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6756
6757 {
6758   proto_tree    *LockType_tree;
6759   proto_item    *ti;
6760   guint8        LockType;
6761   guint8        WordCount;
6762   guint8        OplockLevel;
6763   guint8        AndXReserved;
6764   guint8        AndXCommand = 0xFF;
6765   guint32       Timeout;
6766   guint16       NumberofLocks;
6767   guint16       NumberOfUnlocks;
6768   guint16       FID;
6769   guint16       ByteCount;
6770   guint16       AndXoffset;
6771   guint16       AndXOffset = 0;
6772
6773   if (dirn == 1) { /* Request(s) dissect code */
6774
6775     /* Build display for: Word Count (WCT) */
6776
6777     WordCount = GBYTE(pd, offset);
6778
6779     if (tree) {
6780
6781       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6782
6783     }
6784
6785     offset += 1; /* Skip Word Count (WCT) */
6786
6787     /* Build display for: AndXCommand */
6788
6789     AndXCommand = GBYTE(pd, offset);
6790
6791     if (tree) {
6792
6793       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6794
6795     }
6796
6797     offset += 1; /* Skip AndXCommand */
6798
6799     /* Build display for: AndXReserved */
6800
6801     AndXReserved = GBYTE(pd, offset);
6802
6803     if (tree) {
6804
6805       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6806
6807     }
6808
6809     offset += 1; /* Skip AndXReserved */
6810
6811     /* Build display for: AndXOffset */
6812
6813     AndXOffset = GSHORT(pd, offset);
6814
6815     if (tree) {
6816
6817       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6818
6819     }
6820
6821     offset += 2; /* Skip AndXOffset */
6822
6823     /* Build display for: FID */
6824
6825     FID = GSHORT(pd, offset);
6826
6827     if (tree) {
6828
6829       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6830
6831     }
6832
6833     offset += 2; /* Skip FID */
6834
6835     /* Build display for: Lock Type */
6836
6837     LockType = GBYTE(pd, offset);
6838
6839     if (tree) {
6840
6841       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
6842       LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
6843       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6844                           decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
6845       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6846                           decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
6847       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6848                           decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
6849       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6850                           decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
6851       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6852                           decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
6853     
6854 }
6855
6856     offset += 1; /* Skip Lock Type */
6857
6858     /* Build display for: OplockLevel */
6859
6860     OplockLevel = GBYTE(pd, offset);
6861
6862     if (tree) {
6863
6864       proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);
6865
6866     }
6867
6868     offset += 1; /* Skip OplockLevel */
6869
6870     /* Build display for: Timeout */
6871
6872     Timeout = GWORD(pd, offset);
6873
6874     if (tree) {
6875
6876       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
6877
6878     }
6879
6880     offset += 4; /* Skip Timeout */
6881
6882     /* Build display for: Number Of Unlocks */
6883
6884     NumberOfUnlocks = GSHORT(pd, offset);
6885
6886     if (tree) {
6887
6888       proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
6889
6890     }
6891
6892     offset += 2; /* Skip Number Of Unlocks */
6893
6894     /* Build display for: Number of Locks */
6895
6896     NumberofLocks = GSHORT(pd, offset);
6897
6898     if (tree) {
6899
6900       proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
6901
6902     }
6903
6904     offset += 2; /* Skip Number of Locks */
6905
6906     /* Build display for: Byte Count (BCC) */
6907
6908     ByteCount = GSHORT(pd, offset);
6909
6910     if (tree) {
6911
6912       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6913
6914     }
6915
6916     offset += 2; /* Skip Byte Count (BCC) */
6917
6918
6919     if (AndXCommand != 0xFF) {
6920
6921       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
6922
6923     }
6924
6925   }
6926
6927   if (dirn == 0) { /* Response(s) dissect code */
6928
6929     /* Build display for: Word Count (WCT) */
6930
6931     WordCount = GBYTE(pd, offset);
6932
6933     if (tree) {
6934
6935       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6936
6937     }
6938
6939     offset += 1; /* Skip Word Count (WCT) */
6940
6941     if (WordCount > 0) {
6942
6943       /* Build display for: AndXCommand */
6944
6945       AndXCommand = GBYTE(pd, offset);
6946
6947       if (tree) {
6948
6949         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
6950                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
6951
6952       }
6953
6954       offset += 1; /* Skip AndXCommand */
6955
6956       /* Build display for: AndXReserved */
6957
6958       AndXReserved = GBYTE(pd, offset);
6959
6960       if (tree) {
6961
6962         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6963
6964       }
6965
6966       offset += 1; /* Skip AndXReserved */
6967
6968       /* Build display for: AndXoffset */
6969
6970       AndXoffset = GSHORT(pd, offset);
6971
6972       if (tree) {
6973
6974         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
6975
6976       }
6977
6978       offset += 2; /* Skip AndXoffset */
6979
6980     }
6981
6982     /* Build display for: Byte Count */
6983
6984     ByteCount = GSHORT(pd, offset);
6985
6986     if (tree) {
6987
6988       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
6989
6990     }
6991
6992     offset += 2; /* Skip Byte Count */
6993
6994
6995     if (AndXCommand != 0xFF) {
6996
6997       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
6998
6999     }
7000
7001   }
7002
7003 }
7004
7005 void
7006 dissect_unlock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7007
7008 {
7009   guint8        WordCount;
7010   guint32       Offset;
7011   guint32       Count;
7012   guint16       FID;
7013   guint16       ByteCount;
7014
7015   if (dirn == 1) { /* Request(s) dissect code */
7016
7017     /* Build display for: Word Count (WCT) */
7018
7019     WordCount = GBYTE(pd, offset);
7020
7021     if (tree) {
7022
7023       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7024
7025     }
7026
7027     offset += 1; /* Skip Word Count (WCT) */
7028
7029     /* Build display for: FID */
7030
7031     FID = GSHORT(pd, offset);
7032
7033     if (tree) {
7034
7035       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7036
7037     }
7038
7039     offset += 2; /* Skip FID */
7040
7041     /* Build display for: Count */
7042
7043     Count = GWORD(pd, offset);
7044
7045     if (tree) {
7046
7047       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
7048
7049     }
7050
7051     offset += 4; /* Skip Count */
7052
7053     /* Build display for: Offset */
7054
7055     Offset = GWORD(pd, offset);
7056
7057     if (tree) {
7058
7059       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7060
7061     }
7062
7063     offset += 4; /* Skip Offset */
7064
7065     /* Build display for: Byte Count (BCC) */
7066
7067     ByteCount = GSHORT(pd, offset);
7068
7069     if (tree) {
7070
7071       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7072
7073     }
7074
7075     offset += 2; /* Skip Byte Count (BCC) */
7076
7077   }
7078
7079   if (dirn == 0) { /* Response(s) dissect code */
7080
7081     /* Build display for: Word Count (WCT) */
7082
7083     WordCount = GBYTE(pd, offset);
7084
7085     if (tree) {
7086
7087       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7088
7089     }
7090
7091     offset += 1; /* Skip Word Count (WCT) */
7092
7093     /* Build display for: Byte Count (BCC) */
7094
7095     ByteCount = GSHORT(pd, offset);
7096
7097     if (tree) {
7098
7099       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7100
7101     }
7102
7103     offset += 2; /* Skip Byte Count (BCC) */
7104
7105   }
7106
7107 }
7108
7109 void
7110 dissect_create_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7111
7112 {
7113   proto_tree    *Attributes_tree;
7114   proto_item    *ti;
7115   guint8        WordCount;
7116   guint8        BufferFormat;
7117   guint16       FID;
7118   guint16       CreationTime;
7119   guint16       ByteCount;
7120   guint16       Attributes;
7121   const char    *FileName;
7122
7123   if (dirn == 1) { /* Request(s) dissect code */
7124
7125     /* Build display for: Word Count (WCT) */
7126
7127     WordCount = GBYTE(pd, offset);
7128
7129     if (tree) {
7130
7131       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7132
7133     }
7134
7135     offset += 1; /* Skip Word Count (WCT) */
7136
7137     /* Build display for: Attributes */
7138
7139     Attributes = GSHORT(pd, offset);
7140
7141     if (tree) {
7142
7143       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
7144       Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
7145       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7146                           decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
7147       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7148                           decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
7149       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7150                           decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
7151       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7152                           decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
7153       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7154                           decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
7155       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7156                           decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
7157     
7158 }
7159
7160     offset += 2; /* Skip Attributes */
7161
7162     /* Build display for: Creation Time */
7163
7164     CreationTime = GSHORT(pd, offset);
7165
7166     if (tree) {
7167
7168       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
7169
7170     }
7171
7172     offset += 2; /* Skip Creation Time */
7173
7174     /* Build display for: Byte Count (BCC) */
7175
7176     ByteCount = GSHORT(pd, offset);
7177
7178     if (tree) {
7179
7180       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7181
7182     }
7183
7184     offset += 2; /* Skip Byte Count (BCC) */
7185
7186     /* Build display for: Buffer Format */
7187
7188     BufferFormat = GBYTE(pd, offset);
7189
7190     if (tree) {
7191
7192       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7193
7194     }
7195
7196     offset += 1; /* Skip Buffer Format */
7197
7198     /* Build display for: File Name */
7199
7200     FileName = pd + offset;
7201
7202     if (tree) {
7203
7204       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
7205
7206     }
7207
7208     offset += strlen(FileName) + 1; /* Skip File Name */
7209
7210   }
7211
7212   if (dirn == 0) { /* Response(s) dissect code */
7213
7214     /* Build display for: Word Count (WCT) */
7215
7216     WordCount = GBYTE(pd, offset);
7217
7218     if (tree) {
7219
7220       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7221
7222     }
7223
7224     offset += 1; /* Skip Word Count (WCT) */
7225
7226     if (WordCount > 0) {
7227
7228       /* Build display for: FID */
7229
7230       FID = GSHORT(pd, offset);
7231
7232       if (tree) {
7233
7234         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7235
7236       }
7237
7238       offset += 2; /* Skip FID */
7239       
7240     }
7241     
7242     /* Build display for: Byte Count (BCC) */
7243
7244     ByteCount = GSHORT(pd, offset);
7245
7246     if (tree) {
7247
7248       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7249
7250     }
7251
7252     offset += 2; /* Skip Byte Count (BCC) */
7253
7254   }
7255
7256 }
7257
7258 void
7259 dissect_search_dir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7260
7261 {
7262   guint8        WordCount;
7263   guint8        BufferFormat2;
7264   guint8        BufferFormat1;
7265   guint8        BufferFormat;
7266   guint16       SearchAttributes;
7267   guint16       ResumeKeyLength;
7268   guint16       MaxCount;
7269   guint16       DataLength;
7270   guint16       Count;
7271   guint16       ByteCount;
7272   const char    *FileName;
7273
7274   if (dirn == 1) { /* Request(s) dissect code */
7275
7276     /* Build display for: Word Count (WCT) */
7277
7278     WordCount = GBYTE(pd, offset);
7279
7280     if (tree) {
7281
7282       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7283
7284     }
7285
7286     offset += 1; /* Skip Word Count (WCT) */
7287
7288     /* Build display for: Max Count */
7289
7290     MaxCount = GSHORT(pd, offset);
7291
7292     if (tree) {
7293
7294       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
7295
7296     }
7297
7298     offset += 2; /* Skip Max Count */
7299
7300     /* Build display for: Search Attributes */
7301
7302     SearchAttributes = GSHORT(pd, offset);
7303
7304     if (tree) {
7305
7306       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
7307
7308     }
7309
7310     offset += 2; /* Skip Search Attributes */
7311
7312     /* Build display for: Byte Count (BCC) */
7313
7314     ByteCount = GSHORT(pd, offset);
7315
7316     if (tree) {
7317
7318       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7319
7320     }
7321
7322     offset += 2; /* Skip Byte Count (BCC) */
7323
7324     /* Build display for: Buffer Format 1 */
7325
7326     BufferFormat1 = GBYTE(pd, offset);
7327
7328     if (tree) {
7329
7330       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %u", BufferFormat1);
7331
7332     }
7333
7334     offset += 1; /* Skip Buffer Format 1 */
7335
7336     /* Build display for: File Name */
7337
7338     FileName = pd + offset;
7339
7340     if (tree) {
7341
7342       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
7343
7344     }
7345
7346     offset += strlen(FileName) + 1; /* Skip File Name */
7347
7348     /* Build display for: Buffer Format 2 */
7349
7350     BufferFormat2 = GBYTE(pd, offset);
7351
7352     if (tree) {
7353
7354       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %u", BufferFormat2);
7355
7356     }
7357
7358     offset += 1; /* Skip Buffer Format 2 */
7359
7360     /* Build display for: Resume Key Length */
7361
7362     ResumeKeyLength = GSHORT(pd, offset);
7363
7364     if (tree) {
7365
7366       proto_tree_add_text(tree, NullTVB, offset, 2, "Resume Key Length: %u", ResumeKeyLength);
7367
7368     }
7369
7370     offset += 2; /* Skip Resume Key Length */
7371
7372   }
7373
7374   if (dirn == 0) { /* Response(s) dissect code */
7375
7376     /* Build display for: Word Count (WCT) */
7377
7378     WordCount = GBYTE(pd, offset);
7379
7380     if (tree) {
7381
7382       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7383
7384     }
7385
7386     offset += 1; /* Skip Word Count (WCT) */
7387
7388     if (WordCount > 0) {
7389
7390       /* Build display for: Count */
7391
7392       Count = GSHORT(pd, offset);
7393
7394       if (tree) {
7395
7396         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7397
7398       }
7399
7400       offset += 2; /* Skip Count */
7401
7402     }
7403
7404     /* Build display for: Byte Count (BCC) */
7405
7406     ByteCount = GSHORT(pd, offset);
7407
7408     if (tree) {
7409
7410       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7411
7412     }
7413
7414     offset += 2; /* Skip Byte Count (BCC) */
7415
7416     /* Build display for: Buffer Format */
7417
7418     BufferFormat = GBYTE(pd, offset);
7419
7420     if (tree) {
7421
7422       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7423
7424     }
7425
7426     offset += 1; /* Skip Buffer Format */
7427
7428     /* Build display for: Data Length */
7429
7430     DataLength = GSHORT(pd, offset);
7431
7432     if (tree) {
7433
7434       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7435
7436     }
7437
7438     offset += 2; /* Skip Data Length */
7439
7440   }
7441
7442 }
7443
7444 void
7445 dissect_create_temporary_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7446
7447 {
7448   guint8        WordCount;
7449   guint8        BufferFormat;
7450   guint16       Reserved;
7451   guint16       FID;
7452   guint16       CreationTime;
7453   guint16       CreationDate;
7454   guint16       ByteCount;
7455   const char    *FileName;
7456   const char    *DirectoryName;
7457
7458   if (dirn == 1) { /* Request(s) dissect code */
7459
7460     /* Build display for: Word Count (WCT) */
7461
7462     WordCount = GBYTE(pd, offset);
7463
7464     if (tree) {
7465
7466       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7467
7468     }
7469
7470     offset += 1; /* Skip Word Count (WCT) */
7471
7472     /* Build display for: Reserved */
7473
7474     Reserved = GSHORT(pd, offset);
7475
7476     if (tree) {
7477
7478       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
7479
7480     }
7481
7482     offset += 2; /* Skip Reserved */
7483
7484     /* Build display for: Creation Time */
7485
7486     CreationTime = GSHORT(pd, offset);
7487
7488     if (tree) {
7489
7490       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
7491
7492     }
7493
7494     offset += 2; /* Skip Creation Time */
7495
7496     /* Build display for: Creation Date */
7497
7498     CreationDate = GSHORT(pd, offset);
7499
7500     if (tree) {
7501
7502       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
7503
7504     }
7505
7506     offset += 2; /* Skip Creation Date */
7507
7508     /* Build display for: Byte Count (BCC) */
7509
7510     ByteCount = GSHORT(pd, offset);
7511
7512     if (tree) {
7513
7514       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7515
7516     }
7517
7518     offset += 2; /* Skip Byte Count (BCC) */
7519
7520     /* Build display for: Buffer Format */
7521
7522     BufferFormat = GBYTE(pd, offset);
7523
7524     if (tree) {
7525
7526       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7527
7528     }
7529
7530     offset += 1; /* Skip Buffer Format */
7531
7532     /* Build display for: Directory Name */
7533
7534     DirectoryName = pd + offset;
7535
7536     if (tree) {
7537
7538       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
7539
7540     }
7541
7542     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
7543
7544   }
7545
7546   if (dirn == 0) { /* Response(s) dissect code */
7547
7548     /* Build display for: Word Count (WCT) */
7549
7550     WordCount = GBYTE(pd, offset);
7551
7552     if (tree) {
7553
7554       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7555
7556     }
7557
7558     offset += 1; /* Skip Word Count (WCT) */
7559
7560     if (WordCount > 0) {
7561
7562       /* Build display for: FID */
7563
7564       FID = GSHORT(pd, offset);
7565
7566       if (tree) {
7567
7568         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7569
7570       }
7571
7572       offset += 2; /* Skip FID */
7573
7574     }
7575
7576     /* Build display for: Byte Count (BCC) */
7577
7578     ByteCount = GSHORT(pd, offset);
7579
7580     if (tree) {
7581
7582       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7583
7584     }
7585
7586     offset += 2; /* Skip Byte Count (BCC) */
7587
7588     /* Build display for: Buffer Format */
7589
7590     BufferFormat = GBYTE(pd, offset);
7591
7592     if (tree) {
7593
7594       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7595
7596     }
7597
7598     offset += 1; /* Skip Buffer Format */
7599
7600     /* Build display for: File Name */
7601
7602     FileName = pd + offset;
7603
7604     if (tree) {
7605
7606       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
7607
7608     }
7609
7610     offset += strlen(FileName) + 1; /* Skip File Name */
7611
7612   }
7613
7614 }
7615
7616 void
7617 dissect_close_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7618
7619 {
7620   guint8        WordCount;
7621   guint16       LastWriteTime;
7622   guint16       LastWriteDate;
7623   guint16       FID;
7624   guint16       ByteCount;
7625
7626   if (dirn == 1) { /* Request(s) dissect code */
7627
7628     /* Build display for: Word Count (WCT) */
7629
7630     WordCount = GBYTE(pd, offset);
7631
7632     if (tree) {
7633
7634       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7635
7636     }
7637
7638     offset += 1; /* Skip Word Count (WCT) */
7639
7640     /* Build display for: FID */
7641
7642     FID = GSHORT(pd, offset);
7643
7644     if (tree) {
7645
7646       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7647
7648     }
7649
7650     offset += 2; /* Skip FID */
7651
7652     /* Build display for: Last Write Time */
7653
7654     LastWriteTime = GSHORT(pd, offset);
7655
7656     if (tree) {
7657
7658       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
7659
7660     }
7661
7662     offset += 2; /* Skip Last Write Time */
7663
7664     /* Build display for: Last Write Date */
7665
7666     LastWriteDate = GSHORT(pd, offset);
7667
7668     if (tree) {
7669
7670       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
7671
7672     }
7673
7674     offset += 2; /* Skip Last Write Date */
7675
7676     /* Build display for: Byte Count (BCC) */
7677
7678     ByteCount = GSHORT(pd, offset);
7679
7680     if (tree) {
7681
7682       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7683
7684     }
7685
7686     offset += 2; /* Skip Byte Count (BCC) */
7687
7688   }
7689
7690   if (dirn == 0) { /* Response(s) dissect code */
7691
7692     /* Build display for: Word Count (WCT) */
7693
7694     WordCount = GBYTE(pd, offset);
7695
7696     if (tree) {
7697
7698       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7699
7700     }
7701
7702     offset += 1; /* Skip Word Count (WCT) */
7703
7704     /* Build display for: Byte Count (BCC) */
7705
7706     ByteCount = GSHORT(pd, offset);
7707
7708     if (tree) {
7709
7710       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7711
7712     }
7713
7714     offset += 2; /* Skip Byte Count (BCC) */
7715
7716   }
7717
7718 }
7719
7720 void
7721 dissect_write_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7722
7723 {
7724   guint8        WordCount;
7725   guint8        BufferFormat;
7726   guint16       FID;
7727   guint16       DataLength;
7728   guint16       ByteCount;
7729
7730   if (dirn == 1) { /* Request(s) dissect code */
7731
7732     /* Build display for: Word Count (WCT) */
7733
7734     WordCount = GBYTE(pd, offset);
7735
7736     if (tree) {
7737
7738       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7739
7740     }
7741
7742     offset += 1; /* Skip Word Count (WCT) */
7743
7744     /* Build display for: FID */
7745
7746     FID = GSHORT(pd, offset);
7747
7748     if (tree) {
7749
7750       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7751
7752     }
7753
7754     offset += 2; /* Skip FID */
7755
7756     /* Build display for: Byte Count (BCC) */
7757
7758     ByteCount = GSHORT(pd, offset);
7759
7760     if (tree) {
7761
7762       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7763
7764     }
7765
7766     offset += 2; /* Skip Byte Count (BCC) */
7767
7768     /* Build display for: Buffer Format */
7769
7770     BufferFormat = GBYTE(pd, offset);
7771
7772     if (tree) {
7773
7774       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7775
7776     }
7777
7778     offset += 1; /* Skip Buffer Format */
7779
7780     /* Build display for: Data Length */
7781
7782     DataLength = GSHORT(pd, offset);
7783
7784     if (tree) {
7785
7786       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7787
7788     }
7789
7790     offset += 2; /* Skip Data Length */
7791
7792   }
7793
7794   if (dirn == 0) { /* Response(s) dissect code */
7795
7796     /* Build display for: Word Count (WCT) */
7797
7798     WordCount = GBYTE(pd, offset);
7799
7800     if (tree) {
7801
7802       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7803
7804     }
7805
7806     offset += 1; /* Skip Word Count (WCT) */
7807
7808     /* Build display for: Byte Count (BCC) */
7809
7810     ByteCount = GSHORT(pd, offset);
7811
7812     if (tree) {
7813
7814       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7815
7816     }
7817
7818     offset += 2; /* Skip Byte Count (BCC) */
7819
7820   }
7821
7822 }
7823
7824 void
7825 dissect_lock_and_read_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7826
7827 {
7828   guint8        WordCount;
7829   guint8        BufferFormat;
7830   guint32       Offset;
7831   guint16       Reserved4;
7832   guint16       Reserved3;
7833   guint16       Reserved2;
7834   guint16       Reserved1;
7835   guint16       Remaining;
7836   guint16       FID;
7837   guint16       DataLength;
7838   guint16       Count;
7839   guint16       ByteCount;
7840
7841   if (dirn == 1) { /* Request(s) dissect code */
7842
7843     /* Build display for: Word Count (WCT) */
7844
7845     WordCount = GBYTE(pd, offset);
7846
7847     if (tree) {
7848
7849       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7850
7851     }
7852
7853     offset += 1; /* Skip Word Count (WCT) */
7854
7855     /* Build display for: FID */
7856
7857     FID = GSHORT(pd, offset);
7858
7859     if (tree) {
7860
7861       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7862
7863     }
7864
7865     offset += 2; /* Skip FID */
7866
7867     /* Build display for: Count */
7868
7869     Count = GSHORT(pd, offset);
7870
7871     if (tree) {
7872
7873       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7874
7875     }
7876
7877     offset += 2; /* Skip Count */
7878
7879     /* Build display for: Offset */
7880
7881     Offset = GWORD(pd, offset);
7882
7883     if (tree) {
7884
7885       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7886
7887     }
7888
7889     offset += 4; /* Skip Offset */
7890
7891     /* Build display for: Remaining */
7892
7893     Remaining = GSHORT(pd, offset);
7894
7895     if (tree) {
7896
7897       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
7898
7899     }
7900
7901     offset += 2; /* Skip Remaining */
7902
7903     /* Build display for: Byte Count (BCC) */
7904
7905     ByteCount = GSHORT(pd, offset);
7906
7907     if (tree) {
7908
7909       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7910
7911     }
7912
7913     offset += 2; /* Skip Byte Count (BCC) */
7914
7915   }
7916
7917   if (dirn == 0) { /* Response(s) dissect code */
7918
7919     /* Build display for: Word Count (WCT) */
7920
7921     WordCount = GBYTE(pd, offset);
7922
7923     if (tree) {
7924
7925       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7926
7927     }
7928
7929     offset += 1; /* Skip Word Count (WCT) */
7930
7931     if (WordCount > 0) {
7932
7933       /* Build display for: Count */
7934
7935       Count = GSHORT(pd, offset);
7936
7937       if (tree) {
7938
7939         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7940
7941       }
7942
7943       offset += 2; /* Skip Count */
7944
7945       /* Build display for: Reserved 1 */
7946
7947       Reserved1 = GSHORT(pd, offset);
7948
7949       if (tree) {
7950
7951         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
7952
7953       }
7954
7955       offset += 2; /* Skip Reserved 1 */
7956
7957       /* Build display for: Reserved 2 */
7958
7959       Reserved2 = GSHORT(pd, offset);
7960
7961       if (tree) {
7962
7963         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
7964
7965       }
7966
7967       offset += 2; /* Skip Reserved 2 */
7968
7969       /* Build display for: Reserved 3 */
7970
7971       Reserved3 = GSHORT(pd, offset);
7972
7973       if (tree) {
7974
7975         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
7976
7977       }
7978
7979       offset += 2; /* Skip Reserved 3 */
7980
7981       /* Build display for: Reserved 4 */
7982
7983       Reserved4 = GSHORT(pd, offset);
7984
7985       if (tree) {
7986
7987         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
7988
7989       }
7990
7991       offset += 2; /* Skip Reserved 4 */
7992
7993       /* Build display for: Byte Count (BCC) */
7994
7995       ByteCount = GSHORT(pd, offset);
7996
7997       if (tree) {
7998
7999         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8000
8001       }
8002
8003     }
8004
8005     offset += 2; /* Skip Byte Count (BCC) */
8006
8007     /* Build display for: Buffer Format */
8008
8009     BufferFormat = GBYTE(pd, offset);
8010
8011     if (tree) {
8012
8013       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
8014
8015     }
8016
8017     offset += 1; /* Skip Buffer Format */
8018
8019     /* Build display for: Data Length */
8020
8021     DataLength = GSHORT(pd, offset);
8022
8023     if (tree) {
8024
8025       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8026
8027     }
8028
8029     offset += 2; /* Skip Data Length */
8030
8031   }
8032
8033 }
8034
8035 void
8036 dissect_process_exit_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8037
8038 {
8039   guint8        WordCount;
8040   guint16       ByteCount;
8041
8042   if (dirn == 1) { /* Request(s) dissect code */
8043
8044     /* Build display for: Word Count (WCT) */
8045
8046     WordCount = GBYTE(pd, offset);
8047
8048     if (tree) {
8049
8050       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8051
8052     }
8053
8054     offset += 1; /* Skip Word Count (WCT) */
8055
8056     /* Build display for: Byte Count (BCC) */
8057
8058     ByteCount = GSHORT(pd, offset);
8059
8060     if (tree) {
8061
8062       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8063
8064     }
8065
8066     offset += 2; /* Skip Byte Count (BCC) */
8067
8068   }
8069
8070   if (dirn == 0) { /* Response(s) dissect code */
8071
8072     /* Build display for: Word Count (WCT) */
8073
8074     WordCount = GBYTE(pd, offset);
8075
8076     if (tree) {
8077
8078       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8079
8080     }
8081
8082     offset += 1; /* Skip Word Count (WCT) */
8083
8084     /* Build display for: Byte Count (BCC) */
8085
8086     ByteCount = GSHORT(pd, offset);
8087
8088     if (tree) {
8089
8090       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8091
8092     }
8093
8094     offset += 2; /* Skip Byte Count (BCC) */
8095
8096   }
8097
8098 }
8099
8100 void
8101 dissect_get_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8102
8103 {
8104   proto_tree    *Attributes_tree;
8105   proto_item    *ti;
8106   guint8        WordCount;
8107   guint8        BufferFormat;
8108   guint32       FileSize;
8109   guint16       Reserved5;
8110   guint16       Reserved4;
8111   guint16       Reserved3;
8112   guint16       Reserved2;
8113   guint16       Reserved1;
8114   guint16       LastWriteTime;
8115   guint16       LastWriteDate;
8116   guint16       ByteCount;
8117   guint16       Attributes;
8118   const char    *FileName;
8119
8120   if (dirn == 1) { /* Request(s) dissect code */
8121
8122     /* Build display for: Word Count (WCT) */
8123
8124     WordCount = GBYTE(pd, offset);
8125
8126     if (tree) {
8127
8128       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8129
8130     }
8131
8132     offset += 1; /* Skip Word Count (WCT) */
8133
8134     /* Build display for: Byte Count (BCC) */
8135
8136     ByteCount = GSHORT(pd, offset);
8137
8138     if (tree) {
8139
8140       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8141
8142     }
8143
8144     offset += 2; /* Skip Byte Count (BCC) */
8145
8146     /* Build display for: Buffer Format */
8147
8148     BufferFormat = GBYTE(pd, offset);
8149
8150     if (tree) {
8151
8152       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
8153
8154     }
8155
8156     offset += 1; /* Skip Buffer Format */
8157
8158     /* Build display for: File Name */
8159
8160     FileName = pd + offset;
8161
8162     if (tree) {
8163
8164       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
8165
8166     }
8167
8168     offset += strlen(FileName) + 1; /* Skip File Name */
8169
8170   }
8171
8172   if (dirn == 0) { /* Response(s) dissect code */
8173
8174     /* Build display for: Word Count (WCT) */
8175
8176     WordCount = GBYTE(pd, offset);
8177
8178     if (tree) {
8179
8180       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8181
8182     }
8183
8184     offset += 1; /* Skip Word Count (WCT) */
8185
8186     if (WordCount > 0) {
8187
8188       /* Build display for: Attributes */
8189
8190       Attributes = GSHORT(pd, offset);
8191
8192       if (tree) {
8193
8194         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
8195         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
8196         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8197                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
8198         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8199                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
8200         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8201                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
8202         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8203                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
8204         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8205                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
8206         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8207                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
8208         
8209       }
8210
8211       offset += 2; /* Skip Attributes */
8212
8213       /* Build display for: Last Write Time */
8214
8215       LastWriteTime = GSHORT(pd, offset);
8216
8217       if (tree) {
8218
8219       }
8220
8221       offset += 2; /* Skip Last Write Time */
8222
8223       /* Build display for: Last Write Date */
8224
8225       LastWriteDate = GSHORT(pd, offset);
8226
8227       if (tree) {
8228
8229         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
8230
8231         proto_tree_add_text(tree, NullTVB, offset - 2, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
8232
8233       }
8234
8235       offset += 2; /* Skip Last Write Date */
8236
8237       /* Build display for: File Size */
8238
8239       FileSize = GWORD(pd, offset);
8240
8241       if (tree) {
8242
8243         proto_tree_add_text(tree, NullTVB, offset, 4, "File Size: %u", FileSize);
8244
8245       }
8246
8247       offset += 4; /* Skip File Size */
8248
8249       /* Build display for: Reserved 1 */
8250
8251       Reserved1 = GSHORT(pd, offset);
8252
8253       if (tree) {
8254
8255         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
8256
8257       }
8258
8259       offset += 2; /* Skip Reserved 1 */
8260
8261       /* Build display for: Reserved 2 */
8262
8263       Reserved2 = GSHORT(pd, offset);
8264
8265       if (tree) {
8266
8267         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
8268
8269       }
8270
8271       offset += 2; /* Skip Reserved 2 */
8272
8273       /* Build display for: Reserved 3 */
8274
8275       Reserved3 = GSHORT(pd, offset);
8276
8277       if (tree) {
8278
8279         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
8280
8281       }
8282
8283       offset += 2; /* Skip Reserved 3 */
8284
8285       /* Build display for: Reserved 4 */
8286
8287       Reserved4 = GSHORT(pd, offset);
8288
8289       if (tree) {
8290
8291         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
8292
8293       }
8294
8295       offset += 2; /* Skip Reserved 4 */
8296
8297       /* Build display for: Reserved 5 */
8298
8299       Reserved5 = GSHORT(pd, offset);
8300
8301       if (tree) {
8302
8303         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
8304
8305       }
8306
8307       offset += 2; /* Skip Reserved 5 */
8308
8309     }
8310
8311     /* Build display for: Byte Count (BCC) */
8312
8313     ByteCount = GSHORT(pd, offset);
8314
8315     if (tree) {
8316
8317       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8318
8319     }
8320
8321     offset += 2; /* Skip Byte Count (BCC) */
8322
8323   }
8324
8325 }
8326
8327 void
8328 dissect_read_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8329
8330 {
8331   guint8        WordCount;
8332   guint32       Offset;
8333   guint16       Reserved4;
8334   guint16       Reserved3;
8335   guint16       Reserved2;
8336   guint16       Reserved1;
8337   guint16       Remaining;
8338   guint16       FID;
8339   guint16       DataLength;
8340   guint16       Count;
8341   guint16       ByteCount;
8342   guint16       BufferFormat;
8343
8344   if (dirn == 1) { /* Request(s) dissect code */
8345
8346     /* Build display for: Word Count (WCT) */
8347
8348     WordCount = GBYTE(pd, offset);
8349
8350     if (tree) {
8351
8352       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8353
8354     }
8355
8356     offset += 1; /* Skip Word Count (WCT) */
8357
8358     /* Build display for: FID */
8359
8360     FID = GSHORT(pd, offset);
8361
8362     if (tree) {
8363
8364       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8365
8366     }
8367
8368     offset += 2; /* Skip FID */
8369
8370     /* Build display for: Count */
8371
8372     Count = GSHORT(pd, offset);
8373
8374     if (tree) {
8375
8376       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8377
8378     }
8379
8380     offset += 2; /* Skip Count */
8381
8382     /* Build display for: Offset */
8383
8384     Offset = GWORD(pd, offset);
8385
8386     if (tree) {
8387
8388       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
8389
8390     }
8391
8392     offset += 4; /* Skip Offset */
8393
8394     /* Build display for: Remaining */
8395
8396     Remaining = GSHORT(pd, offset);
8397
8398     if (tree) {
8399
8400       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
8401
8402     }
8403
8404     offset += 2; /* Skip Remaining */
8405
8406     /* Build display for: Byte Count (BCC) */
8407
8408     ByteCount = GSHORT(pd, offset);
8409
8410     if (tree) {
8411
8412       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8413
8414     }
8415
8416     offset += 2; /* Skip Byte Count (BCC) */
8417
8418   }
8419
8420   if (dirn == 0) { /* Response(s) dissect code */
8421
8422     /* Build display for: Word Count (WCT) */
8423
8424     WordCount = GBYTE(pd, offset);
8425
8426     if (tree) {
8427
8428       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8429
8430     }
8431
8432     offset += 1; /* Skip Word Count (WCT) */
8433
8434     if (WordCount > 0) {
8435
8436       /* Build display for: Count */
8437
8438       Count = GSHORT(pd, offset);
8439
8440       if (tree) {
8441
8442         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8443
8444       }
8445
8446       offset += 2; /* Skip Count */
8447
8448       /* Build display for: Reserved 1 */
8449
8450       Reserved1 = GSHORT(pd, offset);
8451
8452       if (tree) {
8453
8454         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
8455
8456       }
8457
8458       offset += 2; /* Skip Reserved 1 */
8459
8460       /* Build display for: Reserved 2 */
8461
8462       Reserved2 = GSHORT(pd, offset);
8463
8464       if (tree) {
8465
8466         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
8467
8468       }
8469
8470       offset += 2; /* Skip Reserved 2 */
8471
8472       /* Build display for: Reserved 3 */
8473
8474       Reserved3 = GSHORT(pd, offset);
8475
8476       if (tree) {
8477
8478         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
8479
8480       }
8481
8482       offset += 2; /* Skip Reserved 3 */
8483
8484       /* Build display for: Reserved 4 */
8485
8486       Reserved4 = GSHORT(pd, offset);
8487
8488       if (tree) {
8489
8490         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
8491
8492       }
8493
8494       offset += 2; /* Skip Reserved 4 */
8495
8496     }
8497     
8498     /* Build display for: Byte Count (BCC) */
8499     
8500     ByteCount = GSHORT(pd, offset);
8501       
8502     if (tree) {
8503
8504       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8505
8506     }
8507
8508     offset += 2; /* Skip Byte Count (BCC) */
8509
8510     /* Build display for: Buffer Format */
8511
8512     BufferFormat = GSHORT(pd, offset);
8513
8514     if (tree) {
8515
8516       proto_tree_add_text(tree, NullTVB, offset, 2, "Buffer Format: %u", BufferFormat);
8517
8518     }
8519
8520     offset += 2; /* Skip Buffer Format */
8521
8522     /* Build display for: Data Length */
8523
8524     DataLength = GSHORT(pd, offset);
8525
8526     if (tree) {
8527
8528       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8529
8530     }
8531
8532     offset += 2; /* Skip Data Length */
8533
8534   }
8535
8536 }
8537
8538 void
8539 dissect_write_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8540
8541 {
8542   proto_tree    *WriteMode_tree;
8543   proto_item    *ti;
8544   guint8        WordCount;
8545   guint8        Pad;
8546   guint32       Timeout;
8547   guint32       ResponseMask;
8548   guint32       RequestMask;
8549   guint16       WriteMode;
8550   guint16       Reserved1;
8551   guint16       FID;
8552   guint16       DataOffset;
8553   guint16       DataLength;
8554   guint16       Count;
8555   guint16       ByteCount;
8556
8557   if (dirn == 1) { /* Request(s) dissect code */
8558
8559     /* Build display for: Word Count (WCT) */
8560
8561     WordCount = GBYTE(pd, offset);
8562
8563     if (tree) {
8564
8565       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8566
8567     }
8568
8569     offset += 1; /* Skip Word Count (WCT) */
8570
8571     /* Build display for: FID */
8572
8573     FID = GSHORT(pd, offset);
8574
8575     if (tree) {
8576
8577       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8578
8579     }
8580
8581     offset += 2; /* Skip FID */
8582
8583     /* Build display for: Count */
8584
8585     Count = GSHORT(pd, offset);
8586
8587     if (tree) {
8588
8589       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8590
8591     }
8592
8593     offset += 2; /* Skip Count */
8594
8595     /* Build display for: Reserved 1 */
8596
8597     Reserved1 = GSHORT(pd, offset);
8598
8599     if (tree) {
8600
8601       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
8602
8603     }
8604
8605     offset += 2; /* Skip Reserved 1 */
8606
8607     /* Build display for: Timeout */
8608
8609     Timeout = GWORD(pd, offset);
8610
8611     if (tree) {
8612
8613       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
8614
8615     }
8616
8617     offset += 4; /* Skip Timeout */
8618
8619     /* Build display for: WriteMode */
8620
8621     WriteMode = GSHORT(pd, offset);
8622
8623     if (tree) {
8624
8625       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
8626       WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
8627       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
8628                           decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
8629       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
8630                           decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining", "Dont return Remaining"));
8631       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
8632                           decode_boolean_bitfield(WriteMode, 0x40, 16, "Connectionless mode requested", "Connectionless mode not requested"));
8633     
8634 }
8635
8636     offset += 2; /* Skip WriteMode */
8637
8638     /* Build display for: Request Mask */
8639
8640     RequestMask = GWORD(pd, offset);
8641
8642     if (tree) {
8643
8644       proto_tree_add_text(tree, NullTVB, offset, 4, "Request Mask: %u", RequestMask);
8645
8646     }
8647
8648     offset += 4; /* Skip Request Mask */
8649
8650     /* Build display for: Data Length */
8651
8652     DataLength = GSHORT(pd, offset);
8653
8654     if (tree) {
8655
8656       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8657
8658     }
8659
8660     offset += 2; /* Skip Data Length */
8661
8662     /* Build display for: Data Offset */
8663
8664     DataOffset = GSHORT(pd, offset);
8665
8666     if (tree) {
8667
8668       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
8669
8670     }
8671
8672     offset += 2; /* Skip Data Offset */
8673
8674     /* Build display for: Byte Count (BCC) */
8675
8676     ByteCount = GSHORT(pd, offset);
8677
8678     if (tree) {
8679
8680       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8681
8682     }
8683
8684     offset += 2; /* Skip Byte Count (BCC) */
8685
8686     /* Build display for: Pad */
8687
8688     Pad = GBYTE(pd, offset);
8689
8690     if (tree) {
8691
8692       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
8693
8694     }
8695
8696     offset += 1; /* Skip Pad */
8697
8698   }
8699
8700   if (dirn == 0) { /* Response(s) dissect code */
8701
8702     /* Build display for: Word Count (WCT) */
8703
8704     WordCount = GBYTE(pd, offset);
8705
8706     if (tree) {
8707
8708       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8709
8710     }
8711
8712     offset += 1; /* Skip Word Count (WCT) */
8713
8714     if (WordCount > 0) {
8715
8716       /* Build display for: Response Mask */
8717
8718       ResponseMask = GWORD(pd, offset);
8719
8720       if (tree) {
8721
8722         proto_tree_add_text(tree, NullTVB, offset, 4, "Response Mask: %u", ResponseMask);
8723
8724       }
8725
8726       offset += 4; /* Skip Response Mask */
8727
8728       /* Build display for: Byte Count (BCC) */
8729
8730       ByteCount = GSHORT(pd, offset);
8731
8732       if (tree) {
8733
8734         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8735
8736       }
8737
8738     }
8739
8740     offset += 2; /* Skip Byte Count (BCC) */
8741
8742   }
8743
8744 }
8745
8746 void
8747 dissect_find_close2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8748
8749 {
8750   guint8        WordCount;
8751   guint8        ByteCount;
8752   guint16       FID;
8753
8754   if (dirn == 1) { /* Request(s) dissect code */
8755
8756     /* Build display for: Word Count (WTC) */
8757
8758     WordCount = GBYTE(pd, offset);
8759
8760     if (tree) {
8761
8762       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WTC): %u", WordCount);
8763
8764     }
8765
8766     offset += 1; /* Skip Word Count (WTC) */
8767
8768     /* Build display for: FID */
8769
8770     FID = GSHORT(pd, offset);
8771
8772     if (tree) {
8773
8774       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8775
8776     }
8777
8778     offset += 2; /* Skip FID */
8779
8780     /* Build display for: Byte Count (BCC) */
8781
8782     ByteCount = GSHORT(pd, offset);
8783
8784     if (tree) {
8785
8786       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8787
8788     }
8789
8790     offset += 2; /* Skip Byte Count (BCC) */
8791
8792   }
8793
8794   if (dirn == 0) { /* Response(s) dissect code */
8795
8796     /* Build display for: Word Count (WCT) */
8797
8798     WordCount = GBYTE(pd, offset);
8799
8800     if (tree) {
8801
8802       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8803
8804     }
8805
8806     offset += 1; /* Skip Word Count (WCT) */
8807
8808     /* Build display for: Byte Count (BCC) */
8809
8810     ByteCount = GBYTE(pd, offset);
8811
8812     if (tree) {
8813
8814       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
8815
8816     }
8817
8818     offset += 1; /* Skip Byte Count (BCC) */
8819
8820   }
8821
8822 }
8823
8824 char *trans2_cmd_names[] = {
8825   "TRANS2_OPEN",
8826   "TRANS2_FIND_FIRST2",
8827   "TRANS2_FIND_NEXT2",
8828   "TRANS2_QUERY_FS_INFORMATION",
8829   "no such command",
8830   "TRANS2_QUERY_PATH_INFORMATION",
8831   "TRANS2_SET_PATH_INFORMATION",
8832   "TRANS2_QUERY_FILE_INFORMATION",
8833   "TRANS2_SET_FILE_INFORMATION",
8834   "TRANS2_FSCTL",
8835   "TRANS2_IOCTL2",
8836   "TRANS2_FIND_NOTIFY_FIRST",
8837   "TRANS2_FIND_NOTIFY_NEXT",
8838   "TRANS2_CREATE_DIRECTORY",
8839   "TRANS2_SESSION_SETUP",
8840   "TRANS2_GET_DFS_REFERRAL",
8841   "no such command",
8842   "TRANS2_REPORT_DFS_INCONSISTENCY"};
8843
8844 char *decode_trans2_name(int code)
8845 {
8846
8847   if (code > 17 || code < 0) {
8848
8849     return("no such command");
8850
8851   }
8852
8853   return trans2_cmd_names[code];
8854
8855 }
8856
8857
8858 void
8859 dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8860
8861 {
8862   proto_tree    *Flags_tree;
8863   proto_item    *ti;
8864   guint8        WordCount;
8865   guint8        SetupCount;
8866   guint8        Reserved3;
8867   guint8        Reserved1;
8868   guint8        MaxSetupCount;
8869   guint8        Data;
8870   guint32       Timeout;
8871   guint16       TotalParameterCount;
8872   guint16       TotalDataCount;
8873   guint16       Setup = 0;
8874   guint16       Reserved2;
8875   guint16       ParameterOffset;
8876   guint16       ParameterDisplacement;
8877   guint16       ParameterCount;
8878   guint16       MaxParameterCount;
8879   guint16       MaxDataCount;
8880   guint16       Flags;
8881   guint16       DataOffset;
8882   guint16       DataDisplacement;
8883   guint16       DataCount;
8884   guint16       ByteCount;
8885   conversation_t *conversation;
8886   struct smb_request_key      request_key, *new_request_key;
8887   struct smb_request_val      *request_val;
8888
8889   /*
8890    * Find out what conversation this packet is part of.
8891    * XXX - this should really be done by the transport-layer protocol,
8892    * although for connectionless transports, we may not want to do that
8893    * unless we know some higher-level protocol will want it - or we
8894    * may want to do it, so you can say e.g. "show only the packets in
8895    * this UDP 'connection'".
8896    *
8897    * Note that we don't have to worry about the direction this packet
8898    * was going - the conversation code handles that for us, treating
8899    * packets from A:X to B:Y as being part of the same conversation as
8900    * packets from B:Y to A:X.
8901    */
8902   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
8903                                 pi.srcport, pi.destport, 0);
8904   if (conversation == NULL) {
8905     /* It's not part of any conversation - create a new one. */
8906     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
8907                                 pi.srcport, pi.destport, NULL, 0);
8908   }
8909
8910   si.conversation = conversation;  /* Save this for later */
8911
8912   /*
8913    * Check for and insert entry in request hash table if does not exist
8914    */
8915   request_key.conversation = conversation->index;
8916   request_key.mid          = si.mid;
8917
8918   request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
8919
8920   if (!request_val) { /* Create one */
8921
8922     new_request_key = g_mem_chunk_alloc(smb_request_keys);
8923     new_request_key -> conversation = conversation->index;
8924     new_request_key -> mid          = si.mid;
8925
8926     request_val = g_mem_chunk_alloc(smb_request_vals);
8927     request_val -> mid = si.mid;
8928     request_val -> last_transact2_command = 0xFFFF;
8929
8930     g_hash_table_insert(smb_request_hash, new_request_key, request_val);
8931     
8932   }
8933   else { /* Update the transact request */
8934
8935     request_val -> mid = si.mid;
8936
8937   }
8938
8939   si.request_val = request_val;  /* Save this for later */
8940
8941
8942   if (dirn == 1) { /* Request(s) dissect code */
8943   
8944     /* Build display for: Word Count (WCT) */
8945
8946     WordCount = GBYTE(pd, offset);
8947
8948     if (tree) {
8949
8950       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8951
8952     }
8953
8954     offset += 1; /* Skip Word Count (WCT) */
8955
8956     /* Build display for: Total Parameter Count */
8957
8958     TotalParameterCount = GSHORT(pd, offset);
8959
8960     if (tree) {
8961
8962       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
8963
8964     }
8965
8966     offset += 2; /* Skip Total Parameter Count */
8967
8968     /* Build display for: Total Data Count */
8969
8970     TotalDataCount = GSHORT(pd, offset);
8971
8972     if (tree) {
8973
8974       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
8975
8976     }
8977
8978     offset += 2; /* Skip Total Data Count */
8979
8980     /* Build display for: Max Parameter Count */
8981
8982     MaxParameterCount = GSHORT(pd, offset);
8983
8984     if (tree) {
8985
8986       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
8987
8988     }
8989
8990     offset += 2; /* Skip Max Parameter Count */
8991
8992     /* Build display for: Max Data Count */
8993
8994     MaxDataCount = GSHORT(pd, offset);
8995
8996     if (tree) {
8997
8998       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
8999
9000     }
9001
9002     offset += 2; /* Skip Max Data Count */
9003
9004     /* Build display for: Max Setup Count */
9005
9006     MaxSetupCount = GBYTE(pd, offset);
9007
9008     if (tree) {
9009
9010       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
9011
9012     }
9013
9014     offset += 1; /* Skip Max Setup Count */
9015
9016     /* Build display for: Reserved1 */
9017
9018     Reserved1 = GBYTE(pd, offset);
9019
9020     if (tree) {
9021
9022       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
9023
9024     }
9025
9026     offset += 1; /* Skip Reserved1 */
9027
9028     /* Build display for: Flags */
9029
9030     Flags = GSHORT(pd, offset);
9031
9032     if (tree) {
9033
9034       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
9035       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
9036       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9037                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
9038       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9039                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
9040     
9041 }
9042
9043     offset += 2; /* Skip Flags */
9044
9045     /* Build display for: Timeout */
9046
9047     Timeout = GWORD(pd, offset);
9048
9049     if (tree) {
9050
9051       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
9052
9053     }
9054
9055     offset += 4; /* Skip Timeout */
9056
9057     /* Build display for: Reserved2 */
9058
9059     Reserved2 = GSHORT(pd, offset);
9060
9061     if (tree) {
9062
9063       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9064
9065     }
9066
9067     offset += 2; /* Skip Reserved2 */
9068
9069     /* Build display for: Parameter Count */
9070
9071     ParameterCount = GSHORT(pd, offset);
9072
9073     if (tree) {
9074
9075       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9076
9077     }
9078
9079     offset += 2; /* Skip Parameter Count */
9080
9081     /* Build display for: Parameter Offset */
9082
9083     ParameterOffset = GSHORT(pd, offset);
9084
9085     if (tree) {
9086
9087       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9088
9089     }
9090
9091     offset += 2; /* Skip Parameter Offset */
9092
9093     /* Build display for: Data Count */
9094
9095     DataCount = GSHORT(pd, offset);
9096
9097     if (tree) {
9098
9099       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9100
9101     }
9102
9103     offset += 2; /* Skip Data Count */
9104
9105     /* Build display for: Data Offset */
9106
9107     DataOffset = GSHORT(pd, offset);
9108
9109     if (tree) {
9110
9111       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9112
9113     }
9114
9115     offset += 2; /* Skip Data Offset */
9116
9117     /* Build display for: Setup Count */
9118
9119     SetupCount = GBYTE(pd, offset);
9120
9121     if (tree) {
9122
9123       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9124
9125     }
9126
9127     offset += 1; /* Skip Setup Count */
9128
9129     /* Build display for: Reserved3 */
9130
9131     Reserved3 = GBYTE(pd, offset);
9132
9133     if (tree) {
9134
9135       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9136
9137     }
9138
9139     offset += 1; /* Skip Reserved3 */
9140
9141     /* Build display for: Setup */
9142
9143     if (SetupCount > 0) {
9144
9145       int i = SetupCount;
9146
9147       Setup = GSHORT(pd, offset);
9148
9149       request_val -> last_transact2_command = Setup;  /* Save for later */
9150
9151       if (check_col(fd, COL_INFO)) {
9152
9153         col_add_fstr(fd, COL_INFO, "%s %s", decode_trans2_name(Setup), (dirn ? "Request" : "Response"));
9154
9155       }
9156
9157       for (i = 1; i <= SetupCount; i++) {
9158         int Setup1;
9159
9160         Setup1 = GSHORT(pd, offset);
9161
9162         if (tree) {
9163
9164           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup1);
9165
9166         }
9167
9168         offset += 2; /* Skip Setup */
9169
9170       }
9171
9172     }
9173
9174     /* Build display for: Byte Count (BCC) */
9175
9176     ByteCount = GSHORT(pd, offset);
9177
9178     if (tree) {
9179
9180       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9181
9182     }
9183
9184     offset += 2; /* Skip Byte Count (BCC) */
9185
9186     /* Build display for: Transact Name */
9187
9188     if (tree) {
9189
9190       proto_tree_add_text(tree, NullTVB, offset, 2, "Transact Name: %s", decode_trans2_name(Setup));
9191
9192     }
9193
9194     if (offset < (SMB_offset + ParameterOffset)) {
9195
9196       int pad1Count = SMB_offset + ParameterOffset - offset;
9197
9198       /* Build display for: Pad1 */
9199
9200       if (tree) {
9201
9202         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s", format_text(pd + offset, pad1Count));
9203       }
9204
9205       offset += pad1Count; /* Skip Pad1 */
9206
9207     }
9208
9209     if (ParameterCount > 0) {
9210
9211       /* Build display for: Parameters */
9212
9213       if (tree) {
9214
9215         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset, ParameterCount, "Parameters: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
9216
9217       }
9218
9219       offset += ParameterCount; /* Skip Parameters */
9220
9221     }
9222
9223     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
9224
9225       int pad2Count = SMB_offset + DataOffset - offset;
9226         
9227       /* Build display for: Pad2 */
9228
9229       if (tree) {
9230
9231         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s", format_text(pd + offset, pad2Count));
9232
9233       }
9234
9235       offset += pad2Count; /* Skip Pad2 */
9236
9237     }
9238
9239     if (DataCount > 0) {
9240
9241       /* Build display for: Data */
9242
9243       Data = GBYTE(pd, offset);
9244
9245       if (tree) {
9246
9247         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset, DataCount, "Data: %s", format_text(&pd[offset], DataCount));
9248
9249       }
9250
9251       offset += DataCount; /* Skip Data */
9252
9253     }
9254   }
9255
9256   if (dirn == 0) { /* Response(s) dissect code */
9257
9258     /* Pick up the last transact2 command and put it in the right places */
9259
9260     if (check_col(fd, COL_INFO)) {
9261
9262       col_add_fstr(fd, COL_INFO, "%s %s", decode_trans2_name(request_val -> last_transact2_command), "response");
9263
9264     }
9265
9266     /* Build display for: Word Count (WCT) */
9267
9268     WordCount = GBYTE(pd, offset);
9269
9270     if (tree) {
9271
9272       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9273
9274     }
9275
9276     offset += 1; /* Skip Word Count (WCT) */
9277
9278     /* Build display for: Total Parameter Count */
9279
9280     TotalParameterCount = GSHORT(pd, offset);
9281
9282     if (tree) {
9283
9284       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9285
9286     }
9287
9288     offset += 2; /* Skip Total Parameter Count */
9289
9290     /* Build display for: Total Data Count */
9291
9292     TotalDataCount = GSHORT(pd, offset);
9293
9294     if (tree) {
9295
9296       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
9297
9298     }
9299
9300     offset += 2; /* Skip Total Data Count */
9301
9302     /* Build display for: Reserved2 */
9303
9304     Reserved2 = GSHORT(pd, offset);
9305
9306     if (tree) {
9307
9308       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9309
9310     }
9311
9312     offset += 2; /* Skip Reserved2 */
9313
9314     /* Build display for: Parameter Count */
9315
9316     ParameterCount = GSHORT(pd, offset);
9317
9318     if (tree) {
9319
9320       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9321
9322     }
9323
9324     offset += 2; /* Skip Parameter Count */
9325
9326     /* Build display for: Parameter Offset */
9327
9328     ParameterOffset = GSHORT(pd, offset);
9329
9330     if (tree) {
9331
9332       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9333
9334     }
9335
9336     offset += 2; /* Skip Parameter Offset */
9337
9338     /* Build display for: Parameter Displacement */
9339
9340     ParameterDisplacement = GSHORT(pd, offset);
9341
9342     if (tree) {
9343
9344       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
9345
9346     }
9347
9348     offset += 2; /* Skip Parameter Displacement */
9349
9350     /* Build display for: Data Count */
9351
9352     DataCount = GSHORT(pd, offset);
9353
9354     if (tree) {
9355
9356       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9357
9358     }
9359
9360     offset += 2; /* Skip Data Count */
9361
9362     /* Build display for: Data Offset */
9363
9364     DataOffset = GSHORT(pd, offset);
9365
9366     if (tree) {
9367
9368       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9369
9370     }
9371
9372     offset += 2; /* Skip Data Offset */
9373
9374     /* Build display for: Data Displacement */
9375
9376     DataDisplacement = GSHORT(pd, offset);
9377
9378     if (tree) {
9379
9380       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
9381
9382     }
9383
9384     offset += 2; /* Skip Data Displacement */
9385
9386     /* Build display for: Setup Count */
9387
9388     SetupCount = GBYTE(pd, offset);
9389
9390     if (tree) {
9391
9392       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9393
9394     }
9395
9396     offset += 1; /* Skip Setup Count */
9397
9398     /* Build display for: Reserved3 */
9399
9400     Reserved3 = GBYTE(pd, offset);
9401
9402     if (tree) {
9403
9404       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9405
9406     }
9407
9408     offset += 1; /* Skip Reserved3 */
9409
9410     if (SetupCount > 0) {
9411
9412       int i = SetupCount;
9413
9414       Setup = GSHORT(pd, offset);
9415
9416       for (i = 1; i <= SetupCount; i++) {
9417         
9418         Setup = GSHORT(pd, offset);
9419
9420         if (tree) {
9421
9422           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
9423
9424         }
9425
9426         offset += 2; /* Skip Setup */
9427
9428       }
9429     }
9430
9431     /* Build display for: Byte Count (BCC) */
9432
9433     ByteCount = GSHORT(pd, offset);
9434
9435     if (tree) {
9436
9437       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9438
9439     }
9440
9441     offset += 2; /* Skip Byte Count (BCC) */
9442
9443     if (offset < (SMB_offset + ParameterOffset)) {
9444
9445       int pad1Count = SMB_offset + ParameterOffset - offset;
9446
9447       /* Build display for: Pad1 */
9448
9449       if (tree) {
9450
9451         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s", format_text(pd + offset, pad1Count));
9452       }
9453
9454       offset += pad1Count; /* Skip Pad1 */
9455
9456     }
9457
9458     /* Build display for: Parameter */
9459
9460     if (ParameterCount > 0) {
9461
9462       if (tree) {
9463
9464         proto_tree_add_text(tree, NullTVB, offset, ParameterCount, "Parameter: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
9465
9466       }
9467
9468       offset += ParameterCount; /* Skip Parameter */
9469
9470     }
9471
9472     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
9473
9474       int pad2Count = SMB_offset + DataOffset - offset;
9475         
9476       /* Build display for: Pad2 */
9477
9478       if (tree) {
9479
9480         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s", format_text(pd + offset, pad2Count));
9481
9482       }
9483
9484       offset += pad2Count; /* Skip Pad2 */
9485
9486     }
9487
9488     /* Build display for: Data */
9489
9490     if (DataCount > 0) {
9491
9492       if (tree) {
9493
9494         proto_tree_add_text(tree, NullTVB, offset, DataCount, "Data: %s", format_text(pd + SMB_offset + DataOffset, DataCount));
9495
9496       }
9497
9498       offset += DataCount; /* Skip Data */
9499
9500     }
9501
9502   }
9503
9504 }
9505
9506
9507 void 
9508 dissect_transact_params(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn, int DataOffset, int DataCount, int ParameterOffset, int ParameterCount, int SetupAreaOffset, int SetupCount, const char *TransactName)
9509 {
9510   char             *TransactNameCopy;
9511   char             *trans_type = NULL, *trans_cmd, *loc_of_slash = NULL;
9512   int              index;
9513   const gchar      *Data;
9514
9515   if (!TransactName)
9516           return;
9517
9518   TransactNameCopy = g_malloc(TransactName ? strlen(TransactName) + 1 : 1);
9519
9520   /* Should check for error here ... */
9521
9522   strcpy(TransactNameCopy, TransactName ? TransactName : "");
9523   if (TransactNameCopy[0] == '\\') {
9524     trans_type = TransactNameCopy + 1;  /* Skip the slash */
9525     loc_of_slash = trans_type ? strchr(trans_type, '\\') : NULL;
9526   }
9527
9528   if (loc_of_slash) {
9529     index = loc_of_slash - trans_type;  /* Make it a real index */
9530     trans_cmd = trans_type + index + 1;
9531     trans_type[index] = '\0';
9532   }
9533   else
9534     trans_cmd = NULL;
9535
9536   if ((trans_cmd == NULL) ||
9537       (((trans_type == NULL || strcmp(trans_type, "MAILSLOT") != 0) ||
9538        !dissect_mailslot_smb(pd, SetupAreaOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, trans_cmd, SMB_offset + DataOffset, DataCount, SMB_offset + ParameterOffset, ParameterCount)) &&
9539       ((trans_type == NULL || strcmp(trans_type, "PIPE") != 0) ||
9540        !dissect_pipe_smb(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, trans_cmd, DataOffset, DataCount, ParameterOffset, ParameterCount)))) {
9541     
9542     if (ParameterCount > 0) {
9543
9544       /* Build display for: Parameters */
9545       
9546       if (tree) {
9547
9548         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset, ParameterCount, "Parameters: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
9549           
9550       }
9551         
9552       offset = SMB_offset + ParameterOffset + ParameterCount; /* Skip Parameters */
9553
9554     }
9555
9556     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
9557
9558       int pad2Count = SMB_offset + DataOffset - offset;
9559         
9560       /* Build display for: Pad2 */
9561
9562       if (tree) {
9563
9564         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s", format_text(pd + offset, pad2Count));
9565
9566       }
9567
9568       offset += pad2Count; /* Skip Pad2 */
9569
9570     }
9571
9572     if (DataCount > 0) {
9573
9574       /* Build display for: Data */
9575
9576       Data = pd + SMB_offset + DataOffset;
9577
9578       if (tree) {
9579
9580         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset, DataCount, "Data: %s", format_text(pd + SMB_offset + DataOffset, DataCount));
9581
9582       }
9583
9584       offset += DataCount; /* Skip Data */
9585
9586     }
9587   }
9588
9589 }
9590
9591 void
9592 dissect_transact_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
9593
9594 {
9595   proto_tree    *Flags_tree;
9596   proto_item    *ti;
9597   guint8        WordCount;
9598   guint8        SetupCount;
9599   guint8        Reserved3;
9600   guint8        Reserved1;
9601   guint8        MaxSetupCount;
9602   guint32       Timeout;
9603   guint16       TotalParameterCount;
9604   guint16       TotalDataCount;
9605   guint16       Setup = 0;
9606   guint16       Reserved2;
9607   guint16       ParameterOffset;
9608   guint16       ParameterDisplacement;
9609   guint16       ParameterCount;
9610   guint16       MaxParameterCount;
9611   guint16       MaxDataCount;
9612   guint16       Flags;
9613   guint16       DataOffset;
9614   guint16       DataDisplacement;
9615   guint16       DataCount;
9616   guint16       ByteCount;
9617   int           TNlen;
9618   const char    *TransactName;
9619   conversation_t *conversation;
9620   struct smb_request_key   request_key, *new_request_key;
9621   struct smb_request_val   *request_val;
9622  
9623   guint16       SetupAreaOffset;
9624
9625
9626   /*
9627    * Find out what conversation this packet is part of
9628    */
9629
9630   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
9631                                    pi.srcport, pi.destport, 0);
9632
9633   if (conversation == NULL) {  /* Create a new conversation */
9634
9635     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
9636                                     pi.srcport, pi.destport, NULL, 0);
9637
9638   }
9639
9640   si.conversation = conversation;  /* Save this */
9641
9642   /*
9643    * Check for and insert entry in request hash table if does not exist
9644    */
9645   request_key.conversation = conversation->index;
9646   request_key.mid          = si.mid;
9647
9648   request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
9649
9650   if (!request_val) { /* Create one */
9651
9652     new_request_key = g_mem_chunk_alloc(smb_request_keys);
9653     new_request_key -> conversation = conversation -> index;
9654     new_request_key -> mid          = si.mid;
9655
9656     request_val = g_mem_chunk_alloc(smb_request_vals);
9657     request_val -> mid = si.mid;
9658     request_val -> last_transact_command = NULL;
9659     request_val -> last_param_descrip = NULL;
9660     request_val -> last_data_descrip = NULL;
9661
9662     g_hash_table_insert(smb_request_hash, new_request_key, request_val);
9663
9664   }
9665
9666   si.request_val = request_val;  /* Save this for later */
9667
9668   if (dirn == 1) { /* Request(s) dissect code */
9669
9670     /* Build display for: Word Count (WCT) */
9671
9672     WordCount = GBYTE(pd, offset);
9673
9674     if (tree) {
9675
9676       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9677
9678     }
9679
9680     offset += 1; /* Skip Word Count (WCT) */
9681
9682     /* Build display for: Total Parameter Count */
9683
9684     TotalParameterCount = GSHORT(pd, offset);
9685
9686     if (tree) {
9687
9688       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9689
9690     }
9691
9692     offset += 2; /* Skip Total Parameter Count */
9693
9694     /* Build display for: Total Data Count */
9695
9696     TotalDataCount = GSHORT(pd, offset);
9697
9698     if (tree) {
9699
9700       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
9701
9702     }
9703
9704     offset += 2; /* Skip Total Data Count */
9705
9706     /* Build display for: Max Parameter Count */
9707
9708     MaxParameterCount = GSHORT(pd, offset);
9709
9710     if (tree) {
9711
9712       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
9713
9714     }
9715
9716     offset += 2; /* Skip Max Parameter Count */
9717
9718     /* Build display for: Max Data Count */
9719
9720     MaxDataCount = GSHORT(pd, offset);
9721
9722     if (tree) {
9723
9724       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
9725
9726     }
9727
9728     offset += 2; /* Skip Max Data Count */
9729
9730     /* Build display for: Max Setup Count */
9731
9732     MaxSetupCount = GBYTE(pd, offset);
9733
9734     if (tree) {
9735
9736       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
9737
9738     }
9739
9740     offset += 1; /* Skip Max Setup Count */
9741
9742     /* Build display for: Reserved1 */
9743
9744     Reserved1 = GBYTE(pd, offset);
9745
9746     if (tree) {
9747
9748       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
9749
9750     }
9751
9752     offset += 1; /* Skip Reserved1 */
9753
9754     /* Build display for: Flags */
9755
9756     Flags = GSHORT(pd, offset);
9757
9758     if (tree) {
9759
9760       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
9761       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
9762       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9763                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
9764       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9765                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
9766     
9767 }
9768
9769     offset += 2; /* Skip Flags */
9770
9771     /* Build display for: Timeout */
9772
9773     Timeout = GWORD(pd, offset);
9774
9775     if (tree) {
9776
9777       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
9778
9779     }
9780
9781     offset += 4; /* Skip Timeout */
9782
9783     /* Build display for: Reserved2 */
9784
9785     Reserved2 = GSHORT(pd, offset);
9786
9787     if (tree) {
9788
9789       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9790
9791     }
9792
9793     offset += 2; /* Skip Reserved2 */
9794
9795     /* Build display for: Parameter Count */
9796
9797     ParameterCount = GSHORT(pd, offset);
9798
9799     if (tree) {
9800
9801       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9802
9803     }
9804
9805     offset += 2; /* Skip Parameter Count */
9806
9807     /* Build display for: Parameter Offset */
9808
9809     ParameterOffset = GSHORT(pd, offset);
9810
9811     if (tree) {
9812
9813       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9814
9815     }
9816
9817     offset += 2; /* Skip Parameter Offset */
9818
9819     /* Build display for: Data Count */
9820
9821     DataCount = GSHORT(pd, offset);
9822
9823     if (tree) {
9824
9825       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9826
9827     }
9828
9829     offset += 2; /* Skip Data Count */
9830
9831     /* Build display for: Data Offset */
9832
9833     DataOffset = GSHORT(pd, offset);
9834
9835     if (tree) {
9836
9837       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9838
9839     }
9840
9841     offset += 2; /* Skip Data Offset */
9842
9843     /* Build display for: Setup Count */
9844
9845     SetupCount = GBYTE(pd, offset);
9846
9847     if (tree) {
9848
9849       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9850
9851     }
9852
9853     offset += 1; /* Skip Setup Count */
9854
9855     /* Build display for: Reserved3 */
9856
9857     Reserved3 = GBYTE(pd, offset);
9858
9859     if (tree) {
9860
9861       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9862     }
9863
9864     offset += 1; /* Skip Reserved3 */
9865  
9866     SetupAreaOffset = offset;
9867
9868     /* Build display for: Setup */
9869
9870     if (SetupCount > 0) {
9871
9872       int i = SetupCount;
9873
9874       Setup = GSHORT(pd, offset);
9875
9876       for (i = 1; i <= SetupCount; i++) {
9877         
9878         Setup = GSHORT(pd, offset);
9879
9880         if (tree) {
9881
9882           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
9883
9884         }
9885
9886         offset += 2; /* Skip Setup */
9887
9888       }
9889
9890     }
9891
9892     /* Build display for: Byte Count (BCC) */
9893
9894     ByteCount = GSHORT(pd, offset);
9895
9896     if (tree) {
9897
9898       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9899
9900     }
9901
9902     offset += 2; /* Skip Byte Count (BCC) */
9903
9904     /* Build display for: Transact Name */
9905
9906     /* Watch out for Unicode names */
9907
9908     if (si.unicode) {
9909
9910       if (offset % 2) offset++;   /* Looks like a pad byte there sometimes */
9911
9912       TransactName = unicode_to_str(pd + offset, &TNlen);
9913       TNlen += 2;
9914
9915     }
9916     else { 
9917       TransactName = pd + offset;
9918       TNlen = strlen(TransactName) + 1;
9919     }
9920
9921     if (request_val -> last_transact_command) g_free(request_val -> last_transact_command);
9922
9923     request_val -> last_transact_command = g_malloc(strlen(TransactName) + 1);
9924
9925     if (request_val -> last_transact_command) 
9926       strcpy(request_val -> last_transact_command, TransactName);
9927
9928     if (check_col(fd, COL_INFO)) {
9929
9930       col_add_fstr(fd, COL_INFO, "%s %s", TransactName, (dirn ? "Request" : "Response"));
9931
9932     }
9933
9934     if (tree) {
9935
9936       proto_tree_add_text(tree, NullTVB, offset, TNlen, "Transact Name: %s", TransactName);
9937
9938     }
9939
9940     offset += TNlen; /* Skip Transact Name */
9941     if (si.unicode) offset += 2;   /* There are two more extraneous bytes there*/
9942
9943     if (offset < (SMB_offset + ParameterOffset)) {
9944
9945       int pad1Count = SMB_offset + ParameterOffset - offset;
9946
9947       /* Build display for: Pad1 */
9948
9949       if (tree) {
9950
9951         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s", format_text(pd + offset, pad1Count));
9952       }
9953
9954       offset += pad1Count; /* Skip Pad1 */
9955
9956     }
9957
9958     /* Let's see if we can decode this */
9959
9960     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, DataOffset, DataCount, ParameterOffset, ParameterCount, SetupAreaOffset, SetupCount, TransactName);
9961
9962   }
9963
9964   if (dirn == 0) { /* Response(s) dissect code */
9965
9966     if (check_col(fd, COL_INFO)) {
9967       if ( request_val -> last_transact_command )
9968         col_add_fstr(fd, COL_INFO, "%s %s", request_val -> last_transact_command, "Response");
9969       else col_add_fstr(fd, COL_INFO, "Response to unknown message");
9970
9971     }
9972
9973     /* Build display for: Word Count (WCT) */
9974
9975     WordCount = GBYTE(pd, offset);
9976
9977     if (tree) {
9978
9979       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9980
9981     }
9982
9983     offset += 1; /* Skip Word Count (WCT) */
9984
9985     /* Build display for: Total Parameter Count */
9986
9987     TotalParameterCount = GSHORT(pd, offset);
9988
9989     if (tree) {
9990
9991       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9992
9993     }
9994
9995     offset += 2; /* Skip Total Parameter Count */
9996
9997     /* Build display for: Total Data Count */
9998
9999     TotalDataCount = GSHORT(pd, offset);
10000
10001     if (tree) {
10002
10003       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
10004
10005     }
10006
10007     offset += 2; /* Skip Total Data Count */
10008
10009     /* Build display for: Reserved2 */
10010
10011     Reserved2 = GSHORT(pd, offset);
10012
10013     if (tree) {
10014
10015       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
10016
10017     }
10018
10019     offset += 2; /* Skip Reserved2 */
10020
10021     /* Build display for: Parameter Count */
10022
10023     ParameterCount = GSHORT(pd, offset);
10024
10025     if (tree) {
10026
10027       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
10028
10029     }
10030
10031     offset += 2; /* Skip Parameter Count */
10032
10033     /* Build display for: Parameter Offset */
10034
10035     ParameterOffset = GSHORT(pd, offset);
10036
10037     if (tree) {
10038
10039       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
10040
10041     }
10042
10043     offset += 2; /* Skip Parameter Offset */
10044
10045     /* Build display for: Parameter Displacement */
10046
10047     ParameterDisplacement = GSHORT(pd, offset);
10048
10049     if (tree) {
10050
10051       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
10052
10053     }
10054
10055     offset += 2; /* Skip Parameter Displacement */
10056
10057     /* Build display for: Data Count */
10058
10059     DataCount = GSHORT(pd, offset);
10060
10061     if (tree) {
10062
10063       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
10064
10065     }
10066
10067     offset += 2; /* Skip Data Count */
10068
10069     /* Build display for: Data Offset */
10070
10071     DataOffset = GSHORT(pd, offset);
10072
10073     if (tree) {
10074
10075       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
10076
10077     }
10078
10079     offset += 2; /* Skip Data Offset */
10080
10081     /* Build display for: Data Displacement */
10082
10083     DataDisplacement = GSHORT(pd, offset);
10084
10085     if (tree) {
10086
10087       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
10088
10089     }
10090
10091     offset += 2; /* Skip Data Displacement */
10092
10093     /* Build display for: Setup Count */
10094
10095     SetupCount = GBYTE(pd, offset);
10096
10097     if (tree) {
10098
10099       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
10100
10101     }
10102
10103     offset += 1; /* Skip Setup Count */
10104
10105  
10106     /* Build display for: Reserved3 */
10107
10108     Reserved3 = GBYTE(pd, offset);
10109
10110     if (tree) {
10111
10112       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
10113
10114     }
10115
10116  
10117     offset += 1; /* Skip Reserved3 */
10118  
10119     SetupAreaOffset = offset;   
10120
10121     /* Build display for: Setup */
10122
10123     if (SetupCount > 0) {
10124
10125       int i = SetupCount;
10126
10127       Setup = GSHORT(pd, offset);
10128
10129       for (i = 1; i <= SetupCount; i++) {
10130         
10131         Setup = GSHORT(pd, offset);
10132
10133         if (tree) {
10134
10135           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
10136
10137         }
10138
10139         offset += 2; /* Skip Setup */
10140
10141       }
10142
10143     }
10144
10145     /* Build display for: Byte Count (BCC) */
10146
10147     ByteCount = GSHORT(pd, offset);
10148
10149     if (tree) {
10150
10151       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
10152
10153     }
10154
10155     offset += 2; /* Skip Byte Count (BCC) */
10156
10157     /* Build display for: Pad1 */
10158
10159     if (offset < (SMB_offset + ParameterOffset)) {
10160
10161       int pad1Count = SMB_offset + ParameterOffset - offset;
10162
10163       /* Build display for: Pad1 */
10164
10165       if (tree) {
10166
10167         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s", format_text(pd + offset, pad1Count));
10168       }
10169
10170       offset += pad1Count; /* Skip Pad1 */
10171
10172     }
10173
10174     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, DataOffset, DataCount, ParameterOffset, ParameterCount, SetupAreaOffset, SetupCount, si.request_val -> last_transact_command);
10175
10176   }
10177
10178 }
10179
10180
10181
10182
10183
10184 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int) = {
10185
10186   dissect_createdir_smb,    /* unknown SMB 0x00 */
10187   dissect_deletedir_smb,    /* unknown SMB 0x01 */
10188   dissect_unknown_smb,      /* SMBopen open a file */
10189   dissect_create_file_smb,  /* SMBcreate create a file */
10190   dissect_close_smb,        /* SMBclose close a file */
10191   dissect_flush_file_smb,   /* SMBflush flush a file */
10192   dissect_delete_file_smb,  /* SMBunlink delete a file */
10193   dissect_rename_file_smb,  /* SMBmv rename a file */
10194   dissect_get_file_attr_smb,/* SMBgetatr get file attributes */
10195   dissect_set_file_attr_smb,/* SMBsetatr set file attributes */
10196   dissect_read_file_smb,    /* SMBread read from a file */
10197   dissect_write_file_smb,   /* SMBwrite write to a file */
10198   dissect_lock_bytes_smb,   /* SMBlock lock a byte range */
10199   dissect_unlock_bytes_smb, /* SMBunlock unlock a byte range */
10200   dissect_create_temporary_file_smb,/* SMBctemp create a temporary file */
10201   dissect_unknown_smb,      /* SMBmknew make a new file */
10202   dissect_checkdir_smb,     /* SMBchkpth check a directory path */
10203   dissect_process_exit_smb,      /* SMBexit process exit */
10204   dissect_unknown_smb,      /* SMBlseek seek */
10205   dissect_lock_and_read_smb,/* SMBlockread Lock a range and read it */
10206   dissect_write_and_unlock_smb,/* SMBwriteunlock Unlock a range and then write */
10207   dissect_unknown_smb,      /* unknown SMB 0x15 */
10208   dissect_unknown_smb,      /* unknown SMB 0x16 */
10209   dissect_unknown_smb,      /* unknown SMB 0x17 */
10210   dissect_unknown_smb,      /* unknown SMB 0x18 */
10211   dissect_unknown_smb,      /* unknown SMB 0x19 */
10212   dissect_read_raw_smb,     /* SMBreadBraw read block raw */
10213   dissect_read_mpx_smb,     /* SMBreadBmpx read block multiplexed */
10214   dissect_unknown_smb,      /* SMBreadBs read block (secondary response) */
10215   dissect_write_raw_smb,    /* SMBwriteBraw write block raw */
10216   dissect_write_mpx_smb,    /* SMBwriteBmpx write block multiplexed */
10217   dissect_unknown_smb,      /* SMBwriteBs write block (secondary request) */
10218   dissect_unknown_smb,      /* SMBwriteC write complete response */
10219   dissect_unknown_smb,      /* unknown SMB 0x21 */
10220   dissect_set_info2_smb,    /* SMBsetattrE set file attributes expanded */
10221   dissect_query_info2_smb,  /* SMBgetattrE get file attributes expanded */
10222   dissect_locking_andx_smb, /* SMBlockingX lock/unlock byte ranges and X */
10223   dissect_transact_smb,      /* SMBtrans transaction - name, bytes in/out */
10224   dissect_unknown_smb,      /* SMBtranss transaction (secondary request/response) */
10225   dissect_unknown_smb,      /* SMBioctl IOCTL */
10226   dissect_unknown_smb,      /* SMBioctls IOCTL (secondary request/response) */
10227   dissect_unknown_smb,      /* SMBcopy copy */
10228   dissect_move_smb,      /* SMBmove move */
10229   dissect_unknown_smb,      /* SMBecho echo */
10230   dissect_unknown_smb,      /* SMBwriteclose write a file and then close it */
10231   dissect_open_andx_smb,      /* SMBopenX open and X */
10232   dissect_read_andx_smb,    /* SMBreadX read and X */
10233   dissect_unknown_smb,      /* SMBwriteX write and X */
10234   dissect_unknown_smb,      /* unknown SMB 0x30 */
10235   dissect_unknown_smb,      /* unknown SMB 0x31 */
10236   dissect_transact2_smb,    /* unknown SMB 0x32 */
10237   dissect_unknown_smb,      /* unknown SMB 0x33 */
10238   dissect_find_close2_smb,  /* unknown SMB 0x34 */
10239   dissect_unknown_smb,      /* unknown SMB 0x35 */
10240   dissect_unknown_smb,      /* unknown SMB 0x36 */
10241   dissect_unknown_smb,      /* unknown SMB 0x37 */
10242   dissect_unknown_smb,      /* unknown SMB 0x38 */
10243   dissect_unknown_smb,      /* unknown SMB 0x39 */
10244   dissect_unknown_smb,      /* unknown SMB 0x3a */
10245   dissect_unknown_smb,      /* unknown SMB 0x3b */
10246   dissect_unknown_smb,      /* unknown SMB 0x3c */
10247   dissect_unknown_smb,      /* unknown SMB 0x3d */
10248   dissect_unknown_smb,      /* unknown SMB 0x3e */
10249   dissect_unknown_smb,      /* unknown SMB 0x3f */
10250   dissect_unknown_smb,      /* unknown SMB 0x40 */
10251   dissect_unknown_smb,      /* unknown SMB 0x41 */
10252   dissect_unknown_smb,      /* unknown SMB 0x42 */
10253   dissect_unknown_smb,      /* unknown SMB 0x43 */
10254   dissect_unknown_smb,      /* unknown SMB 0x44 */
10255   dissect_unknown_smb,      /* unknown SMB 0x45 */
10256   dissect_unknown_smb,      /* unknown SMB 0x46 */
10257   dissect_unknown_smb,      /* unknown SMB 0x47 */
10258   dissect_unknown_smb,      /* unknown SMB 0x48 */
10259   dissect_unknown_smb,      /* unknown SMB 0x49 */
10260   dissect_unknown_smb,      /* unknown SMB 0x4a */
10261   dissect_unknown_smb,      /* unknown SMB 0x4b */
10262   dissect_unknown_smb,      /* unknown SMB 0x4c */
10263   dissect_unknown_smb,      /* unknown SMB 0x4d */
10264   dissect_unknown_smb,      /* unknown SMB 0x4e */
10265   dissect_unknown_smb,      /* unknown SMB 0x4f */
10266   dissect_unknown_smb,      /* unknown SMB 0x50 */
10267   dissect_unknown_smb,      /* unknown SMB 0x51 */
10268   dissect_unknown_smb,      /* unknown SMB 0x52 */
10269   dissect_unknown_smb,      /* unknown SMB 0x53 */
10270   dissect_unknown_smb,      /* unknown SMB 0x54 */
10271   dissect_unknown_smb,      /* unknown SMB 0x55 */
10272   dissect_unknown_smb,      /* unknown SMB 0x56 */
10273   dissect_unknown_smb,      /* unknown SMB 0x57 */
10274   dissect_unknown_smb,      /* unknown SMB 0x58 */
10275   dissect_unknown_smb,      /* unknown SMB 0x59 */
10276   dissect_unknown_smb,      /* unknown SMB 0x5a */
10277   dissect_unknown_smb,      /* unknown SMB 0x5b */
10278   dissect_unknown_smb,      /* unknown SMB 0x5c */
10279   dissect_unknown_smb,      /* unknown SMB 0x5d */
10280   dissect_unknown_smb,      /* unknown SMB 0x5e */
10281   dissect_unknown_smb,      /* unknown SMB 0x5f */
10282   dissect_unknown_smb,      /* unknown SMB 0x60 */
10283   dissect_unknown_smb,      /* unknown SMB 0x61 */
10284   dissect_unknown_smb,      /* unknown SMB 0x62 */
10285   dissect_unknown_smb,      /* unknown SMB 0x63 */
10286   dissect_unknown_smb,      /* unknown SMB 0x64 */
10287   dissect_unknown_smb,      /* unknown SMB 0x65 */
10288   dissect_unknown_smb,      /* unknown SMB 0x66 */
10289   dissect_unknown_smb,      /* unknown SMB 0x67 */
10290   dissect_unknown_smb,      /* unknown SMB 0x68 */
10291   dissect_unknown_smb,      /* unknown SMB 0x69 */
10292   dissect_unknown_smb,      /* unknown SMB 0x6a */
10293   dissect_unknown_smb,      /* unknown SMB 0x6b */
10294   dissect_unknown_smb,      /* unknown SMB 0x6c */
10295   dissect_unknown_smb,      /* unknown SMB 0x6d */
10296   dissect_unknown_smb,      /* unknown SMB 0x6e */
10297   dissect_unknown_smb,      /* unknown SMB 0x6f */
10298   dissect_treecon_smb,      /* SMBtcon tree connect */
10299   dissect_tdis_smb,         /* SMBtdis tree disconnect */
10300   dissect_negprot_smb,      /* SMBnegprot negotiate a protocol */
10301   dissect_ssetup_andx_smb,  /* SMBsesssetupX Session Set Up & X (including User Logon) */
10302   dissect_logoff_andx_smb,  /* SMBlogof Logoff & X */
10303   dissect_tcon_andx_smb,    /* SMBtconX tree connect and X */
10304   dissect_unknown_smb,      /* unknown SMB 0x76 */
10305   dissect_unknown_smb,      /* unknown SMB 0x77 */
10306   dissect_unknown_smb,      /* unknown SMB 0x78 */
10307   dissect_unknown_smb,      /* unknown SMB 0x79 */
10308   dissect_unknown_smb,      /* unknown SMB 0x7a */
10309   dissect_unknown_smb,      /* unknown SMB 0x7b */
10310   dissect_unknown_smb,      /* unknown SMB 0x7c */
10311   dissect_unknown_smb,      /* unknown SMB 0x7d */
10312   dissect_unknown_smb,      /* unknown SMB 0x7e */
10313   dissect_unknown_smb,      /* unknown SMB 0x7f */
10314   dissect_get_disk_attr_smb,/* SMBdskattr get disk attributes */
10315   dissect_search_dir_smb,   /* SMBsearch search a directory */
10316   dissect_unknown_smb,      /* SMBffirst find first */
10317   dissect_unknown_smb,      /* SMBfunique find unique */
10318   dissect_unknown_smb,      /* SMBfclose find close */
10319   dissect_unknown_smb,      /* unknown SMB 0x85 */
10320   dissect_unknown_smb,      /* unknown SMB 0x86 */
10321   dissect_unknown_smb,      /* unknown SMB 0x87 */
10322   dissect_unknown_smb,      /* unknown SMB 0x88 */
10323   dissect_unknown_smb,      /* unknown SMB 0x89 */
10324   dissect_unknown_smb,      /* unknown SMB 0x8a */
10325   dissect_unknown_smb,      /* unknown SMB 0x8b */
10326   dissect_unknown_smb,      /* unknown SMB 0x8c */
10327   dissect_unknown_smb,      /* unknown SMB 0x8d */
10328   dissect_unknown_smb,      /* unknown SMB 0x8e */
10329   dissect_unknown_smb,      /* unknown SMB 0x8f */
10330   dissect_unknown_smb,      /* unknown SMB 0x90 */
10331   dissect_unknown_smb,      /* unknown SMB 0x91 */
10332   dissect_unknown_smb,      /* unknown SMB 0x92 */
10333   dissect_unknown_smb,      /* unknown SMB 0x93 */
10334   dissect_unknown_smb,      /* unknown SMB 0x94 */
10335   dissect_unknown_smb,      /* unknown SMB 0x95 */
10336   dissect_unknown_smb,      /* unknown SMB 0x96 */
10337   dissect_unknown_smb,      /* unknown SMB 0x97 */
10338   dissect_unknown_smb,      /* unknown SMB 0x98 */
10339   dissect_unknown_smb,      /* unknown SMB 0x99 */
10340   dissect_unknown_smb,      /* unknown SMB 0x9a */
10341   dissect_unknown_smb,      /* unknown SMB 0x9b */
10342   dissect_unknown_smb,      /* unknown SMB 0x9c */
10343   dissect_unknown_smb,      /* unknown SMB 0x9d */
10344   dissect_unknown_smb,      /* unknown SMB 0x9e */
10345   dissect_unknown_smb,      /* unknown SMB 0x9f */
10346   dissect_unknown_smb,      /* unknown SMB 0xa0 */
10347   dissect_unknown_smb,      /* unknown SMB 0xa1 */
10348   dissect_unknown_smb,      /* unknown SMB 0xa2 */
10349   dissect_unknown_smb,      /* unknown SMB 0xa3 */
10350   dissect_unknown_smb,      /* unknown SMB 0xa4 */
10351   dissect_unknown_smb,      /* unknown SMB 0xa5 */
10352   dissect_unknown_smb,      /* unknown SMB 0xa6 */
10353   dissect_unknown_smb,      /* unknown SMB 0xa7 */
10354   dissect_unknown_smb,      /* unknown SMB 0xa8 */
10355   dissect_unknown_smb,      /* unknown SMB 0xa9 */
10356   dissect_unknown_smb,      /* unknown SMB 0xaa */
10357   dissect_unknown_smb,      /* unknown SMB 0xab */
10358   dissect_unknown_smb,      /* unknown SMB 0xac */
10359   dissect_unknown_smb,      /* unknown SMB 0xad */
10360   dissect_unknown_smb,      /* unknown SMB 0xae */
10361   dissect_unknown_smb,      /* unknown SMB 0xaf */
10362   dissect_unknown_smb,      /* unknown SMB 0xb0 */
10363   dissect_unknown_smb,      /* unknown SMB 0xb1 */
10364   dissect_unknown_smb,      /* unknown SMB 0xb2 */
10365   dissect_unknown_smb,      /* unknown SMB 0xb3 */
10366   dissect_unknown_smb,      /* unknown SMB 0xb4 */
10367   dissect_unknown_smb,      /* unknown SMB 0xb5 */
10368   dissect_unknown_smb,      /* unknown SMB 0xb6 */
10369   dissect_unknown_smb,      /* unknown SMB 0xb7 */
10370   dissect_unknown_smb,      /* unknown SMB 0xb8 */
10371   dissect_unknown_smb,      /* unknown SMB 0xb9 */
10372   dissect_unknown_smb,      /* unknown SMB 0xba */
10373   dissect_unknown_smb,      /* unknown SMB 0xbb */
10374   dissect_unknown_smb,      /* unknown SMB 0xbc */
10375   dissect_unknown_smb,      /* unknown SMB 0xbd */
10376   dissect_unknown_smb,      /* unknown SMB 0xbe */
10377   dissect_unknown_smb,      /* unknown SMB 0xbf */
10378   dissect_unknown_smb,      /* SMBsplopen open a print spool file */
10379   dissect_write_print_file_smb,/* SMBsplwr write to a print spool file */
10380   dissect_close_print_file_smb,/* SMBsplclose close a print spool file */
10381   dissect_get_print_queue_smb, /* SMBsplretq return print queue */
10382   dissect_unknown_smb,      /* unknown SMB 0xc4 */
10383   dissect_unknown_smb,      /* unknown SMB 0xc5 */
10384   dissect_unknown_smb,      /* unknown SMB 0xc6 */
10385   dissect_unknown_smb,      /* unknown SMB 0xc7 */
10386   dissect_unknown_smb,      /* unknown SMB 0xc8 */
10387   dissect_unknown_smb,      /* unknown SMB 0xc9 */
10388   dissect_unknown_smb,      /* unknown SMB 0xca */
10389   dissect_unknown_smb,      /* unknown SMB 0xcb */
10390   dissect_unknown_smb,      /* unknown SMB 0xcc */
10391   dissect_unknown_smb,      /* unknown SMB 0xcd */
10392   dissect_unknown_smb,      /* unknown SMB 0xce */
10393   dissect_unknown_smb,      /* unknown SMB 0xcf */
10394   dissect_unknown_smb,      /* SMBsends send a single block message */
10395   dissect_unknown_smb,      /* SMBsendb send a broadcast message */
10396   dissect_unknown_smb,      /* SMBfwdname forward user name */
10397   dissect_unknown_smb,      /* SMBcancelf cancel forward */
10398   dissect_unknown_smb,      /* SMBgetmac get a machine name */
10399   dissect_unknown_smb,      /* SMBsendstrt send start of multi-block message */
10400   dissect_unknown_smb,      /* SMBsendend send end of multi-block message */
10401   dissect_unknown_smb,      /* SMBsendtxt send text of multi-block message */
10402   dissect_unknown_smb,      /* unknown SMB 0xd8 */
10403   dissect_unknown_smb,      /* unknown SMB 0xd9 */
10404   dissect_unknown_smb,      /* unknown SMB 0xda */
10405   dissect_unknown_smb,      /* unknown SMB 0xdb */
10406   dissect_unknown_smb,      /* unknown SMB 0xdc */
10407   dissect_unknown_smb,      /* unknown SMB 0xdd */
10408   dissect_unknown_smb,      /* unknown SMB 0xde */
10409   dissect_unknown_smb,      /* unknown SMB 0xdf */
10410   dissect_unknown_smb,      /* unknown SMB 0xe0 */
10411   dissect_unknown_smb,      /* unknown SMB 0xe1 */
10412   dissect_unknown_smb,      /* unknown SMB 0xe2 */
10413   dissect_unknown_smb,      /* unknown SMB 0xe3 */
10414   dissect_unknown_smb,      /* unknown SMB 0xe4 */
10415   dissect_unknown_smb,      /* unknown SMB 0xe5 */
10416   dissect_unknown_smb,      /* unknown SMB 0xe6 */
10417   dissect_unknown_smb,      /* unknown SMB 0xe7 */
10418   dissect_unknown_smb,      /* unknown SMB 0xe8 */
10419   dissect_unknown_smb,      /* unknown SMB 0xe9 */
10420   dissect_unknown_smb,      /* unknown SMB 0xea */
10421   dissect_unknown_smb,      /* unknown SMB 0xeb */
10422   dissect_unknown_smb,      /* unknown SMB 0xec */
10423   dissect_unknown_smb,      /* unknown SMB 0xed */
10424   dissect_unknown_smb,      /* unknown SMB 0xee */
10425   dissect_unknown_smb,      /* unknown SMB 0xef */
10426   dissect_unknown_smb,      /* unknown SMB 0xf0 */
10427   dissect_unknown_smb,      /* unknown SMB 0xf1 */
10428   dissect_unknown_smb,      /* unknown SMB 0xf2 */
10429   dissect_unknown_smb,      /* unknown SMB 0xf3 */
10430   dissect_unknown_smb,      /* unknown SMB 0xf4 */
10431   dissect_unknown_smb,      /* unknown SMB 0xf5 */
10432   dissect_unknown_smb,      /* unknown SMB 0xf6 */
10433   dissect_unknown_smb,      /* unknown SMB 0xf7 */
10434   dissect_unknown_smb,      /* unknown SMB 0xf8 */
10435   dissect_unknown_smb,      /* unknown SMB 0xf9 */
10436   dissect_unknown_smb,      /* unknown SMB 0xfa */
10437   dissect_unknown_smb,      /* unknown SMB 0xfb */
10438   dissect_unknown_smb,      /* unknown SMB 0xfc */
10439   dissect_unknown_smb,      /* unknown SMB 0xfd */
10440   dissect_unknown_smb,      /* SMBinvalid invalid command */
10441   dissect_unknown_smb       /* unknown SMB 0xff */
10442
10443 };
10444
10445 static const value_string errcls_types[] = {
10446   { SMB_SUCCESS, "Success"},
10447   { SMB_ERRDOS, "DOS Error"},
10448   { SMB_ERRSRV, "Server Error"},
10449   { SMB_ERRHRD, "Hardware Error"},
10450   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
10451   { 0, NULL }
10452 };
10453
10454 char *decode_smb_name(unsigned char cmd)
10455 {
10456
10457   return(SMB_names[cmd]);
10458
10459 }
10460
10461 static const value_string DOS_errors[] = {
10462   {SMBE_badfunc, "Invalid function (or system call)"},
10463   {SMBE_badfile, "File not found (pathname error)"},
10464   {SMBE_badpath, "Directory not found"},
10465   {SMBE_nofids, "Too many open files"},
10466   {SMBE_noaccess, "Access denied"},
10467   {SMBE_badfid, "Invalid fid"},
10468   {SMBE_nomem,  "Out of memory"},
10469   {SMBE_badmem, "Invalid memory block address"},
10470   {SMBE_badenv, "Invalid environment"},
10471   {SMBE_badaccess, "Invalid open mode"},
10472   {SMBE_baddata, "Invalid data (only from ioctl call)"},
10473   {SMBE_res, "Reserved error code?"}, 
10474   {SMBE_baddrive, "Invalid drive"},
10475   {SMBE_remcd, "Attempt to delete current directory"},
10476   {SMBE_diffdevice, "Rename/move across different filesystems"},
10477   {SMBE_nofiles, "no more files found in file search"},
10478   {SMBE_badshare, "Share mode on file conflict with open mode"},
10479   {SMBE_lock, "Lock request conflicts with existing lock"},
10480   {SMBE_unsup, "Request unsupported, returned by Win 95"},
10481   {SMBE_filexists, "File in operation already exists"},
10482   {SMBE_cannotopen, "Cannot open the file specified"},
10483   {SMBE_unknownlevel, "Unknown level??"},
10484   {SMBE_badpipe, "Named pipe invalid"},
10485   {SMBE_pipebusy, "All instances of pipe are busy"},
10486   {SMBE_pipeclosing, "Named pipe close in progress"},
10487   {SMBE_notconnected, "No process on other end of named pipe"},
10488   {SMBE_moredata, "More data to be returned"},
10489   {SMBE_baddirectory,  "Invalid directory name in a path."},
10490   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
10491   {SMBE_eas_nsup, "Extended attributes not supported"},
10492   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
10493   {SMBE_unknownipc, "Unknown IPC Operation"},
10494   {SMBE_noipc, "Don't support ipc"},
10495   {0, NULL}
10496   };
10497
10498 /* Error codes for the ERRSRV class */
10499
10500 static const value_string SRV_errors[] = {
10501   {SMBE_error, "Non specific error code"},
10502   {SMBE_badpw, "Bad password"},
10503   {SMBE_badtype, "Reserved"},
10504   {SMBE_access, "No permissions to perform the requested operation"},
10505   {SMBE_invnid, "TID invalid"},
10506   {SMBE_invnetname, "Invalid network name. Service not found"},
10507   {SMBE_invdevice, "Invalid device"},
10508   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
10509   {SMBE_qfull, "Print queue full"},
10510   {SMBE_qtoobig, "Queued item too big"},
10511   {SMBE_qeof, "EOF on print queue dump"},
10512   {SMBE_invpfid, "Invalid print file in smb_fid"},
10513   {SMBE_smbcmd, "Unrecognised command"},
10514   {SMBE_srverror, "SMB server internal error"},
10515   {SMBE_filespecs, "Fid and pathname invalid combination"},
10516   {SMBE_badlink, "Bad link in request ???"},
10517   {SMBE_badpermits, "Access specified for a file is not valid"},
10518   {SMBE_badpid, "Bad process id in request"},
10519   {SMBE_setattrmode, "Attribute mode invalid"},
10520   {SMBE_paused, "Message server paused"},
10521   {SMBE_msgoff, "Not receiving messages"},
10522   {SMBE_noroom, "No room for message"},
10523   {SMBE_rmuns, "Too many remote usernames"},
10524   {SMBE_timeout, "Operation timed out"},
10525   {SMBE_noresource, "No resources currently available for request."},
10526   {SMBE_toomanyuids, "Too many userids"},
10527   {SMBE_baduid, "Bad userid"},
10528   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
10529   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
10530   {SMBE_contMPX, "Resume MPX mode"},
10531   {SMBE_badPW, "Bad Password???"},
10532   {SMBE_nosupport, "Operation not supported"},
10533   { 0, NULL}
10534 };
10535
10536 /* Error codes for the ERRHRD class */
10537
10538 static const value_string HRD_errors[] = {
10539   {SMBE_nowrite, "read only media"},
10540   {SMBE_badunit, "Unknown device"},
10541   {SMBE_notready, "Drive not ready"},
10542   {SMBE_badcmd, "Unknown command"},
10543   {SMBE_data, "Data (CRC) error"},
10544   {SMBE_badreq, "Bad request structure length"},
10545   {SMBE_seek, "Seek error???"},
10546   {SMBE_badmedia, "Bad media???"},
10547   {SMBE_badsector, "Bad sector???"},
10548   {SMBE_nopaper, "No paper in printer???"},
10549   {SMBE_write, "Write error???"},
10550   {SMBE_read, "Read error???"},
10551   {SMBE_general, "General error???"},
10552   {SMBE_badshare, "A open conflicts with an existing open"},
10553   {SMBE_lock, "Lock/unlock error"},
10554   {SMBE_wrongdisk,  "Wrong disk???"},
10555   {SMBE_FCBunavail, "FCB unavailable???"},
10556   {SMBE_sharebufexc, "Share buffer excluded???"},
10557   {SMBE_diskfull, "Disk full???"},
10558   {0, NULL}
10559 };
10560
10561 char *decode_smb_error(guint8 errcls, guint16 errcode)
10562 {
10563
10564   switch (errcls) {
10565
10566   case SMB_SUCCESS:
10567
10568     return("No Error");   /* No error ??? */
10569     break;
10570
10571   case SMB_ERRDOS:
10572
10573     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
10574     break;
10575
10576   case SMB_ERRSRV:
10577
10578     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
10579     break;
10580
10581   case SMB_ERRHRD:
10582
10583     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
10584     break;
10585
10586   default:
10587
10588     return("Unknown error class!");
10589
10590   }
10591
10592 }
10593
10594 #define SMB_FLAGS_DIRN 0x80
10595
10596 void
10597 dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
10598 {
10599         proto_tree      *smb_tree = tree, *flags_tree, *flags2_tree;
10600         proto_item      *ti, *tf;
10601         guint8          cmd, errcls, errcode1, flags;
10602         guint16         flags2, errcode, tid, pid, uid, mid;
10603         guint32         status;
10604         int             SMB_offset = offset;
10605         struct smb_info si;
10606
10607         OLD_CHECK_DISPLAY_AS_DATA(proto_smb, pd, offset, fd, tree);
10608
10609         si.unicode = 0;
10610
10611         cmd = pd[offset + SMB_hdr_com_offset];
10612
10613         if (check_col(fd, COL_PROTOCOL))
10614                 col_set_str(fd, COL_PROTOCOL, "SMB");
10615
10616         /* Hmmm, poor coding here ... Also, should check the type */
10617
10618         if (check_col(fd, COL_INFO)) {
10619
10620           col_add_fstr(fd, COL_INFO, "%s %s", decode_smb_name(cmd), (pi.match_port == pi.destport)? "Request" : "Response");
10621
10622         }
10623
10624         if (tree) {
10625
10626           ti = proto_tree_add_item(tree, proto_smb, NullTVB, offset, END_OF_FRAME, FALSE);
10627           smb_tree = proto_item_add_subtree(ti, ett_smb);
10628
10629           /* 0xFFSMB is actually a 1 byte msg type and 3 byte server
10630            * component ... SMB is only one used
10631            */
10632
10633           proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Message Type: 0xFF");
10634           proto_tree_add_text(smb_tree, NullTVB, offset+1, 3, "Server Component: SMB");
10635
10636         }
10637
10638         offset += 4;  /* Skip the marker */
10639
10640         if (tree) {
10641
10642           proto_tree_add_uint(smb_tree, hf_smb_cmd, NullTVB, offset, 1, cmd);
10643
10644         }
10645
10646         offset += 1;
10647
10648         /* Handle error code */
10649
10650         if (GSHORT(pd, SMB_offset + 10) & 0x4000) {
10651
10652             /* handle NT 32 bit error code */
10653             errcode = 0;        /* better than a random number */
10654             status = GWORD(pd, offset); 
10655
10656             if (tree) {
10657
10658                 proto_tree_add_text(smb_tree, NullTVB, offset, 4, "Status: 0x%08x",
10659                                     status);
10660
10661             }
10662
10663             offset += 4;
10664
10665         }
10666         else {
10667             /* handle DOS error code & class */
10668
10669             /* Next, look at the error class, SMB_RETCLASS */
10670
10671             errcls = pd[offset];
10672
10673             if (tree) {
10674
10675                 proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Error Class: %s", 
10676                                     val_to_str((guint8)pd[offset], errcls_types, "Unknown Error Class (%x)"));
10677             }
10678
10679             offset += 1;
10680
10681             /* Error code, SMB_HEINFO ... */
10682
10683             errcode1 = pd[offset];
10684
10685             if (tree) {
10686
10687                 proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Reserved: %i", errcode1); 
10688
10689             }
10690
10691             offset += 1;
10692
10693             errcode = GSHORT(pd, offset); 
10694
10695             if (tree) {
10696
10697                 proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Error Code: %s",
10698                                     decode_smb_error(errcls, errcode));
10699
10700             }
10701
10702             offset += 2;
10703         }
10704
10705         /* Now for the flags: Bit 0 = 0 means cmd, 0 = 1 means resp */
10706
10707         flags = pd[offset];
10708
10709         if (tree) {
10710
10711           tf = proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Flags: 0x%02x", flags);
10712
10713           flags_tree = proto_item_add_subtree(tf, ett_smb_flags);
10714           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10715                               decode_boolean_bitfield(flags, 0x01, 8,
10716                                                       "Lock&Read, Write&Unlock supported",
10717                                                       "Lock&Read, Write&Unlock not supported"));
10718           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10719                               decode_boolean_bitfield(flags, 0x02, 8,
10720                                                       "Receive buffer posted",
10721                                                       "Receive buffer not posted"));
10722           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10723                               decode_boolean_bitfield(flags, 0x08, 8, 
10724                                                       "Path names caseless",
10725                                                       "Path names case sensitive"));
10726           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10727                               decode_boolean_bitfield(flags, 0x10, 8,
10728                                                       "Pathnames canonicalized",
10729                                                       "Pathnames not canonicalized"));
10730           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10731                               decode_boolean_bitfield(flags, 0x20, 8,
10732                                                       "OpLocks requested/granted",
10733                                                       "OpLocks not requested/granted"));
10734           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10735                               decode_boolean_bitfield(flags, 0x40, 8, 
10736                                                       "Notify all",
10737                                                       "Notify open only"));
10738
10739           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10740                               decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
10741                                                       8, "Response to client/redirector", "Request to server"));
10742
10743         }
10744
10745         offset += 1;
10746
10747         flags2 = GSHORT(pd, offset);
10748
10749         if (tree) {
10750
10751           tf = proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Flags2: 0x%04x", flags2);
10752
10753           flags2_tree = proto_item_add_subtree(tf, ett_smb_flags2);
10754           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10755                               decode_boolean_bitfield(flags2, 0x0001, 16,
10756                                                       "Long file names supported",
10757                                                       "Long file names not supported"));
10758           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10759                               decode_boolean_bitfield(flags2, 0x0002, 16,
10760                                                       "Extended attributes supported",
10761                                                       "Extended attributes not supported"));
10762           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10763                               decode_boolean_bitfield(flags2, 0x0004, 16,
10764                                                       "Security signatures supported",
10765                                                       "Security signatures not supported"));
10766           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10767                               decode_boolean_bitfield(flags2, 0x0800, 16,
10768                                                       "Extended security negotiation supported",
10769                                                       "Extended security negotiation not supported"));
10770           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10771                               decode_boolean_bitfield(flags2, 0x1000, 16, 
10772                                                       "Resolve pathnames with DFS",
10773                                                       "Don't resolve pathnames with DFS"));
10774           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10775                               decode_boolean_bitfield(flags2, 0x2000, 16,
10776                                                       "Permit reads if execute-only",
10777                                                       "Don't permit reads if execute-only"));
10778           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10779                               decode_boolean_bitfield(flags2, 0x4000, 16,
10780                                                       "Error codes are NT error codes",
10781                                                       "Error codes are DOS error codes"));
10782           proto_tree_add_text(flags2_tree, NullTVB, offset, 2, "%s",
10783                               decode_boolean_bitfield(flags2, 0x8000, 16, 
10784                                                       "Strings are Unicode",
10785                                                       "Strings are ASCII"));
10786
10787         }
10788
10789         if (flags2 & 0x8000) si.unicode = 1; /* Mark them as Unicode */
10790
10791         offset += 2;
10792
10793         if (tree) {
10794
10795           proto_tree_add_text(smb_tree, NullTVB, offset, 12, "Reserved: 6 WORDS");
10796
10797         }
10798
10799         offset += 12;
10800
10801         /* Now the TID, tree ID */
10802
10803         tid = GSHORT(pd, offset);
10804         si.tid = tid;
10805
10806         if (tree) {
10807
10808           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Network Path/Tree ID (TID): %i (%04x)", tid, tid); 
10809
10810         }
10811
10812         offset += 2;
10813
10814         /* Now the PID, Process ID */
10815
10816         pid = GSHORT(pd, offset);
10817         si.pid = pid;
10818
10819         if (tree) {
10820
10821           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Process ID (PID): %i (%04x)", pid, pid); 
10822
10823         }
10824
10825         offset += 2;
10826
10827         /* Now the UID, User ID */
10828
10829         uid = GSHORT(pd, offset);
10830         si.uid = uid;
10831
10832         if (tree) {
10833
10834           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "User ID (UID): %i (%04x)", uid, uid); 
10835
10836         }
10837         
10838         offset += 2;
10839
10840         /* Now the MID, Multiplex ID */
10841
10842         mid = GSHORT(pd, offset);
10843         si.mid = mid;
10844
10845         if (tree) {
10846
10847           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Multiplex ID (MID): %i (%04x)", mid, mid); 
10848
10849         }
10850
10851         offset += 2;
10852
10853         /* Now vector through the table to dissect them */
10854
10855         (dissect[cmd])(pd, offset, fd, tree, smb_tree, si, max_data, SMB_offset, errcode,
10856                        ((flags & 0x80) == 0));
10857
10858
10859 }
10860
10861 /*** External routines called during the registration process */
10862
10863 extern void register_proto_smb_browse( void);
10864 extern void register_proto_smb_logon( void);
10865 extern void register_proto_smb_mailslot( void);
10866 extern void register_proto_smb_pipe( void);
10867 extern void register_proto_smb_mailslot( void);
10868
10869
10870 void
10871 proto_register_smb(void)
10872 {
10873   static hf_register_info hf[] = {
10874     { &hf_smb_cmd,
10875       { "SMB Command", "smb.cmd",
10876         FT_UINT8, BASE_HEX, VALS(smb_cmd_vals), 0x0, "" }}
10877
10878
10879   };
10880         static gint *ett[] = {
10881                 &ett_smb,
10882                 &ett_smb_fileattributes,
10883                 &ett_smb_capabilities,
10884                 &ett_smb_aflags,
10885                 &ett_smb_dialects,
10886                 &ett_smb_mode,
10887                 &ett_smb_rawmode,
10888                 &ett_smb_flags,
10889                 &ett_smb_flags2,
10890                 &ett_smb_desiredaccess,
10891                 &ett_smb_search,
10892                 &ett_smb_file,
10893                 &ett_smb_openfunction,
10894                 &ett_smb_filetype,
10895                 &ett_smb_action,
10896                 &ett_smb_writemode,
10897                 &ett_smb_lock_type,
10898         };
10899
10900         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
10901             "SMB", "smb");
10902
10903         proto_register_subtree_array(ett, array_length(ett));
10904         proto_register_field_array(proto_smb, hf, array_length(hf));
10905         register_init_routine(&smb_init_protocol);
10906         
10907         register_proto_smb_browse();
10908         register_proto_smb_logon( );
10909         register_proto_smb_mailslot();
10910         register_proto_smb_pipe();
10911
10912 }