2 * Routines for smb packet dissection
3 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
5 * $Id: packet-smb.c,v 1.19 1999/07/13 02:52:56 gram Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-pop.c
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.
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.
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.
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
47 #include "alignment.h"
49 extern packet_info pi;
51 char *decode_smb_name(unsigned char);
52 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, int, int);
54 char *SMB_names[256] = {
104 "SMBcloseandtreedisc",
106 "SMBtrans2secondary",
108 "SMBfindnotifyclose",
216 "SMBnttransactsecondary",
314 dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
319 proto_tree_add_text(tree, offset, END_OF_FRAME, "Data (%u bytes)",
327 * Dissect a DOS-format date.
330 dissect_dos_date(guint16 date)
332 static char datebuf[4+2+2+1];
334 sprintf(datebuf, "%04d-%02d-%02d",
335 ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
340 * Dissect a DOS-format time.
343 dissect_dos_time(guint16 time)
345 static char timebuf[2+2+2+1];
347 sprintf(timebuf, "%02d:%02d:%02d",
348 (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
352 /* Max string length for displaying Unicode strings. */
353 #define MAX_UNICODE_STR_LEN 256
355 /* Turn a little-endian Unicode '\0'-terminated string into a string we
357 XXX - for now, we just handle the ISO 8859-1 characters. */
359 unicode_to_str(const guint8 *us, int *us_lenp) {
360 static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
367 if (cur == &str[0][0]) {
369 } else if (cur == &str[1][0]) {
375 len = MAX_UNICODE_STR_LEN;
377 while (*us != 0 || *(us + 1) != 0) {
387 /* Note that we're not showing the full string. */
398 * Each dissect routine is passed an offset to wct and works from there
402 dissect_treecon_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
406 guint8 BufferFormat3;
407 guint8 BufferFormat2;
408 guint8 BufferFormat1;
410 guint16 MaxBufferSize;
412 const char *SharePath;
414 const char *Password;
416 if (dirn == 1) { /* Request(s) dissect code */
418 /* Build display for: Word Count (WCT) */
420 WordCount = GBYTE(pd, offset);
424 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
428 offset += 1; /* Skip Word Count (WCT) */
430 /* Build display for: Byte Count (BCC) */
432 ByteCount = GSHORT(pd, offset);
436 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
440 offset += 2; /* Skip Byte Count (BCC) */
442 /* Build display for: BufferFormat1 */
444 BufferFormat1 = GBYTE(pd, offset);
448 proto_tree_add_text(tree, offset, 1, "BufferFormat1: %u", BufferFormat1);
452 offset += 1; /* Skip BufferFormat1 */
454 /* Build display for: Share Path */
456 SharePath = pd + offset;
460 proto_tree_add_text(tree, offset, strlen(SharePath) + 1, "Share Path: %s", SharePath);
464 offset += strlen(SharePath) + 1; /* Skip Share Path */
466 /* Build display for: BufferFormat2 */
468 BufferFormat2 = GBYTE(pd, offset);
472 proto_tree_add_text(tree, offset, 1, "BufferFormat2: %u", BufferFormat2);
476 offset += 1; /* Skip BufferFormat2 */
478 /* Build display for: Password */
480 Password = pd + offset;
484 proto_tree_add_text(tree, offset, strlen(Password) + 1, "Password: %s", Password);
488 offset += strlen(Password) + 1; /* Skip Password */
490 /* Build display for: BufferFormat3 */
492 BufferFormat3 = GBYTE(pd, offset);
496 proto_tree_add_text(tree, offset, 1, "BufferFormat3: %u", BufferFormat3);
500 offset += 1; /* Skip BufferFormat3 */
502 /* Build display for: Service */
504 Service = pd + offset;
508 proto_tree_add_text(tree, offset, strlen(Service) + 1, "Service: %s", Service);
512 offset += strlen(Service) + 1; /* Skip Service */
516 if (dirn == 0) { /* Response(s) dissect code */
518 /* Build display for: Word Count (WCT) */
520 WordCount = GBYTE(pd, offset);
524 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
528 offset += 1; /* Skip Word Count (WCT) */
530 /* Build display for: Max Buffer Size */
532 MaxBufferSize = GSHORT(pd, offset);
536 proto_tree_add_text(tree, offset, 2, "Max Buffer Size: %u", MaxBufferSize);
540 offset += 2; /* Skip Max Buffer Size */
542 /* Build display for: TID */
544 TID = GSHORT(pd, offset);
548 proto_tree_add_text(tree, offset, 2, "TID: %u", TID);
552 offset += 2; /* Skip TID */
554 /* Build display for: Byte Count (BCC) */
556 ByteCount = GSHORT(pd, offset);
560 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
564 offset += 2; /* Skip Byte Count (BCC) */
570 /* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
572 dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
575 proto_tree *Capabilities_tree;
582 guint32 Capabilities;
584 guint16 UNICODEAccountPasswordLength;
587 guint16 MaxBufferSize;
591 guint16 ANSIAccountPasswordLength;
592 const char *UNICODEPassword;
593 const char *PrimaryDomain;
594 const char *NativeOS;
595 const char *NativeLanManType;
596 const char *NativeLanMan;
597 const char *AccountName;
598 const char *ANSIPassword;
600 if (dirn == 1) { /* Request(s) dissect code */
602 WordCount = GBYTE(pd, offset);
608 /* Build display for: Word Count (WCT) */
610 WordCount = GBYTE(pd, offset);
614 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
618 offset += 1; /* Skip Word Count (WCT) */
620 /* Build display for: AndXCommand */
622 AndXCommand = GBYTE(pd, offset);
626 proto_tree_add_text(tree, offset, 1, "AndXCommand: %u", AndXCommand);
630 offset += 1; /* Skip AndXCommand */
632 /* Build display for: AndXReserved */
634 AndXReserved = GBYTE(pd, offset);
638 proto_tree_add_text(tree, offset, 1, "AndXReserved: %u", AndXReserved);
642 offset += 1; /* Skip AndXReserved */
644 /* Build display for: AndXOffset */
646 AndXOffset = GSHORT(pd, offset);
650 proto_tree_add_text(tree, offset, 2, "AndXOffset: %u", AndXOffset);
654 offset += 2; /* Skip AndXOffset */
656 /* Build display for: MaxBufferSize */
658 MaxBufferSize = GSHORT(pd, offset);
662 proto_tree_add_text(tree, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
666 offset += 2; /* Skip MaxBufferSize */
668 /* Build display for: MaxMpxCount */
670 MaxMpxCount = GSHORT(pd, offset);
674 proto_tree_add_text(tree, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
678 offset += 2; /* Skip MaxMpxCount */
680 /* Build display for: VcNumber */
682 VcNumber = GSHORT(pd, offset);
686 proto_tree_add_text(tree, offset, 2, "VcNumber: %u", VcNumber);
690 offset += 2; /* Skip VcNumber */
692 /* Build display for: SessionKey */
694 SessionKey = GWORD(pd, offset);
698 proto_tree_add_text(tree, offset, 4, "SessionKey: %u", SessionKey);
702 offset += 4; /* Skip SessionKey */
704 /* Build display for: PasswordLen */
706 PasswordLen = GSHORT(pd, offset);
710 proto_tree_add_text(tree, offset, 2, "PasswordLen: %u", PasswordLen);
714 offset += 2; /* Skip PasswordLen */
716 /* Build display for: Reserved */
718 Reserved = GWORD(pd, offset);
722 proto_tree_add_text(tree, offset, 4, "Reserved: %u", Reserved);
726 offset += 4; /* Skip Reserved */
728 /* Build display for: Byte Count (BCC) */
730 ByteCount = GSHORT(pd, offset);
734 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
738 offset += 2; /* Skip Byte Count (BCC) */
740 /* Build display for: AccountName */
742 AccountName = pd + offset;
746 proto_tree_add_text(tree, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
750 offset += strlen(AccountName) + 1; /* Skip AccountName */
752 /* Build display for: PrimaryDomain */
754 PrimaryDomain = pd + offset;
758 proto_tree_add_text(tree, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
762 offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
764 /* Build display for: NativeOS */
766 NativeOS = pd + offset;
770 proto_tree_add_text(tree, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);
774 offset += strlen(NativeOS) + 1; /* Skip NativeOS */
780 /* Build display for: Word Count (WCT) */
782 WordCount = GBYTE(pd, offset);
786 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
790 offset += 1; /* Skip Word Count (WCT) */
792 /* Build display for: AndXCommand */
794 AndXCommand = GBYTE(pd, offset);
798 proto_tree_add_text(tree, offset, 1, "AndXCommand: %u", AndXCommand);
802 offset += 1; /* Skip AndXCommand */
804 /* Build display for: AndXReserved */
806 AndXReserved = GBYTE(pd, offset);
810 proto_tree_add_text(tree, offset, 1, "AndXReserved: %u", AndXReserved);
814 offset += 1; /* Skip AndXReserved */
816 /* Build display for: AndXOffset */
818 AndXOffset = GSHORT(pd, offset);
822 proto_tree_add_text(tree, offset, 2, "AndXOffset: %u", AndXOffset);
826 offset += 2; /* Skip AndXOffset */
828 /* Build display for: MaxBufferSize */
830 MaxBufferSize = GSHORT(pd, offset);
834 proto_tree_add_text(tree, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
838 offset += 2; /* Skip MaxBufferSize */
840 /* Build display for: MaxMpxCount */
842 MaxMpxCount = GSHORT(pd, offset);
846 proto_tree_add_text(tree, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
850 offset += 2; /* Skip MaxMpxCount */
852 /* Build display for: VcNumber */
854 VcNumber = GSHORT(pd, offset);
858 proto_tree_add_text(tree, offset, 2, "VcNumber: %u", VcNumber);
862 offset += 2; /* Skip VcNumber */
864 /* Build display for: SessionKey */
866 SessionKey = GWORD(pd, offset);
870 proto_tree_add_text(tree, offset, 4, "SessionKey: %u", SessionKey);
874 offset += 4; /* Skip SessionKey */
876 /* Build display for: ANSI Account Password Length */
878 ANSIAccountPasswordLength = GSHORT(pd, offset);
882 proto_tree_add_text(tree, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
886 offset += 2; /* Skip ANSI Account Password Length */
888 /* Build display for: UNICODE Account Password Length */
890 UNICODEAccountPasswordLength = GSHORT(pd, offset);
894 proto_tree_add_text(tree, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
898 offset += 2; /* Skip UNICODE Account Password Length */
900 /* Build display for: Reserved */
902 Reserved = GWORD(pd, offset);
906 proto_tree_add_text(tree, offset, 4, "Reserved: %u", Reserved);
910 offset += 4; /* Skip Reserved */
912 /* Build display for: Capabilities */
914 Capabilities = GWORD(pd, offset);
918 ti = proto_tree_add_text(tree, offset, 4, "Capabilities: 0x%04x", Capabilities);
919 Capabilities_tree = proto_item_add_subtree(ti, ETT_SMB_CAPABILITIES);
920 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
921 decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
922 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
923 decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
924 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
925 decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
926 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
927 decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
928 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
929 decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
930 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
931 decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
932 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
933 decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
934 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
935 decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
936 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
937 decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
938 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
939 decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
940 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
941 decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
942 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
943 decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
944 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
945 decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
946 proto_tree_add_text(Capabilities_tree, offset, 4, "%s",
947 decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
951 offset += 4; /* Skip Capabilities */
953 /* Build display for: Byte Count */
955 ByteCount = GSHORT(pd, offset);
959 proto_tree_add_text(tree, offset, 2, "Byte Count: %u", ByteCount);
963 offset += 2; /* Skip Byte Count */
965 /* Build display for: ANSI Password */
967 ANSIPassword = pd + offset;
971 proto_tree_add_text(tree, offset, strlen(ANSIPassword) + 1, "ANSI Password: %s", ANSIPassword);
975 offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
977 /* Build display for: UNICODE Password */
979 UNICODEPassword = pd + offset;
981 if (UNICODEAccountPasswordLength > 0) {
985 proto_tree_add_text(tree, offset, strlen(UNICODEPassword) + 1, "UNICODE Password: %s", UNICODEPassword);
989 offset += strlen(UNICODEPassword) + 1; /* Skip UNICODE Password */
993 /* Build display for: Account Name */
995 AccountName = pd + offset;
999 proto_tree_add_text(tree, offset, strlen(AccountName) + 1, "Account Name: %s", AccountName);
1003 offset += strlen(AccountName) + 1; /* Skip Account Name */
1005 /* Build display for: Primary Domain */
1007 PrimaryDomain = pd + offset;
1011 proto_tree_add_text(tree, offset, strlen(PrimaryDomain) + 1, "Primary Domain: %s", PrimaryDomain);
1015 offset += strlen(PrimaryDomain) + 1; /* Skip Primary Domain */
1017 /* Build display for: Native OS */
1019 NativeOS = pd + offset;
1023 proto_tree_add_text(tree, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
1027 offset += strlen(NativeOS) + 1; /* Skip Native OS */
1029 /* Build display for: Native LanMan Type */
1031 NativeLanManType = pd + offset;
1035 proto_tree_add_text(tree, offset, strlen(NativeLanManType) + 1, "Native LanMan Type: %s", NativeLanManType);
1039 offset += strlen(NativeLanManType) + 1; /* Skip Native LanMan Type */
1046 if (AndXCommand != 0xFF) {
1048 (dissect[AndXCommand])(pd, offset, fd, tree, max_data, dirn);
1054 if (dirn == 0) { /* Response(s) dissect code */
1056 /* Build display for: Word Count (WCT) */
1058 WordCount = GBYTE(pd, offset);
1062 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
1066 offset += 1; /* Skip Word Count (WCT) */
1068 /* Build display for: AndXCommand */
1070 AndXCommand = GBYTE(pd, offset);
1074 proto_tree_add_text(tree, offset, 1, "AndXCommand: %u", AndXCommand);
1078 offset += 1; /* Skip AndXCommand */
1080 /* Build display for: AndXReserved */
1082 AndXReserved = GBYTE(pd, offset);
1086 proto_tree_add_text(tree, offset, 1, "AndXReserved: %u", AndXReserved);
1090 offset += 1; /* Skip AndXReserved */
1092 /* Build display for: AndXOffset */
1094 AndXOffset = GSHORT(pd, offset);
1098 proto_tree_add_text(tree, offset, 2, "AndXOffset: %u", AndXOffset);
1102 offset += 2; /* Skip AndXOffset */
1104 /* Build display for: Action */
1106 Action = GSHORT(pd, offset);
1110 proto_tree_add_text(tree, offset, 2, "Action: %u", Action);
1114 offset += 2; /* Skip Action */
1116 /* Build display for: Byte Count (BCC) */
1118 ByteCount = GSHORT(pd, offset);
1122 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
1126 offset += 2; /* Skip Byte Count (BCC) */
1128 /* Build display for: NativeOS */
1130 NativeOS = pd + offset;
1134 proto_tree_add_text(tree, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);
1138 offset += strlen(NativeOS) + 1; /* Skip NativeOS */
1140 /* Build display for: NativeLanMan */
1142 NativeLanMan = pd + offset;
1146 proto_tree_add_text(tree, offset, strlen(NativeLanMan) + 1, "NativeLanMan: %s", NativeLanMan);
1150 offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
1152 /* Build display for: PrimaryDomain */
1154 PrimaryDomain = pd + offset;
1158 proto_tree_add_text(tree, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
1162 offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
1165 if (AndXCommand != 0xFF) {
1167 (dissect[AndXCommand])(pd, offset, fd, tree, max_data, dirn);
1176 dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
1179 guint8 wct, andxcmd;
1180 guint16 andxoffs, flags, passwdlen, bcc, optionsup;
1182 proto_tree *flags_tree;
1187 /* Now figure out what format we are talking about, 2, 3, or 4 response
1191 if (!((dirn == 1) && (wct == 4)) && !((dirn == 0) && (wct == 2)) &&
1192 !((dirn == 0) && (wct == 3))) {
1196 proto_tree_add_text(tree, offset, 1, "Invalid TCON_ANDX format. WCT should be 2, 3, or 4 ..., not %u", wct);
1198 proto_tree_add_text(tree, offset, END_OF_FRAME, "Data");
1208 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", wct);
1214 andxcmd = pd[offset];
1218 proto_tree_add_text(tree, offset, 1, "Next Command: %s",
1219 (andxcmd == 0xFF) ? "No further commands":
1220 decode_smb_name(andxcmd));
1222 proto_tree_add_text(tree, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
1228 andxoffs = GSHORT(pd, offset);
1232 proto_tree_add_text(tree, offset, 2, "Offset to next command: %u", andxoffs);
1242 flags = GSHORT(pd, offset);
1246 ti = proto_tree_add_text(tree, offset, 2, "Additional Flags: 0x%02x", flags);
1247 flags_tree = proto_item_add_subtree(ti, ETT_SMB_AFLAGS);
1248 proto_tree_add_text(flags_tree, offset, 2, "%s",
1249 decode_boolean_bitfield(flags, 0x01, 16,
1251 "Don't disconnect TID"));
1257 passwdlen = GSHORT(pd, offset);
1261 proto_tree_add_text(tree, offset, 2, "Password Length: %u", passwdlen);
1267 bcc = GSHORT(pd, offset);
1271 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1281 proto_tree_add_text(tree, offset, strlen(str) + 1, "Password: %s", str);
1285 offset += strlen(str) + 1;
1291 proto_tree_add_text(tree, offset, strlen(str) + 1, "Path: %s", str);
1295 offset += strlen(str) + 1;
1301 proto_tree_add_text(tree, offset, strlen(str) + 1, "Service: %s", str);
1311 bcc = GSHORT(pd, offset);
1315 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1325 proto_tree_add_text(tree, offset, strlen(str) + 1, "Service Type: %s",
1330 offset += strlen(str) + 1;
1336 optionsup = GSHORT(pd, offset);
1338 if (tree) { /* Should break out the bits */
1340 proto_tree_add_text(tree, offset, 2, "Optional Support: 0x%04x",
1347 bcc = GSHORT(pd, offset);
1351 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1361 proto_tree_add_text(tree, offset, strlen(str) + 1, "Service: %s", str);
1365 offset += strlen(str) + 1;
1371 proto_tree_add_text(tree, offset, strlen(str) + 1, "Native File System: %s", str);
1375 offset += strlen(str) + 1;
1385 if (andxcmd != 0xFF) /* Process that next command ... ??? */
1387 (dissect[andxcmd])(pd, offset, fd, tree, max_data - offset, dirn);
1392 dissect_negprot_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
1394 guint8 wct, enckeylen;
1395 guint16 bcc, mode, rawmode, dialect;
1397 proto_tree *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree;
1403 wct = pd[offset]; /* Should be 0, 1 or 13 or 17, I think */
1405 if (!((wct == 0) && (dirn == 1)) && !((wct == 1) && (dirn == 0)) &&
1406 !((wct == 13) && (dirn == 0)) && !((wct == 17) && (dirn == 0))) {
1409 proto_tree_add_text(tree, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., not %u", wct);
1411 proto_tree_add_text(tree, offset, END_OF_FRAME, "Data");
1419 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %d", wct);
1425 /* Now decode the various formats ... */
1429 case 0: /* A request */
1431 bcc = GSHORT(pd, offset);
1435 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1443 ti = proto_tree_add_text(tree, offset, END_OF_FRAME, "Dialects");
1444 dialects = proto_item_add_subtree(ti, ETT_SMB_DIALECTS);
1448 while (fd->cap_len > offset) {
1453 proto_tree_add_text(dialects, offset, 1, "Dialect Marker: %d", pd[offset]);
1463 proto_tree_add_text(dialects, offset, strlen(str)+1, "Dialect: %s", str);
1467 offset += strlen(str) + 1;
1472 case 1: /* PC NETWORK PROGRAM 1.0 */
1474 dialect = GSHORT(pd, offset);
1476 if (tree) { /* Hmmmm, what if none of the dialects is recognized */
1478 if (dialect == 0xFFFF) { /* Server didn't like them dialects */
1480 proto_tree_add_text(tree, offset, 2, "Supplied dialects not recognized");
1485 proto_tree_add_text(tree, offset, 2, "Dialect Index: %u, PC NETWORK PROTGRAM 1.0", dialect);
1493 bcc = GSHORT(pd, offset);
1497 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1503 case 13: /* Greater than Core and up to and incl LANMAN2.1 */
1507 proto_tree_add_text(tree, offset, 2, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
1511 /* Much of this is similar to response 17 below */
1515 mode = GSHORT(pd, offset);
1519 ti = proto_tree_add_text(tree, offset, 2, "Security Mode: 0x%04x", mode);
1520 mode_tree = proto_item_add_subtree(ti, ETT_SMB_MODE);
1521 proto_tree_add_text(mode_tree, offset, 2, "%s",
1522 decode_boolean_bitfield(mode, 0x0001, 16,
1524 "Security = Share"));
1525 proto_tree_add_text(mode_tree, offset, 2, "%s",
1526 decode_boolean_bitfield(mode, 0x0002, 16,
1527 "Passwords = Encrypted",
1528 "Passwords = Plaintext"));
1536 proto_tree_add_text(tree, offset, 2, "Max buffer size: %u", GSHORT(pd, offset));
1544 proto_tree_add_text(tree, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
1552 proto_tree_add_text(tree, offset, 2, "Max vcs: %u", GSHORT(pd, offset));
1558 rawmode = GSHORT(pd, offset);
1562 ti = proto_tree_add_text(tree, offset, 2, "Raw Mode: 0x%04x", rawmode);
1563 rawmode_tree = proto_item_add_subtree(ti, ETT_SMB_RAWMODE);
1564 proto_tree_add_text(rawmode_tree, offset, 2, "%s",
1565 decode_boolean_bitfield(rawmode, 0x01, 16,
1566 "Read Raw supported",
1567 "Read Raw not supported"));
1568 proto_tree_add_text(rawmode_tree, offset, 2, "%s",
1569 decode_boolean_bitfield(rawmode, 0x02, 16,
1570 "Write Raw supported",
1571 "Write Raw not supported"));
1579 proto_tree_add_text(tree, offset, 4, "Session key: %08x", GWORD(pd, offset));
1585 /* Now the server time, two short parameters ... */
1589 proto_tree_add_text(tree, offset, 2, "Server Time: %s",
1590 dissect_dos_time(GSHORT(pd, offset)));
1591 proto_tree_add_text(tree, offset + 2, 2, "Server Date: %s",
1592 dissect_dos_date(GSHORT(pd, offset + 2)));
1598 /* Server Time Zone, SHORT */
1602 proto_tree_add_text(tree, offset, 2, "Server time zone: %i min from UTC",
1603 (signed)GSSHORT(pd, offset));
1609 /* Challenge Length */
1611 enckeylen = GSHORT(pd, offset);
1615 proto_tree_add_text(tree, offset, 2, "Challenge Length: %u", enckeylen);
1623 proto_tree_add_text(tree, offset, 2, "Reserved: %u (MBZ)", GSHORT(pd, offset));
1629 bcc = GSHORT(pd, offset);
1633 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", bcc);
1639 if (enckeylen) { /* only if non-zero key len */
1645 proto_tree_add_text(tree, offset, enckeylen, "Challenge: %s",
1646 bytes_to_str(str, enckeylen));
1649 offset += enckeylen;
1653 /* Primary Domain ... */
1659 proto_tree_add_text(tree, offset, strlen(str)+1, "Primary Domain: %s", str);
1665 case 17: /* Greater than LANMAN2.1 */
1669 proto_tree_add_text(tree, offset, 2, "Dialect Index: %u, Greater than LANMAN2.1", GSHORT(pd, offset));
1675 mode = GBYTE(pd, offset);
1679 ti = proto_tree_add_text(tree, offset, 1, "Security Mode: 0x%02x", mode);
1680 mode_tree = proto_item_add_subtree(ti, ETT_SMB_MODE);
1681 proto_tree_add_text(mode_tree, offset, 1, "%s",
1682 decode_boolean_bitfield(mode, 0x01, 8,
1684 "Security = Share"));
1685 proto_tree_add_text(mode_tree, offset, 1, "%s",
1686 decode_boolean_bitfield(mode, 0x02, 8,
1687 "Passwords = Encrypted",
1688 "Passwords = Plaintext"));
1689 proto_tree_add_text(mode_tree, offset, 1, "%s",
1690 decode_boolean_bitfield(mode, 0x04, 8,
1691 "Security signatures enabled",
1692 "Security signatures not enabled"));
1693 proto_tree_add_text(mode_tree, offset, 1, "%s",
1694 decode_boolean_bitfield(mode, 0x08, 8,
1695 "Security signatures required",
1696 "Security signatures not required"));
1704 proto_tree_add_text(tree, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
1712 proto_tree_add_text(tree, offset, 2, "Max vcs: %u", GSHORT(pd, offset));
1720 proto_tree_add_text(tree, offset, 2, "Max buffer size: %u", GWORD(pd, offset));
1728 proto_tree_add_text(tree, offset, 4, "Max raw size: %u", GWORD(pd, offset));
1736 proto_tree_add_text(tree, offset, 4, "Session key: %08x", GWORD(pd, offset));
1742 caps = GWORD(pd, offset);
1746 ti = proto_tree_add_text(tree, offset, 4, "Capabilities: 0x%04x", caps);
1747 caps_tree = proto_item_add_subtree(ti, ETT_SMB_CAPABILITIES);
1748 proto_tree_add_text(caps_tree, offset, 4, "%s",
1749 decode_boolean_bitfield(caps, 0x0001, 32,
1750 "Raw Mode supported",
1751 "Raw Mode not supported"));
1752 proto_tree_add_text(caps_tree, offset, 4, "%s",
1753 decode_boolean_bitfield(caps, 0x0002, 32,
1754 "MPX Mode supported",
1755 "MPX Mode not supported"));
1756 proto_tree_add_text(caps_tree, offset, 4, "%s",
1757 decode_boolean_bitfield(caps, 0x0004, 32,
1758 "Unicode supported",
1759 "Unicode not supported"));
1760 proto_tree_add_text(caps_tree, offset, 4, "%s",
1761 decode_boolean_bitfield(caps, 0x0008, 32,
1762 "Large files supported",
1763 "Large files not supported"));
1764 proto_tree_add_text(caps_tree, offset, 4, "%s",
1765 decode_boolean_bitfield(caps, 0x0010, 32,
1766 "NT LM 0.12 SMBs supported",
1767 "NT LM 0.12 SMBs not supported"));
1768 proto_tree_add_text(caps_tree, offset, 4, "%s",
1769 decode_boolean_bitfield(caps, 0x0020, 32,
1770 "RPC remote APIs supported",
1771 "RPC remote APIs not supported"));
1772 proto_tree_add_text(caps_tree, offset, 4, "%s",
1773 decode_boolean_bitfield(caps, 0x0040, 32,
1774 "NT status codes supported",
1775 "NT status codes not supported"));
1776 proto_tree_add_text(caps_tree, offset, 4, "%s",
1777 decode_boolean_bitfield(caps, 0x0080, 32,
1778 "Level 2 OpLocks supported",
1779 "Level 2 OpLocks not supported"));
1780 proto_tree_add_text(caps_tree, offset, 4, "%s",
1781 decode_boolean_bitfield(caps, 0x0100, 32,
1782 "Lock&Read supported",
1783 "Lock&Read not supported"));
1784 proto_tree_add_text(caps_tree, offset, 4, "%s",
1785 decode_boolean_bitfield(caps, 0x0200, 32,
1786 "NT Find supported",
1787 "NT Find not supported"));
1788 proto_tree_add_text(caps_tree, offset, 4, "%s",
1789 decode_boolean_bitfield(caps, 0x1000, 32,
1791 "DFS not supported"));
1792 proto_tree_add_text(caps_tree, offset, 4, "%s",
1793 decode_boolean_bitfield(caps, 0x4000, 32,
1794 "Large READX supported",
1795 "Large READX not supported"));
1796 proto_tree_add_text(caps_tree, offset, 4, "%s",
1797 decode_boolean_bitfield(caps, 0x8000, 32,
1798 "Large WRITEX supported",
1799 "Large WRITEX not supported"));
1800 proto_tree_add_text(caps_tree, offset, 4, "%s",
1801 decode_boolean_bitfield(caps, 0x80000000, 32,
1802 "Extended security exchanges supported",
1803 "Extended security exchanges not supported"));
1808 /* Server time, 2 WORDS */
1812 proto_tree_add_text(tree, offset, 4, "System Time Low: 0x%08x", GWORD(pd, offset));
1813 proto_tree_add_text(tree, offset + 4, 4, "System Time High: 0x%08x", GWORD(pd, offset + 4));
1819 /* Server Time Zone, SHORT */
1823 proto_tree_add_text(tree, offset, 2, "Server time zone: %i min from UTC",
1824 (signed)GSSHORT(pd, offset));
1830 /* Encryption key len */
1832 enckeylen = pd[offset];
1836 proto_tree_add_text(tree, offset, 1, "Encryption key len: %u", enckeylen);
1842 bcc = GSHORT(pd, offset);
1846 proto_tree_add_text(tree, offset, 2, "Byte count (BCC): %u", bcc);
1852 if (enckeylen) { /* only if non-zero key len */
1854 /* Encryption challenge key */
1860 proto_tree_add_text(tree, offset, enckeylen, "Challenge encryption key: %s",
1861 bytes_to_str(str, enckeylen));
1865 offset += enckeylen;
1869 /* The domain, a null terminated string; Unicode if "caps" has
1870 the 0x0004 bit set, ASCII (OEM character set) otherwise.
1871 XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
1877 if (caps & 0x0004) {
1878 ustr = unicode_to_str(str, &ustr_len);
1879 proto_tree_add_text(tree, offset, ustr_len+2, "OEM domain name: %s", ustr);
1881 proto_tree_add_text(tree, offset, strlen(str)+1, "OEM domain name: %s", str);
1888 default: /* Baddd */
1891 proto_tree_add_text(tree, offset, 1, "Bad format, should never get here");
1899 dissect_deletedir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
1903 guint8 BufferFormat;
1905 const char *DirectoryName;
1907 if (dirn == 1) { /* Request(s) dissect code */
1909 /* Build display for: Word Count (WCT) */
1911 WordCount = GBYTE(pd, offset);
1915 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
1919 offset += 1; /* Skip Word Count (WCT) */
1921 /* Build display for: Byte Count (BCC) */
1923 ByteCount = GSHORT(pd, offset);
1927 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
1931 offset += 2; /* Skip Byte Count (BCC) */
1933 /* Build display for: Buffer Format */
1935 BufferFormat = GBYTE(pd, offset);
1939 proto_tree_add_text(tree, offset, 1, "Buffer Format: %u", BufferFormat);
1943 offset += 1; /* Skip Buffer Format */
1945 /* Build display for: Directory Name */
1947 DirectoryName = pd + offset;
1951 proto_tree_add_text(tree, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
1955 offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
1959 if (dirn == 0) { /* Response(s) dissect code */
1961 /* Build display for: Word Count (WCT) */
1963 WordCount = GBYTE(pd, offset);
1967 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
1971 offset += 1; /* Skip Word Count (WCT) */
1973 /* Build display for: Byte Count (BCC) */
1975 ByteCount = GSHORT(pd, offset);
1979 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
1983 offset += 2; /* Skip Byte Count (BCC) */
1990 dissect_createdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
1994 guint8 BufferFormat;
1996 const char *DirectoryName;
1998 if (dirn == 1) { /* Request(s) dissect code */
2000 /* Build display for: Word Count (WCT) */
2002 WordCount = GBYTE(pd, offset);
2006 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2010 offset += 1; /* Skip Word Count (WCT) */
2012 /* Build display for: Byte Count (BCC) */
2014 ByteCount = GSHORT(pd, offset);
2018 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
2022 offset += 2; /* Skip Byte Count (BCC) */
2024 /* Build display for: Buffer Format */
2026 BufferFormat = GBYTE(pd, offset);
2030 proto_tree_add_text(tree, offset, 1, "Buffer Format: %u", BufferFormat);
2034 offset += 1; /* Skip Buffer Format */
2036 /* Build display for: Directory Name */
2038 DirectoryName = pd + offset;
2042 proto_tree_add_text(tree, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
2046 offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
2050 if (dirn == 0) { /* Response(s) dissect code */
2052 /* Build display for: Word Count (WCT) */
2054 WordCount = GBYTE(pd, offset);
2058 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2062 offset += 1; /* Skip Word Count (WCT) */
2064 /* Build display for: Byte Count (BCC) */
2066 ByteCount = GSHORT(pd, offset);
2070 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
2074 offset += 2; /* Skip Byte Count (BCC) */
2081 dissect_checkdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
2085 guint8 BufferFormat;
2087 const char *DirectoryName;
2089 if (dirn == 1) { /* Request(s) dissect code */
2091 /* Build display for: Word Count (WCT) */
2093 WordCount = GBYTE(pd, offset);
2097 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2101 offset += 1; /* Skip Word Count (WCT) */
2103 /* Build display for: Byte Count (BCC) */
2105 ByteCount = GSHORT(pd, offset);
2109 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
2113 offset += 2; /* Skip Byte Count (BCC) */
2115 /* Build display for: Buffer Format */
2117 BufferFormat = GBYTE(pd, offset);
2121 proto_tree_add_text(tree, offset, 1, "Buffer Format: %u", BufferFormat);
2125 offset += 1; /* Skip Buffer Format */
2127 /* Build display for: Directory Name */
2129 DirectoryName = pd + offset;
2133 proto_tree_add_text(tree, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
2137 offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
2141 if (dirn == 0) { /* Response(s) dissect code */
2143 /* Build display for: Word Count (WCT) */
2145 WordCount = GBYTE(pd, offset);
2149 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2153 offset += 1; /* Skip Word Count (WCT) */
2155 /* Build display for: Byte Count (BCC) */
2157 ByteCount = GSHORT(pd, offset);
2161 proto_tree_add_text(tree, offset, 2, "Byte Count (BCC): %u", ByteCount);
2165 offset += 2; /* Skip Byte Count (BCC) */
2172 dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
2175 static const value_string OpenFunction_0x10[] = {
2176 { 0, "Fail if file does not exist"},
2177 { 16, "Create file if it does not exist"},
2180 static const value_string OpenFunction_0x03[] = {
2181 { 0, "Fail if file exists"},
2182 { 1, "Open file if it exists"},
2183 { 2, "Truncate File if it exists"},
2186 static const value_string FileType_0xFFFF[] = {
2187 { 0, "Disk file or directory"},
2188 { 1, "Named pipe in byte mode"},
2189 { 2, "Named pipe in message mode"},
2190 { 3, "Spooled printer"},
2193 static const value_string DesiredAccess_0x70[] = {
2194 { 00, "Compatibility mode"},
2195 { 16, "Deny read/write/execute (exclusive)"},
2196 { 32, "Deny write"},
2197 { 48, "Deny read/execute"},
2201 static const value_string DesiredAccess_0x700[] = {
2202 { 0, "Locality of reference unknown"},
2203 { 256, "Mainly sequential access"},
2204 { 512, "Mainly random access"},
2205 { 768, "Random access with some locality"},
2208 static const value_string DesiredAccess_0x4000[] = {
2209 { 0, "Write through mode disabled"},
2210 { 16384, "Write through mode enabled"},
2213 static const value_string DesiredAccess_0x1000[] = {
2214 { 0, "Normal file (caching permitted)"},
2215 { 4096, "Do not cache this file"},
2218 static const value_string DesiredAccess_0x07[] = {
2219 { 0, "Open for reading"},
2220 { 1, "Open for writing"},
2221 { 2, "Open for reading and writing"},
2222 { 3, "Open for execute"},
2225 static const value_string Action_0x8000[] = {
2226 { 0, "File opened by another user (or mode not supported by server)"},
2227 { 32768, "File is opened only by this user at present"},
2230 static const value_string Action_0x0003[] = {
2231 { 0, "No action taken?"},
2232 { 1, "The file existed and was opened"},
2233 { 2, "The file did not exist but was created"},
2234 { 3, "The file existed and was truncated"},
2237 proto_tree *Search_tree;
2238 proto_tree *OpenFunction_tree;
2239 proto_tree *Flags_tree;
2240 proto_tree *File_tree;
2241 proto_tree *FileType_tree;
2242 proto_tree *FileAttributes_tree;
2243 proto_tree *DesiredAccess_tree;
2244 proto_tree *Action_tree;
2247 guint8 BufferFormat;
2248 guint8 AndXReserved;
2254 guint32 AllocatedSize;
2257 guint16 OpenFunction;
2258 guint16 LastWriteTime;
2259 guint16 LastWriteDate;
2260 guint16 GrantedAccess;
2263 guint16 FileAttributes;
2266 guint16 DeviceState;
2267 guint16 DesiredAccess;
2268 guint16 CreationTime;
2269 guint16 CreationDate;
2273 const char *FileName;
2275 if (dirn == 1) { /* Request(s) dissect code */
2277 /* Build display for: Word Count (WCT) */
2279 WordCount = GBYTE(pd, offset);
2283 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2287 offset += 1; /* Skip Word Count (WCT) */
2289 /* Build display for: AndXCommand */
2291 AndXCommand = GBYTE(pd, offset);
2295 proto_tree_add_text(tree, offset, 1, "AndXCommand: %u", AndXCommand);
2299 offset += 1; /* Skip AndXCommand */
2301 /* Build display for: AndXReserved */
2303 AndXReserved = GBYTE(pd, offset);
2307 proto_tree_add_text(tree, offset, 1, "AndXReserved: %u", AndXReserved);
2311 offset += 1; /* Skip AndXReserved */
2313 /* Build display for: AndXOffset */
2315 AndXOffset = GSHORT(pd, offset);
2319 proto_tree_add_text(tree, offset, 2, "AndXOffset: %u", AndXOffset);
2323 offset += 2; /* Skip AndXOffset */
2325 /* Build display for: Flags */
2327 Flags = GSHORT(pd, offset);
2331 ti = proto_tree_add_text(tree, offset, 2, "Flags: 0x%02x", Flags);
2332 Flags_tree = proto_item_add_subtree(ti, ETT_SMB_FLAGS);
2333 proto_tree_add_text(Flags_tree, offset, 2, "%s",
2334 decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
2335 proto_tree_add_text(Flags_tree, offset, 2, "%s",
2336 decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
2337 proto_tree_add_text(Flags_tree, offset, 2, "%s",
2338 decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
2342 offset += 2; /* Skip Flags */
2344 /* Build display for: Desired Access */
2346 DesiredAccess = GSHORT(pd, offset);
2350 ti = proto_tree_add_text(tree, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
2351 DesiredAccess_tree = proto_item_add_subtree(ti, ETT_SMB_DESIREDACCESS);
2352 proto_tree_add_text(DesiredAccess_tree, offset, 2, "%s",
2353 decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
2354 proto_tree_add_text(DesiredAccess_tree, offset, 2, "%s",
2355 decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
2356 proto_tree_add_text(DesiredAccess_tree, offset, 2, "%s",
2357 decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
2358 proto_tree_add_text(DesiredAccess_tree, offset, 2, "%s",
2359 decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
2360 proto_tree_add_text(DesiredAccess_tree, offset, 2, "%s",
2361 decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
2365 offset += 2; /* Skip Desired Access */
2367 /* Build display for: Search */
2369 Search = GSHORT(pd, offset);
2373 ti = proto_tree_add_text(tree, offset, 2, "Search: 0x%02x", Search);
2374 Search_tree = proto_item_add_subtree(ti, ETT_SMB_SEARCH);
2375 proto_tree_add_text(Search_tree, offset, 2, "%s",
2376 decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
2377 proto_tree_add_text(Search_tree, offset, 2, "%s",
2378 decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
2379 proto_tree_add_text(Search_tree, offset, 2, "%s",
2380 decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
2381 proto_tree_add_text(Search_tree, offset, 2, "%s",
2382 decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
2383 proto_tree_add_text(Search_tree, offset, 2, "%s",
2384 decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
2385 proto_tree_add_text(Search_tree, offset, 2, "%s",
2386 decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
2390 offset += 2; /* Skip Search */
2392 /* Build display for: File */
2394 File = GSHORT(pd, offset);
2398 ti = proto_tree_add_text(tree, offset, 2, "File: 0x%02x", File);
2399 File_tree = proto_item_add_subtree(ti, ETT_SMB_FILE);
2400 proto_tree_add_text(File_tree, offset, 2, "%s",
2401 decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
2402 proto_tree_add_text(File_tree, offset, 2, "%s",
2403 decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
2404 proto_tree_add_text(File_tree, offset, 2, "%s",
2405 decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
2406 proto_tree_add_text(File_tree, offset, 2, "%s",
2407 decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
2408 proto_tree_add_text(File_tree, offset, 2, "%s",
2409 decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
2410 proto_tree_add_text(File_tree, offset, 2, "%s",
2411 decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
2415 offset += 2; /* Skip File */
2417 /* Build display for: Creation Time */
2419 CreationTime = GSHORT(pd, offset);
2423 proto_tree_add_text(tree, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
2427 offset += 2; /* Skip Creation Time */
2429 /* Build display for: Creation Date */
2431 CreationDate = GSHORT(pd, offset);
2435 proto_tree_add_text(tree, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
2439 offset += 2; /* Skip Creation Date */
2441 /* Build display for: Open Function */
2443 OpenFunction = GSHORT(pd, offset);
2447 ti = proto_tree_add_text(tree, offset, 2, "Open Function: 0x%02x", OpenFunction);
2448 OpenFunction_tree = proto_item_add_subtree(ti, ETT_SMB_OPENFUNCTION);
2449 proto_tree_add_text(OpenFunction_tree, offset, 2, "%s",
2450 decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
2451 proto_tree_add_text(OpenFunction_tree, offset, 2, "%s",
2452 decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
2456 offset += 2; /* Skip Open Function */
2458 /* Build display for: Allocated Size */
2460 AllocatedSize = GWORD(pd, offset);
2464 proto_tree_add_text(tree, offset, 4, "Allocated Size: %u", AllocatedSize);
2468 offset += 4; /* Skip Allocated Size */
2470 /* Build display for: Reserved1 */
2472 Reserved1 = GWORD(pd, offset);
2476 proto_tree_add_text(tree, offset, 4, "Reserved1: %u", Reserved1);
2480 offset += 4; /* Skip Reserved1 */
2482 /* Build display for: Reserved2 */
2484 Reserved2 = GWORD(pd, offset);
2488 proto_tree_add_text(tree, offset, 4, "Reserved2: %u", Reserved2);
2492 offset += 4; /* Skip Reserved2 */
2494 /* Build display for: Byte Count */
2496 ByteCount = GSHORT(pd, offset);
2500 proto_tree_add_text(tree, offset, 2, "Byte Count: %u", ByteCount);
2504 offset += 2; /* Skip Byte Count */
2506 /* Build display for: Buffer Format */
2508 BufferFormat = GBYTE(pd, offset);
2512 proto_tree_add_text(tree, offset, 1, "Buffer Format: %u", BufferFormat);
2516 offset += 1; /* Skip Buffer Format */
2518 /* Build display for: File Name */
2520 FileName = pd + offset;
2524 proto_tree_add_text(tree, offset, strlen(FileName) + 1, "File Name: %s", FileName);
2528 offset += strlen(FileName) + 1; /* Skip File Name */
2531 if (AndXCommand != 0xFF) {
2533 (dissect[AndXCommand])(pd, offset, fd, tree, max_data, dirn);
2539 if (dirn == 0) { /* Response(s) dissect code */
2541 /* Build display for: Word Count (WCT) */
2543 WordCount = GBYTE(pd, offset);
2547 proto_tree_add_text(tree, offset, 1, "Word Count (WCT): %u", WordCount);
2551 offset += 1; /* Skip Word Count (WCT) */
2553 /* Build display for: AndXCommand */
2555 AndXCommand = GBYTE(pd, offset);
2559 proto_tree_add_text(tree, offset, 1, "AndXCommand: %u", AndXCommand);
2563 offset += 1; /* Skip AndXCommand */
2565 /* Build display for: AndXReserved */
2567 AndXReserved = GBYTE(pd, offset);
2571 proto_tree_add_text(tree, offset, 1, "AndXReserved: %u", AndXReserved);
2575 offset += 1; /* Skip AndXReserved */
2577 /* Build display for: AndXOffset */
2579 AndXOffset = GSHORT(pd, offset);
2583 proto_tree_add_text(tree, offset, 2, "AndXOffset: %u", AndXOffset);
2587 offset += 2; /* Skip AndXOffset */
2589 /* Build display for: FID */
2591 FID = GSHORT(pd, offset);
2595 proto_tree_add_text(tree, offset, 2, "FID: %u", FID);
2599 offset += 2; /* Skip FID */
2601 /* Build display for: FileAttributes */
2603 FileAttributes = GSHORT(pd, offset);
2607 ti = proto_tree_add_text(tree, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
2608 FileAttributes_tree = proto_item_add_subtree(ti, ETT_SMB_FILEATTRIBUTES);
2609 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2610 decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
2611 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2612 decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
2613 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2614 decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
2615 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2616 decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
2617 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2618 decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
2619 proto_tree_add_text(FileAttributes_tree, offset, 2, "%s",
2620 decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
2624 offset += 2; /* Skip FileAttributes */
2626 /* Build display for: Last Write Time */
2628 LastWriteTime = GSHORT(pd, offset);
2632 proto_tree_add_text(tree, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
2636 offset += 2; /* Skip Last Write Time */
2638 /* Build display for: Last Write Date */
2640 LastWriteDate = GSHORT(pd, offset);
2644 proto_tree_add_text(tree, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
2648 offset += 2; /* Skip Last Write Date */
2650 /* Build display for: Data Size */
2652 DataSize = GWORD(pd, offset);
2656 proto_tree_add_text(tree, offset, 4, "Data Size: %u", DataSize);
2660 offset += 4; /* Skip Data Size */
2662 /* Build display for: Granted Access */
2664 GrantedAccess = GSHORT(pd, offset);
2668 proto_tree_add_text(tree, offset, 2, "Granted Access: %u", GrantedAccess);
2672 offset += 2; /* Skip Granted Access */
2674 /* Build display for: File Type */
2676 FileType = GSHORT(pd, offset);
2680 ti = proto_tree_add_text(tree, offset, 2, "File Type: 0x%02x", FileType);
2681 FileType_tree = proto_item_add_subtree(ti, ETT_SMB_FILETYPE);
2682 proto_tree_add_text(FileType_tree, offset, 2, "%s",
2683 decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
2687 offset += 2; /* Skip File Type */
2689 /* Build display for: Device State */
2691 DeviceState = GSHORT(pd, offset);
2695 proto_tree_add_text(tree, offset, 2, "Device State: %u", DeviceState);
2699 offset += 2; /* Skip Device State */
2701 /* Build display for: Action */
2703 Action = GSHORT(pd, offset);
2707 ti = proto_tree_add_text(tree, offset, 2, "Action: 0x%02x", Action);
2708 Action_tree = proto_item_add_subtree(ti, ETT_SMB_ACTION);
2709 proto_tree_add_text(Action_tree, offset, 2, "%s",
2710 decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
2711 proto_tree_add_text(Action_tree, offset, 2, "%s",
2712 decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
2716 offset += 2; /* Skip Action */
2718 /* Build display for: Server FID */
2720 ServerFID = GWORD(pd, offset);
2724 proto_tree_add_text(tree, offset, 4, "Server FID: %u", ServerFID);
2728 offset += 4; /* Skip Server FID */
2730 /* Build display for: Reserved */
2732 Reserved = GSHORT(pd, offset);
2736 proto_tree_add_text(tree, offset, 2, "Reserved: %u", Reserved);
2740 offset += 2; /* Skip Reserved */
2742 /* Build display for: Byte Count */
2744 ByteCount = GSHORT(pd, offset);
2748 proto_tree_add_text(tree, offset, 2, "Byte Count: %u", ByteCount);
2752 offset += 2; /* Skip Byte Count */
2755 if (AndXCommand != 0xFF) {
2757 (dissect[AndXCommand])(pd, offset, fd, tree, max_data, dirn);
2765 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, int, int) = {
2767 dissect_unknown_smb, /* unknown SMB 0x00 */
2768 dissect_unknown_smb, /* unknown SMB 0x01 */
2769 dissect_unknown_smb, /* SMBopen open a file */
2770 dissect_unknown_smb, /* SMBcreate create a file */
2771 dissect_unknown_smb, /* SMBclose close a file */
2772 dissect_unknown_smb, /* SMBflush flush a file */
2773 dissect_unknown_smb, /* SMBunlink delete a file */
2774 dissect_unknown_smb, /* SMBmv rename a file */
2775 dissect_unknown_smb, /* SMBgetatr get file attributes */
2776 dissect_unknown_smb, /* SMBsetatr set file attributes */
2777 dissect_unknown_smb, /* SMBread read from a file */
2778 dissect_unknown_smb, /* SMBwrite write to a file */
2779 dissect_unknown_smb, /* SMBlock lock a byte range */
2780 dissect_unknown_smb, /* SMBunlock unlock a byte range */
2781 dissect_unknown_smb, /* SMBctemp create a temporary file */
2782 dissect_unknown_smb, /* SMBmknew make a new file */
2783 dissect_unknown_smb, /* SMBchkpth check a directory path */
2784 dissect_unknown_smb, /* SMBexit process exit */
2785 dissect_unknown_smb, /* SMBlseek seek */
2786 dissect_unknown_smb, /* SMBlockread Lock a range and read it */
2787 dissect_unknown_smb, /* SMBwriteunlock Unlock a range and then write */
2788 dissect_unknown_smb, /* unknown SMB 0x15 */
2789 dissect_unknown_smb, /* unknown SMB 0x16 */
2790 dissect_unknown_smb, /* unknown SMB 0x17 */
2791 dissect_unknown_smb, /* unknown SMB 0x18 */
2792 dissect_unknown_smb, /* unknown SMB 0x19 */
2793 dissect_unknown_smb, /* SMBreadBraw read block raw */
2794 dissect_unknown_smb, /* SMBreadBmpx read block multiplexed */
2795 dissect_unknown_smb, /* SMBreadBs read block (secondary response) */
2796 dissect_unknown_smb, /* SMBwriteBraw write block raw */
2797 dissect_unknown_smb, /* SMBwriteBmpx write block multiplexed */
2798 dissect_unknown_smb, /* SMBwriteBs write block (secondary request) */
2799 dissect_unknown_smb, /* SMBwriteC write complete response */
2800 dissect_unknown_smb, /* unknown SMB 0x21 */
2801 dissect_unknown_smb, /* SMBsetattrE set file attributes expanded */
2802 dissect_unknown_smb, /* SMBgetattrE get file attributes expanded */
2803 dissect_unknown_smb, /* SMBlockingX lock/unlock byte ranges and X */
2804 dissect_unknown_smb, /* SMBtrans transaction - name, bytes in/out */
2805 dissect_unknown_smb, /* SMBtranss transaction (secondary request/response) */
2806 dissect_unknown_smb, /* SMBioctl IOCTL */
2807 dissect_unknown_smb, /* SMBioctls IOCTL (secondary request/response) */
2808 dissect_unknown_smb, /* SMBcopy copy */
2809 dissect_unknown_smb, /* SMBmove move */
2810 dissect_unknown_smb, /* SMBecho echo */
2811 dissect_unknown_smb, /* SMBwriteclose write a file and then close it */
2812 dissect_open_andx_smb, /* SMBopenX open and X */
2813 dissect_unknown_smb, /* SMBreadX read and X */
2814 dissect_unknown_smb, /* SMBwriteX write and X */
2815 dissect_unknown_smb, /* unknown SMB 0x30 */
2816 dissect_unknown_smb, /* unknown SMB 0x31 */
2817 dissect_unknown_smb, /* unknown SMB 0x32 */
2818 dissect_unknown_smb, /* unknown SMB 0x33 */
2819 dissect_unknown_smb, /* unknown SMB 0x34 */
2820 dissect_unknown_smb, /* unknown SMB 0x35 */
2821 dissect_unknown_smb, /* unknown SMB 0x36 */
2822 dissect_unknown_smb, /* unknown SMB 0x37 */
2823 dissect_unknown_smb, /* unknown SMB 0x38 */
2824 dissect_unknown_smb, /* unknown SMB 0x39 */
2825 dissect_unknown_smb, /* unknown SMB 0x3a */
2826 dissect_unknown_smb, /* unknown SMB 0x3b */
2827 dissect_unknown_smb, /* unknown SMB 0x3c */
2828 dissect_unknown_smb, /* unknown SMB 0x3d */
2829 dissect_unknown_smb, /* unknown SMB 0x3e */
2830 dissect_unknown_smb, /* unknown SMB 0x3f */
2831 dissect_unknown_smb, /* unknown SMB 0x40 */
2832 dissect_unknown_smb, /* unknown SMB 0x41 */
2833 dissect_unknown_smb, /* unknown SMB 0x42 */
2834 dissect_unknown_smb, /* unknown SMB 0x43 */
2835 dissect_unknown_smb, /* unknown SMB 0x44 */
2836 dissect_unknown_smb, /* unknown SMB 0x45 */
2837 dissect_unknown_smb, /* unknown SMB 0x46 */
2838 dissect_unknown_smb, /* unknown SMB 0x47 */
2839 dissect_unknown_smb, /* unknown SMB 0x48 */
2840 dissect_unknown_smb, /* unknown SMB 0x49 */
2841 dissect_unknown_smb, /* unknown SMB 0x4a */
2842 dissect_unknown_smb, /* unknown SMB 0x4b */
2843 dissect_unknown_smb, /* unknown SMB 0x4c */
2844 dissect_unknown_smb, /* unknown SMB 0x4d */
2845 dissect_unknown_smb, /* unknown SMB 0x4e */
2846 dissect_unknown_smb, /* unknown SMB 0x4f */
2847 dissect_unknown_smb, /* unknown SMB 0x50 */
2848 dissect_unknown_smb, /* unknown SMB 0x51 */
2849 dissect_unknown_smb, /* unknown SMB 0x52 */
2850 dissect_unknown_smb, /* unknown SMB 0x53 */
2851 dissect_unknown_smb, /* unknown SMB 0x54 */
2852 dissect_unknown_smb, /* unknown SMB 0x55 */
2853 dissect_unknown_smb, /* unknown SMB 0x56 */
2854 dissect_unknown_smb, /* unknown SMB 0x57 */
2855 dissect_unknown_smb, /* unknown SMB 0x58 */
2856 dissect_unknown_smb, /* unknown SMB 0x59 */
2857 dissect_unknown_smb, /* unknown SMB 0x5a */
2858 dissect_unknown_smb, /* unknown SMB 0x5b */
2859 dissect_unknown_smb, /* unknown SMB 0x5c */
2860 dissect_unknown_smb, /* unknown SMB 0x5d */
2861 dissect_unknown_smb, /* unknown SMB 0x5e */
2862 dissect_unknown_smb, /* unknown SMB 0x5f */
2863 dissect_unknown_smb, /* unknown SMB 0x60 */
2864 dissect_unknown_smb, /* unknown SMB 0x61 */
2865 dissect_unknown_smb, /* unknown SMB 0x62 */
2866 dissect_unknown_smb, /* unknown SMB 0x63 */
2867 dissect_unknown_smb, /* unknown SMB 0x64 */
2868 dissect_unknown_smb, /* unknown SMB 0x65 */
2869 dissect_unknown_smb, /* unknown SMB 0x66 */
2870 dissect_unknown_smb, /* unknown SMB 0x67 */
2871 dissect_unknown_smb, /* unknown SMB 0x68 */
2872 dissect_unknown_smb, /* unknown SMB 0x69 */
2873 dissect_unknown_smb, /* unknown SMB 0x6a */
2874 dissect_unknown_smb, /* unknown SMB 0x6b */
2875 dissect_unknown_smb, /* unknown SMB 0x6c */
2876 dissect_unknown_smb, /* unknown SMB 0x6d */
2877 dissect_unknown_smb, /* unknown SMB 0x6e */
2878 dissect_unknown_smb, /* unknown SMB 0x6f */
2879 dissect_treecon_smb, /* SMBtcon tree connect */
2880 dissect_unknown_smb, /* SMBtdis tree disconnect */
2881 dissect_negprot_smb, /* SMBnegprot negotiate a protocol */
2882 dissect_ssetup_andx_smb, /* SMBsesssetupX Session Set Up & X (including User Logon) */
2883 dissect_unknown_smb, /* unknown SMB 0x74 */
2884 dissect_tcon_andx_smb, /* SMBtconX tree connect and X */
2885 dissect_unknown_smb, /* unknown SMB 0x76 */
2886 dissect_unknown_smb, /* unknown SMB 0x77 */
2887 dissect_unknown_smb, /* unknown SMB 0x78 */
2888 dissect_unknown_smb, /* unknown SMB 0x79 */
2889 dissect_unknown_smb, /* unknown SMB 0x7a */
2890 dissect_unknown_smb, /* unknown SMB 0x7b */
2891 dissect_unknown_smb, /* unknown SMB 0x7c */
2892 dissect_unknown_smb, /* unknown SMB 0x7d */
2893 dissect_unknown_smb, /* unknown SMB 0x7e */
2894 dissect_unknown_smb, /* unknown SMB 0x7f */
2895 dissect_unknown_smb, /* SMBdskattr get disk attributes */
2896 dissect_unknown_smb, /* SMBsearch search a directory */
2897 dissect_unknown_smb, /* SMBffirst find first */
2898 dissect_unknown_smb, /* SMBfunique find unique */
2899 dissect_unknown_smb, /* SMBfclose find close */
2900 dissect_unknown_smb, /* unknown SMB 0x85 */
2901 dissect_unknown_smb, /* unknown SMB 0x86 */
2902 dissect_unknown_smb, /* unknown SMB 0x87 */
2903 dissect_unknown_smb, /* unknown SMB 0x88 */
2904 dissect_unknown_smb, /* unknown SMB 0x89 */
2905 dissect_unknown_smb, /* unknown SMB 0x8a */
2906 dissect_unknown_smb, /* unknown SMB 0x8b */
2907 dissect_unknown_smb, /* unknown SMB 0x8c */
2908 dissect_unknown_smb, /* unknown SMB 0x8d */
2909 dissect_unknown_smb, /* unknown SMB 0x8e */
2910 dissect_unknown_smb, /* unknown SMB 0x8f */
2911 dissect_unknown_smb, /* unknown SMB 0x90 */
2912 dissect_unknown_smb, /* unknown SMB 0x91 */
2913 dissect_unknown_smb, /* unknown SMB 0x92 */
2914 dissect_unknown_smb, /* unknown SMB 0x93 */
2915 dissect_unknown_smb, /* unknown SMB 0x94 */
2916 dissect_unknown_smb, /* unknown SMB 0x95 */
2917 dissect_unknown_smb, /* unknown SMB 0x96 */
2918 dissect_unknown_smb, /* unknown SMB 0x97 */
2919 dissect_unknown_smb, /* unknown SMB 0x98 */
2920 dissect_unknown_smb, /* unknown SMB 0x99 */
2921 dissect_unknown_smb, /* unknown SMB 0x9a */
2922 dissect_unknown_smb, /* unknown SMB 0x9b */
2923 dissect_unknown_smb, /* unknown SMB 0x9c */
2924 dissect_unknown_smb, /* unknown SMB 0x9d */
2925 dissect_unknown_smb, /* unknown SMB 0x9e */
2926 dissect_unknown_smb, /* unknown SMB 0x9f */
2927 dissect_unknown_smb, /* unknown SMB 0xa0 */
2928 dissect_unknown_smb, /* unknown SMB 0xa1 */
2929 dissect_unknown_smb, /* unknown SMB 0xa2 */
2930 dissect_unknown_smb, /* unknown SMB 0xa3 */
2931 dissect_unknown_smb, /* unknown SMB 0xa4 */
2932 dissect_unknown_smb, /* unknown SMB 0xa5 */
2933 dissect_unknown_smb, /* unknown SMB 0xa6 */
2934 dissect_unknown_smb, /* unknown SMB 0xa7 */
2935 dissect_unknown_smb, /* unknown SMB 0xa8 */
2936 dissect_unknown_smb, /* unknown SMB 0xa9 */
2937 dissect_unknown_smb, /* unknown SMB 0xaa */
2938 dissect_unknown_smb, /* unknown SMB 0xab */
2939 dissect_unknown_smb, /* unknown SMB 0xac */
2940 dissect_unknown_smb, /* unknown SMB 0xad */
2941 dissect_unknown_smb, /* unknown SMB 0xae */
2942 dissect_unknown_smb, /* unknown SMB 0xaf */
2943 dissect_unknown_smb, /* unknown SMB 0xb0 */
2944 dissect_unknown_smb, /* unknown SMB 0xb1 */
2945 dissect_unknown_smb, /* unknown SMB 0xb2 */
2946 dissect_unknown_smb, /* unknown SMB 0xb3 */
2947 dissect_unknown_smb, /* unknown SMB 0xb4 */
2948 dissect_unknown_smb, /* unknown SMB 0xb5 */
2949 dissect_unknown_smb, /* unknown SMB 0xb6 */
2950 dissect_unknown_smb, /* unknown SMB 0xb7 */
2951 dissect_unknown_smb, /* unknown SMB 0xb8 */
2952 dissect_unknown_smb, /* unknown SMB 0xb9 */
2953 dissect_unknown_smb, /* unknown SMB 0xba */
2954 dissect_unknown_smb, /* unknown SMB 0xbb */
2955 dissect_unknown_smb, /* unknown SMB 0xbc */
2956 dissect_unknown_smb, /* unknown SMB 0xbd */
2957 dissect_unknown_smb, /* unknown SMB 0xbe */
2958 dissect_unknown_smb, /* unknown SMB 0xbf */
2959 dissect_unknown_smb, /* SMBsplopen open a print spool file */
2960 dissect_unknown_smb, /* SMBsplwr write to a print spool file */
2961 dissect_unknown_smb, /* SMBsplclose close a print spool file */
2962 dissect_unknown_smb, /* SMBsplretq return print queue */
2963 dissect_unknown_smb, /* unknown SMB 0xc4 */
2964 dissect_unknown_smb, /* unknown SMB 0xc5 */
2965 dissect_unknown_smb, /* unknown SMB 0xc6 */
2966 dissect_unknown_smb, /* unknown SMB 0xc7 */
2967 dissect_unknown_smb, /* unknown SMB 0xc8 */
2968 dissect_unknown_smb, /* unknown SMB 0xc9 */
2969 dissect_unknown_smb, /* unknown SMB 0xca */
2970 dissect_unknown_smb, /* unknown SMB 0xcb */
2971 dissect_unknown_smb, /* unknown SMB 0xcc */
2972 dissect_unknown_smb, /* unknown SMB 0xcd */
2973 dissect_unknown_smb, /* unknown SMB 0xce */
2974 dissect_unknown_smb, /* unknown SMB 0xcf */
2975 dissect_unknown_smb, /* SMBsends send a single block message */
2976 dissect_unknown_smb, /* SMBsendb send a broadcast message */
2977 dissect_unknown_smb, /* SMBfwdname forward user name */
2978 dissect_unknown_smb, /* SMBcancelf cancel forward */
2979 dissect_unknown_smb, /* SMBgetmac get a machine name */
2980 dissect_unknown_smb, /* SMBsendstrt send start of multi-block message */
2981 dissect_unknown_smb, /* SMBsendend send end of multi-block message */
2982 dissect_unknown_smb, /* SMBsendtxt send text of multi-block message */
2983 dissect_unknown_smb, /* unknown SMB 0xd8 */
2984 dissect_unknown_smb, /* unknown SMB 0xd9 */
2985 dissect_unknown_smb, /* unknown SMB 0xda */
2986 dissect_unknown_smb, /* unknown SMB 0xdb */
2987 dissect_unknown_smb, /* unknown SMB 0xdc */
2988 dissect_unknown_smb, /* unknown SMB 0xdd */
2989 dissect_unknown_smb, /* unknown SMB 0xde */
2990 dissect_unknown_smb, /* unknown SMB 0xdf */
2991 dissect_unknown_smb, /* unknown SMB 0xe0 */
2992 dissect_unknown_smb, /* unknown SMB 0xe1 */
2993 dissect_unknown_smb, /* unknown SMB 0xe2 */
2994 dissect_unknown_smb, /* unknown SMB 0xe3 */
2995 dissect_unknown_smb, /* unknown SMB 0xe4 */
2996 dissect_unknown_smb, /* unknown SMB 0xe5 */
2997 dissect_unknown_smb, /* unknown SMB 0xe6 */
2998 dissect_unknown_smb, /* unknown SMB 0xe7 */
2999 dissect_unknown_smb, /* unknown SMB 0xe8 */
3000 dissect_unknown_smb, /* unknown SMB 0xe9 */
3001 dissect_unknown_smb, /* unknown SMB 0xea */
3002 dissect_unknown_smb, /* unknown SMB 0xeb */
3003 dissect_unknown_smb, /* unknown SMB 0xec */
3004 dissect_unknown_smb, /* unknown SMB 0xed */
3005 dissect_unknown_smb, /* unknown SMB 0xee */
3006 dissect_unknown_smb, /* unknown SMB 0xef */
3007 dissect_unknown_smb, /* unknown SMB 0xf0 */
3008 dissect_unknown_smb, /* unknown SMB 0xf1 */
3009 dissect_unknown_smb, /* unknown SMB 0xf2 */
3010 dissect_unknown_smb, /* unknown SMB 0xf3 */
3011 dissect_unknown_smb, /* unknown SMB 0xf4 */
3012 dissect_unknown_smb, /* unknown SMB 0xf5 */
3013 dissect_unknown_smb, /* unknown SMB 0xf6 */
3014 dissect_unknown_smb, /* unknown SMB 0xf7 */
3015 dissect_unknown_smb, /* unknown SMB 0xf8 */
3016 dissect_unknown_smb, /* unknown SMB 0xf9 */
3017 dissect_unknown_smb, /* unknown SMB 0xfa */
3018 dissect_unknown_smb, /* unknown SMB 0xfb */
3019 dissect_unknown_smb, /* unknown SMB 0xfc */
3020 dissect_unknown_smb, /* unknown SMB 0xfd */
3021 dissect_unknown_smb, /* SMBinvalid invalid command */
3022 dissect_unknown_smb /* unknown SMB 0xff */
3026 static const value_string errcls_types[] = {
3027 { SMB_SUCCESS, "Success"},
3028 { SMB_ERRDOS, "DOS Error"},
3029 { SMB_ERRSRV, "Server Error"},
3030 { SMB_ERRHRD, "Hardware Error"},
3031 { SMB_ERRCMD, "Command Error - Not an SMB format command"},
3035 char *decode_smb_name(unsigned char cmd)
3038 return(SMB_names[cmd]);
3042 static const value_string DOS_errors[] = {
3043 {SMBE_badfunc, "Invalid function (or system call)"},
3044 {SMBE_badfile, "File not found (pathname error)"},
3045 {SMBE_badpath, "Directory not found"},
3046 {SMBE_nofids, "Too many open files"},
3047 {SMBE_noaccess, "Access denied"},
3048 {SMBE_badfid, "Invalid fid"},
3049 {SMBE_nomem, "Out of memory"},
3050 {SMBE_badmem, "Invalid memory block address"},
3051 {SMBE_badenv, "Invalid environment"},
3052 {SMBE_badaccess, "Invalid open mode"},
3053 {SMBE_baddata, "Invalid data (only from ioctl call)"},
3054 {SMBE_res, "Reserved error code?"},
3055 {SMBE_baddrive, "Invalid drive"},
3056 {SMBE_remcd, "Attempt to delete current directory"},
3057 {SMBE_diffdevice, "Rename/move across different filesystems"},
3058 {SMBE_nofiles, "no more files found in file search"},
3059 {SMBE_badshare, "Share mode on file conflict with open mode"},
3060 {SMBE_lock, "Lock request conflicts with existing lock"},
3061 {SMBE_unsup, "Request unsupported, returned by Win 95"},
3062 {SMBE_filexists, "File in operation already exists"},
3063 {SMBE_cannotopen, "Cannot open the file specified"},
3064 {SMBE_unknownlevel, "Unknown level??"},
3065 {SMBE_badpipe, "Named pipe invalid"},
3066 {SMBE_pipebusy, "All instances of pipe are busy"},
3067 {SMBE_pipeclosing, "Named pipe close in progress"},
3068 {SMBE_notconnected, "No process on other end of named pipe"},
3069 {SMBE_moredata, "More data to be returned"},
3070 {SMBE_baddirectory, "Invalid directory name in a path."},
3071 {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
3072 {SMBE_eas_nsup, "Extended attributes not supported"},
3073 {SMBE_notify_buf_small, "Buffer too small to return change notify."},
3074 {SMBE_unknownipc, "Unknown IPC Operation"},
3075 {SMBE_noipc, "Don't support ipc"},
3079 /* Error codes for the ERRSRV class */
3081 static const value_string SRV_errors[] = {
3082 {SMBE_error, "Non specific error code"},
3083 {SMBE_badpw, "Bad password"},
3084 {SMBE_badtype, "Reserved"},
3085 {SMBE_access, "No permissions to perform the requested operation"},
3086 {SMBE_invnid, "TID invalid"},
3087 {SMBE_invnetname, "Invalid servername"},
3088 {SMBE_invdevice, "Invalid device"},
3089 {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
3090 {SMBE_qfull, "Print queue full"},
3091 {SMBE_qtoobig, "Queued item too big"},
3092 {SMBE_qeof, "EOF on print queue dump"},
3093 {SMBE_invpfid, "Invalid print file in smb_fid"},
3094 {SMBE_smbcmd, "Unrecognised command"},
3095 {SMBE_srverror, "SMB server internal error"},
3096 {SMBE_filespecs, "Fid and pathname invalid combination"},
3097 {SMBE_badlink, "Bad link in request ???"},
3098 {SMBE_badpermits, "Access specified for a file is not valid"},
3099 {SMBE_badpid, "Bad process id in request"},
3100 {SMBE_setattrmode, "Attribute mode invalid"},
3101 {SMBE_paused, "Message server paused"},
3102 {SMBE_msgoff, "Not receiving messages"},
3103 {SMBE_noroom, "No room for message"},
3104 {SMBE_rmuns, "Too many remote usernames"},
3105 {SMBE_timeout, "Operation timed out"},
3106 {SMBE_noresource, "No resources currently available for request."},
3107 {SMBE_toomanyuids, "Too many userids"},
3108 {SMBE_baduid, "Bad userid"},
3109 {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
3110 {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
3111 {SMBE_contMPX, "Resume MPX mode"},
3112 {SMBE_badPW, "Bad Password???"},
3113 {SMBE_nosupport, "Operation not supported???"},
3117 /* Error codes for the ERRHRD class */
3119 static const value_string HRD_errors[] = {
3120 {SMBE_nowrite, "read only media"},
3121 {SMBE_badunit, "Unknown device"},
3122 {SMBE_notready, "Drive not ready"},
3123 {SMBE_badcmd, "Unknown command"},
3124 {SMBE_data, "Data (CRC) error"},
3125 {SMBE_badreq, "Bad request structure length"},
3126 {SMBE_seek, "Seek error???"},
3127 {SMBE_badmedia, "Bad media???"},
3128 {SMBE_badsector, "Bad sector???"},
3129 {SMBE_nopaper, "No paper in printer???"},
3130 {SMBE_write, "Write error???"},
3131 {SMBE_read, "Read error???"},
3132 {SMBE_general, "General error???"},
3133 {SMBE_badshare, "A open conflicts with an existing open"},
3134 {SMBE_lock, "Lock/unlock error"},
3135 {SMBE_wrongdisk, "Wrong disk???"},
3136 {SMBE_FCBunavail, "FCB unavailable???"},
3137 {SMBE_sharebufexc, "Share buffer excluded???"},
3138 {SMBE_diskfull, "Disk full???"},
3142 char *decode_smb_error(guint8 errcls, guint8 errcode)
3149 return("No Error"); /* No error ??? */
3154 return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
3159 return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
3164 return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
3169 return("Unknown error class!");
3175 #define SMB_FLAGS_DIRN 0x80
3178 dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
3180 proto_tree *smb_tree = tree, *flags_tree, *flags2_tree;
3181 proto_item *ti, *tf;
3182 guint8 cmd, errcls, errcode1, flags;
3183 guint16 flags2, errcode, tid, pid, uid, mid;
3185 cmd = pd[offset + SMB_hdr_com_offset];
3187 if (check_col(fd, COL_PROTOCOL))
3188 col_add_str(fd, COL_PROTOCOL, "SMB");
3190 /* Hmmm, poor coding here ... Also, should check the type */
3192 if (check_col(fd, COL_INFO)) {
3194 col_add_fstr(fd, COL_INFO, "%s %s", decode_smb_name(cmd), (pi.match_port == pi.destport)? "Request" : "Response");
3200 ti = proto_tree_add_text(tree, offset, END_OF_FRAME,
3201 "Server Message Block Protocol");
3202 smb_tree = proto_item_add_subtree(ti, ETT_SMB);
3204 /* 0xFFSMB is actually a 1 byte msg type and 3 byte server
3205 * component ... SMB is only one used
3208 proto_tree_add_text(smb_tree, offset, 1, "Message Type: 0xFF");
3209 proto_tree_add_text(smb_tree, offset+1, 3, "Server Component: SMB");
3213 offset += 4; /* Skip the marker */
3217 proto_tree_add_text(smb_tree, offset, 1, "Command: %s", decode_smb_name(cmd));
3223 /* Next, look at the error class, SMB_RETCLASS */
3225 errcls = pd[offset];
3229 proto_tree_add_text(smb_tree, offset, 1, "Error Class: %s",
3230 val_to_str((guint8)pd[offset], errcls_types, "Unknown Error Class (%x)"));
3235 /* Error code, SMB_HEINFO ... */
3237 errcode1 = pd[offset];
3241 proto_tree_add_text(smb_tree, offset, 1, "Reserved: %i", errcode1);
3247 errcode = GSHORT(pd, offset);
3251 proto_tree_add_text(smb_tree, offset, 2, "Error Code: %s",
3252 decode_smb_error(errcls, errcode));
3258 /* Now for the flags: Bit 0 = 0 means cmd, 0 = 1 means resp */
3264 tf = proto_tree_add_text(smb_tree, offset, 1, "Flags: 0x%02x", flags);
3266 flags_tree = proto_item_add_subtree(tf, ETT_SMB_FLAGS);
3267 proto_tree_add_text(flags_tree, offset, 1, "%s",
3268 decode_boolean_bitfield(flags, 0x01, 8,
3269 "Lock&Read, Write&Unlock supported",
3270 "Lock&Read, Write&Unlock not supported"));
3271 proto_tree_add_text(flags_tree, offset, 1, "%s",
3272 decode_boolean_bitfield(flags, 0x02, 8,
3273 "Receive buffer posted",
3274 "Receive buffer not posted"));
3275 proto_tree_add_text(flags_tree, offset, 1, "%s",
3276 decode_boolean_bitfield(flags, 0x08, 8,
3277 "Path names caseless",
3278 "Path names case sensitive"));
3279 proto_tree_add_text(flags_tree, offset, 1, "%s",
3280 decode_boolean_bitfield(flags, 0x10, 8,
3281 "Pathnames canonicalized",
3282 "Pathnames not canonicalized"));
3283 proto_tree_add_text(flags_tree, offset, 1, "%s",
3284 decode_boolean_bitfield(flags, 0x20, 8,
3285 "OpLocks requested/granted",
3286 "OpLocks not requested/granted"));
3287 proto_tree_add_text(flags_tree, offset, 1, "%s",
3288 decode_boolean_bitfield(flags, 0x40, 8,
3290 "Notify open only"));
3292 proto_tree_add_text(flags_tree, offset, 1, "%s",
3293 decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
3294 8, "Response to client/redirector", "Request to server"));
3300 flags2 = GSHORT(pd, offset);
3304 tf = proto_tree_add_text(smb_tree, offset, 1, "Flags2: 0x%04x", flags2);
3306 flags2_tree = proto_item_add_subtree(tf, ETT_SMB_FLAGS2);
3307 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3308 decode_boolean_bitfield(flags2, 0x0001, 16,
3309 "Long file names supported",
3310 "Long file names not supported"));
3311 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3312 decode_boolean_bitfield(flags2, 0x0002, 16,
3313 "Extended attributes supported",
3314 "Extended attributes not supported"));
3315 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3316 decode_boolean_bitfield(flags2, 0x0004, 16,
3317 "Security signatures supported",
3318 "Security signatures not supported"));
3319 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3320 decode_boolean_bitfield(flags2, 0x0800, 16,
3321 "Extended security negotiation supported",
3322 "Extended security negotiation not supported"));
3323 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3324 decode_boolean_bitfield(flags2, 0x1000, 16,
3325 "Resolve pathnames with DFS",
3326 "Don't resolve pathnames with DFS"));
3327 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3328 decode_boolean_bitfield(flags2, 0x2000, 16,
3329 "Permit reads if execute-only",
3330 "Don't permit reads if execute-only"));
3331 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3332 decode_boolean_bitfield(flags2, 0x4000, 16,
3333 "Error codes are NT error codes",
3334 "Error codes are DOS error codes"));
3335 proto_tree_add_text(flags2_tree, offset, 1, "%s",
3336 decode_boolean_bitfield(flags2, 0x8000, 16,
3337 "Strings are Unicode",
3338 "Strings are ASCII"));
3346 proto_tree_add_text(smb_tree, offset, 12, "Reserved: 6 WORDS");
3352 /* Now the TID, tree ID */
3354 tid = GSHORT(pd, offset);
3358 proto_tree_add_text(smb_tree, offset, 2, "Network Path/Tree ID (TID): %i (%04x)", tid, tid);
3364 /* Now the PID, Process ID */
3366 pid = GSHORT(pd, offset);
3370 proto_tree_add_text(smb_tree, offset, 2, "Process ID (PID): %i (%04x)", pid, pid);
3376 /* Now the UID, User ID */
3378 uid = GSHORT(pd, offset);
3382 proto_tree_add_text(smb_tree, offset, 2, "User ID (UID): %i (%04x)", uid, uid);
3388 /* Now the MID, Multiplex ID */
3390 mid = GSHORT(pd, offset);
3394 proto_tree_add_text(smb_tree, offset, 2, "Multiplex ID (MID): %i (%04x)", mid, mid);
3400 /* Now vector through the table to dissect them */
3402 (dissect[cmd])(pd, offset, fd, smb_tree, max_data,
3403 ((flags & 0x80) == 0));