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