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