* Routines for smb packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-smb.c,v 1.128 2001/11/04 00:53:46 guy Exp $
+ * $Id: packet-smb.c,v 1.129 2001/11/04 12:44:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
static int hf_smb_file_name = -1;
static int hf_smb_open_function_open = -1;
static int hf_smb_open_function_create = -1;
+static int hf_smb_fid = -1;
+static int hf_smb_file_attr_read_only = -1;
+static int hf_smb_file_attr_hidden = -1;
+static int hf_smb_file_attr_system = -1;
+static int hf_smb_file_attr_volume = -1;
+static int hf_smb_file_attr_directory = -1;
+static int hf_smb_file_attr_archive = -1;
+static int hf_smb_file_attr_device = -1;
+static int hf_smb_file_attr_normal = -1;
+static int hf_smb_file_attr_temporary = -1;
+static int hf_smb_file_attr_sparse = -1;
+static int hf_smb_file_attr_reparse = -1;
+static int hf_smb_file_attr_compressed = -1;
+static int hf_smb_file_attr_offline = -1;
+static int hf_smb_file_attr_not_content_indexed = -1;
+static int hf_smb_file_attr_encrypted = -1;
+static int hf_smb_file_size = -1;
+static int hf_smb_last_write_time = -1;
+static int hf_smb_search_attribute_read_only = -1;
+static int hf_smb_search_attribute_hidden = -1;
+static int hf_smb_search_attribute_system = -1;
+static int hf_smb_search_attribute_volume = -1;
+static int hf_smb_search_attribute_directory = -1;
+static int hf_smb_search_attribute_archive = -1;
+static int hf_smb_access_mode = -1;
+static int hf_smb_access_sharing = -1;
+static int hf_smb_access_locality = -1;
+static int hf_smb_access_caching = -1;
+static int hf_smb_access_writetru = -1;
+static int hf_smb_create_time = -1;
+static int hf_smb_last_write_date = -1;
+static int hf_smb_last_write_dos_date = -1;
+static int hf_smb_last_write_dos_time = -1;
+static int hf_smb_old_file_name = -1;
+static int hf_smb_offset = -1;
+static int hf_smb_remaining = -1;
+static int hf_smb_padding = -1;
+static int hf_smb_file_data = -1;
+static int hf_smb_data_len = -1;
+static int hf_smb_seek_mode = -1;
static gint ett_smb = -1;
static gint ett_smb_time_date = -1;
static gint ett_smb_64bit_time = -1;
static gint ett_smb_move_flags = -1;
+static gint ett_smb_file_attributes = -1;
static char *decode_smb_name(unsigned char);
{0, NULL}
};
+/*
+ * UTIME - this is *almost* like a UNIX time stamp, except that it's
+ * in seconds since January 1, 1970, 00:00:00 *local* time, not since
+ * January 1, 1970, 00:00:00 GMT.
+ *
+ * This means we have to do some extra work to convert it. This code is
+ * based on the Samba code:
+ *
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * time handling functions
+ * Copyright (C) Andrew Tridgell 1992-1998
+ */
+
+/*
+ * Yield the difference between *A and *B, in seconds, ignoring leap
+ * seconds.
+ */
+#define TM_YEAR_BASE 1900
+
+static int
+tm_diff(struct tm *a, struct tm *b)
+{
+ int ay = a->tm_year + (TM_YEAR_BASE - 1);
+ int by = b->tm_year + (TM_YEAR_BASE - 1);
+ int intervening_leap_days =
+ (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
+ int years = ay - by;
+ int days =
+ 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
+ int hours = 24*days + (a->tm_hour - b->tm_hour);
+ int minutes = 60*hours + (a->tm_min - b->tm_min);
+ int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
+
+ return seconds;
+}
+
+/*
+ * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
+ * determined.
+ */
+static int
+TimeZone(time_t t)
+{
+ struct tm *tm = gmtime(&t);
+ struct tm tm_utc;
+
+ if (tm == NULL)
+ return 0;
+ tm_utc = *tm;
+ tm = localtime(&t);
+ if (tm == NULL)
+ return 0;
+ return tm_diff(&tm_utc,tm);
+}
+
+/*
+ * Return the same value as TimeZone, but it should be more efficient.
+ *
+ * We keep a table of DST offsets to prevent calling localtime() on each
+ * call of this function. This saves a LOT of time on many unixes.
+ *
+ * Updated by Paul Eggert <eggert@twinsun.com>
+ */
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef TIME_T_MIN
+#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
+ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
+#endif
+#ifndef TIME_T_MAX
+#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
+#endif
+
+static int
+TimeZoneFaster(time_t t)
+{
+ static struct dst_table {time_t start,end; int zone;} *tdt;
+ static struct dst_table *dst_table = NULL;
+ static int table_size = 0;
+ int i;
+ int zone = 0;
+
+ if (t == 0)
+ t = time(NULL);
+
+ /* Tunis has a 8 day DST region, we need to be careful ... */
+#define MAX_DST_WIDTH (365*24*60*60)
+#define MAX_DST_SKIP (7*24*60*60)
+
+ for (i = 0; i < table_size; i++) {
+ if (t >= dst_table[i].start && t <= dst_table[i].end)
+ break;
+ }
+
+ if (i < table_size) {
+ zone = dst_table[i].zone;
+ } else {
+ time_t low,high;
+
+ zone = TimeZone(t);
+ if (dst_table == NULL)
+ tdt = g_malloc(sizeof(dst_table[0])*(i+1));
+ else
+ tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
+ if (tdt == NULL) {
+ if (dst_table)
+ free(dst_table);
+ table_size = 0;
+ } else {
+ dst_table = tdt;
+ table_size++;
+
+ dst_table[i].zone = zone;
+ dst_table[i].start = dst_table[i].end = t;
+
+ /* no entry will cover more than 6 months */
+ low = t - MAX_DST_WIDTH/2;
+ if (t < low)
+ low = TIME_T_MIN;
+
+ high = t + MAX_DST_WIDTH/2;
+ if (high < t)
+ high = TIME_T_MAX;
+
+ /*
+ * Widen the new entry using two bisection searches.
+ */
+ while (low+60*60 < dst_table[i].start) {
+ if (dst_table[i].start - low > MAX_DST_SKIP*2)
+ t = dst_table[i].start - MAX_DST_SKIP;
+ else
+ t = low + (dst_table[i].start-low)/2;
+ if (TimeZone(t) == zone)
+ dst_table[i].start = t;
+ else
+ low = t;
+ }
+
+ while (high-60*60 > dst_table[i].end) {
+ if (high - dst_table[i].end > MAX_DST_SKIP*2)
+ t = dst_table[i].end + MAX_DST_SKIP;
+ else
+ t = high - (high-dst_table[i].end)/2;
+ if (TimeZone(t) == zone)
+ dst_table[i].end = t;
+ else
+ high = t;
+ }
+ }
+ }
+ return zone;
+}
+
+/*
+ * Return the UTC offset in seconds west of UTC, adjusted for extra time
+ * offset, for a local time value. If ut = lt + LocTimeDiff(lt), then
+ * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
+ * daylight savings transitions because some local times are ambiguous.
+ * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
+ */
+static int
+LocTimeDiff(time_t lt)
+{
+ int d = TimeZoneFaster(lt);
+ time_t t = lt + d;
+
+ /* if overflow occurred, ignore all the adjustments so far */
+ if (((t < lt) ^ (d < 0)))
+ t = lt;
+
+ /*
+ * Now t should be close enough to the true UTC to yield the
+ * right answer.
+ */
+ return TimeZoneFaster(t);
+}
+
+static int
+dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
+{
+ guint32 timeval;
+ nstime_t ts;
+
+ timeval = tvb_get_letohl(tvb, offset);
+ if (timeval == 0xffffffff) {
+ proto_tree_add_text(tree, tvb, offset, 4,
+ "%s: No time specified (0xffffffff)",
+ proto_registrar_get_name(hf_date));
+ offset += 4;
+ return offset;
+ }
+
+ /*
+ * We add the local time offset.
+ */
+ ts.secs = timeval + LocTimeDiff(timeval);
+ ts.nsecs = 0;
+
+ proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
+ offset += 4;
+
+ return offset;
+}
+
static int
dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date)
{
return offset;
}
+
+static const value_string da_access_vals[] = {
+ { 0x00, "Open for reading"},
+ { 0x01, "Open for writing"},
+ { 0x02, "Open for reading and writing"},
+ { 0x03, "Open for execute"},
+ {0, NULL}
+};
+static const value_string da_sharing_vals[] = {
+ { 0x00, "Compatibility mode"},
+ { 0x01, "Deny read/write/execute (exclusive)"},
+ { 0x02, "Deny write"},
+ { 0x03, "Deny read/execute"},
+ { 0x04, "Deny none"},
+ {0, NULL}
+};
+static const value_string da_locality_vals[] = {
+ { 0x00, "Locality of reference unknown"},
+ { 0x01, "Mainly sequential access"},
+ { 0x02, "Mainly random access"},
+ { 0x03, "Random access with some locality"},
+ {0, NULL}
+};
+static const true_false_string tfs_da_caching = {
+ "Do NOT cache this file",
+ "CACHING permitted on this file"
+};
+static const true_false_string tfs_da_writetru = {
+ "Writethrough ENABLED",
+ "Writethrough DISABLED"
+};
+static int
+dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
+{
+ guint16 mask;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+
+ mask = tvb_get_letohs(tvb, offset);
+
+ if(parent_tree){
+ item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+ "%s Access: 0x%04x", type, mask);
+ tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_access_writetru,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_access_caching,
+ tvb, offset, 2, mask);
+ proto_tree_add_uint(tree, hf_smb_access_locality,
+ tvb, offset, 2, mask);
+ proto_tree_add_uint(tree, hf_smb_access_sharing,
+ tvb, offset, 2, mask);
+ proto_tree_add_uint(tree, hf_smb_access_mode,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+#define FILE_ATTRIBUTE_READ_ONLY 0x00000001
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define FILE_ATTRIBUTE_VOLUME 0x00000008
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define FILE_ATTRIBUTE_DEVICE 0x00000040
+#define FILE_ATTRIBUTE_NORMAL 0x00000080
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define FILE_ATTRIBUTE_SPARSE 0x00000200
+#define FILE_ATTRIBUTE_REPARSE 0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+
+/*
+ * These are flags to be used in NT Create operations.
+ */
+#define FILE_ATTRIBUTE_WRITE_THROUGH 0x80000000
+#define FILE_ATTRIBUTE_NO_BUFFERING 0x20000000
+#define FILE_ATTRIBUTE_RANDOM_ACCESS 0x10000000
+#define FILE_ATTRIBUTE_SEQUENTIAL_SCAN 0x08000000
+#define FILE_ATTRIBUTE_DELETE_ON_CLOSE 0x04000000
+#define FILE_ATTRIBUTE_BACKUP_SEMANTICS 0x02000000
+#define FILE_ATTRIBUTE_POSIX_SEMANTICS 0x01000000
+
+static const true_false_string tfs_file_attribute_write_through = {
+ "This object requires WRITE THROUGH",
+ "This object does NOT require write through",
+};
+static const true_false_string tfs_file_attribute_no_buffering = {
+ "This object requires NO BUFFERING",
+ "This object can be buffered",
+};
+static const true_false_string tfs_file_attribute_random_access = {
+ "This object will be RANDOM ACCESSed",
+ "Random access is NOT requested",
+};
+static const true_false_string tfs_file_attribute_sequential_scan = {
+ "This object is optimized for SEQUENTIAL SCAN",
+ "This object is NOT optimized for sequential scan",
+};
+static const true_false_string tfs_file_attribute_delete_on_close = {
+ "This object will be DELETED ON CLOSE",
+ "This object will not be deleted on close",
+};
+static const true_false_string tfs_file_attribute_backup_semantics = {
+ "This object supports BACKUP SEMANTICS",
+ "This object does NOT support backup semantics",
+};
+static const true_false_string tfs_file_attribute_posix_semantics = {
+ "This object supports POSIX SEMANTICS",
+ "This object does NOT support posix semantics",
+};
+static const true_false_string tfs_file_attribute_read_only = {
+ "This file is READ ONLY",
+ "This file is NOT read only",
+};
+static const true_false_string tfs_file_attribute_hidden = {
+ "This is a HIDDEN file",
+ "This is NOT a hidden file"
+};
+static const true_false_string tfs_file_attribute_system = {
+ "This is a SYSTEM file",
+ "This is NOT a system file"
+};
+static const true_false_string tfs_file_attribute_volume = {
+ "This is a volume ID",
+ "This is NOT a volume ID"
+};
+static const true_false_string tfs_file_attribute_directory = {
+ "This is a DIRECTORY",
+ "This is NOT a directory"
+};
+static const true_false_string tfs_file_attribute_archive = {
+ "This is an ARCHIVE file",
+ "This is NOT an archive file"
+};
+static const true_false_string tfs_file_attribute_device = {
+ "This is a DEVICE",
+ "This is NOT a device"
+};
+static const true_false_string tfs_file_attribute_normal = {
+ "This file is an ordinary file",
+ "This file has some attribute set"
+};
+static const true_false_string tfs_file_attribute_temporary = {
+ "This is a TEMPORARY file",
+ "This is NOT a temporary file"
+};
+static const true_false_string tfs_file_attribute_sparse = {
+ "This is a SPARSE file",
+ "This is NOT a sparse file"
+};
+static const true_false_string tfs_file_attribute_reparse = {
+ "This file has an associated REPARSE POINT",
+ "This file does NOT have an associated reparse point"
+};
+static const true_false_string tfs_file_attribute_compressed = {
+ "This is a COMPRESSED file",
+ "This is NOT a compressed file"
+};
+static const true_false_string tfs_file_attribute_offline = {
+ "This file is OFFLINE",
+ "This file is NOT offline"
+};
+static const true_false_string tfs_file_attribute_not_content_indexed = {
+ "This file MAY NOT be indexed by the CONTENT INDEXING service",
+ "This file MAY be indexed by the content indexing service"
+};
+static const true_false_string tfs_file_attribute_encrypted = {
+ "This is an ENCRYPTED file",
+ "This is NOT an encrypted file"
+};
+
+static int
+dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+{
+ guint16 mask;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+
+ mask = tvb_get_letohs(tvb, offset);
+
+ if(parent_tree){
+ item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+ "File Attributes: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_file_attributes);
+ }
+ proto_tree_add_boolean(tree, hf_smb_file_attr_read_only,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_hidden,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_system,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_volume,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_directory,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_archive,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+static int
+dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+{
+ guint16 mask;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+
+ mask = tvb_get_letohs(tvb, offset);
+
+ if(parent_tree){
+ item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+ "Search Attributes: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_search);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+ return offset;
+}
+
+static int
+dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+{
+ guint32 mask;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+
+ mask = tvb_get_letohl(tvb, offset);
+
+ if(parent_tree){
+ item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+ "File Attributes: 0x%08x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_file_attributes);
+ }
+ proto_tree_add_boolean(tree, hf_smb_file_attr_read_only,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_hidden,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_system,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_volume,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_directory,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_archive,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_device,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+
#define SERVER_CAP_RAW_MODE 0x00000001
#define SERVER_CAP_MPX_MODE 0x00000002
#define SERVER_CAP_UNICODE 0x00000004
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 2,
- "Open Function: 0x%04x ", mask);
+ "Open Function: 0x%04x", mask);
tree = proto_item_add_subtree(item, ett_smb_openfunction);
}
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 2,
- "Flags: 0x%04x ", mask);
+ "Flags: 0x%04x", mask);
tree = proto_item_add_subtree(item, ett_smb_move_flags);
}
return offset;
}
+
+static int
+dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
+
+ WORD_COUNT;
+
+ /* desired access */
+ offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+
+ /* Search Attributes */
+ offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+
+ BYTE_COUNT;
+
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
+
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
+
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
+
+ END_OF_SMB
+
+ return offset;
+}
+static int
+dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
+ WORD_COUNT;
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+ /* File Attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
-typedef struct _smb_function {
- int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
- int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
-} smb_function;
+ /* last write time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+
+ /* File Size */
+ proto_tree_add_uint(tree, hf_smb_file_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
-smb_function smb_dissector[256] = {
- /* 0x00 Create Dir*/ {dissect_old_dir_request, dissect_empty},
- /* 0x01 Delete Dir*/ {dissect_old_dir_request, dissect_empty},
- /* 0x02 */ {NULL, NULL},
- /* 0x03 */ {NULL, NULL},
- /* 0x04 */ {NULL, NULL},
- /* 0x05 */ {NULL, NULL},
- /* 0x06 */ {NULL, NULL},
- /* 0x07 */ {NULL, NULL},
- /* 0x08 */ {NULL, NULL},
- /* 0x09 */ {NULL, NULL},
- /* 0x0a */ {NULL, NULL},
- /* 0x0b */ {NULL, NULL},
- /* 0x0c */ {NULL, NULL},
- /* 0x0d */ {NULL, NULL},
- /* 0x0e */ {NULL, NULL},
- /* 0x0f */ {NULL, NULL},
- /* 0x10 Check Dir*/ {dissect_old_dir_request, dissect_empty},
- /* 0x11 Process Exit*/ {dissect_empty, dissect_empty},
- /* 0x12 */ {NULL, NULL},
- /* 0x13 */ {NULL, NULL},
- /* 0x14 */ {NULL, NULL},
- /* 0x15 */ {NULL, NULL},
- /* 0x16 */ {NULL, NULL},
- /* 0x17 */ {NULL, NULL},
- /* 0x18 */ {NULL, NULL},
- /* 0x19 */ {NULL, NULL},
- /* 0x1a */ {NULL, NULL},
- /* 0x1b */ {NULL, NULL},
- /* 0x1c */ {NULL, NULL},
- /* 0x1d */ {NULL, NULL},
- /* 0x1e */ {NULL, NULL},
- /* 0x1f */ {NULL, NULL},
- /* 0x20 */ {NULL, NULL},
- /* 0x21 */ {NULL, NULL},
- /* 0x22 */ {NULL, NULL},
- /* 0x23 */ {NULL, NULL},
- /* 0x24 */ {NULL, NULL},
- /* 0x25 */ {NULL, NULL},
- /* 0x26 */ {NULL, NULL},
- /* 0x27 */ {NULL, NULL},
- /* 0x28 */ {NULL, NULL},
- /* 0x29 */ {NULL, NULL},
- /* 0x2a Move File*/ {dissect_move_request, dissect_move_response},
- /* 0x2b Echo*/ {dissect_echo_request, dissect_echo_response},
- /* 0x2c */ {NULL, NULL},
- /* 0x2d */ {NULL, NULL},
- /* 0x2e */ {NULL, NULL},
- /* 0x2f */ {NULL, NULL},
- /* 0x30 */ {NULL, NULL},
- /* 0x31 */ {NULL, NULL},
- /* 0x32 */ {NULL, NULL},
- /* 0x33 */ {NULL, NULL},
- /* 0x34 */ {NULL, NULL},
- /* 0x35 */ {NULL, NULL},
- /* 0x36 */ {NULL, NULL},
- /* 0x37 */ {NULL, NULL},
- /* 0x38 */ {NULL, NULL},
- /* 0x39 */ {NULL, NULL},
- /* 0x3a */ {NULL, NULL},
- /* 0x3b */ {NULL, NULL},
- /* 0x3c */ {NULL, NULL},
- /* 0x3d */ {NULL, NULL},
- /* 0x3e */ {NULL, NULL},
- /* 0x3f */ {NULL, NULL},
- /* 0x40 */ {NULL, NULL},
- /* 0x41 */ {NULL, NULL},
- /* 0x42 */ {NULL, NULL},
- /* 0x43 */ {NULL, NULL},
- /* 0x44 */ {NULL, NULL},
- /* 0x45 */ {NULL, NULL},
- /* 0x46 */ {NULL, NULL},
- /* 0x47 */ {NULL, NULL},
- /* 0x48 */ {NULL, NULL},
- /* 0x49 */ {NULL, NULL},
- /* 0x4a */ {NULL, NULL},
- /* 0x4b */ {NULL, NULL},
- /* 0x4c */ {NULL, NULL},
- /* 0x4d */ {NULL, NULL},
- /* 0x4e */ {NULL, NULL},
- /* 0x4f */ {NULL, NULL},
- /* 0x50 */ {NULL, NULL},
- /* 0x51 */ {NULL, NULL},
- /* 0x52 */ {NULL, NULL},
- /* 0x53 */ {NULL, NULL},
- /* 0x54 */ {NULL, NULL},
- /* 0x55 */ {NULL, NULL},
- /* 0x56 */ {NULL, NULL},
- /* 0x57 */ {NULL, NULL},
- /* 0x58 */ {NULL, NULL},
- /* 0x59 */ {NULL, NULL},
- /* 0x5a */ {NULL, NULL},
- /* 0x5b */ {NULL, NULL},
- /* 0x5c */ {NULL, NULL},
- /* 0x5d */ {NULL, NULL},
- /* 0x5e */ {NULL, NULL},
- /* 0x5f */ {NULL, NULL},
- /* 0x60 */ {NULL, NULL},
- /* 0x61 */ {NULL, NULL},
- /* 0x62 */ {NULL, NULL},
- /* 0x63 */ {NULL, NULL},
- /* 0x64 */ {NULL, NULL},
- /* 0x65 */ {NULL, NULL},
- /* 0x66 */ {NULL, NULL},
- /* 0x67 */ {NULL, NULL},
- /* 0x68 */ {NULL, NULL},
- /* 0x69 */ {NULL, NULL},
- /* 0x6a */ {NULL, NULL},
- /* 0x6b */ {NULL, NULL},
- /* 0x6c */ {NULL, NULL},
- /* 0x6d */ {NULL, NULL},
- /* 0x6e */ {NULL, NULL},
- /* 0x6f */ {NULL, NULL},
- /* 0x70 Tree Connect*/ {dissect_tree_connect_request, dissect_tree_connect_response},
- /* 0x71 Tree Disconnect*/ {dissect_empty, dissect_empty},
- /* 0x72 Negotiate Protocol*/ {dissect_negprot_request, dissect_negprot_response},
- /* 0x73 */ {NULL, NULL},
- /* 0x74 */ {NULL, NULL},
- /* 0x75 */ {NULL, NULL},
- /* 0x76 */ {NULL, NULL},
- /* 0x77 */ {NULL, NULL},
- /* 0x78 */ {NULL, NULL},
- /* 0x79 */ {NULL, NULL},
- /* 0x7a */ {NULL, NULL},
- /* 0x7b */ {NULL, NULL},
- /* 0x7c */ {NULL, NULL},
- /* 0x7d */ {NULL, NULL},
- /* 0x7e */ {NULL, NULL},
- /* 0x7f */ {NULL, NULL},
- /* 0x80 */ {NULL, NULL},
- /* 0x81 */ {NULL, NULL},
- /* 0x82 */ {NULL, NULL},
- /* 0x83 */ {NULL, NULL},
- /* 0x84 */ {NULL, NULL},
- /* 0x85 */ {NULL, NULL},
- /* 0x86 */ {NULL, NULL},
- /* 0x87 */ {NULL, NULL},
- /* 0x88 */ {NULL, NULL},
- /* 0x89 */ {NULL, NULL},
- /* 0x8a */ {NULL, NULL},
- /* 0x8b */ {NULL, NULL},
- /* 0x8c */ {NULL, NULL},
- /* 0x8d */ {NULL, NULL},
- /* 0x8e */ {NULL, NULL},
- /* 0x8f */ {NULL, NULL},
- /* 0x90 */ {NULL, NULL},
- /* 0x91 */ {NULL, NULL},
- /* 0x92 */ {NULL, NULL},
- /* 0x93 */ {NULL, NULL},
- /* 0x94 */ {NULL, NULL},
- /* 0x95 */ {NULL, NULL},
- /* 0x96 */ {NULL, NULL},
- /* 0x97 */ {NULL, NULL},
- /* 0x98 */ {NULL, NULL},
- /* 0x99 */ {NULL, NULL},
- /* 0x9a */ {NULL, NULL},
- /* 0x9b */ {NULL, NULL},
- /* 0x9c */ {NULL, NULL},
- /* 0x9d */ {NULL, NULL},
- /* 0x9e */ {NULL, NULL},
- /* 0x9f */ {NULL, NULL},
- /* 0xa0 */ {NULL, NULL},
- /* 0xa1 */ {NULL, NULL},
- /* 0xa2 */ {NULL, NULL},
- /* 0xa3 */ {NULL, NULL},
- /* 0xa4 */ {NULL, NULL},
- /* 0xa5 */ {NULL, NULL},
- /* 0xa6 */ {NULL, NULL},
- /* 0xa7 */ {NULL, NULL},
- /* 0xa8 */ {NULL, NULL},
- /* 0xa9 */ {NULL, NULL},
- /* 0xaa */ {NULL, NULL},
- /* 0xab */ {NULL, NULL},
- /* 0xac */ {NULL, NULL},
- /* 0xad */ {NULL, NULL},
- /* 0xae */ {NULL, NULL},
- /* 0xaf */ {NULL, NULL},
- /* 0xb0 */ {NULL, NULL},
- /* 0xb1 */ {NULL, NULL},
- /* 0xb2 */ {NULL, NULL},
- /* 0xb3 */ {NULL, NULL},
- /* 0xb4 */ {NULL, NULL},
- /* 0xb5 */ {NULL, NULL},
- /* 0xb6 */ {NULL, NULL},
- /* 0xb7 */ {NULL, NULL},
- /* 0xb8 */ {NULL, NULL},
- /* 0xb9 */ {NULL, NULL},
- /* 0xba */ {NULL, NULL},
- /* 0xbb */ {NULL, NULL},
- /* 0xbc */ {NULL, NULL},
- /* 0xbd */ {NULL, NULL},
- /* 0xbe */ {NULL, NULL},
- /* 0xbf */ {NULL, NULL},
- /* 0xc0 */ {NULL, NULL},
- /* 0xc1 */ {NULL, NULL},
- /* 0xc2 */ {NULL, NULL},
- /* 0xc3 */ {NULL, NULL},
- /* 0xc4 */ {NULL, NULL},
- /* 0xc5 */ {NULL, NULL},
- /* 0xc6 */ {NULL, NULL},
- /* 0xc7 */ {NULL, NULL},
- /* 0xc8 */ {NULL, NULL},
- /* 0xc9 */ {NULL, NULL},
- /* 0xca */ {NULL, NULL},
- /* 0xcb */ {NULL, NULL},
- /* 0xcc */ {NULL, NULL},
- /* 0xcd */ {NULL, NULL},
- /* 0xce */ {NULL, NULL},
- /* 0xcf */ {NULL, NULL},
- /* 0xd0 */ {NULL, NULL},
- /* 0xd1 */ {NULL, NULL},
- /* 0xd2 */ {NULL, NULL},
- /* 0xd3 */ {NULL, NULL},
- /* 0xd4 */ {NULL, NULL},
- /* 0xd5 */ {NULL, NULL},
- /* 0xd6 */ {NULL, NULL},
- /* 0xd7 */ {NULL, NULL},
- /* 0xd8 */ {NULL, NULL},
- /* 0xd9 */ {NULL, NULL},
- /* 0xda */ {NULL, NULL},
- /* 0xdb */ {NULL, NULL},
- /* 0xdc */ {NULL, NULL},
- /* 0xdd */ {NULL, NULL},
- /* 0xde */ {NULL, NULL},
- /* 0xdf */ {NULL, NULL},
- /* 0xe0 */ {NULL, NULL},
- /* 0xe1 */ {NULL, NULL},
- /* 0xe2 */ {NULL, NULL},
- /* 0xe3 */ {NULL, NULL},
- /* 0xe4 */ {NULL, NULL},
- /* 0xe5 */ {NULL, NULL},
- /* 0xe6 */ {NULL, NULL},
- /* 0xe7 */ {NULL, NULL},
- /* 0xe8 */ {NULL, NULL},
- /* 0xe9 */ {NULL, NULL},
- /* 0xea */ {NULL, NULL},
- /* 0xeb */ {NULL, NULL},
- /* 0xec */ {NULL, NULL},
- /* 0xed */ {NULL, NULL},
- /* 0xee */ {NULL, NULL},
- /* 0xef */ {NULL, NULL},
- /* 0xf0 */ {NULL, NULL},
- /* 0xf1 */ {NULL, NULL},
- /* 0xf2 */ {NULL, NULL},
- /* 0xf3 */ {NULL, NULL},
- /* 0xf4 */ {NULL, NULL},
- /* 0xf5 */ {NULL, NULL},
- /* 0xf6 */ {NULL, NULL},
- /* 0xf7 */ {NULL, NULL},
- /* 0xf8 */ {NULL, NULL},
- /* 0xf9 */ {NULL, NULL},
- /* 0xfa */ {NULL, NULL},
- /* 0xfb */ {NULL, NULL},
- /* 0xfc */ {NULL, NULL},
- /* 0xfd */ {NULL, NULL},
- /* 0xfe */ {NULL, NULL},
- /* 0xff */ {NULL, NULL},
-};
+ /* granted access */
+ offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+
+ BYTE_COUNT;
+ END_OF_SMB
+
+ return offset;
+}
static int
-dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
+dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- int old_offset = offset;
- smb_info_t *si;
-
- si = pinfo->private_data;
- if(cmd!=0xff){
- proto_item *cmd_item;
- proto_tree *cmd_tree;
- int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
+ guint8 wc;
+ guint16 bc;
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "%s %s",
- decode_smb_name(cmd),
- (si->request)? "Request" : "Response");
- }
+ WORD_COUNT;
- cmd_item = proto_tree_add_text(smb_tree, tvb, offset,
- 0, "%s %s (0x%02x)",
- decode_smb_name(cmd),
- (si->request)?"Request":"Response",
- cmd);
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
- cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
+ BYTE_COUNT;
- dissector = (si->request)?
- smb_dissector[cmd].request:smb_dissector[cmd].response;
+ END_OF_SMB
- if(dissector){
- offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
- }
- proto_item_set_len(cmd_item, offset-old_offset);
+ return offset;
+}
+
+static int
+dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
+
+ WORD_COUNT;
+
+ /* file attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+ /* creation time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+
+ BYTE_COUNT;
+
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
+
+ /* File Name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
+
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
}
+
+ END_OF_SMB
+
return offset;
}
+static int
+dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
-/* NOTE: this value_string array will also be used to access data directly by
- * index instead of val_to_str() since
- * 1, the array will always span every value from 0x00 to 0xff and
- * 2, smb_cmd_vals[i].strptr is much cheaper than val_to_str(i, smb_cmd_vals,)
- * This means that this value_string array MUST always
- * 1, contain all entries 0x00 to 0xff
- * 2, all entries must be in order.
- */
-static const value_string smb_cmd_vals[] = {
- { 0x00, "Create Directory" },
- { 0x01, "Delete Directory" },
- { 0x02, "Open" },
- { 0x03, "Create" },
- { 0x04, "Close" },
- { 0x05, "Flush" },
- { 0x06, "Delete" },
- { 0x07, "Rename" },
- { 0x08, "Query Information" },
- { 0x09, "Set Information" },
- { 0x0A, "Read" },
- { 0x0B, "Write" },
- { 0x0C, "Lock Byte Range" },
- { 0x0D, "Unlock Byte Range" },
- { 0x0E, "Create Temp" },
- { 0x0F, "Create New" },
- { 0x10, "Check Directory" },
- { 0x11, "Process Exit" },
- { 0x12, "Seek" },
- { 0x13, "Lock And Read" },
- { 0x14, "Write And Unlock" },
- { 0x15, "unknown-0x15" },
- { 0x16, "unknown-0x16" },
- { 0x17, "unknown-0x17" },
- { 0x18, "unknown-0x18" },
- { 0x19, "unknown-0x19" },
- { 0x1A, "Read Raw" },
- { 0x1B, "Read MPX" },
- { 0x1C, "Read MPX Secondary" },
- { 0x1D, "Write Raw" },
- { 0x1E, "Write MPX" },
- { 0x1F, "SMBwriteBs" },
- { 0x20, "Write Complete" },
- { 0x21, "unknown-0x21" },
- { 0x22, "Set Information2" },
- { 0x23, "Query Information2" },
- { 0x24, "Locking AndX" },
- { 0x25, "Transaction" },
- { 0x26, "Transaction Secondary" },
- { 0x27, "IOCTL" },
- { 0x28, "IOCTL Secondary" },
- { 0x29, "Copy" },
- { 0x2A, "Move" },
- { 0x2B, "Echo" },
- { 0x2C, "Write And Close" },
- { 0x2D, "Open AndX" },
- { 0x2E, "Read AndX" },
- { 0x2F, "Write AndX" },
- { 0x30, "unknown-0x30" },
- { 0x31, "Close And Tree Discover" },
- { 0x32, "Transaction2" },
- { 0x33, "Transaction2 Secondary" },
- { 0x34, "Find Close2" },
- { 0x35, "Find Notify Close" },
- { 0x36, "unknown-0x36" },
- { 0x37, "unknown-0x37" },
- { 0x38, "unknown-0x38" },
- { 0x39, "unknown-0x39" },
- { 0x3A, "unknown-0x3A" },
- { 0x3B, "unknown-0x3B" },
- { 0x3C, "unknown-0x3C" },
- { 0x3D, "unknown-0x3D" },
- { 0x3E, "unknown-0x3E" },
- { 0x3F, "unknown-0x3F" },
- { 0x40, "unknown-0x40" },
- { 0x41, "unknown-0x41" },
- { 0x42, "unknown-0x42" },
- { 0x43, "unknown-0x43" },
- { 0x44, "unknown-0x44" },
- { 0x45, "unknown-0x45" },
- { 0x46, "unknown-0x46" },
- { 0x47, "unknown-0x47" },
- { 0x48, "unknown-0x48" },
- { 0x49, "unknown-0x49" },
- { 0x4A, "unknown-0x4A" },
- { 0x4B, "unknown-0x4B" },
- { 0x4C, "unknown-0x4C" },
- { 0x4D, "unknown-0x4D" },
- { 0x4E, "unknown-0x4E" },
- { 0x4F, "unknown-0x4F" },
- { 0x50, "unknown-0x50" },
- { 0x51, "unknown-0x51" },
- { 0x52, "unknown-0x52" },
- { 0x53, "unknown-0x53" },
- { 0x54, "unknown-0x54" },
- { 0x55, "unknown-0x55" },
- { 0x56, "unknown-0x56" },
- { 0x57, "unknown-0x57" },
- { 0x58, "unknown-0x58" },
- { 0x59, "unknown-0x59" },
- { 0x5A, "unknown-0x5A" },
- { 0x5B, "unknown-0x5B" },
- { 0x5C, "unknown-0x5C" },
- { 0x5D, "unknown-0x5D" },
- { 0x5E, "unknown-0x5E" },
- { 0x5F, "unknown-0x5F" },
- { 0x60, "unknown-0x60" },
- { 0x61, "unknown-0x61" },
- { 0x62, "unknown-0x62" },
- { 0x63, "unknown-0x63" },
- { 0x64, "unknown-0x64" },
- { 0x65, "unknown-0x65" },
- { 0x66, "unknown-0x66" },
- { 0x67, "unknown-0x67" },
- { 0x68, "unknown-0x68" },
- { 0x69, "unknown-0x69" },
- { 0x6A, "unknown-0x6A" },
- { 0x6B, "unknown-0x6B" },
- { 0x6C, "unknown-0x6C" },
- { 0x6D, "unknown-0x6D" },
- { 0x6E, "unknown-0x6E" },
- { 0x6F, "unknown-0x6F" },
- { 0x70, "Tree Connect" },
- { 0x71, "Tree Disconnect" },
- { 0x72, "Negotiate Protocol" },
- { 0x73, "Session Setup AndX" },
- { 0x74, "Logoff AndX" },
- { 0x75, "Tree Connect AndX" },
- { 0x76, "unknown-0x76" },
- { 0x77, "unknown-0x77" },
- { 0x78, "unknown-0x78" },
- { 0x79, "unknown-0x79" },
- { 0x7A, "unknown-0x7A" },
- { 0x7B, "unknown-0x7B" },
- { 0x7C, "unknown-0x7C" },
- { 0x7D, "unknown-0x7D" },
- { 0x7E, "unknown-0x7E" },
- { 0x7F, "unknown-0x7F" },
- { 0x80, "Query Information Disk" },
- { 0x81, "Search" },
- { 0x82, "Find" },
- { 0x83, "Find Unique" },
- { 0x84, "SMBfclose" },
- { 0x85, "unknown-0x85" },
- { 0x86, "unknown-0x86" },
- { 0x87, "unknown-0x87" },
- { 0x88, "unknown-0x88" },
- { 0x89, "unknown-0x89" },
- { 0x8A, "unknown-0x8A" },
- { 0x8B, "unknown-0x8B" },
- { 0x8C, "unknown-0x8C" },
- { 0x8D, "unknown-0x8D" },
- { 0x8E, "unknown-0x8E" },
- { 0x8F, "unknown-0x8F" },
- { 0x90, "unknown-0x90" },
- { 0x91, "unknown-0x91" },
- { 0x92, "unknown-0x92" },
- { 0x93, "unknown-0x93" },
- { 0x94, "unknown-0x94" },
- { 0x95, "unknown-0x95" },
- { 0x96, "unknown-0x96" },
- { 0x97, "unknown-0x97" },
- { 0x98, "unknown-0x98" },
- { 0x99, "unknown-0x99" },
- { 0x9A, "unknown-0x9A" },
- { 0x9B, "unknown-0x9B" },
- { 0x9C, "unknown-0x9C" },
- { 0x9D, "unknown-0x9D" },
- { 0x9E, "unknown-0x9E" },
- { 0x9F, "unknown-0x9F" },
- { 0xA0, "NT Transact" },
- { 0xA1, "NT Transact Secondary" },
- { 0xA2, "NT Create AndX" },
- { 0xA3, "unknown-0xA3" },
- { 0xA4, "NT Cancel" },
- { 0xA5, "unknown-0xA5" },
- { 0xA6, "unknown-0xA6" },
- { 0xA7, "unknown-0xA7" },
- { 0xA8, "unknown-0xA8" },
- { 0xA9, "unknown-0xA9" },
- { 0xAA, "unknown-0xAA" },
- { 0xAB, "unknown-0xAB" },
- { 0xAC, "unknown-0xAC" },
- { 0xAD, "unknown-0xAD" },
- { 0xAE, "unknown-0xAE" },
- { 0xAF, "unknown-0xAF" },
- { 0xB0, "unknown-0xB0" },
- { 0xB1, "unknown-0xB1" },
- { 0xB2, "unknown-0xB2" },
- { 0xB3, "unknown-0xB3" },
- { 0xB4, "unknown-0xB4" },
- { 0xB5, "unknown-0xB5" },
- { 0xB6, "unknown-0xB6" },
- { 0xB7, "unknown-0xB7" },
- { 0xB8, "unknown-0xB8" },
- { 0xB9, "unknown-0xB9" },
- { 0xBA, "unknown-0xBA" },
- { 0xBB, "unknown-0xBB" },
- { 0xBC, "unknown-0xBC" },
- { 0xBD, "unknown-0xBD" },
- { 0xBE, "unknown-0xBE" },
- { 0xBF, "unknown-0xBF" },
- { 0xC0, "Open Print File" },
- { 0xC1, "Write Print File" },
- { 0xC2, "Close Print File" },
- { 0xC3, "Get Print Queue" },
- { 0xC4, "unknown-0xC4" },
- { 0xC5, "unknown-0xC5" },
- { 0xC6, "unknown-0xC6" },
- { 0xC7, "unknown-0xC7" },
- { 0xC8, "unknown-0xC8" },
- { 0xC9, "unknown-0xC9" },
- { 0xCA, "unknown-0xCA" },
- { 0xCB, "unknown-0xCB" },
- { 0xCC, "unknown-0xCC" },
- { 0xCD, "unknown-0xCD" },
- { 0xCE, "unknown-0xCE" },
- { 0xCF, "unknown-0xCF" },
- { 0xD0, "SMBsends" },
- { 0xD1, "SMBsendb" },
- { 0xD2, "SMBfwdname" },
- { 0xD3, "SMBcancelf" },
- { 0xD4, "SMBgetmac" },
- { 0xD5, "SMBsendstrt" },
- { 0xD6, "SMBsendend" },
- { 0xD7, "SMBsendtxt" },
- { 0xD8, "SMBreadbulk" },
- { 0xD9, "SMBwritebulk" },
- { 0xDA, "SMBwritebulkdata" },
- { 0xDB, "unknown-0xDB" },
- { 0xDC, "unknown-0xDC" },
- { 0xDD, "unknown-0xDD" },
- { 0xDE, "unknown-0xDE" },
- { 0xDF, "unknown-0xDF" },
- { 0xE0, "unknown-0xE0" },
- { 0xE1, "unknown-0xE1" },
- { 0xE2, "unknown-0xE2" },
- { 0xE3, "unknown-0xE3" },
- { 0xE4, "unknown-0xE4" },
- { 0xE5, "unknown-0xE5" },
- { 0xE6, "unknown-0xE6" },
- { 0xE7, "unknown-0xE7" },
- { 0xE8, "unknown-0xE8" },
- { 0xE9, "unknown-0xE9" },
- { 0xEA, "unknown-0xEA" },
- { 0xEB, "unknown-0xEB" },
- { 0xEC, "unknown-0xEC" },
- { 0xED, "unknown-0xED" },
- { 0xEE, "unknown-0xEE" },
- { 0xEF, "unknown-0xEF" },
- { 0xF0, "unknown-0xF0" },
- { 0xF1, "unknown-0xF1" },
- { 0xF2, "unknown-0xF2" },
- { 0xF3, "unknown-0xF3" },
- { 0xF4, "unknown-0xF4" },
- { 0xF5, "unknown-0xF5" },
- { 0xF6, "unknown-0xF6" },
- { 0xF7, "unknown-0xF7" },
- { 0xF8, "unknown-0xF8" },
- { 0xF9, "unknown-0xF9" },
- { 0xFA, "unknown-0xFA" },
- { 0xFB, "unknown-0xFB" },
- { 0xFC, "unknown-0xFC" },
- { 0xFD, "unknown-0xFD" },
- { 0xFE, "SMBinvalid" },
- { 0xFF, "unknown-0xFF" },
- { 0x00, NULL },
-};
+ WORD_COUNT;
-static char *decode_smb_name(unsigned char cmd)
-{
- return(smb_cmd_vals[cmd].strptr);
-}
-
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+ /* last write time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- * Everything TVBUFFIFIED above this line
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+ BYTE_COUNT;
+ END_OF_SMB
-/*
- * Struct passed to each SMB decode routine of info it may need
- */
+ return offset;
+}
+static int
+dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
-int smb_packet_init_count = 200;
+ WORD_COUNT;
-/*
- * This is a hash table matching transaction requests and replies.
- *
- * Unfortunately, the MID is not a transaction ID in, say, the ONC RPC
- * sense; instead, it's a "multiplex ID" used when there's more than one
- * request *currently* in flight, to distinguish replies.
- *
- * This means that the MID and PID don't uniquely identify a request in
- * a conversation.
- *
- * Therefore, we have to use some other value to distinguish between
- * requests with the same MID and PID.
- *
- * On the first pass through the capture, when we first see a request,
- * we hash it by conversation, MID, and PID.
- *
- * When we first see a reply to it, we add it to a new hash table,
- * hashing it by conversation, MID, PID, and frame number of the reply.
- *
- * This works as long as
- *
- * 1) a client doesn't screw up and have multiple requests outstanding
- * with the same MID and PID
- *
- * and
- *
- * 2) we don't have, within the same frame, replies to multiple
- * requests with the same MID and PID.
- *
- * 2) should happen only if the server screws up and puts the wrong MID or
- * PID into a reply (in which case not only can we not handle this, the
- * client can't handle it either) or if the client has screwed up as per
- * 1) and the server's dutifully replied to both of the requests with the
- * same MID and PID (in which case, again, neither we nor the client can
- * handle this).
- *
- * We don't have to correctly dissect screwups; we just have to keep from
- * dumping core on them.
- *
- * XXX - in addition, we need to keep a hash table of replies, so that we
- * can associate continuations with the reply to which they're a continuation.
- */
-struct smb_request_key {
- guint32 conversation;
- guint16 mid;
- guint16 pid;
- guint32 frame_num;
-};
+ /* search attributes */
+ offset = dissect_search_attributes(tvb, pinfo, tree, offset);
-static GHashTable *smb_request_hash = NULL;
-static GMemChunk *smb_request_keys = NULL;
-static GMemChunk *smb_request_vals = NULL;
+ BYTE_COUNT;
-/*
- * This is a hash table matching continued transation replies and their
- * continuations.
- *
- * It works similarly to the request/reply hash table.
- */
-static GHashTable *smb_continuation_hash = NULL;
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
-static GMemChunk *smb_continuation_vals = NULL;
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
-/* Hash Functions */
-static gint
-smb_equal(gconstpointer v, gconstpointer w)
-{
- struct smb_request_key *v1 = (struct smb_request_key *)v;
- struct smb_request_key *v2 = (struct smb_request_key *)w;
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
-#if defined(DEBUG_SMB_HASH)
- printf("Comparing %08X:%u:%u:%u\n and %08X:%u:%u:%u\n",
- v1 -> conversation, v1 -> mid, v1 -> pid, v1 -> frame_num,
- v2 -> conversation, v2 -> mid, v2 -> pid, v2 -> frame_num);
-#endif
+ END_OF_SMB
- if (v1 -> conversation == v2 -> conversation &&
- v1 -> mid == v2 -> mid &&
- v1 -> pid == v2 -> pid &&
- v1 -> frame_num == v2 -> frame_num) {
+ return offset;
+}
- return 1;
+static int
+dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
- }
+ WORD_COUNT;
- return 0;
-}
+ /* file attributes */
+ offset = dissect_search_attributes(tvb, pinfo, tree, offset);
-static guint
-smb_hash (gconstpointer v)
-{
- struct smb_request_key *key = (struct smb_request_key *)v;
- guint val;
+ BYTE_COUNT;
- val = (key -> conversation) + (key -> mid) + (key -> pid) +
- (key -> frame_num);
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
-#if defined(DEBUG_SMB_HASH)
- printf("SMB Hash calculated as %u\n", val);
-#endif
+ /* old file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
- return val;
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Old Name: %s", fn);
+ }
-}
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
-/*
- * Free up any state information we've saved, and re-initialize the
- * tables of state information.
- */
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
-/*
- * For a hash table entry, free the address data to which the key refers
- * and the fragment data to which the value refers.
- * (The actual key and value structures get freed by "reassemble_init()".)
- */
-static gboolean
-free_request_val_data(gpointer key, gpointer value, gpointer user_data)
-{
- struct smb_request_val *request_val = value;
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", New Name: %s", fn);
+ }
- if (request_val->last_transact_command != NULL)
- g_free(request_val->last_transact_command);
- if (request_val->last_param_descrip != NULL)
- g_free(request_val->last_param_descrip);
- if (request_val->last_data_descrip != NULL)
- g_free(request_val->last_data_descrip);
- if (request_val->last_aux_data_descrip != NULL)
- g_free(request_val->last_aux_data_descrip);
- return TRUE;
+ END_OF_SMB
+
+ return offset;
}
-static struct smb_request_val *
-do_transaction_hashing(conversation_t *conversation, struct smb_info si,
- frame_data *fd)
+static int
+dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- struct smb_request_key request_key, *new_request_key;
- struct smb_request_val *request_val = NULL;
- gpointer new_request_key_ret, request_val_ret;
+ guint16 bc;
+ guint8 wc;
+ const char *fn;
+ int fn_len;
- if (si.request) {
- /*
- * This is a request.
- *
- * If this is the first time the frame has been seen, check for
- * an entry for the request in the hash table. If it's not found,
- * insert an entry for it.
- *
- * If it's the first time it's been seen, then we can't have seen
- * the reply yet, so the reply frame number should be 0, for
- * "unknown".
- */
- if (!fd->flags.visited) {
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = 0;
+ WORD_COUNT;
- request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
+ BYTE_COUNT;
- if (request_val == NULL) {
- /*
- * Not found.
- */
- new_request_key = g_mem_chunk_alloc(smb_request_keys);
- new_request_key -> conversation = conversation->index;
- new_request_key -> mid = si.mid;
- new_request_key -> pid = si.pid;
- new_request_key -> frame_num = 0;
+ /* Buffer Format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1,
+ tvb_get_guint8(tvb, offset));
+ offset += 1;
- request_val = g_mem_chunk_alloc(smb_request_vals);
- request_val -> frame = fd->num;
- request_val -> last_transact2_command = -1; /* unknown */
- request_val -> last_transact_command = NULL;
- request_val -> last_param_descrip = NULL;
- request_val -> last_data_descrip = NULL;
- request_val -> last_aux_data_descrip = NULL;
+ /* File Name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
- g_hash_table_insert(smb_request_hash, new_request_key, request_val);
- } else {
- /*
- * This means that we've seen another request in this conversation
- * with the same request and reply, and without an intervening
- * reply to that first request, and thus won't be using this
- * "request_val" structure for that request (as we'd use it only
- * for the reply).
- *
- * Clean out the structure, and set it to refer to this frame.
- */
- request_val -> frame = fd->num;
- request_val -> last_transact2_command = -1; /* unknown */
- if (request_val -> last_transact_command)
- g_free(request_val -> last_transact_command);
- request_val -> last_transact_command = NULL;
- if (request_val -> last_param_descrip)
- g_free(request_val -> last_param_descrip);
- request_val -> last_param_descrip = NULL;
- if (request_val -> last_data_descrip)
- g_free(request_val -> last_data_descrip);
- request_val -> last_data_descrip = NULL;
- if (request_val -> last_aux_data_descrip)
- g_free(request_val -> last_aux_data_descrip);
- request_val -> last_aux_data_descrip = NULL;
- }
- }
- } else {
- /*
- * This is a reply.
- */
- if (!fd->flags.visited) {
- /*
- * This is the first time the frame has been seen; check for
- * an entry for a matching request, with an unknown reply frame
- * number, in the hash table.
- *
- * If we find it, re-hash it with this frame's number as the
- * reply frame number.
- */
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = 0;
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
- /*
- * Look it up - and, if we find it, get pointers to the key and
- * value structures for it.
- */
- if (g_hash_table_lookup_extended(smb_request_hash, &request_key,
- &new_request_key_ret,
- &request_val_ret)) {
- new_request_key = new_request_key_ret;
- request_val = request_val_ret;
+ END_OF_SMB
- /*
- * We found it.
- * Remove the old entry.
- */
- g_hash_table_remove(smb_request_hash, &request_key);
+ return offset;
+}
+
+static int
+dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint16 bc;
+ guint8 wc;
+ nstime_t ts;
- /*
- * Now update the key, and put it back into the hash table with
- * the new key.
- */
- new_request_key->frame_num = fd->num;
- g_hash_table_insert(smb_request_hash, new_request_key, request_val);
- }
- } else {
- /*
- * This is not the first time the frame has been seen; check for
- * an entry for a matching request, with this frame's frame
- * number as the reply frame number, in the hash table.
- */
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = fd->num;
+ WORD_COUNT;
- request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
- }
- }
+ /* File Attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
- return request_val;
+ /* Last Write Time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+
+ /* File Size */
+ proto_tree_add_uint(tree, hf_smb_file_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* 10 reserved bytes */
+ proto_tree_add_bytes(tree, hf_smb_reserved, tvb, offset, 10, tvb_get_ptr(tvb, offset, 10));
+ offset += 10;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ return offset;
}
-static struct smb_continuation_val *
-do_continuation_hashing(conversation_t *conversation, struct smb_info si,
- frame_data *fd, guint16 TotalDataCount,
- guint16 DataCount, const char **TransactName)
+static int
+dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- struct smb_request_key request_key, *new_request_key;
- struct smb_continuation_val *continuation_val, *new_continuation_val;
- gpointer new_request_key_ret, continuation_val_ret;
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
- continuation_val = NULL;
- if (si.ddisp != 0) {
- /*
- * This reply isn't the first in the series; there should be a
- * reply of which it is a continuation.
- */
- if (!fd->flags.visited) {
- /*
- * This is the first time the frame has been seen; check for
- * an entry for a matching continued message, with an unknown
- * continuation frame number, in the hash table.
- *
- * If we find it, re-hash it with this frame's number as the
- * continuation frame number.
- */
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = 0;
+ WORD_COUNT;
- /*
- * Look it up - and, if we find it, get pointers to the key and
- * value structures for it.
- */
- if (g_hash_table_lookup_extended(smb_continuation_hash, &request_key,
- &new_request_key_ret,
- &continuation_val_ret)) {
- new_request_key = new_request_key_ret;
- continuation_val = continuation_val_ret;
+ /* file attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
- /*
- * We found it.
- * Remove the old entry.
- */
- g_hash_table_remove(smb_continuation_hash, &request_key);
+ /* last write time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
- /*
- * Now update the key, and put it back into the hash table with
- * the new key.
- */
- new_request_key->frame_num = fd->num;
- g_hash_table_insert(smb_continuation_hash, new_request_key,
- continuation_val);
- }
- } else {
- /*
- * This is not the first time the frame has been seen; check for
- * an entry for a matching request, with this frame's frame
- * number as the continuation frame number, in the hash table.
- */
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = fd->num;
+ /* 10 reserved bytes */
+ proto_tree_add_bytes(tree, hf_smb_reserved, tvb, offset, 10, tvb_get_ptr(tvb, offset, 10));
+ offset += 10;
- continuation_val = (struct smb_continuation_val *)
- g_hash_table_lookup(smb_continuation_hash, &request_key);
- }
- }
+ BYTE_COUNT;
- /*
- * If we found the entry for the message of which this is a continuation,
- * and our caller cares, get the transaction name for that message, as
- * it's the transaction name for this message as well.
- */
- if (continuation_val != NULL && TransactName != NULL)
- *TransactName = continuation_val -> transact_name;
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
- if (TotalDataCount > DataCount + si.ddisp) {
- /*
- * This reply isn't the last in the series; there should be a
- * continuation for it later in the capture.
- *
- * If this is the first time the frame has been seen, check for
- * an entry for the reply in the hash table. If it's not found,
- * insert an entry for it.
- *
- * If it's the first time it's been seen, then we can't have seen
- * the continuation yet, so the continuation frame number should
- * be 0, for "unknown".
- */
- if (!fd->flags.visited) {
- request_key.conversation = conversation->index;
- request_key.mid = si.mid;
- request_key.pid = si.pid;
- request_key.frame_num = 0;
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
- new_continuation_val = (struct smb_continuation_val *)
- g_hash_table_lookup(smb_continuation_hash, &request_key);
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
- if (new_continuation_val == NULL) {
- /*
- * Not found.
- */
- new_request_key = g_mem_chunk_alloc(smb_request_keys);
- new_request_key -> conversation = conversation->index;
- new_request_key -> mid = si.mid;
- new_request_key -> pid = si.pid;
- new_request_key -> frame_num = 0;
+ END_OF_SMB
- new_continuation_val = g_mem_chunk_alloc(smb_continuation_vals);
- new_continuation_val -> frame = fd->num;
- if (TransactName != NULL)
- new_continuation_val -> transact_name = *TransactName;
- else
- new_continuation_val -> transact_name = NULL;
+ return offset;
+}
- g_hash_table_insert(smb_continuation_hash, new_request_key,
- new_continuation_val);
- } else {
- /*
- * This presumably means we never saw the continuation of
- * the message we found, and this is a reply to a different
- * request; as we never saw the continuation of that message,
- * we won't be using this "request_val" structure for that
- * message (as we'd use it only for the continuation).
- *
- * Clean out the structure, and set it to refer to this frame.
- */
- new_continuation_val -> frame = fd->num;
- }
- }
- }
+static int
+dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
- return continuation_val;
+ WORD_COUNT;
+
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ /* read count */
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_uint(tree, hf_smb_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* remaining */
+ proto_tree_add_uint(tree, hf_smb_remaining, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ return offset;
}
-static void
-smb_init_protocol(void)
+static int
+dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
-#if defined(DEBUG_SMB_HASH)
- printf("Initializing SMB hashtable area\n");
-#endif
+ guint16 cnt=0, bc;
+ guint8 wc;
- if (smb_request_hash) {
- /*
- * Remove all entries from the hash table and free all strings
- * attached to the keys and values. (The keys and values
- * themselves are freed with "g_mem_chunk_destroy()" calls
- * below.)
- */
- g_hash_table_foreach_remove(smb_request_hash, free_request_val_data, NULL);
- g_hash_table_destroy(smb_request_hash);
- }
- if (smb_continuation_hash)
- g_hash_table_destroy(smb_continuation_hash);
- if (smb_request_keys)
- g_mem_chunk_destroy(smb_request_keys);
- if (smb_request_vals)
- g_mem_chunk_destroy(smb_request_vals);
- if (smb_continuation_vals)
- g_mem_chunk_destroy(smb_continuation_vals);
+ WORD_COUNT;
- smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
- smb_continuation_hash = g_hash_table_new(smb_hash, smb_equal);
- smb_request_keys = g_mem_chunk_new("smb_request_keys",
- sizeof(struct smb_request_key),
- smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
- smb_request_vals = g_mem_chunk_new("smb_request_vals",
- sizeof(struct smb_request_val),
- smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
- smb_continuation_vals = g_mem_chunk_new("smb_continuation_vals",
- sizeof(struct smb_continuation_val),
- smb_packet_init_count * sizeof(struct smb_continuation_val), G_ALLOC_AND_FREE);
-}
+ /* read count */
+ cnt = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
+ offset += 2;
-static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int);
+ /* 8 reserved bytes */
+ proto_tree_add_bytes(tree, hf_smb_reserved, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8));
+ offset += 8;
-void
-dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-{
+ BYTE_COUNT;
- if (tree) {
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
+ bc -= 1;
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)",
- END_OF_FRAME);
+ /* data len */
+ if (bc < 2)
+ return offset;
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+ bc -= 2;
- }
+ if (bc != 0) {
+ /* file data */
+ if(bc>tvb_length_remaining(tvb, offset)){
+ int len;
+ len = tvb_length_remaining(tvb, offset);
+ proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, len, tvb_get_ptr(tvb, offset, len),"File Data: Incomplete. Only %u of %u bytes", len, bc);
+ offset += len;
+ } else {
+ proto_tree_add_bytes(tree, hf_smb_file_data, tvb, offset, bc, tvb_get_ptr(tvb, offset, bc));
+ offset += bc;
+ }
+ }
+ END_OF_SMB
+
+ return offset;
}
-/*
- * Dissect a UNIX like date ...
- */
+static int
+dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint16 cnt, bc;
+ guint8 wc;
-struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
- conflict with /usr/include/time.h on some NetBSD
- systems */
+ WORD_COUNT;
-static char *
-dissect_smbu_date(guint16 date, guint16 time)
+ /* read count */
+ cnt = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
+ offset += 2;
-{
- static char datebuf[4+2+2+2+1+10];
- time_t ltime = (date << 16) + time;
+ /* 8 reserved bytes */
+ proto_tree_add_bytes(tree, hf_smb_reserved, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8));
+ offset += 8;
- _gtime = gmtime(<ime);
+ BYTE_COUNT;
- if (_gtime)
- sprintf(datebuf, "%04d-%02d-%02d",
- 1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
- else
- sprintf(datebuf, "Bad date format");
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
+ bc -= 1;
- return datebuf;
+ /* data len */
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ END_OF_SMB
+ return offset;
}
-/*
- * Relies on time
- */
-static char *
-dissect_smbu_time(guint16 date, guint16 time)
+static int
+dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- static char timebuf[2+2+2+2+1+10];
+ guint16 cnt=0, bc;
+ guint8 wc;
- if (_gtime)
- sprintf(timebuf, "%02d:%02d:%02d",
- _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
- else
- sprintf(timebuf, "Bad time format");
+ WORD_COUNT;
- return timebuf;
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
-}
+ /* write count */
+ cnt = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
+ offset += 2;
-/*
- * Dissect a DOS-format date.
- */
-static char *
-dissect_dos_date(guint16 date)
+ /* offset */
+ proto_tree_add_uint(tree, hf_smb_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* remaining */
+ proto_tree_add_uint(tree, hf_smb_remaining, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ BYTE_COUNT;
+
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
+ bc -= 1;
+
+ /* data len */
+ if (bc < 2)
+ return offset;
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+ bc -= 2;
+
+ if (bc != 0) {
+ /* file data */
+ if(bc>tvb_length_remaining(tvb, offset)){
+ int len;
+ len = tvb_length_remaining(tvb, offset);
+ proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, len, tvb_get_ptr(tvb, offset, len),"File Data: Incomplete. Only %d of %d bytes", len, bc);
+ offset += len;
+ } else {
+ proto_tree_add_bytes(tree, hf_smb_file_data, tvb, offset, bc, tvb_get_ptr(tvb, offset, bc));
+ offset += bc;
+ }
+ }
+
+ END_OF_SMB
+
+ return offset;
+}
+
+static int
+dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- static char datebuf[4+2+2+1];
+ guint8 wc;
+ guint16 bc;
- sprintf(datebuf, "%04d-%02d-%02d",
- ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
- return datebuf;
+ WORD_COUNT;
+
+ /* write count */
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ return offset;
}
-/*
- * Dissect a DOS-format time.
- */
-static char *
-dissect_dos_time(guint16 time)
+static int
+dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- static char timebuf[2+2+2+1];
+ guint8 wc;
+ guint16 bc;
- sprintf(timebuf, "%02d:%02d:%02d",
- (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
- return timebuf;
+ WORD_COUNT;
+
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
+
+ /* lock count */
+ proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ /* offset */
+ proto_tree_add_uint(tree, hf_smb_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ return offset;
}
-/* Max string length for displaying Unicode strings. */
-#define MAX_UNICODE_STR_LEN 256
+static int
+dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
-/* Turn a little-endian Unicode '\0'-terminated string into a string we
- can display.
- XXX - for now, we just handle the ISO 8859-1 characters. */
-static gchar *
-unicode_to_str(const guint8 *us, int *us_lenp) {
- static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
- static gchar *cur;
- gchar *p;
- int len;
- int us_len;
- int overflow = 0;
+ WORD_COUNT;
- NullTVB; /* remove this function when we are fully tvbuffified */
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
- p = cur;
- len = MAX_UNICODE_STR_LEN;
- us_len = 0;
- while (*us != 0 || *(us + 1) != 0) {
- if (len > 0) {
- *p++ = *us;
- len--;
- } else
- overflow = 1;
- us += 2;
- us_len += 2;
- }
- if (overflow) {
- /* Note that we're not showing the full string. */
- *p++ = '.';
- *p++ = '.';
- *p++ = '.';
- }
- *p = '\0';
- *us_lenp = us_len;
- return cur;
-}
-/* Turn a little-endian Unicode '\0'-terminated string into a string we
- can display.
- XXX - for now, we just handle the ISO 8859-1 characters.
- If exactlen==TRUE then us_lenp contains the exact len of the string in
- bytes. It might not be null terminated !
-*/
-static gchar *
-unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen) {
- static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
- static gchar *cur;
- gchar *p;
- guint16 uchar;
- int len;
- int us_len;
- int overflow = 0;
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
- p = cur;
- len = MAX_UNICODE_STR_LEN;
- us_len = 0;
- while ((uchar = tvb_get_letohs(tvb, offset)) != 0) {
- if (len > 0) {
- if ((uchar & 0xFF00) == 0)
- *p++ = uchar; /* ISO 8859-1 */
- else
- *p++ = '?'; /* not 8859-1 */
- len--;
- } else
- overflow = 1;
- offset += 2;
- us_len += 2;
- if(exactlen){
- if(us_len>= *us_lenp){
- break;
- }
- }
- }
- if (overflow) {
- /* Note that we're not showing the full string. */
- *p++ = '.';
- *p++ = '.';
- *p++ = '.';
- }
- *p = '\0';
- *us_lenp = us_len;
- return cur;
-}
-
+ /* 2 reserved bytes */
+ proto_tree_add_bytes(tree, hf_smb_reserved, tvb, offset, 2, tvb_get_ptr(tvb, offset, 2));
+ offset += 2;
-/* Get a null terminated string, which is Unicode if "is_unicode" is true
- and ASCII (OEM character set) otherwise.
- XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
-static const gchar *
-get_unicode_or_ascii_string(const u_char *pd, int *offsetp, int SMB_offset,
- gboolean is_unicode, int *len)
-{
- int offset = *offsetp;
- const gchar *string;
- int string_len;
+ /* Creation time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
- NullTVB; /* delete this function when we are fully tvbuffified */
- if (is_unicode) {
- if ((offset - SMB_offset) % 2) {
- /*
- * XXX - this should be an offset relative to the beginning of the SMB,
- * not an offset relative to the beginning of the frame; if the stuff
- * before the SMB has an odd number of bytes, an offset relative to
- * the beginning of the frame will give the wrong answer.
- */
- offset++; /* Looks like a pad byte there sometimes */
- *offsetp = offset;
- }
- string = unicode_to_str(pd + offset, &string_len);
- string_len += 2;
- } else {
- string = pd + offset;
- string_len = strlen(string) + 1;
- }
- *len = string_len;
- return string;
-}
+ BYTE_COUNT;
-/* nopad == TRUE : Do not add any padding before this string
- * exactlen == TRUE : len contains the exact len of the string in bytes.
- */
-static const gchar *
-get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen)
-{
- int offset = *offsetp;
- const gchar *string;
- int string_len;
- smb_info_t *si;
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
- si = pinfo->private_data;
- if (si->unicode) {
- if ((!nopad) && (*offsetp % 2)) {
- /*
- * XXX - this should be an offset relative to the beginning of the SMB,
- * not an offset relative to the beginning of the frame; if the stuff
- * before the SMB has an odd number of bytes, an offset relative to
- * the beginning of the frame will give the wrong answer.
- */
- (*offsetp)++; /* Looks like a pad byte there sometimes */
- }
- if(exactlen){
- string_len = *len;
- string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
- } else {
- string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
- string_len += 2;
- }
- } else {
- if(exactlen){
- string = tvb_get_ptr(tvb, *offsetp, *len);
- string_len = *len;
- } else {
- string_len = tvb_strsize(tvb, *offsetp);
- string = tvb_get_ptr(tvb, *offsetp, string_len);
- }
- }
- *len = string_len;
- return string;
-}
+ /* directory name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
-/*
- * Each dissect routine is passed an offset to wct and works from there
- */
+ END_OF_SMB
-void
-dissect_flush_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ return offset;
+}
+static int
+dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- guint8 WordCount;
- guint16 FID;
- guint16 ByteCount;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
+ int fn_len;
+ const char *fn;
+ guint8 wc;
+ guint16 bc;
- /* Build display for: FID */
+ WORD_COUNT;
- FID = GSHORT(pd, offset);
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
- if (tree) {
+ BYTE_COUNT;
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ /* buffer format */
+ proto_tree_add_uint(tree, hf_smb_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1;
- }
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ offset += fn_len;
- offset += 2; /* Skip FID */
+ END_OF_SMB
- /* Build display for: Byte Count */
+ return offset;
+}
- ByteCount = GSHORT(pd, offset);
+static const value_string seek_mode_vals[] = {
+ {0, "From Start Of File"},
+ {1, "From Current Position"},
+ {2, "From End Of File"},
+ {0, NULL}
+};
- if (tree) {
+static int
+dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ WORD_COUNT;
- }
+ /* fid */
+ proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
- offset += 2; /* Skip Byte Count */
+ /* Seek Mode */
+ proto_tree_add_uint(tree, hf_smb_seek_mode, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2;
- } else {
- /* Response(s) dissect code */
+ /* offset */
+ proto_tree_add_uint(tree, hf_smb_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
- /* Build display for: Word Count (WCT) */
+ BYTE_COUNT;
- WordCount = GBYTE(pd, offset);
+ END_OF_SMB
- if (tree) {
+ return offset;
+}
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+static int
+dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
- }
+ WORD_COUNT;
- offset += 1; /* Skip Word Count (WCT) */
+ /* offset */
+ proto_tree_add_uint(tree, hf_smb_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+ offset += 4;
- /* Build display for: Byte Count (BCC) */
+ BYTE_COUNT;
- ByteCount = GSHORT(pd, offset);
+ END_OF_SMB
- if (tree) {
+ return offset;
+}
+
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- }
- offset += 2; /* Skip Byte Count (BCC) */
+typedef struct _smb_function {
+ int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
+ int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
+} smb_function;
- }
-
-}
-
-void
-dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- guint8 WordCount;
- guint16 TotalUnits;
- guint16 Reserved;
- guint16 FreeUnits;
- guint16 ByteCount;
- guint16 BlocksPerUnit;
- guint16 BlockSize;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: Total Units */
-
- TotalUnits = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
-
- }
-
- offset += 2; /* Skip Total Units */
-
- /* Build display for: Blocks Per Unit */
-
- BlocksPerUnit = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
-
- }
-
- offset += 2; /* Skip Blocks Per Unit */
-
- /* Build display for: Block Size */
-
- BlockSize = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
-
- }
-
- offset += 2; /* Skip Block Size */
-
- /* Build display for: Free Units */
-
- FreeUnits = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
-
- }
-
- offset += 2; /* Skip Free Units */
-
- /* Build display for: Reserved */
-
- Reserved = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
-
- }
-
- offset += 2; /* Skip Reserved */
-
- }
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- }
-
-}
-
-void
-dissect_set_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- proto_tree *Attributes_tree;
- proto_item *ti;
- guint8 WordCount;
- guint8 ByteCount;
- guint8 BufferFormat;
- guint16 Reserved5;
- guint16 Reserved4;
- guint16 Reserved3;
- guint16 Reserved2;
- guint16 Reserved1;
- guint16 LastWriteTime;
- guint16 LastWriteDate;
- guint16 Attributes;
- const char *FileName;
- int string_len;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: Attributes */
-
- Attributes = GSHORT(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
- Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
- }
-
- offset += 2; /* Skip Attributes */
-
- /* Build display for: Last Write Time */
-
- LastWriteTime = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
-
- }
-
- offset += 2; /* Skip Last Write Time */
-
- /* Build display for: Last Write Date */
-
- LastWriteDate = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
-
- }
-
- offset += 2; /* Skip Last Write Date */
-
- /* Build display for: Reserved 1 */
-
- Reserved1 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
-
- }
-
- offset += 2; /* Skip Reserved 1 */
-
- /* Build display for: Reserved 2 */
-
- Reserved2 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
-
- }
-
- offset += 2; /* Skip Reserved 2 */
-
- /* Build display for: Reserved 3 */
-
- Reserved3 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
-
- }
-
- offset += 2; /* Skip Reserved 3 */
-
- /* Build display for: Reserved 4 */
-
- Reserved4 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
-
- }
-
- offset += 2; /* Skip Reserved 4 */
-
- /* Build display for: Reserved 5 */
-
- Reserved5 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
-
- }
-
- offset += 2; /* Skip Reserved 5 */
-
- }
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- /* Build display for: Buffer Format */
-
- BufferFormat = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
-
- }
-
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: File Name */
-
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
-
- }
-
- offset += string_len; /* Skip File Name */
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 1; /* Skip Byte Count (BCC) */
-
- }
-
-}
-
-void
-dissect_write_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- guint8 WordCount;
- guint8 BufferFormat;
- guint32 Offset;
- guint16 Remaining;
- guint16 FID;
- guint16 DataLength;
- guint16 Count;
- guint16 ByteCount;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
- }
-
- offset += 2; /* Skip Count */
-
- /* Build display for: Offset */
-
- Offset = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
- }
-
- offset += 4; /* Skip Offset */
-
- /* Build display for: Remaining */
-
- Remaining = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
- }
-
- offset += 2; /* Skip Remaining */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- /* Build display for: Buffer Format */
-
- BufferFormat = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
-
- }
-
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: Data Length */
-
- DataLength = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
-
- }
-
- offset += 2; /* Skip Data Length */
-
- if (DataLength > 0 && tree) {
-
- if(END_OF_FRAME >= DataLength)
- proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
- else
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
-
- }
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
- }
-
- offset += 2; /* Skip Count */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- }
-
-}
-
-void
-dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- guint8 WordCount;
- guint8 Pad;
- guint32 Reserved1;
- guint32 Offset;
- guint16 Reserved2;
- guint16 Reserved;
- guint16 MinCount;
- guint16 MaxCount;
- guint16 FID;
- guint16 DataOffset;
- guint16 DataLength;
- guint16 DataCompactionMode;
- guint16 Count;
- guint16 ByteCount;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: Offset */
-
- Offset = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
- }
-
- offset += 4; /* Skip Offset */
-
- /* Build display for: Max Count */
-
- MaxCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
-
- }
-
- offset += 2; /* Skip Max Count */
-
- /* Build display for: Min Count */
-
- MinCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
-
- }
-
- offset += 2; /* Skip Min Count */
-
- /* Build display for: Reserved 1 */
-
- Reserved1 = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 1: %u", Reserved1);
-
- }
-
- offset += 4; /* Skip Reserved 1 */
-
- /* Build display for: Reserved 2 */
-
- Reserved2 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
-
- }
-
- offset += 2; /* Skip Reserved 2 */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count */
-
- if (WordCount != 0) {
-
- /* Build display for: Offset */
-
- Offset = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
- }
-
- offset += 4; /* Skip Offset */
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
- }
-
- offset += 2; /* Skip Count */
-
- /* Build display for: Reserved */
-
- Reserved = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
-
- }
-
- offset += 2; /* Skip Reserved */
-
- /* Build display for: Data Compaction Mode */
-
- DataCompactionMode = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
-
- }
-
- offset += 2; /* Skip Data Compaction Mode */
-
- /* Build display for: Reserved */
-
- Reserved = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
-
- }
-
- offset += 2; /* Skip Reserved */
-
- /* Build display for: Data Length */
-
- DataLength = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
-
- }
-
- offset += 2; /* Skip Data Length */
-
- /* Build display for: Data Offset */
-
- DataOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
-
- }
-
- offset += 2; /* Skip Data Offset */
-
- }
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- /* Build display for: Pad */
-
- Pad = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
-
- }
-
- offset += 1; /* Skip Pad */
-
- }
-
-}
-
-void
-dissect_delete_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *paernt, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- guint8 WordCount;
- guint8 BufferFormat;
- guint16 SearchAttributes;
- guint16 ByteCount;
- const char *FileName;
- int string_len;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: SearchAttributes */
-
- SearchAttributes = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
- }
-
- offset += 2; /* Skip SearchAttributes */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- /* Build display for: Buffer Format */
-
- BufferFormat = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
-
- }
-
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: File Name */
-
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
-
- }
-
- offset += string_len; /* Skip File Name */
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- }
-
-}
-
-void
-dissect_query_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- proto_tree *Attributes_tree;
- proto_item *ti;
- guint8 WordCount;
- guint32 FileDataSize;
- guint32 FileAllocationSize;
- guint16 LastWriteTime;
- guint16 LastWriteDate;
- guint16 LastAccessTime;
- guint16 LastAccessDate;
- guint16 FID;
- guint16 CreationTime;
- guint16 CreationDate;
- guint16 ByteCount;
- guint16 Attributes;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: Creation Date */
-
- CreationDate = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
-
- }
-
- offset += 2; /* Skip Creation Date */
-
- /* Build display for: Creation Time */
-
- CreationTime = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
-
- }
-
- offset += 2; /* Skip Creation Time */
-
- /* Build display for: Last Access Date */
-
- LastAccessDate = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
-
- }
-
- offset += 2; /* Skip Last Access Date */
-
- /* Build display for: Last Access Time */
-
- LastAccessTime = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
-
- }
-
- offset += 2; /* Skip Last Access Time */
-
- /* Build display for: Last Write Date */
-
- LastWriteDate = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
-
- }
-
- offset += 2; /* Skip Last Write Date */
-
- /* Build display for: Last Write Time */
-
- LastWriteTime = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
-
- }
-
- offset += 2; /* Skip Last Write Time */
-
- /* Build display for: File Data Size */
-
- FileDataSize = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "File Data Size: %u", FileDataSize);
-
- }
-
- offset += 4; /* Skip File Data Size */
-
- /* Build display for: File Allocation Size */
-
- FileAllocationSize = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "File Allocation Size: %u", FileAllocationSize);
-
- }
-
- offset += 4; /* Skip File Allocation Size */
-
- /* Build display for: Attributes */
-
- Attributes = GSHORT(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
- Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
- }
-
- offset += 2; /* Skip Attributes */
-
- }
-
- /* Build display for: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- }
-
-}
-
-/* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
-void
-dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- proto_tree *Capabilities_tree;
- proto_tree *Action_tree;
- proto_item *ti;
- guint8 WordCount;
- guint8 AndXReserved;
- guint8 AndXCommand = 0xFF;
- guint32 SessionKey;
- guint32 Reserved;
- guint32 Capabilities;
- guint16 VcNumber;
- guint16 SecurityBlobLength;
- guint16 ANSIAccountPasswordLength;
- guint16 UNICODEAccountPasswordLength;
- guint16 PasswordLen;
- guint16 MaxMpxCount;
- guint16 MaxBufferSize;
- guint16 ByteCount;
- guint16 AndXOffset = 0;
- guint16 Action;
- const char *ANSIPassword;
- const char *UNICODEPassword;
- const char *SecurityBlob;
- const char *Password;
- const char *PrimaryDomain;
- const char *NativeOS;
- const char *NativeLanManType;
- const char *NativeLanMan;
- const char *AccountName;
- int string_len;
-
- if (si.request) {
- /* Request(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- switch (WordCount) {
-
- case 10:
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
- }
-
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
-
- AndXReserved = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
- }
-
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
-
- AndXOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
- }
-
- offset += 2; /* Skip AndXOffset */
-
- /* Build display for: MaxBufferSize */
-
- MaxBufferSize = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
-
- }
-
- offset += 2; /* Skip MaxBufferSize */
-
- /* Build display for: MaxMpxCount */
-
- MaxMpxCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
-
- }
-
- offset += 2; /* Skip MaxMpxCount */
-
- /* Build display for: VcNumber */
-
- VcNumber = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
-
- }
-
- offset += 2; /* Skip VcNumber */
-
- /* Build display for: SessionKey */
-
- SessionKey = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
-
- }
-
- offset += 4; /* Skip SessionKey */
-
- /* Build display for: PasswordLen */
-
- PasswordLen = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "PasswordLen: %u", PasswordLen);
-
- }
-
- offset += 2; /* Skip PasswordLen */
-
- /* Build display for: Reserved */
-
- Reserved = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
-
- }
-
- offset += 4; /* Skip Reserved */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- if (ByteCount > 0) {
-
- /* Build display for: Password */
-
- Password = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
-
- }
-
- offset += PasswordLen;
-
- /* Build display for: AccountName */
-
- AccountName = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
-
- }
-
- offset += strlen(AccountName) + 1; /* Skip AccountName */
-
- /* Build display for: PrimaryDomain */
-
- PrimaryDomain = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
-
- }
-
- offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
-
- /* Build display for: NativeOS */
-
- NativeOS = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
-
- }
-
- offset += strlen(NativeOS) + 1; /* Skip NativeOS */
-
- /* Build display for: NativeLanMan */
-
- NativeLanMan = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "Native Lan Manager: %s", NativeLanMan);
-
- }
-
- offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
-
- }
-
- break;
-
- case 12:
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
- }
-
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
-
- AndXReserved = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
- }
-
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
-
- AndXOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
- }
-
- offset += 2; /* Skip AndXOffset */
-
- /* Build display for: MaxBufferSize */
-
- MaxBufferSize = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
-
- }
-
- offset += 2; /* Skip MaxBufferSize */
-
- /* Build display for: MaxMpxCount */
-
- MaxMpxCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
-
- }
-
- offset += 2; /* Skip MaxMpxCount */
-
- /* Build display for: VcNumber */
-
- VcNumber = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
-
- }
-
- offset += 2; /* Skip VcNumber */
-
- /* Build display for: SessionKey */
-
- SessionKey = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
-
- }
-
- offset += 4; /* Skip SessionKey */
-
- /* Build display for: Security Blob Length */
-
- SecurityBlobLength = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
-
- }
-
- offset += 2; /* Skip Security Blob Length */
-
- /* Build display for: Reserved */
-
- Reserved = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
-
- }
-
- offset += 4; /* Skip Reserved */
-
- /* Build display for: Capabilities */
-
- Capabilities = GWORD(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
- Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
-
- }
-
- offset += 4; /* Skip Capabilities */
-
- /* Build display for: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- if (ByteCount > 0) {
-
- /* Build display for: Security Blob */
-
- SecurityBlob = pd + offset;
-
- if (SecurityBlobLength > 0) {
-
- /* XXX - is this ASN.1-encoded? Is it a Kerberos data structure,
- at least in NT 5.0-and-later server replies? */
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
- bytes_to_str(SecurityBlob, SecurityBlobLength));
-
- }
-
- offset += SecurityBlobLength; /* Skip Security Blob */
-
- }
-
- /* Build display for: Native OS */
-
- NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
-
- }
-
- offset += string_len; /* Skip Native OS */
-
- /* Build display for: Native LanMan Type */
-
- NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
-
- }
-
- offset += string_len; /* Skip Native LanMan Type */
-
- /* Build display for: Primary Domain */
-
- PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
-
- }
-
- offset += string_len; /* Skip Primary Domain */
-
- }
-
- break;
-
- case 13:
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
- }
-
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
-
- AndXReserved = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+smb_function smb_dissector[256] = {
+ /* 0x00 Create Dir*/ {dissect_old_dir_request, dissect_empty},
+ /* 0x01 Delete Dir*/ {dissect_old_dir_request, dissect_empty},
+ /* 0x02 Open File*/ {dissect_open_file_request, dissect_open_file_response},
+ /* 0x03 Create File*/ {dissect_create_file_request, dissect_fid},
+ /* 0x04 Close File*/ {dissect_close_file_request, dissect_empty},
+ /* 0x05 Flush File*/ {dissect_fid, dissect_empty},
+ /* 0x06 Delete File*/ {dissect_delete_file_request, dissect_empty},
+ /* 0x07 Rename File*/ {dissect_rename_file_request, dissect_empty},
+ /* 0x08 Query Info*/ {dissect_query_information_request, dissect_query_information_response},
+ /* 0x09 Set Info*/ {dissect_set_information_request, dissect_empty},
+ /* 0x0a Read File*/ {dissect_read_file_request, dissect_read_file_response},
+ /* 0x0b Write File*/ {dissect_write_file_request, dissect_write_file_response},
+ /* 0x0c Lock Byte Range*/ {dissect_lock_request, dissect_empty},
+ /* 0x0d Unlock Byte Range*/ {dissect_lock_request, dissect_empty},
+ /* 0x0e Create Temp*/ {dissect_create_temporary_request, dissect_create_temporary_response},
+ /* 0x0f Create New*/ {dissect_create_file_request, dissect_fid},
+ /* 0x10 Check Dir*/ {dissect_old_dir_request, dissect_empty},
+ /* 0x11 Process Exit*/ {dissect_empty, dissect_empty},
+ /* 0x12 Seek File*/ {dissect_seek_file_request, dissect_seek_file_response},
+ /* 0x13 Lock And Read*/ {dissect_read_file_request, dissect_lock_and_read_response},
+ /* 0x14 Write And Unlock*/ {dissect_write_file_request, dissect_write_file_response},
+ /* 0x15 */ {NULL, NULL},
+ /* 0x16 */ {NULL, NULL},
+ /* 0x17 */ {NULL, NULL},
+ /* 0x18 */ {NULL, NULL},
+ /* 0x19 */ {NULL, NULL},
+ /* 0x1a */ {NULL, NULL},
+ /* 0x1b */ {NULL, NULL},
+ /* 0x1c */ {NULL, NULL},
+ /* 0x1d */ {NULL, NULL},
+ /* 0x1e */ {NULL, NULL},
+ /* 0x1f */ {NULL, NULL},
+ /* 0x20 */ {NULL, NULL},
+ /* 0x21 */ {NULL, NULL},
+ /* 0x22 */ {NULL, NULL},
+ /* 0x23 */ {NULL, NULL},
+ /* 0x24 */ {NULL, NULL},
+ /* 0x25 */ {NULL, NULL},
+ /* 0x26 */ {NULL, NULL},
+ /* 0x27 */ {NULL, NULL},
+ /* 0x28 */ {NULL, NULL},
+ /* 0x29 */ {NULL, NULL},
+ /* 0x2a Move File*/ {dissect_move_request, dissect_move_response},
+ /* 0x2b Echo*/ {dissect_echo_request, dissect_echo_response},
+ /* 0x2c */ {NULL, NULL},
+ /* 0x2d */ {NULL, NULL},
+ /* 0x2e */ {NULL, NULL},
+ /* 0x2f */ {NULL, NULL},
+ /* 0x30 */ {NULL, NULL},
+ /* 0x31 */ {NULL, NULL},
+ /* 0x32 */ {NULL, NULL},
+ /* 0x33 */ {NULL, NULL},
+ /* 0x34 */ {NULL, NULL},
+ /* 0x35 */ {NULL, NULL},
+ /* 0x36 */ {NULL, NULL},
+ /* 0x37 */ {NULL, NULL},
+ /* 0x38 */ {NULL, NULL},
+ /* 0x39 */ {NULL, NULL},
+ /* 0x3a */ {NULL, NULL},
+ /* 0x3b */ {NULL, NULL},
+ /* 0x3c */ {NULL, NULL},
+ /* 0x3d */ {NULL, NULL},
+ /* 0x3e */ {NULL, NULL},
+ /* 0x3f */ {NULL, NULL},
+ /* 0x40 */ {NULL, NULL},
+ /* 0x41 */ {NULL, NULL},
+ /* 0x42 */ {NULL, NULL},
+ /* 0x43 */ {NULL, NULL},
+ /* 0x44 */ {NULL, NULL},
+ /* 0x45 */ {NULL, NULL},
+ /* 0x46 */ {NULL, NULL},
+ /* 0x47 */ {NULL, NULL},
+ /* 0x48 */ {NULL, NULL},
+ /* 0x49 */ {NULL, NULL},
+ /* 0x4a */ {NULL, NULL},
+ /* 0x4b */ {NULL, NULL},
+ /* 0x4c */ {NULL, NULL},
+ /* 0x4d */ {NULL, NULL},
+ /* 0x4e */ {NULL, NULL},
+ /* 0x4f */ {NULL, NULL},
+ /* 0x50 */ {NULL, NULL},
+ /* 0x51 */ {NULL, NULL},
+ /* 0x52 */ {NULL, NULL},
+ /* 0x53 */ {NULL, NULL},
+ /* 0x54 */ {NULL, NULL},
+ /* 0x55 */ {NULL, NULL},
+ /* 0x56 */ {NULL, NULL},
+ /* 0x57 */ {NULL, NULL},
+ /* 0x58 */ {NULL, NULL},
+ /* 0x59 */ {NULL, NULL},
+ /* 0x5a */ {NULL, NULL},
+ /* 0x5b */ {NULL, NULL},
+ /* 0x5c */ {NULL, NULL},
+ /* 0x5d */ {NULL, NULL},
+ /* 0x5e */ {NULL, NULL},
+ /* 0x5f */ {NULL, NULL},
+ /* 0x60 */ {NULL, NULL},
+ /* 0x61 */ {NULL, NULL},
+ /* 0x62 */ {NULL, NULL},
+ /* 0x63 */ {NULL, NULL},
+ /* 0x64 */ {NULL, NULL},
+ /* 0x65 */ {NULL, NULL},
+ /* 0x66 */ {NULL, NULL},
+ /* 0x67 */ {NULL, NULL},
+ /* 0x68 */ {NULL, NULL},
+ /* 0x69 */ {NULL, NULL},
+ /* 0x6a */ {NULL, NULL},
+ /* 0x6b */ {NULL, NULL},
+ /* 0x6c */ {NULL, NULL},
+ /* 0x6d */ {NULL, NULL},
+ /* 0x6e */ {NULL, NULL},
+ /* 0x6f */ {NULL, NULL},
+ /* 0x70 Tree Connect*/ {dissect_tree_connect_request, dissect_tree_connect_response},
+ /* 0x71 Tree Disconnect*/ {dissect_empty, dissect_empty},
+ /* 0x72 Negotiate Protocol*/ {dissect_negprot_request, dissect_negprot_response},
+ /* 0x73 */ {NULL, NULL},
+ /* 0x74 */ {NULL, NULL},
+ /* 0x75 */ {NULL, NULL},
+ /* 0x76 */ {NULL, NULL},
+ /* 0x77 */ {NULL, NULL},
+ /* 0x78 */ {NULL, NULL},
+ /* 0x79 */ {NULL, NULL},
+ /* 0x7a */ {NULL, NULL},
+ /* 0x7b */ {NULL, NULL},
+ /* 0x7c */ {NULL, NULL},
+ /* 0x7d */ {NULL, NULL},
+ /* 0x7e */ {NULL, NULL},
+ /* 0x7f */ {NULL, NULL},
+ /* 0x80 */ {NULL, NULL},
+ /* 0x81 */ {NULL, NULL},
+ /* 0x82 */ {NULL, NULL},
+ /* 0x83 */ {NULL, NULL},
+ /* 0x84 */ {NULL, NULL},
+ /* 0x85 */ {NULL, NULL},
+ /* 0x86 */ {NULL, NULL},
+ /* 0x87 */ {NULL, NULL},
+ /* 0x88 */ {NULL, NULL},
+ /* 0x89 */ {NULL, NULL},
+ /* 0x8a */ {NULL, NULL},
+ /* 0x8b */ {NULL, NULL},
+ /* 0x8c */ {NULL, NULL},
+ /* 0x8d */ {NULL, NULL},
+ /* 0x8e */ {NULL, NULL},
+ /* 0x8f */ {NULL, NULL},
+ /* 0x90 */ {NULL, NULL},
+ /* 0x91 */ {NULL, NULL},
+ /* 0x92 */ {NULL, NULL},
+ /* 0x93 */ {NULL, NULL},
+ /* 0x94 */ {NULL, NULL},
+ /* 0x95 */ {NULL, NULL},
+ /* 0x96 */ {NULL, NULL},
+ /* 0x97 */ {NULL, NULL},
+ /* 0x98 */ {NULL, NULL},
+ /* 0x99 */ {NULL, NULL},
+ /* 0x9a */ {NULL, NULL},
+ /* 0x9b */ {NULL, NULL},
+ /* 0x9c */ {NULL, NULL},
+ /* 0x9d */ {NULL, NULL},
+ /* 0x9e */ {NULL, NULL},
+ /* 0x9f */ {NULL, NULL},
+ /* 0xa0 */ {NULL, NULL},
+ /* 0xa1 */ {NULL, NULL},
+ /* 0xa2 */ {NULL, NULL},
+ /* 0xa3 */ {NULL, NULL},
+ /* 0xa4 */ {NULL, NULL},
+ /* 0xa5 */ {NULL, NULL},
+ /* 0xa6 */ {NULL, NULL},
+ /* 0xa7 */ {NULL, NULL},
+ /* 0xa8 */ {NULL, NULL},
+ /* 0xa9 */ {NULL, NULL},
+ /* 0xaa */ {NULL, NULL},
+ /* 0xab */ {NULL, NULL},
+ /* 0xac */ {NULL, NULL},
+ /* 0xad */ {NULL, NULL},
+ /* 0xae */ {NULL, NULL},
+ /* 0xaf */ {NULL, NULL},
+ /* 0xb0 */ {NULL, NULL},
+ /* 0xb1 */ {NULL, NULL},
+ /* 0xb2 */ {NULL, NULL},
+ /* 0xb3 */ {NULL, NULL},
+ /* 0xb4 */ {NULL, NULL},
+ /* 0xb5 */ {NULL, NULL},
+ /* 0xb6 */ {NULL, NULL},
+ /* 0xb7 */ {NULL, NULL},
+ /* 0xb8 */ {NULL, NULL},
+ /* 0xb9 */ {NULL, NULL},
+ /* 0xba */ {NULL, NULL},
+ /* 0xbb */ {NULL, NULL},
+ /* 0xbc */ {NULL, NULL},
+ /* 0xbd */ {NULL, NULL},
+ /* 0xbe */ {NULL, NULL},
+ /* 0xbf */ {NULL, NULL},
+ /* 0xc0 */ {NULL, NULL},
+ /* 0xc1 */ {NULL, NULL},
+ /* 0xc2 Close Print File*/ {dissect_fid, dissect_empty},
+ /* 0xc3 */ {NULL, NULL},
+ /* 0xc4 */ {NULL, NULL},
+ /* 0xc5 */ {NULL, NULL},
+ /* 0xc6 */ {NULL, NULL},
+ /* 0xc7 */ {NULL, NULL},
+ /* 0xc8 */ {NULL, NULL},
+ /* 0xc9 */ {NULL, NULL},
+ /* 0xca */ {NULL, NULL},
+ /* 0xcb */ {NULL, NULL},
+ /* 0xcc */ {NULL, NULL},
+ /* 0xcd */ {NULL, NULL},
+ /* 0xce */ {NULL, NULL},
+ /* 0xcf */ {NULL, NULL},
+ /* 0xd0 */ {NULL, NULL},
+ /* 0xd1 */ {NULL, NULL},
+ /* 0xd2 */ {NULL, NULL},
+ /* 0xd3 */ {NULL, NULL},
+ /* 0xd4 */ {NULL, NULL},
+ /* 0xd5 */ {NULL, NULL},
+ /* 0xd6 */ {NULL, NULL},
+ /* 0xd7 */ {NULL, NULL},
+ /* 0xd8 */ {NULL, NULL},
+ /* 0xd9 */ {NULL, NULL},
+ /* 0xda */ {NULL, NULL},
+ /* 0xdb */ {NULL, NULL},
+ /* 0xdc */ {NULL, NULL},
+ /* 0xdd */ {NULL, NULL},
+ /* 0xde */ {NULL, NULL},
+ /* 0xdf */ {NULL, NULL},
+ /* 0xe0 */ {NULL, NULL},
+ /* 0xe1 */ {NULL, NULL},
+ /* 0xe2 */ {NULL, NULL},
+ /* 0xe3 */ {NULL, NULL},
+ /* 0xe4 */ {NULL, NULL},
+ /* 0xe5 */ {NULL, NULL},
+ /* 0xe6 */ {NULL, NULL},
+ /* 0xe7 */ {NULL, NULL},
+ /* 0xe8 */ {NULL, NULL},
+ /* 0xe9 */ {NULL, NULL},
+ /* 0xea */ {NULL, NULL},
+ /* 0xeb */ {NULL, NULL},
+ /* 0xec */ {NULL, NULL},
+ /* 0xed */ {NULL, NULL},
+ /* 0xee */ {NULL, NULL},
+ /* 0xef */ {NULL, NULL},
+ /* 0xf0 */ {NULL, NULL},
+ /* 0xf1 */ {NULL, NULL},
+ /* 0xf2 */ {NULL, NULL},
+ /* 0xf3 */ {NULL, NULL},
+ /* 0xf4 */ {NULL, NULL},
+ /* 0xf5 */ {NULL, NULL},
+ /* 0xf6 */ {NULL, NULL},
+ /* 0xf7 */ {NULL, NULL},
+ /* 0xf8 */ {NULL, NULL},
+ /* 0xf9 */ {NULL, NULL},
+ /* 0xfa */ {NULL, NULL},
+ /* 0xfb */ {NULL, NULL},
+ /* 0xfc */ {NULL, NULL},
+ /* 0xfd */ {NULL, NULL},
+ /* 0xfe */ {NULL, NULL},
+ /* 0xff */ {NULL, NULL},
+};
- }
+static int
+dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
+{
+ int old_offset = offset;
+ smb_info_t *si;
+
+ si = pinfo->private_data;
+ if(cmd!=0xff){
+ proto_item *cmd_item;
+ proto_tree *cmd_tree;
+ int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
- offset += 1; /* Skip AndXReserved */
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_add_fstr(pinfo->fd, COL_INFO, "%s %s",
+ decode_smb_name(cmd),
+ (si->request)? "Request" : "Response");
+ }
- /* Build display for: AndXOffset */
+ cmd_item = proto_tree_add_text(smb_tree, tvb, offset,
+ 0, "%s %s (0x%02x)",
+ decode_smb_name(cmd),
+ (si->request)?"Request":"Response",
+ cmd);
- AndXOffset = GSHORT(pd, offset);
+ cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
- if (tree) {
+ dissector = (si->request)?
+ smb_dissector[cmd].request:smb_dissector[cmd].response;
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+ if(dissector){
+ offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
+ }
+ proto_item_set_len(cmd_item, offset-old_offset);
+ }
+ return offset;
+}
- }
- offset += 2; /* Skip AndXOffset */
+/* NOTE: this value_string array will also be used to access data directly by
+ * index instead of val_to_str() since
+ * 1, the array will always span every value from 0x00 to 0xff and
+ * 2, smb_cmd_vals[i].strptr is much cheaper than val_to_str(i, smb_cmd_vals,)
+ * This means that this value_string array MUST always
+ * 1, contain all entries 0x00 to 0xff
+ * 2, all entries must be in order.
+ */
+static const value_string smb_cmd_vals[] = {
+ { 0x00, "Create Directory" },
+ { 0x01, "Delete Directory" },
+ { 0x02, "Open" },
+ { 0x03, "Create" },
+ { 0x04, "Close" },
+ { 0x05, "Flush" },
+ { 0x06, "Delete" },
+ { 0x07, "Rename" },
+ { 0x08, "Query Information" },
+ { 0x09, "Set Information" },
+ { 0x0A, "Read" },
+ { 0x0B, "Write" },
+ { 0x0C, "Lock Byte Range" },
+ { 0x0D, "Unlock Byte Range" },
+ { 0x0E, "Create Temp" },
+ { 0x0F, "Create New" },
+ { 0x10, "Check Directory" },
+ { 0x11, "Process Exit" },
+ { 0x12, "Seek" },
+ { 0x13, "Lock And Read" },
+ { 0x14, "Write And Unlock" },
+ { 0x15, "unknown-0x15" },
+ { 0x16, "unknown-0x16" },
+ { 0x17, "unknown-0x17" },
+ { 0x18, "unknown-0x18" },
+ { 0x19, "unknown-0x19" },
+ { 0x1A, "Read Raw" },
+ { 0x1B, "Read MPX" },
+ { 0x1C, "Read MPX Secondary" },
+ { 0x1D, "Write Raw" },
+ { 0x1E, "Write MPX" },
+ { 0x1F, "SMBwriteBs" },
+ { 0x20, "Write Complete" },
+ { 0x21, "unknown-0x21" },
+ { 0x22, "Set Information2" },
+ { 0x23, "Query Information2" },
+ { 0x24, "Locking AndX" },
+ { 0x25, "Transaction" },
+ { 0x26, "Transaction Secondary" },
+ { 0x27, "IOCTL" },
+ { 0x28, "IOCTL Secondary" },
+ { 0x29, "Copy" },
+ { 0x2A, "Move" },
+ { 0x2B, "Echo" },
+ { 0x2C, "Write And Close" },
+ { 0x2D, "Open AndX" },
+ { 0x2E, "Read AndX" },
+ { 0x2F, "Write AndX" },
+ { 0x30, "unknown-0x30" },
+ { 0x31, "Close And Tree Discover" },
+ { 0x32, "Transaction2" },
+ { 0x33, "Transaction2 Secondary" },
+ { 0x34, "Find Close2" },
+ { 0x35, "Find Notify Close" },
+ { 0x36, "unknown-0x36" },
+ { 0x37, "unknown-0x37" },
+ { 0x38, "unknown-0x38" },
+ { 0x39, "unknown-0x39" },
+ { 0x3A, "unknown-0x3A" },
+ { 0x3B, "unknown-0x3B" },
+ { 0x3C, "unknown-0x3C" },
+ { 0x3D, "unknown-0x3D" },
+ { 0x3E, "unknown-0x3E" },
+ { 0x3F, "unknown-0x3F" },
+ { 0x40, "unknown-0x40" },
+ { 0x41, "unknown-0x41" },
+ { 0x42, "unknown-0x42" },
+ { 0x43, "unknown-0x43" },
+ { 0x44, "unknown-0x44" },
+ { 0x45, "unknown-0x45" },
+ { 0x46, "unknown-0x46" },
+ { 0x47, "unknown-0x47" },
+ { 0x48, "unknown-0x48" },
+ { 0x49, "unknown-0x49" },
+ { 0x4A, "unknown-0x4A" },
+ { 0x4B, "unknown-0x4B" },
+ { 0x4C, "unknown-0x4C" },
+ { 0x4D, "unknown-0x4D" },
+ { 0x4E, "unknown-0x4E" },
+ { 0x4F, "unknown-0x4F" },
+ { 0x50, "unknown-0x50" },
+ { 0x51, "unknown-0x51" },
+ { 0x52, "unknown-0x52" },
+ { 0x53, "unknown-0x53" },
+ { 0x54, "unknown-0x54" },
+ { 0x55, "unknown-0x55" },
+ { 0x56, "unknown-0x56" },
+ { 0x57, "unknown-0x57" },
+ { 0x58, "unknown-0x58" },
+ { 0x59, "unknown-0x59" },
+ { 0x5A, "unknown-0x5A" },
+ { 0x5B, "unknown-0x5B" },
+ { 0x5C, "unknown-0x5C" },
+ { 0x5D, "unknown-0x5D" },
+ { 0x5E, "unknown-0x5E" },
+ { 0x5F, "unknown-0x5F" },
+ { 0x60, "unknown-0x60" },
+ { 0x61, "unknown-0x61" },
+ { 0x62, "unknown-0x62" },
+ { 0x63, "unknown-0x63" },
+ { 0x64, "unknown-0x64" },
+ { 0x65, "unknown-0x65" },
+ { 0x66, "unknown-0x66" },
+ { 0x67, "unknown-0x67" },
+ { 0x68, "unknown-0x68" },
+ { 0x69, "unknown-0x69" },
+ { 0x6A, "unknown-0x6A" },
+ { 0x6B, "unknown-0x6B" },
+ { 0x6C, "unknown-0x6C" },
+ { 0x6D, "unknown-0x6D" },
+ { 0x6E, "unknown-0x6E" },
+ { 0x6F, "unknown-0x6F" },
+ { 0x70, "Tree Connect" },
+ { 0x71, "Tree Disconnect" },
+ { 0x72, "Negotiate Protocol" },
+ { 0x73, "Session Setup AndX" },
+ { 0x74, "Logoff AndX" },
+ { 0x75, "Tree Connect AndX" },
+ { 0x76, "unknown-0x76" },
+ { 0x77, "unknown-0x77" },
+ { 0x78, "unknown-0x78" },
+ { 0x79, "unknown-0x79" },
+ { 0x7A, "unknown-0x7A" },
+ { 0x7B, "unknown-0x7B" },
+ { 0x7C, "unknown-0x7C" },
+ { 0x7D, "unknown-0x7D" },
+ { 0x7E, "unknown-0x7E" },
+ { 0x7F, "unknown-0x7F" },
+ { 0x80, "Query Information Disk" },
+ { 0x81, "Search" },
+ { 0x82, "Find" },
+ { 0x83, "Find Unique" },
+ { 0x84, "SMBfclose" },
+ { 0x85, "unknown-0x85" },
+ { 0x86, "unknown-0x86" },
+ { 0x87, "unknown-0x87" },
+ { 0x88, "unknown-0x88" },
+ { 0x89, "unknown-0x89" },
+ { 0x8A, "unknown-0x8A" },
+ { 0x8B, "unknown-0x8B" },
+ { 0x8C, "unknown-0x8C" },
+ { 0x8D, "unknown-0x8D" },
+ { 0x8E, "unknown-0x8E" },
+ { 0x8F, "unknown-0x8F" },
+ { 0x90, "unknown-0x90" },
+ { 0x91, "unknown-0x91" },
+ { 0x92, "unknown-0x92" },
+ { 0x93, "unknown-0x93" },
+ { 0x94, "unknown-0x94" },
+ { 0x95, "unknown-0x95" },
+ { 0x96, "unknown-0x96" },
+ { 0x97, "unknown-0x97" },
+ { 0x98, "unknown-0x98" },
+ { 0x99, "unknown-0x99" },
+ { 0x9A, "unknown-0x9A" },
+ { 0x9B, "unknown-0x9B" },
+ { 0x9C, "unknown-0x9C" },
+ { 0x9D, "unknown-0x9D" },
+ { 0x9E, "unknown-0x9E" },
+ { 0x9F, "unknown-0x9F" },
+ { 0xA0, "NT Transact" },
+ { 0xA1, "NT Transact Secondary" },
+ { 0xA2, "NT Create AndX" },
+ { 0xA3, "unknown-0xA3" },
+ { 0xA4, "NT Cancel" },
+ { 0xA5, "unknown-0xA5" },
+ { 0xA6, "unknown-0xA6" },
+ { 0xA7, "unknown-0xA7" },
+ { 0xA8, "unknown-0xA8" },
+ { 0xA9, "unknown-0xA9" },
+ { 0xAA, "unknown-0xAA" },
+ { 0xAB, "unknown-0xAB" },
+ { 0xAC, "unknown-0xAC" },
+ { 0xAD, "unknown-0xAD" },
+ { 0xAE, "unknown-0xAE" },
+ { 0xAF, "unknown-0xAF" },
+ { 0xB0, "unknown-0xB0" },
+ { 0xB1, "unknown-0xB1" },
+ { 0xB2, "unknown-0xB2" },
+ { 0xB3, "unknown-0xB3" },
+ { 0xB4, "unknown-0xB4" },
+ { 0xB5, "unknown-0xB5" },
+ { 0xB6, "unknown-0xB6" },
+ { 0xB7, "unknown-0xB7" },
+ { 0xB8, "unknown-0xB8" },
+ { 0xB9, "unknown-0xB9" },
+ { 0xBA, "unknown-0xBA" },
+ { 0xBB, "unknown-0xBB" },
+ { 0xBC, "unknown-0xBC" },
+ { 0xBD, "unknown-0xBD" },
+ { 0xBE, "unknown-0xBE" },
+ { 0xBF, "unknown-0xBF" },
+ { 0xC0, "Open Print File" },
+ { 0xC1, "Write Print File" },
+ { 0xC2, "Close Print File" },
+ { 0xC3, "Get Print Queue" },
+ { 0xC4, "unknown-0xC4" },
+ { 0xC5, "unknown-0xC5" },
+ { 0xC6, "unknown-0xC6" },
+ { 0xC7, "unknown-0xC7" },
+ { 0xC8, "unknown-0xC8" },
+ { 0xC9, "unknown-0xC9" },
+ { 0xCA, "unknown-0xCA" },
+ { 0xCB, "unknown-0xCB" },
+ { 0xCC, "unknown-0xCC" },
+ { 0xCD, "unknown-0xCD" },
+ { 0xCE, "unknown-0xCE" },
+ { 0xCF, "unknown-0xCF" },
+ { 0xD0, "SMBsends" },
+ { 0xD1, "SMBsendb" },
+ { 0xD2, "SMBfwdname" },
+ { 0xD3, "SMBcancelf" },
+ { 0xD4, "SMBgetmac" },
+ { 0xD5, "SMBsendstrt" },
+ { 0xD6, "SMBsendend" },
+ { 0xD7, "SMBsendtxt" },
+ { 0xD8, "SMBreadbulk" },
+ { 0xD9, "SMBwritebulk" },
+ { 0xDA, "SMBwritebulkdata" },
+ { 0xDB, "unknown-0xDB" },
+ { 0xDC, "unknown-0xDC" },
+ { 0xDD, "unknown-0xDD" },
+ { 0xDE, "unknown-0xDE" },
+ { 0xDF, "unknown-0xDF" },
+ { 0xE0, "unknown-0xE0" },
+ { 0xE1, "unknown-0xE1" },
+ { 0xE2, "unknown-0xE2" },
+ { 0xE3, "unknown-0xE3" },
+ { 0xE4, "unknown-0xE4" },
+ { 0xE5, "unknown-0xE5" },
+ { 0xE6, "unknown-0xE6" },
+ { 0xE7, "unknown-0xE7" },
+ { 0xE8, "unknown-0xE8" },
+ { 0xE9, "unknown-0xE9" },
+ { 0xEA, "unknown-0xEA" },
+ { 0xEB, "unknown-0xEB" },
+ { 0xEC, "unknown-0xEC" },
+ { 0xED, "unknown-0xED" },
+ { 0xEE, "unknown-0xEE" },
+ { 0xEF, "unknown-0xEF" },
+ { 0xF0, "unknown-0xF0" },
+ { 0xF1, "unknown-0xF1" },
+ { 0xF2, "unknown-0xF2" },
+ { 0xF3, "unknown-0xF3" },
+ { 0xF4, "unknown-0xF4" },
+ { 0xF5, "unknown-0xF5" },
+ { 0xF6, "unknown-0xF6" },
+ { 0xF7, "unknown-0xF7" },
+ { 0xF8, "unknown-0xF8" },
+ { 0xF9, "unknown-0xF9" },
+ { 0xFA, "unknown-0xFA" },
+ { 0xFB, "unknown-0xFB" },
+ { 0xFC, "unknown-0xFC" },
+ { 0xFD, "unknown-0xFD" },
+ { 0xFE, "SMBinvalid" },
+ { 0xFF, "unknown-0xFF" },
+ { 0x00, NULL },
+};
- /* Build display for: MaxBufferSize */
+static char *decode_smb_name(unsigned char cmd)
+{
+ return(smb_cmd_vals[cmd].strptr);
+}
+
- MaxBufferSize = GSHORT(pd, offset);
- if (tree) {
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ * Everything TVBUFFIFIED above this line
+ * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
- }
+/*
+ * Struct passed to each SMB decode routine of info it may need
+ */
- offset += 2; /* Skip MaxBufferSize */
- /* Build display for: MaxMpxCount */
+int smb_packet_init_count = 200;
- MaxMpxCount = GSHORT(pd, offset);
+/*
+ * This is a hash table matching transaction requests and replies.
+ *
+ * Unfortunately, the MID is not a transaction ID in, say, the ONC RPC
+ * sense; instead, it's a "multiplex ID" used when there's more than one
+ * request *currently* in flight, to distinguish replies.
+ *
+ * This means that the MID and PID don't uniquely identify a request in
+ * a conversation.
+ *
+ * Therefore, we have to use some other value to distinguish between
+ * requests with the same MID and PID.
+ *
+ * On the first pass through the capture, when we first see a request,
+ * we hash it by conversation, MID, and PID.
+ *
+ * When we first see a reply to it, we add it to a new hash table,
+ * hashing it by conversation, MID, PID, and frame number of the reply.
+ *
+ * This works as long as
+ *
+ * 1) a client doesn't screw up and have multiple requests outstanding
+ * with the same MID and PID
+ *
+ * and
+ *
+ * 2) we don't have, within the same frame, replies to multiple
+ * requests with the same MID and PID.
+ *
+ * 2) should happen only if the server screws up and puts the wrong MID or
+ * PID into a reply (in which case not only can we not handle this, the
+ * client can't handle it either) or if the client has screwed up as per
+ * 1) and the server's dutifully replied to both of the requests with the
+ * same MID and PID (in which case, again, neither we nor the client can
+ * handle this).
+ *
+ * We don't have to correctly dissect screwups; we just have to keep from
+ * dumping core on them.
+ *
+ * XXX - in addition, we need to keep a hash table of replies, so that we
+ * can associate continuations with the reply to which they're a continuation.
+ */
+struct smb_request_key {
+ guint32 conversation;
+ guint16 mid;
+ guint16 pid;
+ guint32 frame_num;
+};
- if (tree) {
+static GHashTable *smb_request_hash = NULL;
+static GMemChunk *smb_request_keys = NULL;
+static GMemChunk *smb_request_vals = NULL;
- proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
+/*
+ * This is a hash table matching continued transation replies and their
+ * continuations.
+ *
+ * It works similarly to the request/reply hash table.
+ */
+static GHashTable *smb_continuation_hash = NULL;
- }
+static GMemChunk *smb_continuation_vals = NULL;
- offset += 2; /* Skip MaxMpxCount */
+/* Hash Functions */
+static gint
+smb_equal(gconstpointer v, gconstpointer w)
+{
+ struct smb_request_key *v1 = (struct smb_request_key *)v;
+ struct smb_request_key *v2 = (struct smb_request_key *)w;
- /* Build display for: VcNumber */
+#if defined(DEBUG_SMB_HASH)
+ printf("Comparing %08X:%u:%u:%u\n and %08X:%u:%u:%u\n",
+ v1 -> conversation, v1 -> mid, v1 -> pid, v1 -> frame_num,
+ v2 -> conversation, v2 -> mid, v2 -> pid, v2 -> frame_num);
+#endif
- VcNumber = GSHORT(pd, offset);
+ if (v1 -> conversation == v2 -> conversation &&
+ v1 -> mid == v2 -> mid &&
+ v1 -> pid == v2 -> pid &&
+ v1 -> frame_num == v2 -> frame_num) {
- if (tree) {
+ return 1;
- proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
+ }
- }
+ return 0;
+}
- offset += 2; /* Skip VcNumber */
+static guint
+smb_hash (gconstpointer v)
+{
+ struct smb_request_key *key = (struct smb_request_key *)v;
+ guint val;
- /* Build display for: SessionKey */
+ val = (key -> conversation) + (key -> mid) + (key -> pid) +
+ (key -> frame_num);
- SessionKey = GWORD(pd, offset);
+#if defined(DEBUG_SMB_HASH)
+ printf("SMB Hash calculated as %u\n", val);
+#endif
- if (tree) {
+ return val;
- proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
+}
- }
+/*
+ * Free up any state information we've saved, and re-initialize the
+ * tables of state information.
+ */
- offset += 4; /* Skip SessionKey */
+/*
+ * For a hash table entry, free the address data to which the key refers
+ * and the fragment data to which the value refers.
+ * (The actual key and value structures get freed by "reassemble_init()".)
+ */
+static gboolean
+free_request_val_data(gpointer key, gpointer value, gpointer user_data)
+{
+ struct smb_request_val *request_val = value;
- /* Build display for: ANSI Account Password Length */
+ if (request_val->last_transact_command != NULL)
+ g_free(request_val->last_transact_command);
+ if (request_val->last_param_descrip != NULL)
+ g_free(request_val->last_param_descrip);
+ if (request_val->last_data_descrip != NULL)
+ g_free(request_val->last_data_descrip);
+ if (request_val->last_aux_data_descrip != NULL)
+ g_free(request_val->last_aux_data_descrip);
+ return TRUE;
+}
- ANSIAccountPasswordLength = GSHORT(pd, offset);
+static struct smb_request_val *
+do_transaction_hashing(conversation_t *conversation, struct smb_info si,
+ frame_data *fd)
+{
+ struct smb_request_key request_key, *new_request_key;
+ struct smb_request_val *request_val = NULL;
+ gpointer new_request_key_ret, request_val_ret;
- if (tree) {
+ if (si.request) {
+ /*
+ * This is a request.
+ *
+ * If this is the first time the frame has been seen, check for
+ * an entry for the request in the hash table. If it's not found,
+ * insert an entry for it.
+ *
+ * If it's the first time it's been seen, then we can't have seen
+ * the reply yet, so the reply frame number should be 0, for
+ * "unknown".
+ */
+ if (!fd->flags.visited) {
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = 0;
- proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
+ request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
- }
+ if (request_val == NULL) {
+ /*
+ * Not found.
+ */
+ new_request_key = g_mem_chunk_alloc(smb_request_keys);
+ new_request_key -> conversation = conversation->index;
+ new_request_key -> mid = si.mid;
+ new_request_key -> pid = si.pid;
+ new_request_key -> frame_num = 0;
- offset += 2; /* Skip ANSI Account Password Length */
+ request_val = g_mem_chunk_alloc(smb_request_vals);
+ request_val -> frame = fd->num;
+ request_val -> last_transact2_command = -1; /* unknown */
+ request_val -> last_transact_command = NULL;
+ request_val -> last_param_descrip = NULL;
+ request_val -> last_data_descrip = NULL;
+ request_val -> last_aux_data_descrip = NULL;
- /* Build display for: UNICODE Account Password Length */
+ g_hash_table_insert(smb_request_hash, new_request_key, request_val);
+ } else {
+ /*
+ * This means that we've seen another request in this conversation
+ * with the same request and reply, and without an intervening
+ * reply to that first request, and thus won't be using this
+ * "request_val" structure for that request (as we'd use it only
+ * for the reply).
+ *
+ * Clean out the structure, and set it to refer to this frame.
+ */
+ request_val -> frame = fd->num;
+ request_val -> last_transact2_command = -1; /* unknown */
+ if (request_val -> last_transact_command)
+ g_free(request_val -> last_transact_command);
+ request_val -> last_transact_command = NULL;
+ if (request_val -> last_param_descrip)
+ g_free(request_val -> last_param_descrip);
+ request_val -> last_param_descrip = NULL;
+ if (request_val -> last_data_descrip)
+ g_free(request_val -> last_data_descrip);
+ request_val -> last_data_descrip = NULL;
+ if (request_val -> last_aux_data_descrip)
+ g_free(request_val -> last_aux_data_descrip);
+ request_val -> last_aux_data_descrip = NULL;
+ }
+ }
+ } else {
+ /*
+ * This is a reply.
+ */
+ if (!fd->flags.visited) {
+ /*
+ * This is the first time the frame has been seen; check for
+ * an entry for a matching request, with an unknown reply frame
+ * number, in the hash table.
+ *
+ * If we find it, re-hash it with this frame's number as the
+ * reply frame number.
+ */
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = 0;
- UNICODEAccountPasswordLength = GSHORT(pd, offset);
+ /*
+ * Look it up - and, if we find it, get pointers to the key and
+ * value structures for it.
+ */
+ if (g_hash_table_lookup_extended(smb_request_hash, &request_key,
+ &new_request_key_ret,
+ &request_val_ret)) {
+ new_request_key = new_request_key_ret;
+ request_val = request_val_ret;
- if (tree) {
+ /*
+ * We found it.
+ * Remove the old entry.
+ */
+ g_hash_table_remove(smb_request_hash, &request_key);
- proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
+ /*
+ * Now update the key, and put it back into the hash table with
+ * the new key.
+ */
+ new_request_key->frame_num = fd->num;
+ g_hash_table_insert(smb_request_hash, new_request_key, request_val);
+ }
+ } else {
+ /*
+ * This is not the first time the frame has been seen; check for
+ * an entry for a matching request, with this frame's frame
+ * number as the reply frame number, in the hash table.
+ */
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = fd->num;
- }
+ request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
+ }
+ }
- offset += 2; /* Skip UNICODE Account Password Length */
+ return request_val;
+}
- /* Build display for: Reserved */
+static struct smb_continuation_val *
+do_continuation_hashing(conversation_t *conversation, struct smb_info si,
+ frame_data *fd, guint16 TotalDataCount,
+ guint16 DataCount, const char **TransactName)
+{
+ struct smb_request_key request_key, *new_request_key;
+ struct smb_continuation_val *continuation_val, *new_continuation_val;
+ gpointer new_request_key_ret, continuation_val_ret;
- Reserved = GWORD(pd, offset);
+ continuation_val = NULL;
+ if (si.ddisp != 0) {
+ /*
+ * This reply isn't the first in the series; there should be a
+ * reply of which it is a continuation.
+ */
+ if (!fd->flags.visited) {
+ /*
+ * This is the first time the frame has been seen; check for
+ * an entry for a matching continued message, with an unknown
+ * continuation frame number, in the hash table.
+ *
+ * If we find it, re-hash it with this frame's number as the
+ * continuation frame number.
+ */
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = 0;
- if (tree) {
+ /*
+ * Look it up - and, if we find it, get pointers to the key and
+ * value structures for it.
+ */
+ if (g_hash_table_lookup_extended(smb_continuation_hash, &request_key,
+ &new_request_key_ret,
+ &continuation_val_ret)) {
+ new_request_key = new_request_key_ret;
+ continuation_val = continuation_val_ret;
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
+ /*
+ * We found it.
+ * Remove the old entry.
+ */
+ g_hash_table_remove(smb_continuation_hash, &request_key);
+ /*
+ * Now update the key, and put it back into the hash table with
+ * the new key.
+ */
+ new_request_key->frame_num = fd->num;
+ g_hash_table_insert(smb_continuation_hash, new_request_key,
+ continuation_val);
}
+ } else {
+ /*
+ * This is not the first time the frame has been seen; check for
+ * an entry for a matching request, with this frame's frame
+ * number as the continuation frame number, in the hash table.
+ */
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = fd->num;
- offset += 4; /* Skip Reserved */
-
- /* Build display for: Capabilities */
-
- Capabilities = GWORD(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
- Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
- proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
- decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
-
- }
+ continuation_val = (struct smb_continuation_val *)
+ g_hash_table_lookup(smb_continuation_hash, &request_key);
+ }
+ }
- offset += 4; /* Skip Capabilities */
+ /*
+ * If we found the entry for the message of which this is a continuation,
+ * and our caller cares, get the transaction name for that message, as
+ * it's the transaction name for this message as well.
+ */
+ if (continuation_val != NULL && TransactName != NULL)
+ *TransactName = continuation_val -> transact_name;
- /* Build display for: Byte Count */
+ if (TotalDataCount > DataCount + si.ddisp) {
+ /*
+ * This reply isn't the last in the series; there should be a
+ * continuation for it later in the capture.
+ *
+ * If this is the first time the frame has been seen, check for
+ * an entry for the reply in the hash table. If it's not found,
+ * insert an entry for it.
+ *
+ * If it's the first time it's been seen, then we can't have seen
+ * the continuation yet, so the continuation frame number should
+ * be 0, for "unknown".
+ */
+ if (!fd->flags.visited) {
+ request_key.conversation = conversation->index;
+ request_key.mid = si.mid;
+ request_key.pid = si.pid;
+ request_key.frame_num = 0;
- ByteCount = GSHORT(pd, offset);
+ new_continuation_val = (struct smb_continuation_val *)
+ g_hash_table_lookup(smb_continuation_hash, &request_key);
- if (tree) {
+ if (new_continuation_val == NULL) {
+ /*
+ * Not found.
+ */
+ new_request_key = g_mem_chunk_alloc(smb_request_keys);
+ new_request_key -> conversation = conversation->index;
+ new_request_key -> mid = si.mid;
+ new_request_key -> pid = si.pid;
+ new_request_key -> frame_num = 0;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ new_continuation_val = g_mem_chunk_alloc(smb_continuation_vals);
+ new_continuation_val -> frame = fd->num;
+ if (TransactName != NULL)
+ new_continuation_val -> transact_name = *TransactName;
+ else
+ new_continuation_val -> transact_name = NULL;
+ g_hash_table_insert(smb_continuation_hash, new_request_key,
+ new_continuation_val);
+ } else {
+ /*
+ * This presumably means we never saw the continuation of
+ * the message we found, and this is a reply to a different
+ * request; as we never saw the continuation of that message,
+ * we won't be using this "request_val" structure for that
+ * message (as we'd use it only for the continuation).
+ *
+ * Clean out the structure, and set it to refer to this frame.
+ */
+ new_continuation_val -> frame = fd->num;
}
+ }
+ }
- offset += 2; /* Skip Byte Count */
-
- if (ByteCount > 0) {
-
- /* Build display for: ANSI Password */
+ return continuation_val;
+}
- ANSIPassword = pd + offset;
+static void
+smb_init_protocol(void)
+{
+#if defined(DEBUG_SMB_HASH)
+ printf("Initializing SMB hashtable area\n");
+#endif
- if (ANSIAccountPasswordLength > 0) {
+ if (smb_request_hash) {
+ /*
+ * Remove all entries from the hash table and free all strings
+ * attached to the keys and values. (The keys and values
+ * themselves are freed with "g_mem_chunk_destroy()" calls
+ * below.)
+ */
+ g_hash_table_foreach_remove(smb_request_hash, free_request_val_data, NULL);
+ g_hash_table_destroy(smb_request_hash);
+ }
+ if (smb_continuation_hash)
+ g_hash_table_destroy(smb_continuation_hash);
+ if (smb_request_keys)
+ g_mem_chunk_destroy(smb_request_keys);
+ if (smb_request_vals)
+ g_mem_chunk_destroy(smb_request_vals);
+ if (smb_continuation_vals)
+ g_mem_chunk_destroy(smb_continuation_vals);
- if (tree) {
+ smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
+ smb_continuation_hash = g_hash_table_new(smb_hash, smb_equal);
+ smb_request_keys = g_mem_chunk_new("smb_request_keys",
+ sizeof(struct smb_request_key),
+ smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
+ smb_request_vals = g_mem_chunk_new("smb_request_vals",
+ sizeof(struct smb_request_val),
+ smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
+ smb_continuation_vals = g_mem_chunk_new("smb_continuation_vals",
+ sizeof(struct smb_continuation_val),
+ smb_packet_init_count * sizeof(struct smb_continuation_val), G_ALLOC_AND_FREE);
+}
- proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
+static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int);
- }
+/*
+ * XXX - global required to avoid changing the calling sequence of old-style
+ * dissectors.
+ */
+static tvbuff_t *our_tvb;
+static packet_info *our_pinfo;
- offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
+static void
+wrap_dissect_smb_command(proto_tree *top_tree, const guint8 *pd, int offset,
+ proto_tree *smb_tree, guint8 cmd, struct smb_info *si, int max_data,
+ int SMB_offset)
+{
+ if(smb_dissector[cmd].request){
+ /* call smb command dissector */
+ our_pinfo->private_data = si;
+ dissect_smb_command(our_tvb, our_pinfo, top_tree, offset, smb_tree, cmd);
+ } else {
+ offset += SMB_offset;
+ if (check_col(our_pinfo->fd, COL_INFO)) {
+ col_add_fstr(our_pinfo->fd, COL_INFO, "%s %s",
+ decode_smb_name(cmd),
+ (si->request)? "Request" : "Response");
+ }
+ (dissect[cmd])(pd, offset, our_pinfo->fd, top_tree, smb_tree, *si,
+ max_data, SMB_offset);
}
+}
- /* Build display for: UNICODE Password */
-
- UNICODEPassword = pd + offset;
+void
+dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+{
- if (UNICODEAccountPasswordLength > 0) {
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)",
+ END_OF_FRAME);
- proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
+ }
- }
+}
- offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
+/*
+ * Dissect a UNIX like date ...
+ */
- }
+struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
+ conflict with /usr/include/time.h on some NetBSD
+ systems */
- /* Build display for: Account Name */
+static char *
+dissect_smbu_date(guint16 date, guint16 time)
- AccountName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+{
+ static char datebuf[4+2+2+2+1+10];
+ time_t ltime = (date << 16) + time;
- if (tree) {
+ _gtime = gmtime(<ime);
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Account Name: %s", AccountName);
+ if (_gtime)
+ sprintf(datebuf, "%04d-%02d-%02d",
+ 1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
+ else
+ sprintf(datebuf, "Bad date format");
- }
+ return datebuf;
- offset += string_len; /* Skip Account Name */
+}
- /* Build display for: Primary Domain */
+/*
+ * Relies on time
+ */
+static char *
+dissect_smbu_time(guint16 date, guint16 time)
- /*
- * XXX - pre-W2K NT systems sometimes appear to stick an extra
- * byte in front of this, at least if all the strings are
- * ASCII and the account name is empty. Another bug?
- */
+{
+ static char timebuf[2+2+2+2+1+10];
- PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ if (_gtime)
+ sprintf(timebuf, "%02d:%02d:%02d",
+ _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
+ else
+ sprintf(timebuf, "Bad time format");
- if (tree) {
+ return timebuf;
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
+}
- }
+/*
+ * Dissect a DOS-format date.
+ */
+static char *
+dissect_dos_date(guint16 date)
+{
+ static char datebuf[4+2+2+1];
- offset += string_len; /* Skip Primary Domain */
+ sprintf(datebuf, "%04d-%02d-%02d",
+ ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
+ return datebuf;
+}
- /* Build display for: Native OS */
+/*
+ * Dissect a DOS-format time.
+ */
+static char *
+dissect_dos_time(guint16 time)
+{
+ static char timebuf[2+2+2+1];
- NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ sprintf(timebuf, "%02d:%02d:%02d",
+ (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
+ return timebuf;
+}
- if (tree) {
+/* Max string length for displaying Unicode strings. */
+#define MAX_UNICODE_STR_LEN 256
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
+/* Turn a little-endian Unicode '\0'-terminated string into a string we
+ can display.
+ XXX - for now, we just handle the ISO 8859-1 characters. */
+static gchar *
+unicode_to_str(const guint8 *us, int *us_lenp) {
+ static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
+ static gchar *cur;
+ gchar *p;
+ int len;
+ int us_len;
+ int overflow = 0;
- }
+ NullTVB; /* remove this function when we are fully tvbuffified */
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+ p = cur;
+ len = MAX_UNICODE_STR_LEN;
+ us_len = 0;
+ while (*us != 0 || *(us + 1) != 0) {
+ if (len > 0) {
+ *p++ = *us;
+ len--;
+ } else
+ overflow = 1;
+ us += 2;
+ us_len += 2;
+ }
+ if (overflow) {
+ /* Note that we're not showing the full string. */
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+ *p = '\0';
+ *us_lenp = us_len;
+ return cur;
+}
+/* Turn a little-endian Unicode '\0'-terminated string into a string we
+ can display.
+ XXX - for now, we just handle the ISO 8859-1 characters.
+ If exactlen==TRUE then us_lenp contains the exact len of the string in
+ bytes. It might not be null terminated !
+*/
+static gchar *
+unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen) {
+ static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
+ static gchar *cur;
+ gchar *p;
+ guint16 uchar;
+ int len;
+ int us_len;
+ int overflow = 0;
- offset += string_len; /* Skip Native OS */
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+ p = cur;
+ len = MAX_UNICODE_STR_LEN;
+ us_len = 0;
+ while ((uchar = tvb_get_letohs(tvb, offset)) != 0) {
+ if (len > 0) {
+ if ((uchar & 0xFF00) == 0)
+ *p++ = uchar; /* ISO 8859-1 */
+ else
+ *p++ = '?'; /* not 8859-1 */
+ len--;
+ } else
+ overflow = 1;
+ offset += 2;
+ us_len += 2;
+ if(exactlen){
+ if(us_len>= *us_lenp){
+ break;
+ }
+ }
+ }
+ if (overflow) {
+ /* Note that we're not showing the full string. */
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+ *p = '\0';
+ *us_lenp = us_len;
+ return cur;
+}
+
- /* Build display for: Native LanMan Type */
+/* Get a null terminated string, which is Unicode if "is_unicode" is true
+ and ASCII (OEM character set) otherwise.
+ XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
+static const gchar *
+get_unicode_or_ascii_string(const u_char *pd, int *offsetp, int SMB_offset,
+ gboolean is_unicode, int *len)
+{
+ int offset = *offsetp;
+ const gchar *string;
+ int string_len;
- /*
- * XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
- * padding/null string/whatever in front of this. W2K doesn't
- * appear to. I suspect that's a bug that got fixed; I also
- * suspect that, in practice, nobody ever looks at that field
- * because the bug didn't appear to get fixed until NT 5.0....
- */
+ NullTVB; /* delete this function when we are fully tvbuffified */
+ if (is_unicode) {
+ if ((offset - SMB_offset) % 2) {
+ /*
+ * XXX - this should be an offset relative to the beginning of the SMB,
+ * not an offset relative to the beginning of the frame; if the stuff
+ * before the SMB has an odd number of bytes, an offset relative to
+ * the beginning of the frame will give the wrong answer.
+ */
+ offset++; /* Looks like a pad byte there sometimes */
+ *offsetp = offset;
+ }
+ string = unicode_to_str(pd + offset, &string_len);
+ string_len += 2;
+ } else {
+ string = pd + offset;
+ string_len = strlen(string) + 1;
+ }
+ *len = string_len;
+ return string;
+}
- NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+/* nopad == TRUE : Do not add any padding before this string
+ * exactlen == TRUE : len contains the exact len of the string in bytes.
+ */
+static const gchar *
+get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen)
+{
+ int offset = *offsetp;
+ const gchar *string;
+ int string_len;
+ smb_info_t *si;
- if (tree) {
+ si = pinfo->private_data;
+ if (si->unicode) {
+ if ((!nopad) && (*offsetp % 2)) {
+ /*
+ * XXX - this should be an offset relative to the beginning of the SMB,
+ * not an offset relative to the beginning of the frame; if the stuff
+ * before the SMB has an odd number of bytes, an offset relative to
+ * the beginning of the frame will give the wrong answer.
+ */
+ (*offsetp)++; /* Looks like a pad byte there sometimes */
+ }
+ if(exactlen){
+ string_len = *len;
+ string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
+ } else {
+ string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
+ string_len += 2;
+ }
+ } else {
+ if(exactlen){
+ string = tvb_get_ptr(tvb, *offsetp, *len);
+ string_len = *len;
+ } else {
+ string_len = tvb_strsize(tvb, *offsetp);
+ string = tvb_get_ptr(tvb, *offsetp, string_len);
+ }
+ }
+ *len = string_len;
+ return string;
+}
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
- }
+/*
+ * Each dissect routine is passed an offset to wct and works from there
+ */
- offset += string_len; /* Skip Native LanMan Type */
+void
+dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- }
+{
+ guint8 WordCount;
+ guint16 TotalUnits;
+ guint16 Reserved;
+ guint16 FreeUnits;
+ guint16 ByteCount;
+ guint16 BlocksPerUnit;
+ guint16 BlockSize;
- break;
+ if (si.request) {
+ /* Request(s) dissect code */
- default:
+ /* Build display for: Word Count (WCT) */
- /* XXX - dump the parameter words, one word at a time? */
+ WordCount = GBYTE(pd, offset);
- offset += WordCount;
+ if (tree) {
- /* Build display for: Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- ByteCount = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 1; /* Skip Word Count (WCT) */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ /* Build display for: Byte Count (BCC) */
- }
+ ByteCount = GSHORT(pd, offset);
- offset += 2; /* Skip Byte Count (BCC) */
+ if (tree) {
- break;
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
-
- }
+ offset += 2; /* Skip Byte Count (BCC) */
} else {
/* Response(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- switch (WordCount) {
-
- case 3:
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
- }
-
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
-
- AndXReserved = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
- }
-
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
-
- AndXOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
- }
-
- offset += 2; /* Skip AndXOffset */
-
- /* Build display for: Action */
-
- Action = GSHORT(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
- Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
- proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
-
- }
-
- offset += 2; /* Skip Action */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
- if (ByteCount > 0) {
-
- /* Build display for: NativeOS */
-
- NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
-
- }
-
- offset += string_len; /* Skip NativeOS */
-
- /* Build display for: NativeLanMan */
-
- NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
-
- }
-
- offset += string_len; /* Skip NativeLanMan */
-
- /* Build display for: PrimaryDomain */
-
- PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "PrimaryDomain: %s", PrimaryDomain);
-
- }
-
- offset += string_len; /* Skip PrimaryDomain */
-
- }
-
- break;
-
- case 4:
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
- }
-
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
-
- AndXReserved = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
- }
-
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
-
- AndXOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
- }
-
-
- offset += 2; /* Skip AndXOffset */
-
- /* Build display for: Action */
-
- Action = GSHORT(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
- Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
- proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
-
- }
-
- offset += 2; /* Skip Action */
+ if (WordCount != 0) {
- /* Build display for: Security Blob Length */
+ /* Build display for: Total Units */
- SecurityBlobLength = GSHORT(pd, offset);
+ TotalUnits = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
}
- offset += 2; /* Skip Security Blob Length */
+ offset += 2; /* Skip Total Units */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Blocks Per Unit */
- ByteCount = GSHORT(pd, offset);
+ BlocksPerUnit = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
}
- offset += 2; /* Skip Byte Count (BCC) */
-
- if (ByteCount > 0) {
-
- SecurityBlob = pd + offset;
-
- if (SecurityBlobLength > 0) {
-
- /* XXX - is this ASN.1-encoded? Is it a Kerberos data structure,
- at least in NT 5.0-and-later server replies? */
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
- bytes_to_str(SecurityBlob, SecurityBlobLength));
-
- }
-
- offset += SecurityBlobLength; /* Skip Security Blob */
-
- }
-
- /* Build display for: NativeOS */
-
- NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
-
- }
+ offset += 2; /* Skip Blocks Per Unit */
- offset += string_len; /* Skip NativeOS */
+ /* Build display for: Block Size */
- /* Build display for: NativeLanMan */
+ BlockSize = GSHORT(pd, offset);
- NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
- proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
+ }
- }
+ offset += 2; /* Skip Block Size */
- offset += string_len; /* Skip NativeLanMan */
+ /* Build display for: Free Units */
- }
+ FreeUnits = GSHORT(pd, offset);
- break;
+ if (tree) {
- default:
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
- /* XXX - dump the parameter words, one word at a time? */
+ }
- offset += WordCount;
+ offset += 2; /* Skip Free Units */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Reserved */
- ByteCount = GSHORT(pd, offset);
+ Reserved = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
}
- offset += 2; /* Skip Byte Count (BCC) */
-
- break;
+ offset += 2; /* Skip Reserved */
}
- if (AndXCommand != 0xFF) {
+ /* Build display for: Byte Count (BCC) */
+
+ ByteCount = GSHORT(pd, offset);
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
+ offset += 2; /* Skip Byte Count (BCC) */
+
}
}
void
-dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
- guint8 wct, andxcmd = 0xFF;
- guint16 andxoffs = 0, flags, passwdlen, bcc, optionsup;
- const char *str;
- int string_len;
- proto_tree *flags_tree;
- proto_tree *optionsup_tree;
- proto_item *ti;
+ guint8 WordCount;
+ guint8 Pad;
+ guint32 Reserved1;
+ guint32 Offset;
+ guint16 Reserved2;
+ guint16 Reserved;
+ guint16 MinCount;
+ guint16 MaxCount;
+ guint16 FID;
+ guint16 DataOffset;
+ guint16 DataLength;
+ guint16 DataCompactionMode;
+ guint16 Count;
+ guint16 ByteCount;
- wct = pd[offset];
+ if (si.request) {
+ /* Request(s) dissect code */
- /* Now figure out what format we are talking about, 2, 3, or 4 response
- * words ...
- */
+ /* Build display for: Word Count (WCT) */
- if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
- !(!si.request && (wct == 3)) && !(wct == 0)) {
+ WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
+ }
- return;
+ offset += 1; /* Skip Word Count (WCT) */
- }
-
- }
+ /* Build display for: FID */
- if (tree) {
+ FID = GSHORT(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
- offset += 1;
+ }
- if (wct > 0) {
+ offset += 2; /* Skip FID */
- andxcmd = pd[offset];
+ /* Build display for: Offset */
+
+ Offset = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
- (andxcmd == 0xFF) ? "No further commands":
- decode_smb_name(andxcmd));
-
- proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
}
- offset += 2;
+ offset += 4; /* Skip Offset */
- andxoffs = GSHORT(pd, offset);
+ /* Build display for: Max Count */
+
+ MaxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
}
- offset += 2;
-
- }
-
- switch (wct) {
+ offset += 2; /* Skip Max Count */
- case 0:
+ /* Build display for: Min Count */
- bcc = GSHORT(pd, offset);
+ MinCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
}
- break;
+ offset += 2; /* Skip Min Count */
- case 4:
+ /* Build display for: Reserved 1 */
- flags = GSHORT(pd, offset);
+ Reserved1 = GWORD(pd, offset);
if (tree) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%04x", flags);
- flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
- proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(flags, 0x0001, 16,
- "Disconnect TID",
- "Don't disconnect TID"));
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 1: %u", Reserved1);
}
- offset += 2;
+ offset += 4; /* Skip Reserved 1 */
- passwdlen = GSHORT(pd, offset);
+ /* Build display for: Reserved 2 */
+
+ Reserved2 = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
}
- offset += 2;
+ offset += 2; /* Skip Reserved 2 */
- bcc = GSHORT(pd, offset);
+ /* Build display for: Byte Count (BCC) */
+
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 2;
+ offset += 2; /* Skip Byte Count (BCC) */
- str = pd + offset;
+ } else {
+ /* Response(s) dissect code */
+
+ /* Build display for: Word Count */
+
+ WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
}
- offset += passwdlen;
+ offset += 1; /* Skip Word Count */
- str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ if (WordCount != 0) {
- if (tree) {
+ /* Build display for: Offset */
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Path: %s", str);
+ Offset = GWORD(pd, offset);
- }
+ if (tree) {
- offset += string_len;
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
- str = pd + offset;
+ }
- if (tree) {
+ offset += 4; /* Skip Offset */
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
+ /* Build display for: Count */
- }
+ Count = GSHORT(pd, offset);
- break;
+ if (tree) {
- case 2:
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
- bcc = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Count */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+ /* Build display for: Reserved */
- }
+ Reserved = GSHORT(pd, offset);
- offset += 2;
+ if (tree) {
- str = pd + offset;
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
- str);
+ offset += 2; /* Skip Reserved */
- }
+ /* Build display for: Data Compaction Mode */
- offset += strlen(str) + 1;
+ DataCompactionMode = GSHORT(pd, offset);
- break;
+ if (tree) {
- case 3:
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
- optionsup = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Data Compaction Mode */
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x",
- optionsup);
- optionsup_tree = proto_item_add_subtree(ti, ett_smb_optionsup);
- proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(optionsup, 0x0001, 16, "Share supports Search", "Share doesn't support Search"));
- proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(optionsup, 0x0002, 16, "Share is in DFS", "Share isn't in DFS"));
-
- }
+ /* Build display for: Reserved */
+
+ Reserved = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+
+ }
+
+ offset += 2; /* Skip Reserved */
+
+ /* Build display for: Data Length */
+
+ DataLength = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+
+ }
+
+ offset += 2; /* Skip Data Length */
+
+ /* Build display for: Data Offset */
+
+ DataOffset = GSHORT(pd, offset);
- offset += 2;
+ if (tree) {
- bcc = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+ offset += 2; /* Skip Data Offset */
}
- offset += 2;
-
- /*
- * NOTE: the Service string is always ASCII, even if the "strings are
- * Unicode" bit is set in the flags2 field of the SMB.
- */
+ /* Build display for: Byte Count (BCC) */
- str = pd + offset;
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += strlen(str) + 1;
+ offset += 2; /* Skip Byte Count (BCC) */
- str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ /* Build display for: Pad */
+
+ Pad = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native File System: %s", str);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
}
- offset += string_len;
-
-
- break;
+ offset += 1; /* Skip Pad */
- default:
- ; /* nothing */
- break;
}
- if (andxcmd != 0xFF) /* Process that next command ... ??? */
-
- (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset);
-
}
-
-
void
-dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_query_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
- static const value_string OpenFunction_0x10[] = {
- { 0, "Fail if file does not exist"},
- { 16, "Create file if it does not exist"},
- { 0, NULL}
- };
- static const value_string OpenFunction_0x03[] = {
- { 0, "Fail if file exists"},
- { 1, "Open file if it exists"},
- { 2, "Truncate File if it exists"},
- { 0, NULL}
- };
- static const value_string FileType_0xFFFF[] = {
- { 0, "Disk file or directory"},
- { 1, "Named pipe in byte mode"},
- { 2, "Named pipe in message mode"},
- { 3, "Spooled printer"},
- { 0, NULL}
- };
- static const value_string DesiredAccess_0x70[] = {
- { 00, "Compatibility mode"},
- { 16, "Deny read/write/execute (exclusive)"},
- { 32, "Deny write"},
- { 48, "Deny read/execute"},
- { 64, "Deny none"},
- { 0, NULL}
- };
- static const value_string DesiredAccess_0x700[] = {
- { 0, "Locality of reference unknown"},
- { 256, "Mainly sequential access"},
- { 512, "Mainly random access"},
- { 768, "Random access with some locality"},
- {0, NULL}
- };
- static const value_string DesiredAccess_0x4000[] = {
- { 0, "Write through mode disabled"},
- { 16384, "Write through mode enabled"},
- {0, NULL}
- };
- static const value_string DesiredAccess_0x1000[] = {
- { 0, "Normal file (caching permitted)"},
- { 4096, "Do not cache this file"},
- {0, NULL}
- };
- static const value_string DesiredAccess_0x07[] = {
- { 0, "Open for reading"},
- { 1, "Open for writing"},
- { 2, "Open for reading and writing"},
- { 3, "Open for execute"},
- {0, NULL}
- };
- static const value_string Action_0x8000[] = {
- { 0, "File opened by another user (or mode not supported by server)"},
- { 32768, "File is opened only by this user at present"},
- {0, NULL}
- };
- static const value_string Action_0x0003[] = {
- { 0, "No action taken?"},
- { 1, "The file existed and was opened"},
- { 2, "The file did not exist but was created"},
- { 3, "The file existed and was truncated"},
- {0, NULL}
- };
- proto_tree *Search_tree;
- proto_tree *OpenFunction_tree;
- proto_tree *Flags_tree;
- proto_tree *File_tree;
- proto_tree *FileType_tree;
- proto_tree *FileAttributes_tree;
- proto_tree *DesiredAccess_tree;
- proto_tree *Action_tree;
+ proto_tree *Attributes_tree;
proto_item *ti;
guint8 WordCount;
- guint8 AndXReserved;
- guint8 AndXCommand = 0xFF;
- guint32 ServerFID;
- guint32 Reserved2;
- guint32 Reserved1;
- guint32 DataSize;
- guint32 AllocatedSize;
- guint16 Search;
- guint16 Reserved;
- guint16 OpenFunction;
+ guint32 FileDataSize;
+ guint32 FileAllocationSize;
guint16 LastWriteTime;
guint16 LastWriteDate;
- guint16 GrantedAccess;
- guint16 Flags;
- guint16 FileType;
- guint16 FileAttributes;
- guint16 File;
+ guint16 LastAccessTime;
+ guint16 LastAccessDate;
guint16 FID;
- guint16 DeviceState;
- guint16 DesiredAccess;
guint16 CreationTime;
guint16 CreationDate;
guint16 ByteCount;
- guint16 AndXOffset = 0;
- guint16 Action;
- const char *FileName;
- int string_len;
+ guint16 Attributes;
if (si.request) {
/* Request(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: AndXCommand */
+ /* Build display for: FID */
- AndXCommand = GBYTE(pd, offset);
+ FID = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
}
- offset += 1; /* Skip AndXCommand */
+ offset += 2; /* Skip FID */
- /* Build display for: AndXReserved */
+ /* Build display for: Byte Count */
- AndXReserved = GBYTE(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
-
- AndXOffset = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
- }
+ offset += 2; /* Skip Byte Count */
- offset += 2; /* Skip AndXOffset */
+ } else {
+ /* Response(s) dissect code */
- /* Build display for: Flags */
+ /* Build display for: Word Count (WCT) */
- Flags = GSHORT(pd, offset);
+ WordCount = GBYTE(pd, offset);
if (tree) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
- Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
- proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
- proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
- proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
-
- }
-
- offset += 2; /* Skip Flags */
-
- /* Build display for: Desired Access */
-
- DesiredAccess = GSHORT(pd, offset);
-
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
- DesiredAccess_tree = proto_item_add_subtree(ti, ett_smb_desiredaccess);
- proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
- proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
- proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
- proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
- proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
-
}
- offset += 2; /* Skip Desired Access */
-
- /* Build display for: Search */
-
- Search = GSHORT(pd, offset);
+ offset += 1; /* Skip Word Count (WCT) */
- if (tree) {
+ if (WordCount != 0) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Search: 0x%02x", Search);
- Search_tree = proto_item_add_subtree(ti, ett_smb_search);
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
-
- }
+ /* Build display for: Creation Date */
- offset += 2; /* Skip Search */
+ CreationDate = GSHORT(pd, offset);
- /* Build display for: File */
+ if (tree) {
- File = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
- if (tree) {
+ }
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File: 0x%02x", File);
- File_tree = proto_item_add_subtree(ti, ett_smb_file);
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
-
- }
+ offset += 2; /* Skip Creation Date */
- offset += 2; /* Skip File */
+ /* Build display for: Creation Time */
- /* Build display for: Creation Time */
+ CreationTime = GSHORT(pd, offset);
- CreationTime = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
+ }
- }
+ offset += 2; /* Skip Creation Time */
- offset += 2; /* Skip Creation Time */
+ /* Build display for: Last Access Date */
- /* Build display for: Creation Date */
+ LastAccessDate = GSHORT(pd, offset);
- CreationDate = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_smbu_date(CreationDate, CreationTime));
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_smbu_time(CreationDate, CreationTime));
+ }
- }
+ offset += 2; /* Skip Last Access Date */
- offset += 2; /* Skip Creation Date */
+ /* Build display for: Last Access Time */
- /* Build display for: Open Function */
+ LastAccessTime = GSHORT(pd, offset);
- OpenFunction = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: 0x%02x", OpenFunction);
- OpenFunction_tree = proto_item_add_subtree(ti, ett_smb_openfunction);
- proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
- proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
-
- }
+ }
- offset += 2; /* Skip Open Function */
+ offset += 2; /* Skip Last Access Time */
- /* Build display for: Allocated Size */
+ /* Build display for: Last Write Date */
- AllocatedSize = GWORD(pd, offset);
+ LastWriteDate = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
- }
+ }
- offset += 4; /* Skip Allocated Size */
+ offset += 2; /* Skip Last Write Date */
- /* Build display for: Reserved1 */
+ /* Build display for: Last Write Time */
- Reserved1 = GWORD(pd, offset);
+ LastWriteTime = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
- }
+ }
- offset += 4; /* Skip Reserved1 */
+ offset += 2; /* Skip Last Write Time */
- /* Build display for: Reserved2 */
+ /* Build display for: File Data Size */
- Reserved2 = GWORD(pd, offset);
+ FileDataSize = GWORD(pd, offset);
- if (tree) {
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 4, "File Data Size: %u", FileDataSize);
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
+ }
- }
+ offset += 4; /* Skip File Data Size */
- offset += 4; /* Skip Reserved2 */
+ /* Build display for: File Allocation Size */
- /* Build display for: Byte Count */
+ FileAllocationSize = GWORD(pd, offset);
- ByteCount = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 4, "File Allocation Size: %u", FileAllocationSize);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ }
- }
+ offset += 4; /* Skip File Allocation Size */
- offset += 2; /* Skip Byte Count */
+ /* Build display for: Attributes */
- /* Build display for: File Name */
+ Attributes = GSHORT(pd, offset);
+
+ if (tree) {
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
+ Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
+ proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
+
+ }
+
+ offset += 2; /* Skip Attributes */
+
+ }
+
+ /* Build display for: Byte Count */
+
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += string_len; /* Skip File Name */
+ offset += 2; /* Skip Byte Count */
+ }
- if (AndXCommand != 0xFF) {
+}
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+/* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
+void
+dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- }
+{
+ proto_tree *Capabilities_tree;
+ proto_tree *Action_tree;
+ proto_item *ti;
+ guint8 WordCount;
+ guint8 AndXReserved;
+ guint8 AndXCommand = 0xFF;
+ guint32 SessionKey;
+ guint32 Reserved;
+ guint32 Capabilities;
+ guint16 VcNumber;
+ guint16 SecurityBlobLength;
+ guint16 ANSIAccountPasswordLength;
+ guint16 UNICODEAccountPasswordLength;
+ guint16 PasswordLen;
+ guint16 MaxMpxCount;
+ guint16 MaxBufferSize;
+ guint16 ByteCount;
+ guint16 AndXOffset = 0;
+ guint16 Action;
+ const char *ANSIPassword;
+ const char *UNICODEPassword;
+ const char *SecurityBlob;
+ const char *Password;
+ const char *PrimaryDomain;
+ const char *NativeOS;
+ const char *NativeLanManType;
+ const char *NativeLanMan;
+ const char *AccountName;
+ int string_len;
- } else {
- /* Response(s) dissect code */
+ if (si.request) {
+ /* Request(s) dissect code */
/* Build display for: Word Count (WCT) */
offset += 1; /* Skip Word Count (WCT) */
- if (WordCount != 0) {
+ switch (WordCount) {
+
+ case 10:
/* Build display for: AndXCommand */
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
(AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
offset += 2; /* Skip AndXOffset */
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: FileAttributes */
-
- FileAttributes = GSHORT(pd, offset);
-
- if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
- FileAttributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
-
- }
-
- offset += 2; /* Skip FileAttributes */
-
- /* Build display for: Last Write Time */
-
- LastWriteTime = GSHORT(pd, offset);
-
- if (tree) {
-
- }
-
- offset += 2; /* Skip Last Write Time */
-
- /* Build display for: Last Write Date */
-
- LastWriteDate = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
-
-
- }
-
- offset += 2; /* Skip Last Write Date */
-
- /* Build display for: Data Size */
+ /* Build display for: MaxBufferSize */
- DataSize = GWORD(pd, offset);
+ MaxBufferSize = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
}
- offset += 4; /* Skip Data Size */
+ offset += 2; /* Skip MaxBufferSize */
- /* Build display for: Granted Access */
+ /* Build display for: MaxMpxCount */
- GrantedAccess = GSHORT(pd, offset);
+ MaxMpxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
}
- offset += 2; /* Skip Granted Access */
+ offset += 2; /* Skip MaxMpxCount */
- /* Build display for: File Type */
+ /* Build display for: VcNumber */
- FileType = GSHORT(pd, offset);
+ VcNumber = GSHORT(pd, offset);
if (tree) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File Type: 0x%02x", FileType);
- FileType_tree = proto_item_add_subtree(ti, ett_smb_filetype);
- proto_tree_add_text(FileType_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
-
+ proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
+
}
- offset += 2; /* Skip File Type */
+ offset += 2; /* Skip VcNumber */
- /* Build display for: Device State */
+ /* Build display for: SessionKey */
- DeviceState = GSHORT(pd, offset);
+ SessionKey = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
}
- offset += 2; /* Skip Device State */
+ offset += 4; /* Skip SessionKey */
- /* Build display for: Action */
+ /* Build display for: PasswordLen */
- Action = GSHORT(pd, offset);
+ PasswordLen = GSHORT(pd, offset);
if (tree) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: 0x%02x", Action);
- Action_tree = proto_item_add_subtree(ti, ett_smb_openaction);
- proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
- proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
-
+ proto_tree_add_text(tree, NullTVB, offset, 2, "PasswordLen: %u", PasswordLen);
+
}
-
- offset += 2; /* Skip Action */
- /* Build display for: Server FID */
-
- ServerFID = GWORD(pd, offset);
+ offset += 2; /* Skip PasswordLen */
+
+ /* Build display for: Reserved */
+
+ Reserved = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: %u", ServerFID);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
}
- offset += 4; /* Skip Server FID */
+ offset += 4; /* Skip Reserved */
- /* Build display for: Reserved */
+ /* Build display for: Byte Count (BCC) */
- Reserved = GSHORT(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 2; /* Skip Reserved */
+ offset += 2; /* Skip Byte Count (BCC) */
- }
+ if (ByteCount > 0) {
- /* Build display for: Byte Count */
+ /* Build display for: Password */
- ByteCount = GSHORT(pd, offset);
+ Password = pd + offset;
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
- }
+ }
- offset += 2; /* Skip Byte Count */
+ offset += PasswordLen;
+ /* Build display for: AccountName */
- if (AndXCommand != 0xFF) {
+ AccountName = pd + offset;
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
- }
+ }
-}
+ offset += strlen(AccountName) + 1; /* Skip AccountName */
-void
-dissect_write_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ /* Build display for: PrimaryDomain */
-{
- proto_tree *WriteMode_tree;
- proto_item *ti;
- guint8 WordCount;
- guint8 Pad;
- guint32 Timeout;
- guint32 Reserved2;
- guint32 Offset;
- guint16 WriteMode;
- guint16 Reserved1;
- guint16 Remaining;
- guint16 FID;
- guint16 DataOffset;
- guint16 DataLength;
- guint16 Count;
- guint16 ByteCount;
+ PrimaryDomain = pd + offset;
- if (si.request) {
- /* Request(s) dissect code */
+ if (tree) {
- WordCount = GBYTE(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
- switch (WordCount) {
+ }
- case 12:
+ offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: NativeOS */
- WordCount = GBYTE(pd, offset);
+ NativeOS = pd + offset;
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
- }
+ }
- offset += 1; /* Skip Word Count (WCT) */
+ offset += strlen(NativeOS) + 1; /* Skip NativeOS */
- /* Build display for: FID */
+ /* Build display for: NativeLanMan */
- FID = GSHORT(pd, offset);
+ NativeLanMan = pd + offset;
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "Native Lan Manager: %s", NativeLanMan);
+
+ }
+
+ offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
}
- offset += 2; /* Skip FID */
+ break;
- /* Build display for: Count */
+ case 12:
- Count = GSHORT(pd, offset);
+ /* Build display for: AndXCommand */
+
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
- offset += 2; /* Skip Count */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: Reserved 1 */
+ /* Build display for: AndXReserved */
- Reserved1 = GSHORT(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 2; /* Skip Reserved 1 */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Offset */
+ /* Build display for: AndXOffset */
- Offset = GWORD(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 4; /* Skip Offset */
+ offset += 2; /* Skip AndXOffset */
- /* Build display for: Timeout */
+ /* Build display for: MaxBufferSize */
- Timeout = GWORD(pd, offset);
+ MaxBufferSize = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
}
- offset += 4; /* Skip Timeout */
+ offset += 2; /* Skip MaxBufferSize */
- /* Build display for: WriteMode */
+ /* Build display for: MaxMpxCount */
- WriteMode = GSHORT(pd, offset);
+ MaxMpxCount = GSHORT(pd, offset);
if (tree) {
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
- WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
- proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
- proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
-
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
+
}
- offset += 2; /* Skip WriteMode */
+ offset += 2; /* Skip MaxMpxCount */
- /* Build display for: Reserved 2 */
+ /* Build display for: VcNumber */
- Reserved2 = GWORD(pd, offset);
+ VcNumber = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
}
- offset += 4; /* Skip Reserved 2 */
+ offset += 2; /* Skip VcNumber */
- /* Build display for: Data Length */
+ /* Build display for: SessionKey */
- DataLength = GSHORT(pd, offset);
+ SessionKey = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
}
- offset += 2; /* Skip Data Length */
+ offset += 4; /* Skip SessionKey */
- /* Build display for: Data Offset */
+ /* Build display for: Security Blob Length */
- DataOffset = GSHORT(pd, offset);
+ SecurityBlobLength = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
}
- offset += 2; /* Skip Data Offset */
+ offset += 2; /* Skip Security Blob Length */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Reserved */
- ByteCount = GSHORT(pd, offset);
+ Reserved = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 4; /* Skip Reserved */
- /* Build display for: Pad */
+ /* Build display for: Capabilities */
- Pad = GBYTE(pd, offset);
+ Capabilities = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
-
- }
-
- offset += 1; /* Skip Pad */
+ ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
+ Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
- break;
+ }
- case 14:
+ offset += 4; /* Skip Capabilities */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: Byte Count */
- WordCount = GBYTE(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 2; /* Skip Byte Count */
- /* Build display for: FID */
+ if (ByteCount > 0) {
- FID = GSHORT(pd, offset);
+ /* Build display for: Security Blob */
- if (tree) {
+ SecurityBlob = pd + offset;
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ if (SecurityBlobLength > 0) {
- }
+ /* XXX - is this ASN.1-encoded? Is it a Kerberos data structure,
+ at least in NT 5.0-and-later server replies? */
- offset += 2; /* Skip FID */
+ if (tree) {
- /* Build display for: Count */
+ proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
+ bytes_to_str(SecurityBlob, SecurityBlobLength));
- Count = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += SecurityBlobLength; /* Skip Security Blob */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ }
- }
+ /* Build display for: Native OS */
- offset += 2; /* Skip Count */
+ NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- /* Build display for: Reserved 1 */
+ if (tree) {
- Reserved1 = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
+ offset += string_len; /* Skip Native OS */
- }
+ /* Build display for: Native LanMan Type */
- offset += 2; /* Skip Reserved 1 */
+ NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- /* Build display for: Timeout */
+ if (tree) {
- Timeout = GWORD(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+ offset += string_len; /* Skip Native LanMan Type */
- }
+ /* Build display for: Primary Domain */
- offset += 4; /* Skip Timeout */
+ PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- /* Build display for: WriteMode */
+ if (tree) {
- WriteMode = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
- if (tree) {
+ }
+
+ offset += string_len; /* Skip Primary Domain */
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
- WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
- proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
- proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
-
}
- offset += 2; /* Skip WriteMode */
+ break;
- /* Build display for: Reserved 2 */
+ case 13:
- Reserved2 = GWORD(pd, offset);
+ /* Build display for: AndXCommand */
+
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
- offset += 4; /* Skip Reserved 2 */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: Data Length */
+ /* Build display for: AndXReserved */
- DataLength = GSHORT(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 2; /* Skip Data Length */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Data Offset */
+ /* Build display for: AndXOffset */
- DataOffset = GSHORT(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 2; /* Skip Data Offset */
+ offset += 2; /* Skip AndXOffset */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: MaxBufferSize */
- ByteCount = GSHORT(pd, offset);
+ MaxBufferSize = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip MaxBufferSize */
- /* Build display for: Pad */
+ /* Build display for: MaxMpxCount */
- Pad = GBYTE(pd, offset);
+ MaxMpxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
}
- offset += 1; /* Skip Pad */
-
- break;
-
- }
-
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
+ offset += 2; /* Skip MaxMpxCount */
- /* Build display for: Remaining */
+ /* Build display for: VcNumber */
- Remaining = GSHORT(pd, offset);
+ VcNumber = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
}
- offset += 2; /* Skip Remaining */
-
- }
-
- /* Build display for: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- }
-
-}
-
-void
-dissect_rename_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ offset += 2; /* Skip VcNumber */
-{
- guint8 WordCount;
- guint8 BufferFormat2;
- guint8 BufferFormat1;
- guint16 SearchAttributes;
- guint16 ByteCount;
- const char *OldFileName;
- const char *NewFileName;
- int string_len;
+ /* Build display for: SessionKey */
- if (si.request) {
- /* Request(s) dissect code */
+ SessionKey = GWORD(pd, offset);
- /* Build display for: Word Count (WCT) */
+ if (tree) {
- WordCount = GBYTE(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ offset += 4; /* Skip SessionKey */
- }
+ /* Build display for: ANSI Account Password Length */
- offset += 1; /* Skip Word Count (WCT) */
+ ANSIAccountPasswordLength = GSHORT(pd, offset);
- /* Build display for: Search Attributes */
+ if (tree) {
- SearchAttributes = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
+ offset += 2; /* Skip ANSI Account Password Length */
- }
+ /* Build display for: UNICODE Account Password Length */
- offset += 2; /* Skip Search Attributes */
+ UNICODEAccountPasswordLength = GSHORT(pd, offset);
- /* Build display for: Byte Count */
+ if (tree) {
- ByteCount = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ offset += 2; /* Skip UNICODE Account Password Length */
- }
+ /* Build display for: Reserved */
- offset += 2; /* Skip Byte Count */
+ Reserved = GWORD(pd, offset);
- /* Build display for: Buffer Format 1 */
+ if (tree) {
- BufferFormat1 = GBYTE(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
- val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
- BufferFormat1);
+ offset += 4; /* Skip Reserved */
- }
+ /* Build display for: Capabilities */
- offset += 1; /* Skip Buffer Format 1 */
+ Capabilities = GWORD(pd, offset);
- /* Build display for: Old File Name */
+ if (tree) {
- OldFileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
+ Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
+ proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
+ decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
+
+ }
- if (tree) {
+ offset += 4; /* Skip Capabilities */
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Old File Name: %s", OldFileName);
+ /* Build display for: Byte Count */
- }
+ ByteCount = GSHORT(pd, offset);
- offset += string_len; /* Skip Old File Name */
+ if (tree) {
- /* Build display for: Buffer Format 2 */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
- BufferFormat2 = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Byte Count */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
- val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
- BufferFormat2);
+ if (ByteCount > 0) {
- }
+ /* Build display for: ANSI Password */
- offset += 1; /* Skip Buffer Format 2 */
+ ANSIPassword = pd + offset;
- /* Build display for: New File Name */
+ if (ANSIAccountPasswordLength > 0) {
- NewFileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
- proto_tree_add_text(tree, NullTVB, offset, string_len, "New File Name: %s", NewFileName);
+ }
- }
+ offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
+ }
- offset += string_len; /* Skip New File Name */
+ /* Build display for: UNICODE Password */
- } else {
- /* Response(s) dissect code */
+ UNICODEPassword = pd + offset;
- /* Build display for: Word Count (WCT) */
+ if (UNICODEAccountPasswordLength > 0) {
- WordCount = GBYTE(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ }
- }
+ offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
- offset += 1; /* Skip Word Count (WCT) */
+ }
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Account Name */
- ByteCount = GSHORT(pd, offset);
+ AccountName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Account Name: %s", AccountName);
- }
+ }
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += string_len; /* Skip Account Name */
- }
+ /* Build display for: Primary Domain */
-}
+ /*
+ * XXX - pre-W2K NT systems sometimes appear to stick an extra
+ * byte in front of this, at least if all the strings are
+ * ASCII and the account name is empty. Another bug?
+ */
-void
-dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-{
- static const value_string Mode_0x03[] = {
- { 0, "Text mode (DOS expands TABs)"},
- { 1, "Graphics mode"},
- { 0, NULL}
- };
- proto_tree *Mode_tree;
- proto_item *ti;
- guint8 WordCount;
- guint8 BufferFormat;
- guint16 SetupLength;
- guint16 Mode;
- guint16 FID;
- guint16 ByteCount;
- const char *IdentifierString;
- int string_len;
+ if (tree) {
- if (si.request) {
- /* Request(s) dissect code */
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
- /* Build display for: Word Count (WCT) */
+ }
- WordCount = GBYTE(pd, offset);
+ offset += string_len; /* Skip Primary Domain */
- if (tree) {
+ /* Build display for: Native OS */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- }
+ if (tree) {
- offset += 1; /* Skip Word Count (WCT) */
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
- /* Build display for: Setup Length */
+ }
- SetupLength = GSHORT(pd, offset);
+ offset += string_len; /* Skip Native OS */
- if (tree) {
+ /* Build display for: Native LanMan Type */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Setup Length: %u", SetupLength);
+ /*
+ * XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
+ * padding/null string/whatever in front of this. W2K doesn't
+ * appear to. I suspect that's a bug that got fixed; I also
+ * suspect that, in practice, nobody ever looks at that field
+ * because the bug didn't appear to get fixed until NT 5.0....
+ */
- }
+ NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- offset += 2; /* Skip Setup Length */
+ if (tree) {
- /* Build display for: Mode */
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
- Mode = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += string_len; /* Skip Native LanMan Type */
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
- Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
- proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
-
- }
+ }
- offset += 2; /* Skip Mode */
+ break;
- /* Build display for: Byte Count (BCC) */
+ default:
- ByteCount = GSHORT(pd, offset);
+ /* XXX - dump the parameter words, one word at a time? */
- if (tree) {
+ offset += WordCount;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ /* Build display for: Byte Count (BCC) */
- }
+ ByteCount = GSHORT(pd, offset);
- offset += 2; /* Skip Byte Count (BCC) */
+ if (tree) {
- /* Build display for: Buffer Format */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- BufferFormat = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Byte Count (BCC) */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ break;
}
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: Identifier String */
-
- IdentifierString = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
+ if (AndXCommand != 0xFF) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Identifier String: %s", IdentifierString);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
}
- offset += string_len; /* Skip Identifier String */
-
} else {
/* Response(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
+ switch (WordCount) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ case 3:
- }
+ /* Build display for: AndXCommand */
- offset += 2; /* Skip FID */
+ AndXCommand = GBYTE(pd, offset);
- /* Build display for: Byte Count (BCC) */
+ if (tree) {
- ByteCount = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ offset += 1; /* Skip AndXCommand */
- }
+ /* Build display for: AndXReserved */
- offset += 2; /* Skip Byte Count (BCC) */
+ AndXReserved = GBYTE(pd, offset);
- }
+ if (tree) {
-}
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-void
-dissect_close_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ }
-{
- guint8 WordCount;
- guint16 FID;
- guint16 ByteCount;
+ offset += 1; /* Skip AndXReserved */
- if (si.request) {
- /* Request(s) dissect code */
+ /* Build display for: AndXOffset */
- /* Build display for: Word Count (WCT) */
+ AndXOffset = GSHORT(pd, offset);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ }
- }
+ offset += 2; /* Skip AndXOffset */
- offset += 1; /* Skip Word Count (WCT) */
+ /* Build display for: Action */
- /* Build display for: FID */
+ Action = GSHORT(pd, offset);
- FID = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
+ Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
+ proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ }
- }
+ offset += 2; /* Skip Action */
- offset += 2; /* Skip FID */
+ /* Build display for: Byte Count (BCC) */
- /* Build display for: Byte Count (BCC) */
+ ByteCount = GSHORT(pd, offset);
- ByteCount = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ }
- }
+ offset += 2; /* Skip Byte Count (BCC) */
- offset += 2; /* Skip Byte Count (BCC) */
+ if (ByteCount > 0) {
- } else {
- /* Response(s) dissect code */
+ /* Build display for: NativeOS */
- /* Build display for: Word Count */
+ NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
+ }
- }
+ offset += string_len; /* Skip NativeOS */
- offset += 1; /* Skip Word Count */
+ /* Build display for: NativeLanMan */
- /* Build display for: Byte Count (BCC) */
+ NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- ByteCount = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ }
- }
+ offset += string_len; /* Skip NativeLanMan */
- offset += 2; /* Skip Byte Count (BCC) */
+ /* Build display for: PrimaryDomain */
- }
+ PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-}
+ if (tree) {
-void
-dissect_read_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "PrimaryDomain: %s", PrimaryDomain);
-{
- guint8 WordCount;
- guint32 Timeout;
- guint32 OffsetHigh;
- guint32 Offset;
- guint16 Reserved;
- guint16 MinCount;
- guint16 MaxCount;
- guint16 FID;
- guint16 ByteCount;
+ }
- if (si.request) {
- /* Request(s) dissect code */
+ offset += string_len; /* Skip PrimaryDomain */
- WordCount = GBYTE(pd, offset);
+ }
- switch (WordCount) {
+ break;
- case 8:
+ case 4:
- /* Build display for: Word Count (WCT) */
+ /* Build display for: AndXCommand */
- WordCount = GBYTE(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: FID */
+ /* Build display for: AndXReserved */
- FID = GSHORT(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 2; /* Skip FID */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Offset */
+ /* Build display for: AndXOffset */
- Offset = GWORD(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 4; /* Skip Offset */
- /* Build display for: Max Count */
+ offset += 2; /* Skip AndXOffset */
- MaxCount = GSHORT(pd, offset);
+ /* Build display for: Action */
+
+ Action = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
+ Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
+ proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
}
- offset += 2; /* Skip Max Count */
+ offset += 2; /* Skip Action */
- /* Build display for: Min Count */
+ /* Build display for: Security Blob Length */
- MinCount = GSHORT(pd, offset);
+ SecurityBlobLength = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
}
- offset += 2; /* Skip Min Count */
+ offset += 2; /* Skip Security Blob Length */
- /* Build display for: Timeout */
+ /* Build display for: Byte Count (BCC) */
- Timeout = GWORD(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 4; /* Skip Timeout */
+ offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Reserved */
+ if (ByteCount > 0) {
- Reserved = GSHORT(pd, offset);
+ SecurityBlob = pd + offset;
- if (tree) {
+ if (SecurityBlobLength > 0) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+ /* XXX - is this ASN.1-encoded? Is it a Kerberos data structure,
+ at least in NT 5.0-and-later server replies? */
- }
+ if (tree) {
- offset += 2; /* Skip Reserved */
+ proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
+ bytes_to_str(SecurityBlob, SecurityBlobLength));
- /* Build display for: Byte Count (BCC) */
+ }
- ByteCount = GSHORT(pd, offset);
+ offset += SecurityBlobLength; /* Skip Security Blob */
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ /* Build display for: NativeOS */
- }
+ NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- offset += 2; /* Skip Byte Count (BCC) */
+ if (tree) {
- break;
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
- case 10:
+ }
- /* Build display for: Word Count (WCT) */
+ offset += string_len; /* Skip NativeOS */
- WordCount = GBYTE(pd, offset);
+ /* Build display for: NativeLanMan */
- if (tree) {
+ NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
- offset += 1; /* Skip Word Count (WCT) */
+ }
- /* Build display for: FID */
+ offset += string_len; /* Skip NativeLanMan */
- FID = GSHORT(pd, offset);
+ }
- if (tree) {
+ break;
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ default:
- }
+ /* XXX - dump the parameter words, one word at a time? */
- offset += 2; /* Skip FID */
+ offset += WordCount;
- /* Build display for: Offset */
+ /* Build display for: Byte Count (BCC) */
- Offset = GWORD(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 4; /* Skip Offset */
+ offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Max Count */
+ break;
- MaxCount = GSHORT(pd, offset);
+ }
- if (tree) {
+ if (AndXCommand != 0xFF) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
- }
+ }
- offset += 2; /* Skip Max Count */
+ }
- /* Build display for: Min Count */
+}
- MinCount = GSHORT(pd, offset);
+void
+dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- if (tree) {
+{
+ guint8 wct, andxcmd = 0xFF;
+ guint16 andxoffs = 0, flags, passwdlen, bcc, optionsup;
+ const char *str;
+ int string_len;
+ proto_tree *flags_tree;
+ proto_tree *optionsup_tree;
+ proto_item *ti;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
+ wct = pd[offset];
- }
+ /* Now figure out what format we are talking about, 2, 3, or 4 response
+ * words ...
+ */
- offset += 2; /* Skip Min Count */
+ if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
+ !(!si.request && (wct == 3)) && !(wct == 0)) {
- /* Build display for: Timeout */
+ if (tree) {
- Timeout = GWORD(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+ return;
- }
+ }
+
+ }
- offset += 4; /* Skip Timeout */
+ if (tree) {
- /* Build display for: Reserved */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
- Reserved = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 1;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+ if (wct > 0) {
- }
+ andxcmd = pd[offset];
- offset += 2; /* Skip Reserved */
+ if (tree) {
- /* Build display for: Offset High */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
+ (andxcmd == 0xFF) ? "No further commands":
+ decode_smb_name(andxcmd));
+
+ proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
- OffsetHigh = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 2;
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
+ andxoffs = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 4; /* Skip Offset High */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
- /* Build display for: Byte Count (BCC) */
+ }
- ByteCount = GSHORT(pd, offset);
+ offset += 2;
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ switch (wct) {
- }
+ case 0:
- offset += 2; /* Skip Byte Count (BCC) */
+ bcc = GSHORT(pd, offset);
+
+ if (tree) {
- break;
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
}
- } else {
- /* Response(s) dissect code */
+ break;
- }
+ case 4:
-}
+ flags = GSHORT(pd, offset);
-void
-dissect_read_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ if (tree) {
-{
- guint8 WordCount;
- guint8 AndXReserved;
- guint8 AndXCommand = 0xFF;
- guint16 ByteCount;
- guint16 AndXOffset = 0;
- guint16 FID;
- guint16 DataCompactionMode;
- guint16 DataLength;
- guint16 DataOffset;
- guint16 Remaining;
- guint16 MaxCount;
- guint16 MinCount;
- guint16 Reserved;
- guint32 Offset;
- guint32 OffsetHigh;
- int i;
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%04x", flags);
+ flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
+ proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(flags, 0x0001, 16,
+ "Disconnect TID",
+ "Don't disconnect TID"));
- if (si.request) {
- /* Request(s) dissect code */
+ }
- /* Build display for: Word Count (WCT) */
+ offset += 2;
- WordCount = GBYTE(pd, offset);
+ passwdlen = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
}
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: AndXCommand */
+ offset += 2;
- AndXCommand = GBYTE(pd, offset);
+ bcc = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
}
- offset += 1; /* Skip AndXCommand */
-
- /* Build display for: AndXReserved */
+ offset += 2;
- AndXReserved = GBYTE(pd, offset);
+ str = pd + offset;
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
}
- offset += 1; /* Skip AndXReserved */
-
- /* Build display for: AndXOffset */
+ offset += passwdlen;
- AndXOffset = GSHORT(pd, offset);
+ str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Path: %s", str);
}
- offset += 2; /* Skip AndXOffset */
-
- /* Build display for: FID */
+ offset += string_len;
- FID = GSHORT(pd, offset);
+ str = pd + offset;
if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
+
+ proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
+
}
- offset += 2; /* Skip FID */
+ break;
- /* Build display for: Offset */
+ case 2:
- Offset = GWORD(pd, offset);
+ bcc = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
}
- offset += 4; /* Skip Offset */
-
- /* Build display for: Max Count */
+ offset += 2;
- MaxCount = GSHORT(pd, offset);
+ str = pd + offset;
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
+ str);
}
- offset += 2; /* Skip Max Count */
+ offset += strlen(str) + 1;
- /* Build display for: Min Count */
+ break;
- MinCount = GSHORT(pd, offset);
+ case 3:
- if (tree) {
+ optionsup = GSHORT(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
+ if (tree) {
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x",
+ optionsup);
+ optionsup_tree = proto_item_add_subtree(ti, ett_smb_optionsup);
+ proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(optionsup, 0x0001, 16, "Share supports Search", "Share doesn't support Search"));
+ proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(optionsup, 0x0002, 16, "Share is in DFS", "Share isn't in DFS"));
+
}
- offset += 2; /* Skip Min Count */
-
- /* Build display for: Reserved */
+ offset += 2;
- Reserved = GWORD(pd, offset);
+ bcc = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
}
- offset += 4; /* Skip Reserved */
+ offset += 2;
- /* Build display for: Remaining */
+ /*
+ * NOTE: the Service string is always ASCII, even if the "strings are
+ * Unicode" bit is set in the flags2 field of the SMB.
+ */
- Remaining = GSHORT(pd, offset);
+ str = pd + offset;
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+ proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
}
- offset += 2; /* Skip Remaining */
-
- if (WordCount == 12) {
-
- /* Build display for: Offset High */
-
- OffsetHigh = GWORD(pd, offset);
+ offset += strlen(str) + 1;
- if (tree) {
+ str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Native File System: %s", str);
- offset += 4; /* Skip Offset High */
}
- /* Build display for: Byte Count (BCC) */
+ offset += string_len;
- ByteCount = GSHORT(pd, offset);
+
+ break;
- if (tree) {
+ default:
+ ; /* nothing */
+ break;
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ if (andxcmd != 0xFF) /* Process that next command ... ??? */
- }
+ (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset);
- offset += 2; /* Skip Byte Count (BCC) */
+}
- if (AndXCommand != 0xFF) {
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+void
+dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- }
+{
+ static const value_string OpenFunction_0x10[] = {
+ { 0, "Fail if file does not exist"},
+ { 16, "Create file if it does not exist"},
+ { 0, NULL}
+ };
+ static const value_string OpenFunction_0x03[] = {
+ { 0, "Fail if file exists"},
+ { 1, "Open file if it exists"},
+ { 2, "Truncate File if it exists"},
+ { 0, NULL}
+ };
+ static const value_string FileType_0xFFFF[] = {
+ { 0, "Disk file or directory"},
+ { 1, "Named pipe in byte mode"},
+ { 2, "Named pipe in message mode"},
+ { 3, "Spooled printer"},
+ { 0, NULL}
+ };
+ static const value_string DesiredAccess_0x70[] = {
+ { 00, "Compatibility mode"},
+ { 16, "Deny read/write/execute (exclusive)"},
+ { 32, "Deny write"},
+ { 48, "Deny read/execute"},
+ { 64, "Deny none"},
+ { 0, NULL}
+ };
+ static const value_string DesiredAccess_0x700[] = {
+ { 0, "Locality of reference unknown"},
+ { 256, "Mainly sequential access"},
+ { 512, "Mainly random access"},
+ { 768, "Random access with some locality"},
+ {0, NULL}
+ };
+ static const value_string DesiredAccess_0x4000[] = {
+ { 0, "Write through mode disabled"},
+ { 16384, "Write through mode enabled"},
+ {0, NULL}
+ };
+ static const value_string DesiredAccess_0x1000[] = {
+ { 0, "Normal file (caching permitted)"},
+ { 4096, "Do not cache this file"},
+ {0, NULL}
+ };
+ static const value_string DesiredAccess_0x07[] = {
+ { 0, "Open for reading"},
+ { 1, "Open for writing"},
+ { 2, "Open for reading and writing"},
+ { 3, "Open for execute"},
+ {0, NULL}
+ };
+ static const value_string Action_0x8000[] = {
+ { 0, "File opened by another user (or mode not supported by server)"},
+ { 32768, "File is opened only by this user at present"},
+ {0, NULL}
+ };
+ static const value_string Action_0x0003[] = {
+ { 0, "No action taken?"},
+ { 1, "The file existed and was opened"},
+ { 2, "The file did not exist but was created"},
+ { 3, "The file existed and was truncated"},
+ {0, NULL}
+ };
+ proto_tree *Search_tree;
+ proto_tree *OpenFunction_tree;
+ proto_tree *Flags_tree;
+ proto_tree *File_tree;
+ proto_tree *FileType_tree;
+ proto_tree *FileAttributes_tree;
+ proto_tree *DesiredAccess_tree;
+ proto_tree *Action_tree;
+ proto_item *ti;
+ guint8 WordCount;
+ guint8 AndXReserved;
+ guint8 AndXCommand = 0xFF;
+ guint32 ServerFID;
+ guint32 Reserved2;
+ guint32 Reserved1;
+ guint32 DataSize;
+ guint32 AllocatedSize;
+ guint16 Search;
+ guint16 Reserved;
+ guint16 OpenFunction;
+ guint16 LastWriteTime;
+ guint16 LastWriteDate;
+ guint16 GrantedAccess;
+ guint16 Flags;
+ guint16 FileType;
+ guint16 FileAttributes;
+ guint16 File;
+ guint16 FID;
+ guint16 DeviceState;
+ guint16 DesiredAccess;
+ guint16 CreationTime;
+ guint16 CreationDate;
+ guint16 ByteCount;
+ guint16 AndXOffset = 0;
+ guint16 Action;
+ const char *FileName;
+ int string_len;
- } else {
- /* Response(s) dissect code */
+ if (si.request) {
+ /* Request(s) dissect code */
/* Build display for: Word Count (WCT) */
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
offset += 2; /* Skip AndXOffset */
- /* Build display for: Remaining */
+ /* Build display for: Flags */
- Remaining = GSHORT(pd, offset);
+ Flags = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
+ Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
+ proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
+ proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
+ proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
+
}
- offset += 2; /* Skip Remaining */
+ offset += 2; /* Skip Flags */
- /* Build display for: Data Compaction Mode */
+ /* Build display for: Desired Access */
- DataCompactionMode = GSHORT(pd, offset);
+ DesiredAccess = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
+ DesiredAccess_tree = proto_item_add_subtree(ti, ett_smb_desiredaccess);
+ proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
+ proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
+ proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
+ proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
+ proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
+
}
- offset += 2; /* Skip Data Compaction Mode */
+ offset += 2; /* Skip Desired Access */
- /* Build display for: Reserved */
+ /* Build display for: Search */
- Reserved = GSHORT(pd, offset);
+ Search = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Search: 0x%02x", Search);
+ Search_tree = proto_item_add_subtree(ti, ett_smb_search);
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
+ proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
+
}
- offset += 2; /* Skip Reserved */
+ offset += 2; /* Skip Search */
- /* Build display for: Data Length */
+ /* Build display for: File */
- DataLength = GSHORT(pd, offset);
+ File = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File: 0x%02x", File);
+ File_tree = proto_item_add_subtree(ti, ett_smb_file);
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
+ proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
+
}
- offset += 2; /* Skip Data Length */
+ offset += 2; /* Skip File */
- /* Build display for: Data Offset */
+ /* Build display for: Creation Time */
- DataOffset = GSHORT(pd, offset);
+ CreationTime = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
}
- offset += 2; /* Skip Data Offset */
-
- /* Build display for: Reserved[5] */
-
- for(i = 1; i <= 5; ++i) {
-
- Reserved = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);
-
- }
- offset += 2;
- }
+ offset += 2; /* Skip Creation Time */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Creation Date */
- ByteCount = GSHORT(pd, offset);
+ CreationDate = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_smbu_date(CreationDate, CreationTime));
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_smbu_time(CreationDate, CreationTime));
}
- offset += 2; /* Skip Byte Count (BCC) */
-
- /* Build display for data */
-
- if (tree) {
-
- offset = SMB_offset + DataOffset;
- if(END_OF_FRAME >= DataLength)
- proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
- else
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
+ offset += 2; /* Skip Creation Date */
- }
+ /* Build display for: Open Function */
- if (AndXCommand != 0xFF) {
+ OpenFunction = GSHORT(pd, offset);
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ if (tree) {
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: 0x%02x", OpenFunction);
+ OpenFunction_tree = proto_item_add_subtree(ti, ett_smb_openfunction);
+ proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
+ proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
+
}
- }
-
-}
-
-void
-dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- guint8 WordCount;
- guint8 AndXReserved;
- guint8 AndXCommand = 0xFF;
- guint16 ByteCount;
- guint16 AndXOffset = 0;
-
- if (si.request) {
- /* Request(s) dissect code */
+ offset += 2; /* Skip Open Function */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: Allocated Size */
- WordCount = GBYTE(pd, offset);
+ AllocatedSize = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
}
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
+ offset += 4; /* Skip Allocated Size */
- if (tree) {
+ /* Build display for: Reserved1 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+ Reserved1 = GWORD(pd, offset);
- }
+ if (tree) {
- offset += 1; /* Skip AndXCommand */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
- /* Build display for: AndXReserved */
+ }
- AndXReserved = GBYTE(pd, offset);
+ offset += 4; /* Skip Reserved1 */
- if (tree) {
+ /* Build display for: Reserved2 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ Reserved2 = GWORD(pd, offset);
- }
+ if (tree) {
- offset += 1; /* Skip AndXReserved */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
- /* Build display for: AndXOffset */
+ }
- AndXOffset = GSHORT(pd, offset);
+ offset += 4; /* Skip Reserved2 */
- if (tree) {
+ /* Build display for: Byte Count */
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+ ByteCount = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip AndXOffset */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- /* Build display for: Byte Count (BCC) */
+ offset += 2; /* Skip Byte Count */
- ByteCount = GSHORT(pd, offset);
+ /* Build display for: File Name */
+
+ FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += string_len; /* Skip File Name */
if (AndXCommand != 0xFF) {
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
}
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
}
- offset += 1; /* Skip AndXReserved */
+ offset += 1; /* Skip AndXReserved */
+
+ /* Build display for: AndXOffset */
+
+ AndXOffset = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+
+ }
+
+ offset += 2; /* Skip AndXOffset */
+
+ /* Build display for: FID */
+
+ FID = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+
+ }
+
+ offset += 2; /* Skip FID */
- /* Build display for: AndXOffset */
+ /* Build display for: FileAttributes */
- AndXOffset = GSHORT(pd, offset);
+ FileAttributes = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
+ FileAttributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
+ proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
+
}
- offset += 2; /* Skip AndXOffset */
-
- }
+ offset += 2; /* Skip FileAttributes */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Last Write Time */
- ByteCount = GSHORT(pd, offset);
+ LastWriteTime = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ }
- }
+ offset += 2; /* Skip Last Write Time */
- offset += 2; /* Skip Byte Count (BCC) */
+ /* Build display for: Last Write Date */
+ LastWriteDate = GSHORT(pd, offset);
- if (AndXCommand != 0xFF) {
+ if (tree) {
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
- }
- }
+ }
-}
+ offset += 2; /* Skip Last Write Date */
-void
-dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ /* Build display for: Data Size */
-{
- static const value_string Mode_0x03[] = {
- { 0, "Seek from start of file"},
- { 1, "Seek from current position"},
- { 2, "Seek from end of file"},
- { 0, NULL}
- };
- proto_tree *Mode_tree;
- proto_item *ti;
- guint8 WordCount;
- guint32 Offset;
- guint16 Mode;
- guint16 FID;
- guint16 ByteCount;
+ DataSize = GWORD(pd, offset);
- if (si.request) {
- /* Request(s) dissect code */
+ if (tree) {
- /* Build display for: Word Count (WCT) */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
- WordCount = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 4; /* Skip Data Size */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ /* Build display for: Granted Access */
- }
+ GrantedAccess = GSHORT(pd, offset);
- offset += 1; /* Skip Word Count (WCT) */
+ if (tree) {
- /* Build display for: FID */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
- FID = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Granted Access */
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ /* Build display for: File Type */
- }
+ FileType = GSHORT(pd, offset);
- offset += 2; /* Skip FID */
+ if (tree) {
- /* Build display for: Mode */
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File Type: 0x%02x", FileType);
+ FileType_tree = proto_item_add_subtree(ti, ett_smb_filetype);
+ proto_tree_add_text(FileType_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
+
+ }
- Mode = GSHORT(pd, offset);
+ offset += 2; /* Skip File Type */
- if (tree) {
+ /* Build display for: Device State */
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
- Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
- proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
-
- }
+ DeviceState = GSHORT(pd, offset);
- offset += 2; /* Skip Mode */
+ if (tree) {
- /* Build display for: Offset */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
- Offset = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Device State */
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ /* Build display for: Action */
- }
+ Action = GSHORT(pd, offset);
- offset += 4; /* Skip Offset */
+ if (tree) {
- /* Build display for: Byte Count (BCC) */
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: 0x%02x", Action);
+ Action_tree = proto_item_add_subtree(ti, ett_smb_openaction);
+ proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
+ proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
+
+ }
+
+ offset += 2; /* Skip Action */
- ByteCount = GSHORT(pd, offset);
+ /* Build display for: Server FID */
+
+ ServerFID = GWORD(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: %u", ServerFID);
- }
+ }
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 4; /* Skip Server FID */
- } else {
- /* Response(s) dissect code */
+ /* Build display for: Reserved */
- /* Build display for: Word Count (WCT) */
+ Reserved = GSHORT(pd, offset);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ offset += 2; /* Skip Reserved */
}
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: Offset */
+ /* Build display for: Byte Count */
- Offset = GWORD(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += 4; /* Skip Offset */
-
- /* Build display for: Byte Count (BCC) */
+ offset += 2; /* Skip Byte Count */
- ByteCount = GSHORT(pd, offset);
- if (tree) {
+ if (AndXCommand != 0xFF) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
}
- offset += 2; /* Skip Byte Count (BCC) */
-
}
}
void
-dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_write_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
+ proto_tree *WriteMode_tree;
+ proto_item *ti;
guint8 WordCount;
- guint8 BufferFormat;
+ guint8 Pad;
+ guint32 Timeout;
+ guint32 Reserved2;
guint32 Offset;
+ guint16 WriteMode;
+ guint16 Reserved1;
guint16 Remaining;
guint16 FID;
+ guint16 DataOffset;
guint16 DataLength;
guint16 Count;
guint16 ByteCount;
if (si.request) {
/* Request(s) dissect code */
- /* Build display for: Word Count (WCT) */
-
WordCount = GBYTE(pd, offset);
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
- }
-
- offset += 2; /* Skip Count */
-
- /* Build display for: Offset */
-
- Offset = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
- }
-
- offset += 4; /* Skip Offset */
-
- /* Build display for: Remaining */
-
- Remaining = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
- }
-
- offset += 2; /* Skip Remaining */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
+ switch (WordCount) {
- if (tree) {
+ case 12:
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ /* Build display for: Word Count (WCT) */
- }
+ WordCount = GBYTE(pd, offset);
- offset += 2; /* Skip Byte Count (BCC) */
+ if (tree) {
- /* Build display for: Buffer Format */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- BufferFormat = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 1; /* Skip Word Count (WCT) */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ /* Build display for: FID */
- }
+ FID = GSHORT(pd, offset);
- offset += 1; /* Skip Buffer Format */
+ if (tree) {
- /* Build display for: Data Length */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
- DataLength = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip FID */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ /* Build display for: Count */
- }
+ Count = GSHORT(pd, offset);
- offset += 2; /* Skip Data Length */
+ if (tree) {
- } else {
- /* Response(s) dissect code */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
- /* Build display for: Word Count (WCT) */
+ }
- WordCount = GBYTE(pd, offset);
+ offset += 2; /* Skip Count */
- if (tree) {
+ /* Build display for: Reserved 1 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ Reserved1 = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 1; /* Skip Word Count (WCT) */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
- /* Build display for: Count */
+ }
- Count = GSHORT(pd, offset);
+ offset += 2; /* Skip Reserved 1 */
- if (tree) {
+ /* Build display for: Offset */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ Offset = GWORD(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Count */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
- /* Build display for: Byte Count (BCC) */
+ }
- ByteCount = GSHORT(pd, offset);
+ offset += 4; /* Skip Offset */
- if (tree) {
+ /* Build display for: Timeout */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ Timeout = GWORD(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
- }
+ }
-}
+ offset += 4; /* Skip Timeout */
-void
-dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ /* Build display for: WriteMode */
-{
- guint8 WordCount;
- guint16 LastWriteTime;
- guint16 LastWriteDate;
- guint16 LastAccessTime;
- guint16 LastAccessDate;
- guint16 FID;
- guint16 CreationTime;
- guint16 CreationDate;
- guint16 ByteCount;
+ WriteMode = GSHORT(pd, offset);
- if (si.request) {
- /* Request(s) dissect code */
+ if (tree) {
- /* Build display for: Word Count */
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
+ WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
+ proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
+ proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
+
+ }
- WordCount = GBYTE(pd, offset);
+ offset += 2; /* Skip WriteMode */
- if (tree) {
+ /* Build display for: Reserved 2 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
+ Reserved2 = GWORD(pd, offset);
- }
+ if (tree) {
- offset += 1; /* Skip Word Count */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
- /* Build display for: FID */
+ }
- FID = GSHORT(pd, offset);
+ offset += 4; /* Skip Reserved 2 */
- if (tree) {
+ /* Build display for: Data Length */
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ DataLength = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip FID */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
- /* Build display for: Creation Date */
+ }
- CreationDate = GSHORT(pd, offset);
+ offset += 2; /* Skip Data Length */
- if (tree) {
+ /* Build display for: Data Offset */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
+ DataOffset = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Creation Date */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
- /* Build display for: Creation Time */
+ }
- CreationTime = GSHORT(pd, offset);
+ offset += 2; /* Skip Data Offset */
- if (tree) {
+ /* Build display for: Byte Count (BCC) */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
+ ByteCount = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Creation Time */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- /* Build display for: Last Access Date */
+ }
- LastAccessDate = GSHORT(pd, offset);
+ offset += 2; /* Skip Byte Count (BCC) */
- if (tree) {
+ /* Build display for: Pad */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
+ Pad = GBYTE(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Last Access Date */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
- /* Build display for: Last Access Time */
+ }
- LastAccessTime = GSHORT(pd, offset);
+ offset += 1; /* Skip Pad */
- if (tree) {
+ break;
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
+ case 14:
- }
+ /* Build display for: Word Count (WCT) */
- offset += 2; /* Skip Last Access Time */
+ WordCount = GBYTE(pd, offset);
- /* Build display for: Last Write Date */
+ if (tree) {
- LastWriteDate = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
+ offset += 1; /* Skip Word Count (WCT) */
- }
+ /* Build display for: FID */
- offset += 2; /* Skip Last Write Date */
+ FID = GSHORT(pd, offset);
- /* Build display for: Last Write Time */
+ if (tree) {
- LastWriteTime = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
+ offset += 2; /* Skip FID */
- }
+ /* Build display for: Count */
- offset += 2; /* Skip Last Write Time */
+ Count = GSHORT(pd, offset);
- /* Build display for: Byte Count (BCC) */
+ if (tree) {
- ByteCount = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ offset += 2; /* Skip Count */
- }
+ /* Build display for: Reserved 1 */
- offset += 2; /* Skip Byte Count (BCC) */
+ Reserved1 = GSHORT(pd, offset);
- } else {
- /* Response(s) dissect code */
+ if (tree) {
- /* Build display for: Word Count (WCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
- WordCount = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Reserved 1 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
+ /* Build display for: Timeout */
- }
+ Timeout = GWORD(pd, offset);
- offset += 1; /* Skip Word Count (WCC) */
+ if (tree) {
- /* Build display for: Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
- ByteCount = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 4; /* Skip Timeout */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ /* Build display for: WriteMode */
- }
+ WriteMode = GSHORT(pd, offset);
- offset += 2; /* Skip Byte Count (BCC) */
+ if (tree) {
- }
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
+ WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
+ proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
+ proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
+ decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
+
+ }
-}
+ offset += 2; /* Skip WriteMode */
-void
-dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ /* Build display for: Reserved 2 */
-{
- guint8 WordCount;
- guint32 Offset;
- guint32 Count;
- guint16 FID;
- guint16 ByteCount;
+ Reserved2 = GWORD(pd, offset);
- if (si.request) {
- /* Request(s) dissect code */
+ if (tree) {
- /* Build display for: Word Count (WCT) */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
- WordCount = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 4; /* Skip Reserved 2 */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ /* Build display for: Data Length */
- }
+ DataLength = GSHORT(pd, offset);
- offset += 1; /* Skip Word Count (WCT) */
+ if (tree) {
- /* Build display for: FID */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
- FID = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Data Length */
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ /* Build display for: Data Offset */
- }
+ DataOffset = GSHORT(pd, offset);
- offset += 2; /* Skip FID */
+ if (tree) {
- /* Build display for: Count */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
- Count = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Data Offset */
- proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
+ /* Build display for: Byte Count (BCC) */
- }
+ ByteCount = GSHORT(pd, offset);
- offset += 4; /* Skip Count */
+ if (tree) {
- /* Build display for: Offset */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- Offset = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Byte Count (BCC) */
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ /* Build display for: Pad */
- }
+ Pad = GBYTE(pd, offset);
- offset += 4; /* Skip Offset */
+ if (tree) {
- /* Build display for: Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
- ByteCount = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 1; /* Skip Pad */
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ break;
}
- offset += 2; /* Skip Byte Count (BCC) */
-
} else {
/* Response(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Byte Count (BCC) */
+ if (WordCount != 0) {
+
+ /* Build display for: Remaining */
+
+ Remaining = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+
+ }
+
+ offset += 2; /* Skip Remaining */
+
+ }
+
+ /* Build display for: Byte Count */
ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip Byte Count */
}
}
+
void
-dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
+ static const value_string Mode_0x03[] = {
+ { 0, "Text mode (DOS expands TABs)"},
+ { 1, "Graphics mode"},
+ { 0, NULL}
+ };
+ proto_tree *Mode_tree;
+ proto_item *ti;
guint8 WordCount;
guint8 BufferFormat;
- guint16 StartIndex;
- guint16 RestartIndex;
- guint16 MaxCount;
- guint16 DataLength;
- guint16 Count;
+ guint16 SetupLength;
+ guint16 Mode;
+ guint16 FID;
guint16 ByteCount;
+ const char *IdentifierString;
+ int string_len;
if (si.request) {
/* Request(s) dissect code */
- /* Build display for: Word Count */
+ /* Build display for: Word Count (WCT) */
WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
}
- offset += 1; /* Skip Word Count */
+ offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Max Count */
+ /* Build display for: Setup Length */
- MaxCount = GSHORT(pd, offset);
+ SetupLength = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Setup Length: %u", SetupLength);
}
- offset += 2; /* Skip Max Count */
+ offset += 2; /* Skip Setup Length */
- /* Build display for: Start Index */
+ /* Build display for: Mode */
- StartIndex = GSHORT(pd, offset);
+ Mode = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
+ Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
+ proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
+
}
- offset += 2; /* Skip Start Index */
+ offset += 2; /* Skip Mode */
/* Build display for: Byte Count (BCC) */
offset += 2; /* Skip Byte Count (BCC) */
- } else {
- /* Response(s) dissect code */
-
- /* Build display for: Word Count (WCT) */
-
- WordCount = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
- }
-
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
- }
-
- offset += 2; /* Skip Count */
-
- /* Build display for: Restart Index */
-
- RestartIndex = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
-
- }
-
- offset += 2; /* Skip Restart Index */
-
- /* Build display for: Byte Count (BCC) */
-
- }
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count (BCC) */
-
/* Build display for: Buffer Format */
BufferFormat = GBYTE(pd, offset);
offset += 1; /* Skip Buffer Format */
- /* Build display for: Data Length */
+ /* Build display for: Identifier String */
- DataLength = GSHORT(pd, offset);
+ IdentifierString = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "Identifier String: %s", IdentifierString);
}
- offset += 2; /* Skip Data Length */
-
- }
-
-}
-
-void
-dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
-
-{
- proto_tree *LockType_tree;
- proto_item *ti;
- guint8 LockType;
- guint8 WordCount;
- guint8 OplockLevel;
- guint8 AndXReserved;
- guint8 AndXCommand = 0xFF;
- guint32 Timeout;
- guint16 NumberofLocks;
- guint16 NumberOfUnlocks;
- guint16 FID;
- guint16 ByteCount;
- guint16 AndXoffset;
- guint16 AndXOffset = 0;
+ offset += string_len; /* Skip Identifier String */
- if (si.request) {
- /* Request(s) dissect code */
+ } else {
+ /* Response(s) dissect code */
/* Build display for: Word Count (WCT) */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: AndXCommand */
+ /* Build display for: FID */
- AndXCommand = GBYTE(pd, offset);
+ FID = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
}
- offset += 1; /* Skip AndXCommand */
+ offset += 2; /* Skip FID */
- /* Build display for: AndXReserved */
+ /* Build display for: Byte Count (BCC) */
- AndXReserved = GBYTE(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 1; /* Skip AndXReserved */
+ offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: AndXOffset */
+ }
- AndXOffset = GSHORT(pd, offset);
+}
- if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+void
+dissect_read_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- }
+{
+ guint8 WordCount;
+ guint32 Timeout;
+ guint32 OffsetHigh;
+ guint32 Offset;
+ guint16 Reserved;
+ guint16 MinCount;
+ guint16 MaxCount;
+ guint16 FID;
+ guint16 ByteCount;
- offset += 2; /* Skip AndXOffset */
+ if (si.request) {
+ /* Request(s) dissect code */
- /* Build display for: FID */
+ WordCount = GBYTE(pd, offset);
- FID = GSHORT(pd, offset);
+ switch (WordCount) {
- if (tree) {
+ case 8:
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ /* Build display for: Word Count (WCT) */
- }
+ WordCount = GBYTE(pd, offset);
- offset += 2; /* Skip FID */
+ if (tree) {
- /* Build display for: Lock Type */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- LockType = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 1; /* Skip Word Count (WCT) */
- ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
- LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
- proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
- proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
- proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
- proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
- proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
-
- }
+ /* Build display for: FID */
- offset += 1; /* Skip Lock Type */
+ FID = GSHORT(pd, offset);
- /* Build display for: OplockLevel */
+ if (tree) {
- OplockLevel = GBYTE(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);
+ offset += 2; /* Skip FID */
- }
+ /* Build display for: Offset */
- offset += 1; /* Skip OplockLevel */
+ Offset = GWORD(pd, offset);
- /* Build display for: Timeout */
+ if (tree) {
- Timeout = GWORD(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+ offset += 4; /* Skip Offset */
- }
+ /* Build display for: Max Count */
- offset += 4; /* Skip Timeout */
+ MaxCount = GSHORT(pd, offset);
- /* Build display for: Number Of Unlocks */
+ if (tree) {
- NumberOfUnlocks = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
+ offset += 2; /* Skip Max Count */
- }
+ /* Build display for: Min Count */
- offset += 2; /* Skip Number Of Unlocks */
+ MinCount = GSHORT(pd, offset);
- /* Build display for: Number of Locks */
+ if (tree) {
- NumberofLocks = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
+ offset += 2; /* Skip Min Count */
- }
+ /* Build display for: Timeout */
- offset += 2; /* Skip Number of Locks */
+ Timeout = GWORD(pd, offset);
- /* Build display for: Byte Count (BCC) */
+ if (tree) {
- ByteCount = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ offset += 4; /* Skip Timeout */
- }
+ /* Build display for: Reserved */
- offset += 2; /* Skip Byte Count (BCC) */
+ Reserved = GSHORT(pd, offset);
+ if (tree) {
- if (AndXCommand != 0xFF) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ }
- }
+ offset += 2; /* Skip Reserved */
- } else {
- /* Response(s) dissect code */
+ /* Build display for: Byte Count (BCC) */
- /* Build display for: Word Count (WCT) */
+ ByteCount = GSHORT(pd, offset);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ }
- }
+ offset += 2; /* Skip Byte Count (BCC) */
- offset += 1; /* Skip Word Count (WCT) */
+ break;
- if (WordCount != 0) {
+ case 10:
- /* Build display for: AndXCommand */
+ /* Build display for: Word Count (WCT) */
- AndXCommand = GBYTE(pd, offset);
+ WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
}
- offset += 1; /* Skip AndXCommand */
+ offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: AndXReserved */
+ /* Build display for: FID */
- AndXReserved = GBYTE(pd, offset);
+ FID = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
}
- offset += 1; /* Skip AndXReserved */
+ offset += 2; /* Skip FID */
- /* Build display for: AndXoffset */
+ /* Build display for: Offset */
- AndXoffset = GSHORT(pd, offset);
+ Offset = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
}
- offset += 2; /* Skip AndXoffset */
-
- }
+ offset += 4; /* Skip Offset */
- /* Build display for: Byte Count */
+ /* Build display for: Max Count */
- ByteCount = GSHORT(pd, offset);
+ MaxCount = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
- }
+ }
- offset += 2; /* Skip Byte Count */
+ offset += 2; /* Skip Max Count */
+ /* Build display for: Min Count */
- if (AndXCommand != 0xFF) {
+ MinCount = GSHORT(pd, offset);
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
- }
+ }
-}
+ offset += 2; /* Skip Min Count */
-void
-dissect_unlock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ /* Build display for: Timeout */
-{
- guint8 WordCount;
- guint32 Offset;
- guint32 Count;
- guint16 FID;
- guint16 ByteCount;
+ Timeout = GWORD(pd, offset);
- if (si.request) {
- /* Request(s) dissect code */
+ if (tree) {
- /* Build display for: Word Count (WCT) */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
- WordCount = GBYTE(pd, offset);
+ }
- if (tree) {
+ offset += 4; /* Skip Timeout */
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ /* Build display for: Reserved */
- }
+ Reserved = GSHORT(pd, offset);
- offset += 1; /* Skip Word Count (WCT) */
+ if (tree) {
- /* Build display for: FID */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
- FID = GSHORT(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Reserved */
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ /* Build display for: Offset High */
- }
+ OffsetHigh = GWORD(pd, offset);
- offset += 2; /* Skip FID */
+ if (tree) {
- /* Build display for: Count */
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
- Count = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 4; /* Skip Offset High */
- proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
+ /* Build display for: Byte Count (BCC) */
- }
+ ByteCount = GSHORT(pd, offset);
- offset += 4; /* Skip Count */
+ if (tree) {
- /* Build display for: Offset */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- Offset = GWORD(pd, offset);
+ }
- if (tree) {
+ offset += 2; /* Skip Byte Count (BCC) */
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ break;
}
- offset += 4; /* Skip Offset */
-
- /* Build display for: Byte Count (BCC) */
-
- ByteCount = GSHORT(pd, offset);
+ } else {
+ /* Response(s) dissect code */
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+}
- }
+void
+dissect_read_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- offset += 2; /* Skip Byte Count (BCC) */
+{
+ guint8 WordCount;
+ guint8 AndXReserved;
+ guint8 AndXCommand = 0xFF;
+ guint16 ByteCount;
+ guint16 AndXOffset = 0;
+ guint16 FID;
+ guint16 DataCompactionMode;
+ guint16 DataLength;
+ guint16 DataOffset;
+ guint16 Remaining;
+ guint16 MaxCount;
+ guint16 MinCount;
+ guint16 Reserved;
+ guint32 Offset;
+ guint32 OffsetHigh;
+ int i;
- } else {
- /* Response(s) dissect code */
+ if (si.request) {
+ /* Request(s) dissect code */
/* Build display for: Word Count (WCT) */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: AndXCommand */
- ByteCount = GSHORT(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 1; /* Skip AndXCommand */
- }
+ /* Build display for: AndXReserved */
+
+ AndXReserved = GBYTE(pd, offset);
-}
+ if (tree) {
-void
-dissect_create_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-{
- proto_tree *Attributes_tree;
- proto_item *ti;
- guint8 WordCount;
- guint8 BufferFormat;
- guint16 FID;
- guint16 CreationTime;
- guint16 ByteCount;
- guint16 Attributes;
- const char *FileName;
- int string_len;
+ }
- if (si.request) {
- /* Request(s) dissect code */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: AndXOffset */
- WordCount = GBYTE(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 2; /* Skip AndXOffset */
- /* Build display for: Attributes */
+ /* Build display for: FID */
- Attributes = GSHORT(pd, offset);
+ FID = GSHORT(pd, offset);
if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
- Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+
}
- offset += 2; /* Skip Attributes */
+ offset += 2; /* Skip FID */
- /* Build display for: Creation Time */
+ /* Build display for: Offset */
- CreationTime = GSHORT(pd, offset);
+ Offset = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
}
- offset += 2; /* Skip Creation Time */
+ offset += 4; /* Skip Offset */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Max Count */
- ByteCount = GSHORT(pd, offset);
+ MaxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip Max Count */
- /* Build display for: Buffer Format */
+ /* Build display for: Min Count */
- BufferFormat = GBYTE(pd, offset);
+ MinCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
}
- offset += 1; /* Skip Buffer Format */
+ offset += 2; /* Skip Min Count */
- /* Build display for: File Name */
+ /* Build display for: Reserved */
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ Reserved = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
}
- offset += string_len; /* Skip File Name */
-
- } else {
- /* Response(s) dissect code */
+ offset += 4; /* Skip Reserved */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: Remaining */
- WordCount = GBYTE(pd, offset);
+ Remaining = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 2; /* Skip Remaining */
- if (WordCount != 0) {
+ if (WordCount == 12) {
- /* Build display for: FID */
+ /* Build display for: Offset High */
- FID = GSHORT(pd, offset);
+ OffsetHigh = GWORD(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
- }
+ }
- offset += 2; /* Skip FID */
-
+ offset += 4; /* Skip Offset High */
}
-
+
/* Build display for: Byte Count (BCC) */
ByteCount = GSHORT(pd, offset);
offset += 2; /* Skip Byte Count (BCC) */
- }
-}
+ if (AndXCommand != 0xFF) {
-void
-dissect_search_dir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
-{
- guint8 WordCount;
- guint8 BufferFormat2;
- guint8 BufferFormat1;
- guint8 BufferFormat;
- guint16 SearchAttributes;
- guint16 ResumeKeyLength;
- guint16 MaxCount;
- guint16 DataLength;
- guint16 Count;
- guint16 ByteCount;
- const char *FileName;
- int string_len;
+ }
- if (si.request) {
- /* Request(s) dissect code */
+ } else {
+ /* Response(s) dissect code */
/* Build display for: Word Count (WCT) */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Max Count */
+ /* Build display for: AndXCommand */
- MaxCount = GSHORT(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
}
- offset += 2; /* Skip Max Count */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: Search Attributes */
+ /* Build display for: AndXReserved */
- SearchAttributes = GSHORT(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 2; /* Skip Search Attributes */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: AndXOffset */
- ByteCount = GSHORT(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip AndXOffset */
- /* Build display for: Buffer Format 1 */
+ /* Build display for: Remaining */
- BufferFormat1 = GBYTE(pd, offset);
+ Remaining = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
- val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
- BufferFormat1);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
}
- offset += 1; /* Skip Buffer Format 1 */
+ offset += 2; /* Skip Remaining */
- /* Build display for: File Name */
+ /* Build display for: Data Compaction Mode */
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ DataCompactionMode = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
}
- offset += string_len; /* Skip File Name */
+ offset += 2; /* Skip Data Compaction Mode */
- /* Build display for: Buffer Format 2 */
+ /* Build display for: Reserved */
- BufferFormat2 = GBYTE(pd, offset);
+ Reserved = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
- val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
- BufferFormat2);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
}
- offset += 1; /* Skip Buffer Format 2 */
+ offset += 2; /* Skip Reserved */
- /* Build display for: Resume Key Length */
+ /* Build display for: Data Length */
- ResumeKeyLength = GSHORT(pd, offset);
+ DataLength = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Resume Key Length: %u", ResumeKeyLength);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
}
- offset += 2; /* Skip Resume Key Length */
-
- } else {
- /* Response(s) dissect code */
+ offset += 2; /* Skip Data Length */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: Data Offset */
- WordCount = GBYTE(pd, offset);
+ DataOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
}
- offset += 1; /* Skip Word Count (WCT) */
-
- if (WordCount != 0) {
-
- /* Build display for: Count */
-
- Count = GSHORT(pd, offset);
+ offset += 2; /* Skip Data Offset */
- if (tree) {
+ /* Build display for: Reserved[5] */
+
+ for(i = 1; i <= 5; ++i) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ Reserved = GSHORT(pd, offset);
- }
+ if (tree) {
- offset += 2; /* Skip Count */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);
+ }
+ offset += 2;
}
/* Build display for: Byte Count (BCC) */
offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Buffer Format */
-
- BufferFormat = GBYTE(pd, offset);
+ /* Build display for data */
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ offset = SMB_offset + DataOffset;
+ if(END_OF_FRAME >= DataLength)
+ proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
+ else
+ proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
}
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: Data Length */
-
- DataLength = GSHORT(pd, offset);
-
- if (tree) {
+ if (AndXCommand != 0xFF) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
}
- offset += 2; /* Skip Data Length */
-
}
}
void
-dissect_create_temporary_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
guint8 WordCount;
- guint8 BufferFormat;
- guint16 Reserved;
- guint16 FID;
- guint16 CreationTime;
- guint16 CreationDate;
+ guint8 AndXReserved;
+ guint8 AndXCommand = 0xFF;
guint16 ByteCount;
- const char *FileName;
- const char *DirectoryName;
- int string_len;
+ guint16 AndXOffset = 0;
if (si.request) {
/* Request(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Reserved */
+ if (WordCount != 0) {
- Reserved = GSHORT(pd, offset);
+ /* Build display for: AndXCommand */
- if (tree) {
+ AndXCommand = GBYTE(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+ offset += 1; /* Skip AndXCommand */
- }
+ /* Build display for: AndXReserved */
- offset += 2; /* Skip Reserved */
+ AndXReserved = GBYTE(pd, offset);
- /* Build display for: Creation Time */
+ if (tree) {
- CreationTime = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
+ offset += 1; /* Skip AndXReserved */
- }
+ /* Build display for: AndXOffset */
- offset += 2; /* Skip Creation Time */
+ AndXOffset = GSHORT(pd, offset);
- /* Build display for: Creation Date */
+ if (tree) {
- CreationDate = GSHORT(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
- if (tree) {
+ }
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
+ offset += 2; /* Skip AndXOffset */
}
- offset += 2; /* Skip Creation Date */
-
/* Build display for: Byte Count (BCC) */
ByteCount = GSHORT(pd, offset);
offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Buffer Format */
-
- BufferFormat = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
-
- }
-
- offset += 1; /* Skip Buffer Format */
-
- /* Build display for: Directory Name */
-
- DirectoryName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
- if (tree) {
+ if (AndXCommand != 0xFF) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Directory Name: %s", DirectoryName);
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
}
- offset += string_len; /* Skip Directory Name */
-
} else {
/* Response(s) dissect code */
if (WordCount != 0) {
- /* Build display for: FID */
+ /* Build display for: AndXCommand */
- FID = GSHORT(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
}
- offset += 2; /* Skip FID */
+ offset += 1; /* Skip AndXCommand */
- }
+ /* Build display for: AndXReserved */
- /* Build display for: Byte Count (BCC) */
+ AndXReserved = GBYTE(pd, offset);
- ByteCount = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ }
- }
+ offset += 1; /* Skip AndXReserved */
- offset += 2; /* Skip Byte Count (BCC) */
+ /* Build display for: AndXOffset */
- /* Build display for: Buffer Format */
+ AndXOffset = GSHORT(pd, offset);
- BufferFormat = GBYTE(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ }
- }
+ offset += 2; /* Skip AndXOffset */
- offset += 1; /* Skip Buffer Format */
+ }
- /* Build display for: File Name */
+ /* Build display for: Byte Count (BCC) */
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += string_len; /* Skip File Name */
+ offset += 2; /* Skip Byte Count (BCC) */
+
+
+ if (AndXCommand != 0xFF) {
+
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
+
+ }
}
}
void
-dissect_close_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
+ static const value_string Mode_0x03[] = {
+ { 0, "Seek from start of file"},
+ { 1, "Seek from current position"},
+ { 2, "Seek from end of file"},
+ { 0, NULL}
+ };
+ proto_tree *Mode_tree;
+ proto_item *ti;
guint8 WordCount;
- guint16 LastWriteTime;
- guint16 LastWriteDate;
+ guint32 Offset;
+ guint16 Mode;
guint16 FID;
guint16 ByteCount;
offset += 2; /* Skip FID */
- /* Build display for: Last Write Time */
+ /* Build display for: Mode */
- LastWriteTime = GSHORT(pd, offset);
+ Mode = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
-
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
+ Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
+ proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
+
}
- offset += 2; /* Skip Last Write Time */
+ offset += 2; /* Skip Mode */
- /* Build display for: Last Write Date */
+ /* Build display for: Offset */
- LastWriteDate = GSHORT(pd, offset);
+ Offset = GWORD(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
}
- offset += 2; /* Skip Last Write Date */
+ offset += 4; /* Skip Offset */
/* Build display for: Byte Count (BCC) */
offset += 1; /* Skip Word Count (WCT) */
+ /* Build display for: Offset */
+
+ Offset = GWORD(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+
+ }
+
+ offset += 4; /* Skip Offset */
+
/* Build display for: Byte Count (BCC) */
ByteCount = GSHORT(pd, offset);
}
void
-dissect_write_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
guint8 WordCount;
- guint8 BufferFormat;
+ guint16 LastWriteTime;
+ guint16 LastWriteDate;
+ guint16 LastAccessTime;
+ guint16 LastAccessDate;
guint16 FID;
- guint16 DataLength;
+ guint16 CreationTime;
+ guint16 CreationDate;
guint16 ByteCount;
if (si.request) {
/* Request(s) dissect code */
- /* Build display for: Word Count (WCT) */
+ /* Build display for: Word Count */
WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 1; /* Skip Word Count */
/* Build display for: FID */
offset += 2; /* Skip FID */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Creation Date */
- ByteCount = GSHORT(pd, offset);
+ CreationDate = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip Creation Date */
- /* Build display for: Buffer Format */
+ /* Build display for: Creation Time */
- BufferFormat = GBYTE(pd, offset);
+ CreationTime = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
}
- offset += 1; /* Skip Buffer Format */
+ offset += 2; /* Skip Creation Time */
- /* Build display for: Data Length */
+ /* Build display for: Last Access Date */
- DataLength = GSHORT(pd, offset);
+ LastAccessDate = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
}
- offset += 2; /* Skip Data Length */
+ offset += 2; /* Skip Last Access Date */
- } else {
- /* Response(s) dissect code */
+ /* Build display for: Last Access Time */
- /* Build display for: Word Count (WCT) */
+ LastAccessTime = GSHORT(pd, offset);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
+
+ }
+
+ offset += 2; /* Skip Last Access Time */
+
+ /* Build display for: Last Write Date */
+
+ LastWriteDate = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 2; /* Skip Last Write Date */
+
+ /* Build display for: Last Write Time */
+
+ LastWriteTime = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
+
+ }
+
+ offset += 2; /* Skip Last Write Time */
/* Build display for: Byte Count (BCC) */
offset += 2; /* Skip Byte Count (BCC) */
- }
+ } else {
+ /* Response(s) dissect code */
-}
+ /* Build display for: Word Count (WCC) */
-void
-dissect_lock_and_read_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+ WordCount = GBYTE(pd, offset);
-{
- guint8 WordCount;
- guint8 BufferFormat;
- guint32 Offset;
- guint16 Reserved4;
- guint16 Reserved3;
- guint16 Reserved2;
- guint16 Reserved1;
- guint16 Remaining;
- guint16 FID;
- guint16 DataLength;
- guint16 Count;
- guint16 ByteCount;
+ if (tree) {
- if (si.request) {
- /* Request(s) dissect code */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
- /* Build display for: Word Count (WCT) */
+ }
- WordCount = GBYTE(pd, offset);
+ offset += 1; /* Skip Word Count (WCC) */
+
+ /* Build display for: Byte Count (BCC) */
+
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 1; /* Skip Word Count (WCT) */
-
- /* Build display for: FID */
+ offset += 2; /* Skip Byte Count (BCC) */
- FID = GSHORT(pd, offset);
+ }
- if (tree) {
+}
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+void
+dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
- }
+{
+ guint8 WordCount;
+ guint8 BufferFormat;
+ guint16 StartIndex;
+ guint16 RestartIndex;
+ guint16 MaxCount;
+ guint16 DataLength;
+ guint16 Count;
+ guint16 ByteCount;
- offset += 2; /* Skip FID */
+ if (si.request) {
+ /* Request(s) dissect code */
- /* Build display for: Count */
+ /* Build display for: Word Count */
- Count = GSHORT(pd, offset);
+ WordCount = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
}
- offset += 2; /* Skip Count */
+ offset += 1; /* Skip Word Count */
- /* Build display for: Offset */
+ /* Build display for: Max Count */
- Offset = GWORD(pd, offset);
+ MaxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
}
- offset += 4; /* Skip Offset */
+ offset += 2; /* Skip Max Count */
- /* Build display for: Remaining */
+ /* Build display for: Start Index */
- Remaining = GSHORT(pd, offset);
+ StartIndex = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);
}
- offset += 2; /* Skip Remaining */
+ offset += 2; /* Skip Start Index */
/* Build display for: Byte Count (BCC) */
offset += 2; /* Skip Count */
- /* Build display for: Reserved 1 */
-
- Reserved1 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
-
- }
-
- offset += 2; /* Skip Reserved 1 */
-
- /* Build display for: Reserved 2 */
-
- Reserved2 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
-
- }
-
- offset += 2; /* Skip Reserved 2 */
-
- /* Build display for: Reserved 3 */
+ /* Build display for: Restart Index */
- Reserved3 = GSHORT(pd, offset);
+ RestartIndex = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
}
- offset += 2; /* Skip Reserved 3 */
-
- /* Build display for: Reserved 4 */
-
- Reserved4 = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
-
- }
+ offset += 2; /* Skip Restart Index */
- offset += 2; /* Skip Reserved 4 */
+ /* Build display for: Byte Count (BCC) */
}
- /* Build display for: Byte Count (BCC) */
-
ByteCount = GSHORT(pd, offset);
if (tree) {
}
-
void
-dissect_get_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
- proto_tree *Attributes_tree;
+ proto_tree *LockType_tree;
proto_item *ti;
+ guint8 LockType;
guint8 WordCount;
- guint8 BufferFormat;
- guint32 FileSize;
- guint16 Reserved5;
- guint16 Reserved4;
- guint16 Reserved3;
- guint16 Reserved2;
- guint16 Reserved1;
- guint16 LastWriteTime;
- guint16 LastWriteDate;
+ guint8 OplockLevel;
+ guint8 AndXReserved;
+ guint8 AndXCommand = 0xFF;
+ guint32 Timeout;
+ guint16 NumberofLocks;
+ guint16 NumberOfUnlocks;
+ guint16 FID;
guint16 ByteCount;
- guint16 Attributes;
- const char *FileName;
- int string_len;
+ guint16 AndXOffset = 0;
if (si.request) {
/* Request(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: AndXCommand */
- ByteCount = GSHORT(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: Buffer Format */
+ /* Build display for: AndXReserved */
- BufferFormat = GBYTE(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
- val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
- BufferFormat);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 1; /* Skip Buffer Format */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: File Name */
+ /* Build display for: AndXOffset */
- FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += string_len; /* Skip File Name */
+ offset += 2; /* Skip AndXOffset */
- } else {
- /* Response(s) dissect code */
+ /* Build display for: FID */
- /* Build display for: Word Count (WCT) */
+ FID = GSHORT(pd, offset);
- WordCount = GBYTE(pd, offset);
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+
+ }
+
+ offset += 2; /* Skip FID */
+
+ /* Build display for: Lock Type */
+
+ LockType = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+ ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
+ LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
+ proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
+ proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
+ proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
+ proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
+ proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
+
+ }
+
+ offset += 1; /* Skip Lock Type */
+
+ /* Build display for: OplockLevel */
+
+ OplockLevel = GBYTE(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);
}
- offset += 1; /* Skip Word Count (WCT) */
+ offset += 1; /* Skip OplockLevel */
- if (WordCount != 0) {
+ /* Build display for: Timeout */
- /* Build display for: Attributes */
+ Timeout = GWORD(pd, offset);
- Attributes = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
- Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
- proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
- }
+ }
- offset += 2; /* Skip Attributes */
+ offset += 4; /* Skip Timeout */
- /* Build display for: Last Write Time */
+ /* Build display for: Number Of Unlocks */
- LastWriteTime = GSHORT(pd, offset);
+ NumberOfUnlocks = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
- offset += 2; /* Skip Last Write Time */
+ }
- /* Build display for: Last Write Date */
+ offset += 2; /* Skip Number Of Unlocks */
- LastWriteDate = GSHORT(pd, offset);
+ /* Build display for: Number of Locks */
- if (tree) {
+ NumberofLocks = GSHORT(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset - 2, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
- }
+ }
- offset += 2; /* Skip Last Write Date */
+ offset += 2; /* Skip Number of Locks */
- /* Build display for: File Size */
+ /* Build display for: Byte Count (BCC) */
- FileSize = GWORD(pd, offset);
+ ByteCount = GSHORT(pd, offset);
- if (tree) {
+ if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "File Size: %u", FileSize);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- }
+ }
- offset += 4; /* Skip File Size */
+ offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Reserved 1 */
- Reserved1 = GSHORT(pd, offset);
+ if (AndXCommand != 0xFF) {
- if (tree) {
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
+ }
- }
+ } else {
+ /* Response(s) dissect code */
- offset += 2; /* Skip Reserved 1 */
+ /* Build display for: Word Count (WCT) */
- /* Build display for: Reserved 2 */
+ WordCount = GBYTE(pd, offset);
- Reserved2 = GSHORT(pd, offset);
+ if (tree) {
- if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
+ }
- }
+ offset += 1; /* Skip Word Count (WCT) */
- offset += 2; /* Skip Reserved 2 */
+ if (WordCount != 0) {
- /* Build display for: Reserved 3 */
+ /* Build display for: AndXCommand */
- Reserved3 = GSHORT(pd, offset);
+ AndXCommand = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
}
- offset += 2; /* Skip Reserved 3 */
+ offset += 1; /* Skip AndXCommand */
- /* Build display for: Reserved 4 */
+ /* Build display for: AndXReserved */
- Reserved4 = GSHORT(pd, offset);
+ AndXReserved = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
}
- offset += 2; /* Skip Reserved 4 */
+ offset += 1; /* Skip AndXReserved */
- /* Build display for: Reserved 5 */
+ /* Build display for: AndXOffset */
- Reserved5 = GSHORT(pd, offset);
+ AndXOffset = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
}
- offset += 2; /* Skip Reserved 5 */
+ offset += 2; /* Skip AndXOffset */
}
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: Byte Count */
ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += 2; /* Skip Byte Count */
+
+
+ if (AndXCommand != 0xFF) {
+
+ wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
+ &si, max_data, SMB_offset);
+
+ }
}
}
void
-dissect_read_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+dissect_search_dir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
{
guint8 WordCount;
- guint32 Offset;
- guint16 Reserved4;
- guint16 Reserved3;
- guint16 Reserved2;
- guint16 Reserved1;
- guint16 Remaining;
- guint16 FID;
+ guint8 BufferFormat2;
+ guint8 BufferFormat1;
+ guint8 BufferFormat;
+ guint16 SearchAttributes;
+ guint16 ResumeKeyLength;
+ guint16 MaxCount;
guint16 DataLength;
guint16 Count;
guint16 ByteCount;
- guint16 BufferFormat;
+ const char *FileName;
+ int string_len;
if (si.request) {
/* Request(s) dissect code */
offset += 1; /* Skip Word Count (WCT) */
- /* Build display for: FID */
+ /* Build display for: Max Count */
- FID = GSHORT(pd, offset);
+ MaxCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
}
- offset += 2; /* Skip FID */
+ offset += 2; /* Skip Max Count */
- /* Build display for: Count */
+ /* Build display for: Search Attributes */
- Count = GSHORT(pd, offset);
+ SearchAttributes = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
}
- offset += 2; /* Skip Count */
+ offset += 2; /* Skip Search Attributes */
- /* Build display for: Offset */
+ /* Build display for: Byte Count (BCC) */
- Offset = GWORD(pd, offset);
+ ByteCount = GSHORT(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
}
- offset += 4; /* Skip Offset */
+ offset += 2; /* Skip Byte Count (BCC) */
- /* Build display for: Remaining */
+ /* Build display for: Buffer Format 1 */
- Remaining = GSHORT(pd, offset);
+ BufferFormat1 = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
+ val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
+ BufferFormat1);
}
- offset += 2; /* Skip Remaining */
+ offset += 1; /* Skip Buffer Format 1 */
- /* Build display for: Byte Count (BCC) */
+ /* Build display for: File Name */
- ByteCount = GSHORT(pd, offset);
+ FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+ proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
}
- offset += 2; /* Skip Byte Count (BCC) */
+ offset += string_len; /* Skip File Name */
+
+ /* Build display for: Buffer Format 2 */
+
+ BufferFormat2 = GBYTE(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
+ val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
+ BufferFormat2);
+
+ }
+
+ offset += 1; /* Skip Buffer Format 2 */
+
+ /* Build display for: Resume Key Length */
+
+ ResumeKeyLength = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Resume Key Length: %u", ResumeKeyLength);
+
+ }
+
+ offset += 2; /* Skip Resume Key Length */
} else {
/* Response(s) dissect code */
offset += 2; /* Skip Count */
- /* Build display for: Reserved 1 */
+ }
- Reserved1 = GSHORT(pd, offset);
+ /* Build display for: Byte Count (BCC) */
- if (tree) {
+ ByteCount = GSHORT(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
- offset += 2; /* Skip Reserved 1 */
+ }
- /* Build display for: Reserved 2 */
+ offset += 2; /* Skip Byte Count (BCC) */
- Reserved2 = GSHORT(pd, offset);
+ /* Build display for: Buffer Format */
- if (tree) {
+ BufferFormat = GBYTE(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
+ val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
+ BufferFormat);
- offset += 2; /* Skip Reserved 2 */
+ }
- /* Build display for: Reserved 3 */
+ offset += 1; /* Skip Buffer Format */
- Reserved3 = GSHORT(pd, offset);
+ /* Build display for: Data Length */
- if (tree) {
+ DataLength = GSHORT(pd, offset);
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
+ if (tree) {
- }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
- offset += 2; /* Skip Reserved 3 */
+ }
- /* Build display for: Reserved 4 */
+ offset += 2; /* Skip Data Length */
- Reserved4 = GSHORT(pd, offset);
+ }
- if (tree) {
+}
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
- }
+void
+dissect_write_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
+
+{
+ guint8 WordCount;
+ guint8 BufferFormat;
+ guint16 FID;
+ guint16 DataLength;
+ guint16 ByteCount;
+
+ if (si.request) {
+ /* Request(s) dissect code */
+
+ /* Build display for: Word Count (WCT) */
+
+ WordCount = GBYTE(pd, offset);
+
+ if (tree) {
- offset += 2; /* Skip Reserved 4 */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
}
-
+
+ offset += 1; /* Skip Word Count (WCT) */
+
+ /* Build display for: FID */
+
+ FID = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+
+ }
+
+ offset += 2; /* Skip FID */
+
/* Build display for: Byte Count (BCC) */
-
+
ByteCount = GSHORT(pd, offset);
-
+
if (tree) {
proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
/* Build display for: Buffer Format */
- BufferFormat = GSHORT(pd, offset);
+ BufferFormat = GBYTE(pd, offset);
if (tree) {
- proto_tree_add_text(tree, NullTVB, offset, 2, "Buffer Format: %s (%u)",
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
BufferFormat);
}
- offset += 2; /* Skip Buffer Format */
+ offset += 1; /* Skip Buffer Format */
/* Build display for: Data Length */
offset += 2; /* Skip Data Length */
+ } else {
+ /* Response(s) dissect code */
+
+ /* Build display for: Word Count (WCT) */
+
+ WordCount = GBYTE(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+
+ }
+
+ offset += 1; /* Skip Word Count (WCT) */
+
+ /* Build display for: Byte Count (BCC) */
+
+ ByteCount = GSHORT(pd, offset);
+
+ if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+
+ }
+
+ offset += 2; /* Skip Byte Count (BCC) */
+
}
}
dissect_unknown_smb,
dissect_unknown_smb,
- dissect_unknown_smb, /* SMBopen open a file */
- dissect_create_file_smb, /* SMBcreate create a file */
- dissect_close_smb, /* SMBclose close a file */
- dissect_flush_file_smb, /* SMBflush flush a file */
- dissect_delete_file_smb, /* SMBunlink delete a file */
- dissect_rename_file_smb, /* SMBmv rename a file */
- dissect_get_file_attr_smb,/* SMBgetatr get file attributes */
- dissect_set_file_attr_smb,/* SMBsetatr set file attributes */
- dissect_read_file_smb, /* SMBread read from a file */
- dissect_write_file_smb, /* SMBwrite write to a file */
- dissect_lock_bytes_smb, /* SMBlock lock a byte range */
- dissect_unlock_bytes_smb, /* SMBunlock unlock a byte range */
- dissect_create_temporary_file_smb,/* SMBctemp create a temporary file */
- dissect_unknown_smb, /* SMBmknew make a new file */
dissect_unknown_smb,
dissect_unknown_smb,
- dissect_unknown_smb, /* SMBlseek seek */
- dissect_lock_and_read_smb,/* SMBlockread Lock a range and read it */
- dissect_write_and_unlock_smb,/* SMBwriteunlock Unlock a range and then write */
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
dissect_unknown_smb, /* unknown SMB 0x15 */
dissect_unknown_smb, /* unknown SMB 0x16 */
dissect_unknown_smb, /* unknown SMB 0x17 */
dissect_unknown_smb, /* unknown SMB 0xbf */
dissect_unknown_smb, /* SMBsplopen open a print spool file */
dissect_write_print_file_smb,/* SMBsplwr write to a print spool file */
- dissect_close_print_file_smb,/* SMBsplclose close a print spool file */
+ dissect_unknown_smb,
dissect_get_print_queue_smb, /* SMBsplretq return print queue */
dissect_unknown_smb, /* unknown SMB 0xc4 */
dissect_unknown_smb, /* unknown SMB 0xc5 */
sip->mid);
offset += 2;
+ our_tvb = tvb;
+ our_pinfo = pinfo;
if(smb_dissector[sip->cmd].request){
/* call smb command dissector */
pinfo->private_data = sip;
- dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, sip->cmd);
+ dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, sip->cmd);
} else {
const u_char *pd;
int SMB_offset;
{ "Open", "smb.open.function.open", FT_UINT16, BASE_HEX,
VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
+ { &hf_smb_fid,
+ { "FID", "smb.fid", FT_UINT16, BASE_HEX,
+ NULL, 0, "FID: FileID", HFILL }},
+
+ { &hf_smb_file_attr_read_only,
+ { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
+
+ { &hf_smb_file_attr_hidden,
+ { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
+
+ { &hf_smb_file_attr_system,
+ { "System", "smb.file.attribute.system", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
+
+ { &hf_smb_file_attr_volume,
+ { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
+
+ { &hf_smb_file_attr_directory,
+ { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
+
+ { &hf_smb_file_attr_archive,
+ { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
+
+ { &hf_smb_file_attr_device,
+ { "Device", "smb.file.attribute.device", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
+
+ { &hf_smb_file_attr_normal,
+ { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
+
+ { &hf_smb_file_attr_temporary,
+ { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
+
+ { &hf_smb_file_attr_sparse,
+ { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
+
+ { &hf_smb_file_attr_reparse,
+ { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
+
+ { &hf_smb_file_attr_compressed,
+ { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
+
+ { &hf_smb_file_attr_offline,
+ { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
+
+ { &hf_smb_file_attr_not_content_indexed,
+ { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
+
+ { &hf_smb_file_attr_encrypted,
+ { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
+
+ { &hf_smb_file_size,
+ { "File Size", "smb.file.size", FT_UINT32, BASE_DEC,
+ NULL, 0, "File Size", HFILL }},
+
+ { &hf_smb_last_write_time,
+ { "Last Write Time", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_HEX,
+ NULL, 0, "Last time this file was written to", HFILL }},
+
+ { &hf_smb_search_attribute_read_only,
+ { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
+
+ { &hf_smb_search_attribute_hidden,
+ { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
+
+ { &hf_smb_search_attribute_system,
+ { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
+
+ { &hf_smb_search_attribute_volume,
+ { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME search attribute", HFILL }},
+
+ { &hf_smb_search_attribute_directory,
+ { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
+
+ { &hf_smb_search_attribute_archive,
+ { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
+ TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
+
+ { &hf_smb_access_mode,
+ { "Access Mode", "smb.access.mode", FT_UINT16, BASE_HEX,
+ VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
+
+ { &hf_smb_access_sharing,
+ { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_HEX,
+ VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
+
+ { &hf_smb_access_locality,
+ { "Locality", "smb.access.locality", FT_UINT16, BASE_HEX,
+ VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
+
+ { &hf_smb_access_caching,
+ { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
+ TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
+
+ { &hf_smb_access_writetru,
+ { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
+ TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
+
+ { &hf_smb_create_time,
+ { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Creation Time", HFILL }},
+
+ { &hf_smb_last_write_date,
+ { "Last Write", "smb.last_write.date", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Last Write", HFILL }},
+
+ { &hf_smb_last_write_dos_date,
+ { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
+ NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
+
+ { &hf_smb_last_write_dos_time,
+ { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
+ NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
+
+ { &hf_smb_old_file_name,
+ { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
+ NULL, 0, "Old File Name (When renaming a file)", HFILL }},
+
+ { &hf_smb_offset,
+ { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
+ NULL, 0, "Offset in file", HFILL }},
+
+ { &hf_smb_remaining,
+ { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
+ NULL, 0, "Remaining number of bytes", HFILL }},
+
+ { &hf_smb_padding,
+ { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
+ NULL, 0, "Padding or unknown data", HFILL }},
+
+ { &hf_smb_file_data,
+ { "File Data", "smb.file.data", FT_BYTES, BASE_HEX,
+ NULL, 0, "Data read/written to the file", HFILL }},
+
+ { &hf_smb_data_len,
+ { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
+ NULL, 0, "Length of data", HFILL }},
+
+ { &hf_smb_seek_mode,
+ { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
+ VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
+
};
static gint *ett[] = {
&ett_smb_time_date,
&ett_smb_64bit_time,
&ett_smb_move_flags,
+ &ett_smb_file_attributes,
};
proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",