2 * Routines for smb packet dissection
3 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
5 * $Id: packet-smb.c,v 1.4 1999/05/10 20:30:27 guy 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>
42 #include <arpa/tftp.h>
48 #include "alignment.h"
50 extern packet_info pi;
52 char *decode_smb_name(unsigned char);
54 char *SMB_names[256] = {
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_item(tree, offset, END_OF_FRAME, "Data (%d bytes)",
327 * Each dissect routine is passed an offset to wct and works from there
331 dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
335 guint16 andxoffs, flags, passwdlen, bcc;
337 proto_tree *flags_tree;
342 /* Now figure out what format we are talking about, 2, 3, or 4 response
346 if (!((dirn == 1) && (wct == 4)) && !((dirn == 0) && (wct == 2)) &&
347 !((dirn == 0) && (wct == 3))) {
351 proto_tree_add_item(tree, offset, 1, "Invalid TCON_ANDX format. WCT should be 2, 3, or 4 ..., not %d", wct);
353 proto_tree_add_item(tree, offset, END_OF_FRAME, "Data");
363 proto_tree_add_item(tree, offset, 1, "Word Count (WCT): %d", wct);
369 andxcmd = pd[offset];
373 proto_tree_add_item(tree, offset, 1, "Next Command: %s",
374 (andxcmd == 0xFF) ? "No further commands":
375 decode_smb_name(andxcmd));
377 proto_tree_add_item(tree, offset + 1, 1, "Reserved (MBZ): %d", pd[offset+1]);
383 andxoffs = GSHORT(pd, offset);
387 proto_tree_add_item(tree, offset, 2, "Offset to next command: %d", andxoffs);
397 flags = GSHORT(pd, offset);
401 ti = proto_tree_add_item(tree, offset, 2, "Additional Flags: 0x%02x", flags);
402 flags_tree = proto_tree_new();
403 proto_item_add_subtree(ti, flags_tree, ETT_SMB_AFLAGS);
404 proto_tree_add_item(flags_tree, offset, 2, "%s",
405 decode_boolean_bitfield(flags, 0x01, 16,
407 "Don't disconnect TID"));
413 passwdlen = GSHORT(pd, offset);
417 proto_tree_add_item(tree, offset, 2, "Password Length: %d", passwdlen);
423 bcc = GSHORT(pd, offset);
427 proto_tree_add_item(tree, offset, 2, "Byte Count (BCC): %d", bcc);
437 proto_tree_add_item(tree, offset, strlen(str) + 1, "Password: %s", str);
441 offset += strlen(str) + 1;
447 proto_tree_add_item(tree, offset, strlen(str) + 1, "Path: %s", str);
451 offset += strlen(str) + 1;
457 proto_tree_add_item(tree, offset, strlen(str) + 1, "Service: %s", str);
478 dissect_negprot_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int dirn)
480 guint8 wct, enckeylen;
481 guint16 bcc, mode, rawmode;
483 proto_tree *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree;
487 wct = pd[offset]; /* Should be 0, 1 or 13 or 17, I think */
489 if (!((wct == 0) && (dirn == 1)) && !((wct == 1) && (dirn == 0)) &&
490 !((wct == 13) && (dirn == 0)) && !((wct == 17) && (dirn == 0))) {
493 proto_tree_add_item(tree, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., not %d", wct);
495 proto_tree_add_item(tree, offset, END_OF_FRAME, "Data");
503 proto_tree_add_item(tree, offset, 1, "Word Count (WCT): %d", wct);
509 /* Now decode the various formats ... */
513 case 0: /* A request */
515 bcc = GSHORT(pd, offset);
519 proto_tree_add_item(tree, offset, 2, "Byte Count (BCC): %d", bcc);
527 ti = proto_tree_add_item(tree, offset, END_OF_FRAME, "Dialects");
528 dialects = proto_tree_new();
529 proto_item_add_subtree(ti, dialects, ETT_SMB_DIALECTS);
533 while (END_OF_FRAME > 0) {
538 proto_tree_add_item(dialects, offset, 1, "Dialect Marker: %d", pd[offset]);
548 proto_tree_add_item(dialects, offset, strlen(str)+1, "Dialect: %s", str);
552 offset += strlen(str) + 1;
557 case 1: /* PC NETWORK PROGRAM 1.0 */
561 proto_tree_add_item(tree, offset, 2, "Dialect Index: %d, PC NETWORK PROTGRAM 1.0", GSHORT(pd, offset));
567 bcc = GSHORT(pd, offset);
571 proto_tree_add_item(tree, offset, 2, "Byte Count (BCC): %d", bcc);
577 case 13: /* Greater than Core and up to and incl LANMAN2.1 */
581 proto_tree_add_item(tree, offset, 2, "Dialect Index: %d, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
585 /* Much of this is similar to response 17 below */
589 mode = GBYTE(pd, offset);
593 ti = proto_tree_add_item(tree, offset, 1, "Security Mode: 0x%02x", mode);
594 mode_tree = proto_tree_new();
595 proto_item_add_subtree(ti, mode_tree, ETT_SMB_MODE);
596 proto_tree_add_item(mode_tree, offset, 1, "%s",
597 decode_boolean_bitfield(mode, 0x01, 8,
599 "Security = Share"));
600 proto_tree_add_item(mode_tree, offset, 1, "%s",
601 decode_boolean_bitfield(mode, 0x02, 8,
602 "Passwords = Encrypted",
603 "Passwords = Plaintext"));
611 proto_tree_add_item(tree, offset, 2, "Max multiplex count: %d", GSHORT(pd, offset));
619 proto_tree_add_item(tree, offset, 2, "Max vcs: %d", GSHORT(pd, offset));
625 rawmode = GSHORT(pd, offset);
629 ti = proto_tree_add_item(tree, offset, 2, "Raw Mode: 0x%04x", rawmode);
630 rawmode_tree = proto_tree_new();
631 proto_item_add_subtree(ti, rawmode_tree, ETT_SMB_RAWMODE);
632 proto_tree_add_item(rawmode_tree, offset, 2, "%s",
633 decode_boolean_bitfield(rawmode, 0x01, 16,
634 "Read Raw supported",
635 "Read Raw not supported"));
636 proto_tree_add_item(rawmode_tree, offset, 2, "%s",
637 decode_boolean_bitfield(rawmode, 0x02, 16,
638 "Write Raw supported",
639 "Write Raw not supported"));
645 /* Now the server time ... skip 8 bytes ... pick up later */
649 /* Encryption Key Length, should be zero */
653 proto_tree_add_item(tree, offset, 2, "Encryption Key Length: %d (should be zero)", GSHORT(pd, offset));
661 proto_tree_add_item(tree, offset, 2, "Reserved: %d (MBZ)", GSHORT(pd, offset));
667 bcc = GSHORT(pd, offset);
671 proto_tree_add_item(tree, offset, 2, "Byte Count (BCC): %d", bcc);
677 /* Encryption key, might be a null string ??? Not sure */
683 proto_tree_add_item(tree, offset, strlen(str)+1, "Encryption Key: %s", str);
687 offset += strlen(str) + 1;
689 /* Primary Domain ... */
695 proto_tree_add_item(tree, offset, strlen(str)+1, "Primary Domain: %s", str);
701 case 17: /* Greater than LANMAN2.1 */
705 proto_tree_add_item(tree, offset, 2, "Dialect Index: %d, Greater than LANMAN2.1", GSHORT(pd, offset));
711 mode = GBYTE(pd, offset);
715 ti = proto_tree_add_item(tree, offset, 1, "Security Mode: 0x%02x", mode);
716 mode_tree = proto_tree_new();
717 proto_item_add_subtree(ti, mode_tree, ETT_SMB_MODE);
718 proto_tree_add_item(mode_tree, offset, 1, "%s",
719 decode_boolean_bitfield(mode, 0x01, 8,
721 "Security = Share"));
722 proto_tree_add_item(mode_tree, offset, 1, "%s",
723 decode_boolean_bitfield(mode, 0x02, 8,
724 "Passwords = Encrypted",
725 "Passwords = Plaintext"));
733 proto_tree_add_item(tree, offset, 2, "Max multiplex count: %d", GSHORT(pd, offset));
741 proto_tree_add_item(tree, offset, 2, "Max vcs: %d", GSHORT(pd, offset));
749 proto_tree_add_item(tree, offset, 2, "Max buffer size: %d", GWORD(pd, offset));
757 proto_tree_add_item(tree, offset, 4, "Max raw size: %d", GWORD(pd, offset));
765 proto_tree_add_item(tree, offset, 4, "Session key: %08x", GWORD(pd, offset));
771 caps = GWORD(pd, offset);
775 ti = proto_tree_add_item(tree, offset, 4, "Capabilities: 0x%04x", caps);
776 caps_tree = proto_tree_new();
777 proto_item_add_subtree(ti, caps_tree, ETT_SMB_CAPS);
778 proto_tree_add_item(caps_tree, offset, 4, "%s",
779 decode_boolean_bitfield(caps, 0x0001, 32,
780 "Raw Mode supported",
781 "Raw Mode not supported"));
782 proto_tree_add_item(caps_tree, offset, 4, "%s",
783 decode_boolean_bitfield(caps, 0x0002, 32,
784 "MPX Mode supported",
785 "MPX Mode not supported"));
786 proto_tree_add_item(caps_tree, offset, 4, "%s",
787 decode_boolean_bitfield(caps, 0x0004, 32,
789 "Unicode not supported"));
790 proto_tree_add_item(caps_tree, offset, 4, "%s",
791 decode_boolean_bitfield(caps, 0x0008, 32,
792 "Large files supported",
793 "Large files not supported"));
794 proto_tree_add_item(caps_tree, offset, 4, "%s",
795 decode_boolean_bitfield(caps, 0x0010, 32,
796 "NT LM 0.12 SMBs supported",
797 "NT LM 0.12 SMBs not supported"));
798 proto_tree_add_item(caps_tree, offset, 4, "%s",
799 decode_boolean_bitfield(caps, 0x0020, 32,
800 "RPC remote APIs supported",
801 "RPC remote APIs not supported"));
802 proto_tree_add_item(caps_tree, offset, 4, "%s",
803 decode_boolean_bitfield(caps, 0x0040, 32,
804 "NT status codes supported",
805 "NT status codes not supported"));
806 proto_tree_add_item(caps_tree, offset, 4, "%s",
807 decode_boolean_bitfield(caps, 0x0080, 32,
808 "Level 2 OpLocks supported",
809 "Level 2 OpLocks not supported"));
810 proto_tree_add_item(caps_tree, offset, 4, "%s",
811 decode_boolean_bitfield(caps, 0x0100, 32,
812 "Lock&Read supported",
813 "Lock&Read not supported"));
814 proto_tree_add_item(caps_tree, offset, 4, "%s",
815 decode_boolean_bitfield(caps, 0x0200, 32,
817 "NT Find not supported"));
818 proto_tree_add_item(caps_tree, offset, 4, "%s",
819 decode_boolean_bitfield(caps, 0x1000, 32,
821 "DFS not supported"));
822 proto_tree_add_item(caps_tree, offset, 4, "%s",
823 decode_boolean_bitfield(caps, 0x4000, 32,
824 "Large READX supported",
825 "Large READX not supported"));
830 /* Server time, 2 WORDS */
834 /* Server Time Zone, SHORT */
838 proto_tree_add_item(tree, offset, 2, "Server time zone: %i min from UTC",
839 (signed)GSSHORT(pd, offset));
845 /* Encryption key len */
847 enckeylen = pd[offset];
851 proto_tree_add_item(tree, offset, 1, "Encryption key len: %d", enckeylen);
857 bcc = GSHORT(pd, offset);
861 proto_tree_add_item(tree, offset, 2, "Byte count (BCC): %d", bcc);
867 if (enckeylen) { /* only if non-zero key len */
869 /* Encryption challenge key, a NULL terminated string */
875 proto_tree_add_item(tree, offset, strlen(str)+1, "Challenge encryption key: %s", str);
879 offset += strlen(str) + 1;
883 /* The domain, another null terminated string */
889 proto_tree_add_item(tree, offset, strlen(str)+1, "OEM domain name: %s", str);
898 proto_tree_add_item(tree, offset, 1, "Bad format, should never get here");
905 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, int, int) = {
907 dissect_unknown_smb, /* unknown SMB 0x00 */
908 dissect_unknown_smb, /* unknown SMB 0x01 */
909 dissect_unknown_smb, /* SMBopen open a file */
910 dissect_unknown_smb, /* SMBcreate create a file */
911 dissect_unknown_smb, /* SMBclose close a file */
912 dissect_unknown_smb, /* SMBflush flush a file */
913 dissect_unknown_smb, /* SMBunlink delete a file */
914 dissect_unknown_smb, /* SMBmv rename a file */
915 dissect_unknown_smb, /* SMBgetatr get file attributes */
916 dissect_unknown_smb, /* SMBsetatr set file attributes */
917 dissect_unknown_smb, /* SMBread read from a file */
918 dissect_unknown_smb, /* SMBwrite write to a file */
919 dissect_unknown_smb, /* SMBlock lock a byte range */
920 dissect_unknown_smb, /* SMBunlock unlock a byte range */
921 dissect_unknown_smb, /* SMBctemp create a temporary file */
922 dissect_unknown_smb, /* SMBmknew make a new file */
923 dissect_unknown_smb, /* SMBchkpth check a directory path */
924 dissect_unknown_smb, /* SMBexit process exit */
925 dissect_unknown_smb, /* SMBlseek seek */
926 dissect_unknown_smb, /* SMBlockread Lock a range and read it */
927 dissect_unknown_smb, /* SMBwriteunlock Unlock a range and then write */
928 dissect_unknown_smb, /* unknown SMB 0x15 */
929 dissect_unknown_smb, /* unknown SMB 0x16 */
930 dissect_unknown_smb, /* unknown SMB 0x17 */
931 dissect_unknown_smb, /* unknown SMB 0x18 */
932 dissect_unknown_smb, /* unknown SMB 0x19 */
933 dissect_unknown_smb, /* SMBreadBraw read block raw */
934 dissect_unknown_smb, /* SMBreadBmpx read block multiplexed */
935 dissect_unknown_smb, /* SMBreadBs read block (secondary response) */
936 dissect_unknown_smb, /* SMBwriteBraw write block raw */
937 dissect_unknown_smb, /* SMBwriteBmpx write block multiplexed */
938 dissect_unknown_smb, /* SMBwriteBs write block (secondary request) */
939 dissect_unknown_smb, /* SMBwriteC write complete response */
940 dissect_unknown_smb, /* unknown SMB 0x21 */
941 dissect_unknown_smb, /* SMBsetattrE set file attributes expanded */
942 dissect_unknown_smb, /* SMBgetattrE get file attributes expanded */
943 dissect_unknown_smb, /* SMBlockingX lock/unlock byte ranges and X */
944 dissect_unknown_smb, /* SMBtrans transaction - name, bytes in/out */
945 dissect_unknown_smb, /* SMBtranss transaction (secondary request/response) */
946 dissect_unknown_smb, /* SMBioctl IOCTL */
947 dissect_unknown_smb, /* SMBioctls IOCTL (secondary request/response) */
948 dissect_unknown_smb, /* SMBcopy copy */
949 dissect_unknown_smb, /* SMBmove move */
950 dissect_unknown_smb, /* SMBecho echo */
951 dissect_unknown_smb, /* SMBwriteclose write a file and then close it */
952 dissect_unknown_smb, /* SMBopenX open and X */
953 dissect_unknown_smb, /* SMBreadX read and X */
954 dissect_unknown_smb, /* SMBwriteX write and X */
955 dissect_unknown_smb, /* unknown SMB 0x30 */
956 dissect_unknown_smb, /* unknown SMB 0x31 */
957 dissect_unknown_smb, /* unknown SMB 0x32 */
958 dissect_unknown_smb, /* unknown SMB 0x33 */
959 dissect_unknown_smb, /* unknown SMB 0x34 */
960 dissect_unknown_smb, /* unknown SMB 0x35 */
961 dissect_unknown_smb, /* unknown SMB 0x36 */
962 dissect_unknown_smb, /* unknown SMB 0x37 */
963 dissect_unknown_smb, /* unknown SMB 0x38 */
964 dissect_unknown_smb, /* unknown SMB 0x39 */
965 dissect_unknown_smb, /* unknown SMB 0x3a */
966 dissect_unknown_smb, /* unknown SMB 0x3b */
967 dissect_unknown_smb, /* unknown SMB 0x3c */
968 dissect_unknown_smb, /* unknown SMB 0x3d */
969 dissect_unknown_smb, /* unknown SMB 0x3e */
970 dissect_unknown_smb, /* unknown SMB 0x3f */
971 dissect_unknown_smb, /* unknown SMB 0x40 */
972 dissect_unknown_smb, /* unknown SMB 0x41 */
973 dissect_unknown_smb, /* unknown SMB 0x42 */
974 dissect_unknown_smb, /* unknown SMB 0x43 */
975 dissect_unknown_smb, /* unknown SMB 0x44 */
976 dissect_unknown_smb, /* unknown SMB 0x45 */
977 dissect_unknown_smb, /* unknown SMB 0x46 */
978 dissect_unknown_smb, /* unknown SMB 0x47 */
979 dissect_unknown_smb, /* unknown SMB 0x48 */
980 dissect_unknown_smb, /* unknown SMB 0x49 */
981 dissect_unknown_smb, /* unknown SMB 0x4a */
982 dissect_unknown_smb, /* unknown SMB 0x4b */
983 dissect_unknown_smb, /* unknown SMB 0x4c */
984 dissect_unknown_smb, /* unknown SMB 0x4d */
985 dissect_unknown_smb, /* unknown SMB 0x4e */
986 dissect_unknown_smb, /* unknown SMB 0x4f */
987 dissect_unknown_smb, /* unknown SMB 0x50 */
988 dissect_unknown_smb, /* unknown SMB 0x51 */
989 dissect_unknown_smb, /* unknown SMB 0x52 */
990 dissect_unknown_smb, /* unknown SMB 0x53 */
991 dissect_unknown_smb, /* unknown SMB 0x54 */
992 dissect_unknown_smb, /* unknown SMB 0x55 */
993 dissect_unknown_smb, /* unknown SMB 0x56 */
994 dissect_unknown_smb, /* unknown SMB 0x57 */
995 dissect_unknown_smb, /* unknown SMB 0x58 */
996 dissect_unknown_smb, /* unknown SMB 0x59 */
997 dissect_unknown_smb, /* unknown SMB 0x5a */
998 dissect_unknown_smb, /* unknown SMB 0x5b */
999 dissect_unknown_smb, /* unknown SMB 0x5c */
1000 dissect_unknown_smb, /* unknown SMB 0x5d */
1001 dissect_unknown_smb, /* unknown SMB 0x5e */
1002 dissect_unknown_smb, /* unknown SMB 0x5f */
1003 dissect_unknown_smb, /* unknown SMB 0x60 */
1004 dissect_unknown_smb, /* unknown SMB 0x61 */
1005 dissect_unknown_smb, /* unknown SMB 0x62 */
1006 dissect_unknown_smb, /* unknown SMB 0x63 */
1007 dissect_unknown_smb, /* unknown SMB 0x64 */
1008 dissect_unknown_smb, /* unknown SMB 0x65 */
1009 dissect_unknown_smb, /* unknown SMB 0x66 */
1010 dissect_unknown_smb, /* unknown SMB 0x67 */
1011 dissect_unknown_smb, /* unknown SMB 0x68 */
1012 dissect_unknown_smb, /* unknown SMB 0x69 */
1013 dissect_unknown_smb, /* unknown SMB 0x6a */
1014 dissect_unknown_smb, /* unknown SMB 0x6b */
1015 dissect_unknown_smb, /* unknown SMB 0x6c */
1016 dissect_unknown_smb, /* unknown SMB 0x6d */
1017 dissect_unknown_smb, /* unknown SMB 0x6e */
1018 dissect_unknown_smb, /* unknown SMB 0x6f */
1019 dissect_unknown_smb, /* SMBtcon tree connect */
1020 dissect_unknown_smb, /* SMBtdis tree disconnect */
1021 dissect_negprot_smb, /* SMBnegprot negotiate a protocol */
1022 dissect_unknown_smb, /* SMBsesssetupX Session Set Up & X (including User Logon) */
1023 dissect_unknown_smb, /* unknown SMB 0x74 */
1024 dissect_tcon_andx_smb, /* SMBtconX tree connect and X */
1025 dissect_unknown_smb, /* unknown SMB 0x76 */
1026 dissect_unknown_smb, /* unknown SMB 0x77 */
1027 dissect_unknown_smb, /* unknown SMB 0x78 */
1028 dissect_unknown_smb, /* unknown SMB 0x79 */
1029 dissect_unknown_smb, /* unknown SMB 0x7a */
1030 dissect_unknown_smb, /* unknown SMB 0x7b */
1031 dissect_unknown_smb, /* unknown SMB 0x7c */
1032 dissect_unknown_smb, /* unknown SMB 0x7d */
1033 dissect_unknown_smb, /* unknown SMB 0x7e */
1034 dissect_unknown_smb, /* unknown SMB 0x7f */
1035 dissect_unknown_smb, /* SMBdskattr get disk attributes */
1036 dissect_unknown_smb, /* SMBsearch search a directory */
1037 dissect_unknown_smb, /* SMBffirst find first */
1038 dissect_unknown_smb, /* SMBfunique find unique */
1039 dissect_unknown_smb, /* SMBfclose find close */
1040 dissect_unknown_smb, /* unknown SMB 0x85 */
1041 dissect_unknown_smb, /* unknown SMB 0x86 */
1042 dissect_unknown_smb, /* unknown SMB 0x87 */
1043 dissect_unknown_smb, /* unknown SMB 0x88 */
1044 dissect_unknown_smb, /* unknown SMB 0x89 */
1045 dissect_unknown_smb, /* unknown SMB 0x8a */
1046 dissect_unknown_smb, /* unknown SMB 0x8b */
1047 dissect_unknown_smb, /* unknown SMB 0x8c */
1048 dissect_unknown_smb, /* unknown SMB 0x8d */
1049 dissect_unknown_smb, /* unknown SMB 0x8e */
1050 dissect_unknown_smb, /* unknown SMB 0x8f */
1051 dissect_unknown_smb, /* unknown SMB 0x90 */
1052 dissect_unknown_smb, /* unknown SMB 0x91 */
1053 dissect_unknown_smb, /* unknown SMB 0x92 */
1054 dissect_unknown_smb, /* unknown SMB 0x93 */
1055 dissect_unknown_smb, /* unknown SMB 0x94 */
1056 dissect_unknown_smb, /* unknown SMB 0x95 */
1057 dissect_unknown_smb, /* unknown SMB 0x96 */
1058 dissect_unknown_smb, /* unknown SMB 0x97 */
1059 dissect_unknown_smb, /* unknown SMB 0x98 */
1060 dissect_unknown_smb, /* unknown SMB 0x99 */
1061 dissect_unknown_smb, /* unknown SMB 0x9a */
1062 dissect_unknown_smb, /* unknown SMB 0x9b */
1063 dissect_unknown_smb, /* unknown SMB 0x9c */
1064 dissect_unknown_smb, /* unknown SMB 0x9d */
1065 dissect_unknown_smb, /* unknown SMB 0x9e */
1066 dissect_unknown_smb, /* unknown SMB 0x9f */
1067 dissect_unknown_smb, /* unknown SMB 0xa0 */
1068 dissect_unknown_smb, /* unknown SMB 0xa1 */
1069 dissect_unknown_smb, /* unknown SMB 0xa2 */
1070 dissect_unknown_smb, /* unknown SMB 0xa3 */
1071 dissect_unknown_smb, /* unknown SMB 0xa4 */
1072 dissect_unknown_smb, /* unknown SMB 0xa5 */
1073 dissect_unknown_smb, /* unknown SMB 0xa6 */
1074 dissect_unknown_smb, /* unknown SMB 0xa7 */
1075 dissect_unknown_smb, /* unknown SMB 0xa8 */
1076 dissect_unknown_smb, /* unknown SMB 0xa9 */
1077 dissect_unknown_smb, /* unknown SMB 0xaa */
1078 dissect_unknown_smb, /* unknown SMB 0xab */
1079 dissect_unknown_smb, /* unknown SMB 0xac */
1080 dissect_unknown_smb, /* unknown SMB 0xad */
1081 dissect_unknown_smb, /* unknown SMB 0xae */
1082 dissect_unknown_smb, /* unknown SMB 0xaf */
1083 dissect_unknown_smb, /* unknown SMB 0xb0 */
1084 dissect_unknown_smb, /* unknown SMB 0xb1 */
1085 dissect_unknown_smb, /* unknown SMB 0xb2 */
1086 dissect_unknown_smb, /* unknown SMB 0xb3 */
1087 dissect_unknown_smb, /* unknown SMB 0xb4 */
1088 dissect_unknown_smb, /* unknown SMB 0xb5 */
1089 dissect_unknown_smb, /* unknown SMB 0xb6 */
1090 dissect_unknown_smb, /* unknown SMB 0xb7 */
1091 dissect_unknown_smb, /* unknown SMB 0xb8 */
1092 dissect_unknown_smb, /* unknown SMB 0xb9 */
1093 dissect_unknown_smb, /* unknown SMB 0xba */
1094 dissect_unknown_smb, /* unknown SMB 0xbb */
1095 dissect_unknown_smb, /* unknown SMB 0xbc */
1096 dissect_unknown_smb, /* unknown SMB 0xbd */
1097 dissect_unknown_smb, /* unknown SMB 0xbe */
1098 dissect_unknown_smb, /* unknown SMB 0xbf */
1099 dissect_unknown_smb, /* SMBsplopen open a print spool file */
1100 dissect_unknown_smb, /* SMBsplwr write to a print spool file */
1101 dissect_unknown_smb, /* SMBsplclose close a print spool file */
1102 dissect_unknown_smb, /* SMBsplretq return print queue */
1103 dissect_unknown_smb, /* unknown SMB 0xc4 */
1104 dissect_unknown_smb, /* unknown SMB 0xc5 */
1105 dissect_unknown_smb, /* unknown SMB 0xc6 */
1106 dissect_unknown_smb, /* unknown SMB 0xc7 */
1107 dissect_unknown_smb, /* unknown SMB 0xc8 */
1108 dissect_unknown_smb, /* unknown SMB 0xc9 */
1109 dissect_unknown_smb, /* unknown SMB 0xca */
1110 dissect_unknown_smb, /* unknown SMB 0xcb */
1111 dissect_unknown_smb, /* unknown SMB 0xcc */
1112 dissect_unknown_smb, /* unknown SMB 0xcd */
1113 dissect_unknown_smb, /* unknown SMB 0xce */
1114 dissect_unknown_smb, /* unknown SMB 0xcf */
1115 dissect_unknown_smb, /* SMBsends send a single block message */
1116 dissect_unknown_smb, /* SMBsendb send a broadcast message */
1117 dissect_unknown_smb, /* SMBfwdname forward user name */
1118 dissect_unknown_smb, /* SMBcancelf cancel forward */
1119 dissect_unknown_smb, /* SMBgetmac get a machine name */
1120 dissect_unknown_smb, /* SMBsendstrt send start of multi-block message */
1121 dissect_unknown_smb, /* SMBsendend send end of multi-block message */
1122 dissect_unknown_smb, /* SMBsendtxt send text of multi-block message */
1123 dissect_unknown_smb, /* unknown SMB 0xd8 */
1124 dissect_unknown_smb, /* unknown SMB 0xd9 */
1125 dissect_unknown_smb, /* unknown SMB 0xda */
1126 dissect_unknown_smb, /* unknown SMB 0xdb */
1127 dissect_unknown_smb, /* unknown SMB 0xdc */
1128 dissect_unknown_smb, /* unknown SMB 0xdd */
1129 dissect_unknown_smb, /* unknown SMB 0xde */
1130 dissect_unknown_smb, /* unknown SMB 0xdf */
1131 dissect_unknown_smb, /* unknown SMB 0xe0 */
1132 dissect_unknown_smb, /* unknown SMB 0xe1 */
1133 dissect_unknown_smb, /* unknown SMB 0xe2 */
1134 dissect_unknown_smb, /* unknown SMB 0xe3 */
1135 dissect_unknown_smb, /* unknown SMB 0xe4 */
1136 dissect_unknown_smb, /* unknown SMB 0xe5 */
1137 dissect_unknown_smb, /* unknown SMB 0xe6 */
1138 dissect_unknown_smb, /* unknown SMB 0xe7 */
1139 dissect_unknown_smb, /* unknown SMB 0xe8 */
1140 dissect_unknown_smb, /* unknown SMB 0xe9 */
1141 dissect_unknown_smb, /* unknown SMB 0xea */
1142 dissect_unknown_smb, /* unknown SMB 0xeb */
1143 dissect_unknown_smb, /* unknown SMB 0xec */
1144 dissect_unknown_smb, /* unknown SMB 0xed */
1145 dissect_unknown_smb, /* unknown SMB 0xee */
1146 dissect_unknown_smb, /* unknown SMB 0xef */
1147 dissect_unknown_smb, /* unknown SMB 0xf0 */
1148 dissect_unknown_smb, /* unknown SMB 0xf1 */
1149 dissect_unknown_smb, /* unknown SMB 0xf2 */
1150 dissect_unknown_smb, /* unknown SMB 0xf3 */
1151 dissect_unknown_smb, /* unknown SMB 0xf4 */
1152 dissect_unknown_smb, /* unknown SMB 0xf5 */
1153 dissect_unknown_smb, /* unknown SMB 0xf6 */
1154 dissect_unknown_smb, /* unknown SMB 0xf7 */
1155 dissect_unknown_smb, /* unknown SMB 0xf8 */
1156 dissect_unknown_smb, /* unknown SMB 0xf9 */
1157 dissect_unknown_smb, /* unknown SMB 0xfa */
1158 dissect_unknown_smb, /* unknown SMB 0xfb */
1159 dissect_unknown_smb, /* unknown SMB 0xfc */
1160 dissect_unknown_smb, /* unknown SMB 0xfd */
1161 dissect_unknown_smb, /* SMBinvalid invalid command */
1162 dissect_unknown_smb /* unknown SMB 0xff */
1166 static const value_string errcls_types[] = {
1167 { SMB_SUCCESS, "Success"},
1168 { SMB_ERRDOS, "DOS Error"},
1169 { SMB_ERRSRV, "Server Error"},
1170 { SMB_ERRHRD, "Hardware Error"},
1171 { SMB_ERRCMD, "Command Error - Not an SMB format command"},
1175 char *decode_smb_name(unsigned char cmd)
1178 return(SMB_names[cmd]);
1182 static const value_string DOS_errors[] = {
1183 {SMBE_badfunc, "Invalid function (or system call)"},
1184 {SMBE_badfile, "File not found (pathname error)"},
1185 {SMBE_badpath, "Directory not found"},
1186 {SMBE_nofids, "Too many open files"},
1187 {SMBE_noaccess, "Access denied"},
1188 {SMBE_badfid, "Invalid fid"},
1189 {SMBE_nomem, "Out of memory"},
1190 {SMBE_badmem, "Invalid memory block address"},
1191 {SMBE_badenv, "Invalid environment"},
1192 {SMBE_badaccess, "Invalid open mode"},
1193 {SMBE_baddata, "Invalid data (only from ioctl call)"},
1194 {SMBE_res, "Reserved error code?"},
1195 {SMBE_baddrive, "Invalid drive"},
1196 {SMBE_remcd, "Attempt to delete current directory"},
1197 {SMBE_diffdevice, "Rename/move across different filesystems"},
1198 {SMBE_nofiles, "no more files found in file search"},
1199 {SMBE_badshare, "Share mode on file conflict with open mode"},
1200 {SMBE_lock, "Lock request conflicts with existing lock"},
1201 {SMBE_unsup, "Request unsupported, returned by Win 95"},
1202 {SMBE_filexists, "File in operation already exists"},
1203 {SMBE_cannotopen, "Cannot open the file specified"},
1204 {SMBE_unknownlevel, "Unknown level??"},
1205 {SMBE_badpipe, "Named pipe invalid"},
1206 {SMBE_pipebusy, "All instances of pipe are busy"},
1207 {SMBE_pipeclosing, "Named pipe close in progress"},
1208 {SMBE_notconnected, "No process on other end of named pipe"},
1209 {SMBE_moredata, "More data to be returned"},
1210 {SMBE_baddirectory, "Invalid directory name in a path."},
1211 {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
1212 {SMBE_eas_nsup, "Extended attributes not supported"},
1213 {SMBE_notify_buf_small, "Buffer too small to return change notify."},
1214 {SMBE_unknownipc, "Unknown IPC Operation"},
1215 {SMBE_noipc, "Don't support ipc"},
1219 /* Error codes for the ERRSRV class */
1221 static const value_string SRV_errors[] = {
1222 {SMBE_error, "Non specific error code"},
1223 {SMBE_badpw, "Bad password"},
1224 {SMBE_badtype, "Reserved"},
1225 {SMBE_access, "No permissions to perform the requested operation"},
1226 {SMBE_invnid, "TID invalid"},
1227 {SMBE_invnetname, "Invalid servername"},
1228 {SMBE_invdevice, "Invalid device"},
1229 {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
1230 {SMBE_qfull, "Print queue full"},
1231 {SMBE_qtoobig, "Queued item too big"},
1232 {SMBE_invpfid, "Invalid print file in smb_fid"},
1233 {SMBE_smbcmd, "Unrecognised command"},
1234 {SMBE_srverror, "SMB server internal error"},
1235 {SMBE_filespecs, "Fid and pathname invalid combination"},
1236 {SMBE_badlink, "Bad link in request ???"},
1237 {SMBE_badpermits, "Access specified for a file is not valid"},
1238 {SMBE_badpid, "Bad process id in request"},
1239 {SMBE_setattrmode, "Attribute mode invalid"},
1240 {SMBE_paused, "Message server paused"},
1241 {SMBE_msgoff, "Not receiving messages"},
1242 {SMBE_noroom, "No room for message"},
1243 {SMBE_rmuns, "Too many remote usernames"},
1244 {SMBE_timeout, "Operation timed out"},
1245 {SMBE_noresource, "No resources currently available for request."},
1246 {SMBE_toomanyuids, "Too many userids"},
1247 {SMBE_baduid, "Bad userid"},
1248 {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
1249 {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
1250 {SMBE_contMPX, "Resume MPX mode"},
1251 {SMBE_badPW, "Bad Password???"},
1252 {SMBE_nosupport, "Operation not supported???"},
1256 /* Error codes for the ERRHRD class */
1258 static const value_string HRD_errors[] = {
1259 {SMBE_nowrite, "read only media"},
1260 {SMBE_badunit, "Unknown device"},
1261 {SMBE_notready, "Drive not ready"},
1262 {SMBE_badcmd, "Unknown command"},
1263 {SMBE_data, "Data (CRC) error"},
1264 {SMBE_badreq, "Bad request structure length"},
1265 {SMBE_seek, "Seek error???"},
1266 {SMBE_badmedia, "Bad media???"},
1267 {SMBE_badsector, "Bad sector???"},
1268 {SMBE_nopaper, "No paper in printer???"},
1269 {SMBE_write, "Write error???"},
1270 {SMBE_read, "Read error???"},
1271 {SMBE_general, "General error???"},
1272 {SMBE_wrongdisk, "Wrong disk???"},
1273 {SMBE_FCBunavail, "FCB unavailable???"},
1274 {SMBE_sharebufexc, "Share buffer excluded???"},
1275 {SMBE_diskfull, "Disk full???"},
1279 char *decode_smb_error(guint8 errcls, guint8 errcode)
1286 return("No Error"); /* No error ??? */
1291 return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
1296 return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
1301 return(val_to_str(errcode, HRD_errors, "Unknown HRD error(%x)"));
1306 return("Unknown error class!");
1312 #define SMB_FLAGS_DIRN 0x80
1315 dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
1317 proto_tree *smb_tree = tree, *flags_tree, *flags2_tree;
1318 proto_item *ti, *tf;
1319 guint8 cmd, errcls, errcode1, flags;
1320 guint16 flags2, errcode, tid, pid, uid, mid;
1322 cmd = pd[offset + SMB_hdr_com_offset];
1324 if (check_col(fd, COL_PROTOCOL))
1325 col_add_str(fd, COL_PROTOCOL, "SMB");
1327 /* Hmmm, poor coding here ... Also, should check the type */
1329 if (check_col(fd, COL_INFO)) {
1331 col_add_fstr(fd, COL_INFO, "%s %s", decode_smb_name(cmd), (pi.match_port == pi.destport)? "Request" : "Response");
1337 ti = proto_tree_add_item(tree, offset, END_OF_FRAME,
1338 "Server Message Block Protocol");
1339 smb_tree = proto_tree_new();
1340 proto_item_add_subtree(ti, smb_tree, ETT_SMB);
1342 /* 0xFFSMB is actually a 1 byte msg type and 3 byte server
1343 * component ... SMB is only one used
1346 proto_tree_add_item(smb_tree, offset, 1, "Message Type: 0xFF");
1347 proto_tree_add_item(smb_tree, offset+1, 3, "Server Component: SMB");
1351 offset += 4; /* Skip the marker */
1355 proto_tree_add_item(smb_tree, offset, 1, "Command: %s", decode_smb_name(cmd));
1361 /* Next, look at the error class, SMB_RETCLASS */
1363 errcls = pd[offset];
1367 proto_tree_add_item(smb_tree, offset, 1, "Error Class: %s",
1368 val_to_str((guint8)pd[offset], errcls_types, "Unknown Error Class (%x)"));
1373 /* Error code, SMB_HEINFO ... */
1375 errcode1 = pd[offset];
1379 proto_tree_add_item(smb_tree, offset, 1, "Reserved: %i", errcode1);
1385 errcode = GSHORT(pd, offset);
1389 proto_tree_add_item(smb_tree, offset, 2, "Error Code: %s",
1390 decode_smb_error(errcls, errcode));
1396 /* Now for the flags: Bit 0 = 0 means cmd, 0 = 1 means resp */
1402 tf = proto_tree_add_item(smb_tree, offset, 1, "Flags: 0x%02x", flags);
1404 flags_tree = proto_tree_new();
1405 proto_item_add_subtree(tf, flags_tree, ETT_SMB_FLAGS);
1406 proto_tree_add_item(flags_tree, offset, 1, "%s",
1407 decode_boolean_bitfield(flags, 0x01, 8,
1408 "Lock&Read, Write&Unlock supported",
1409 "Lock&Read, Write&Unlock not supported"));
1410 proto_tree_add_item(flags_tree, offset, 1, "%s",
1411 decode_boolean_bitfield(flags, 0x02, 8,
1412 "Receive buffer posted",
1413 "Receive buffer not posted"));
1414 proto_tree_add_item(flags_tree, offset, 1, "%s",
1415 decode_boolean_bitfield(flags, 0x08, 8,
1416 "Path names caseless",
1417 "Path names case sensitive"));
1418 proto_tree_add_item(flags_tree, offset, 1, "%s",
1419 decode_boolean_bitfield(flags, 0x10, 8,
1420 "Pathnames canonicalized",
1421 "Pathnames not canonicalized"));
1422 proto_tree_add_item(flags_tree, offset, 1, "%s",
1423 decode_boolean_bitfield(flags, 0x20, 8,
1424 "OpLocks requested/granted",
1425 "OpLocks not requested/granted"));
1426 proto_tree_add_item(flags_tree, offset, 1, "%s",
1427 decode_boolean_bitfield(flags, 0x40, 8,
1429 "Notify open only"));
1431 proto_tree_add_item(flags_tree, offset, 1, "%s",
1432 decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
1433 8, "Response to client/redirector", "Request to server"));
1439 flags2 = GSHORT(pd, offset);
1443 tf = proto_tree_add_item(smb_tree, offset, 1, "Flags2: 0x%04x", flags2);
1445 flags2_tree = proto_tree_new();
1446 proto_item_add_subtree(tf, flags2_tree, ETT_SMB_FLAGS2);
1447 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1448 decode_boolean_bitfield(flags2, 0x0001, 16,
1449 "Long file names supported",
1450 "Long file names not supported"));
1451 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1452 decode_boolean_bitfield(flags2, 0x0002, 16,
1453 "Extended attributes supported",
1454 "Extended attributes not supported"));
1455 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1456 decode_boolean_bitfield(flags2, 0x1000, 16,
1457 "Resolve pathnames with Dfs",
1458 "Don't resolve pathnames with Dfs"));
1459 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1460 decode_boolean_bitfield(flags2, 0x2000, 16,
1461 "Permit reads if execute-only",
1462 "Don't permit reads if execute-only"));
1463 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1464 decode_boolean_bitfield(flags2, 0x4000, 16,
1465 "Error codes are NT error codes",
1466 "Error codes are DOS error codes"));
1467 proto_tree_add_item(flags2_tree, offset, 1, "%s",
1468 decode_boolean_bitfield(flags2, 0x8000, 16,
1469 "Strings are Unicode",
1470 "Strings are ASCII"));
1478 proto_tree_add_item(smb_tree, offset, 12, "Reserved: 6 WORDS");
1484 /* Now the TID, tree ID */
1486 tid = GSHORT(pd, offset);
1490 proto_tree_add_item(smb_tree, offset, 2, "Network Path/Tree ID (TID): %i (%04x)", tid, tid);
1496 /* Now the PID, Process ID */
1498 pid = GSHORT(pd, offset);
1502 proto_tree_add_item(smb_tree, offset, 2, "Process ID (PID): %i (%04x)", pid, pid);
1508 /* Now the UID, User ID */
1510 uid = GSHORT(pd, offset);
1514 proto_tree_add_item(smb_tree, offset, 2, "User ID (UID): %i (%04x)", uid, uid);
1520 /* Now the MID, Multiplex ID */
1522 mid = GSHORT(pd, offset);
1526 proto_tree_add_item(smb_tree, offset, 2, "Multiplex ID (MID): %i (%04x)", mid, mid);
1532 /* Now vector through the table to dissect them */
1534 (dissect[cmd])(pd, offset, fd, smb_tree, max_data,
1535 ((flags & 0x80) == 0));