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