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