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