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