aboutsummaryrefslogtreecommitdiffstats
path: root/packet-smb.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-11-07 08:05:04 +0000
committerGuy Harris <guy@alum.mit.edu>2001-11-07 08:05:04 +0000
commit588cd161845175d7e0e75da58389cc20d01d00fc (patch)
treed5baba9f45a100169e94d9c9fe26e9cabca8086a /packet-smb.c
parentf551a6cc4cc1c27c3a70b545e584602daa3ff82b (diff)
Further tvbuffication from Ronnie Sahlberg.
Get rid of a bunch of stuff for which said tvbuffication removes the need. When dissecting byte parameters, make sure you don't consume more bytes than the byte count, and handle captures where the last string in the byte parameters area isn't properly null-terminated (I think I've seen that in packets from various versions of Windows NT). Make various bitfields given as decimal in SMB specs decimal. svn path=/trunk/; revision=4172
Diffstat (limited to 'packet-smb.c')
-rw-r--r--packet-smb.c4918
1 files changed, 1928 insertions, 2990 deletions
diff --git a/packet-smb.c b/packet-smb.c
index 13e781690f..03faa6484d 100644
--- a/packet-smb.c
+++ b/packet-smb.c
@@ -2,7 +2,7 @@
* Routines for smb packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-smb.c,v 1.134 2001/11/05 07:58:33 guy Exp $
+ * $Id: packet-smb.c,v 1.135 2001/11/07 08:05:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -120,6 +120,7 @@ static int hf_smb_encryption_key = -1;
static int hf_smb_primary_domain = -1;
static int hf_smb_max_raw_buf_size = -1;
static int hf_smb_server_guid = -1;
+static int hf_smb_security_blob_len = -1;
static int hf_smb_security_blob = -1;
static int hf_smb_sm_mode16 = -1;
static int hf_smb_sm_password16 = -1;
@@ -159,6 +160,11 @@ static int hf_smb_echo_data = -1;
static int hf_smb_echo_seq_num = -1;
static int hf_smb_max_buf_size = -1;
static int hf_smb_password = -1;
+static int hf_smb_password_len = -1;
+static int hf_smb_ansi_password = -1;
+static int hf_smb_ansi_password_len = -1;
+static int hf_smb_unicode_password = -1;
+static int hf_smb_unicode_password_len = -1;
static int hf_smb_path = -1;
static int hf_smb_service = -1;
static int hf_smb_move_flags_file = -1;
@@ -191,7 +197,6 @@ 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;
@@ -206,7 +211,7 @@ static int hf_smb_access_writetru = -1;
static int hf_smb_create_time = -1;
static int hf_smb_create_dos_date = -1;
static int hf_smb_create_dos_time = -1;
-static int hf_smb_last_write_date = -1;
+static int hf_smb_last_write_time = -1;
static int hf_smb_last_write_dos_date = -1;
static int hf_smb_last_write_dos_time = -1;
static int hf_smb_access_time = -1;
@@ -240,7 +245,35 @@ static int hf_smb_write_raw_mode_connectionless = -1;
static int hf_smb_resume_key_len = -1;
static int hf_smb_resume_server_cookie = -1;
static int hf_smb_resume_client_cookie = -1;
-
+static int hf_smb_andxoffset = -1;
+static int hf_smb_lock_type_large = -1;
+static int hf_smb_lock_type_cancel = -1;
+static int hf_smb_lock_type_change = -1;
+static int hf_smb_lock_type_oplock = -1;
+static int hf_smb_lock_type_shared = -1;
+static int hf_smb_locking_ol = -1;
+static int hf_smb_number_of_locks = -1;
+static int hf_smb_number_of_unlocks = -1;
+static int hf_smb_lock_long_offset = -1;
+static int hf_smb_lock_long_length = -1;
+static int hf_smb_file_type = -1;
+static int hf_smb_device_state = -1;
+static int hf_smb_server_fid = -1;
+static int hf_smb_open_flags_add_info = -1;
+static int hf_smb_open_flags_ex_oplock = -1;
+static int hf_smb_open_flags_batch_oplock = -1;
+static int hf_smb_open_flags_ealen = -1;
+static int hf_smb_open_action_open = -1;
+static int hf_smb_open_action_lock = -1;
+static int hf_smb_vc_num = -1;
+static int hf_smb_account = -1;
+static int hf_smb_os = -1;
+static int hf_smb_lanman = -1;
+static int hf_smb_setup_action_guest = -1;
+static int hf_smb_fs = -1;
+static int hf_smb_connect_flags_dtid = -1;
+static int hf_smb_connect_support_search = -1;
+static int hf_smb_connect_support_in_dfs = -1;
static gint ett_smb = -1;
static gint ett_smb_hdr = -1;
@@ -270,11 +303,22 @@ static gint ett_smb_move_flags = -1;
static gint ett_smb_file_attributes = -1;
static gint ett_smb_search_resume_key = -1;
static gint ett_smb_search_dir_info = -1;
+static gint ett_smb_unlocks = -1;
+static gint ett_smb_unlock = -1;
+static gint ett_smb_locks = -1;
+static gint ett_smb_lock = -1;
+static gint ett_smb_open_flags = -1;
+static gint ett_smb_open_action = -1;
+static gint ett_smb_setup_action = -1;
+static gint ett_smb_connect_flags = -1;
+static gint ett_smb_connect_support_bits = -1;
static char *decode_smb_name(unsigned char);
static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
-static const gchar *get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen);
+static const gchar *get_unicode_or_ascii_string_tvb(tvbuff_t *tvb,
+ int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
+ gboolean exactlen, guint16 *bc);
#define WORD_COUNT \
@@ -293,7 +337,19 @@ static const gchar *get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp,
offset += 2; \
if(bc==0) goto endofcommand;
+#define CHECK_BYTE_COUNT(len) \
+ if (bc < len) goto endofcommand;
+
+#define COUNT_BYTES(len) \
+ offset += len; \
+ bc -= len;
+
#define END_OF_SMB \
+ if (bc != 0) { \
+ proto_tree_add_text(tree, tvb, offset, bc, \
+ "Extra byte parameters"); \
+ offset += bc; \
+ } \
endofcommand:
@@ -723,34 +779,34 @@ dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
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, "Open for reading"},
+ { 1, "Open for writing"},
+ { 2, "Open for reading and writing"},
+ { 3, "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, "Compatibility mode"},
+ { 1, "Deny read/write/execute (exclusive)"},
+ { 2, "Deny write"},
+ { 3, "Deny read/execute"},
+ { 4, "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, "Locality of reference unknown"},
+ { 1, "Mainly sequential access"},
+ { 2, "Mainly random access"},
+ { 3, "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"
+ "Do not cache this file",
+ "Caching permitted on this file"
};
static const true_false_string tfs_da_writetru = {
- "Writethrough ENABLED",
- "Writethrough DISABLED"
+ "Write through enabled",
+ "Write through disabled"
};
static int
dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
@@ -1310,6 +1366,7 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
proto_item *dit = NULL;
proto_tree *dtr = NULL;
+ /* XXX - what if this runs past bc? */
len = tvb_strsize(tvb, offset+1);
str = tvb_get_ptr(tvb, offset+1, len);
@@ -1320,16 +1377,16 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
}
/* Buffer Format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
TRUE);
- offset += 1;
- bc -= 1;
+ COUNT_BYTES(1);
/*Dialect Name */
+ CHECK_BYTE_COUNT(len);
proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
len, str);
- offset += len;
- bc -= len;
+ COUNT_BYTES(len);
}
END_OF_SMB
@@ -1349,7 +1406,6 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
guint32 caps=0;
gint16 tz;
-
WORD_COUNT;
/* Dialect Index */
@@ -1489,74 +1545,71 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
switch(wc){
case 13:
- /* challange/ encryption key */
+ /* challenge/response encryption key */
if(ekl){
+ CHECK_BYTE_COUNT(ekl);
proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
- offset += ekl;
+ COUNT_BYTES(ekl);
}
- /* is this string optional ? */
- if(tvb_reported_length_remaining(tvb, offset)>0){
- /* domain */
- dn = get_unicode_or_ascii_string_tvb(tvb, &offset,
- pinfo, &dn_len, FALSE, FALSE);
- proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
- offset, dn_len,dn);
- offset += dn_len;
- }
+ /* domain */
+ dn = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &dn_len, FALSE, FALSE, &bc);
+ if (dn == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
+ offset, dn_len,dn);
+ COUNT_BYTES(dn_len);
break;
case 17:
if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
smb_info_t *si;
- /* challange/ encryption key */
+ /* challenge/response encryption key */
+ /* XXX - is this aligned on an even boundary? */
if(ekl){
+ CHECK_BYTE_COUNT(ekl);
proto_tree_add_item(tree, hf_smb_encryption_key,
tvb, offset, ekl, TRUE);
- offset += ekl;
+ COUNT_BYTES(ekl);
}
- if(tvb_reported_length_remaining(tvb, offset)){
- /* domain */
- /* this string is special, unicode is flagged in caps */
- /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
- si = pinfo->private_data;
- si->unicode = (caps&SERVER_CAP_UNICODE);
- dn = get_unicode_or_ascii_string_tvb(tvb,
- &offset, pinfo, &dn_len, TRUE, FALSE);
- proto_tree_add_string(tree, hf_smb_primary_domain,
- tvb, offset, dn_len,dn);
- offset += dn_len;
- }
+ /* domain */
+ /* this string is special, unicode is flagged in caps */
+ /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
+ si = pinfo->private_data;
+ si->unicode = (caps&SERVER_CAP_UNICODE);
+ dn = get_unicode_or_ascii_string_tvb(tvb,
+ &offset, pinfo, &dn_len, TRUE, FALSE,
+ &bc);
+ if (dn == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_primary_domain,
+ tvb, offset, dn_len, dn);
+ COUNT_BYTES(dn_len);
} else {
int len;
/* guid */
/* XXX - show it in the standard Microsoft format
for GUIDs? */
+ CHECK_BYTE_COUNT(16);
proto_tree_add_item(tree, hf_smb_server_guid,
tvb, offset, 16, TRUE);
- offset += 16;
+ COUNT_BYTES(16);
/* security blob */
/* XXX - is this ASN.1-encoded? Is it a Kerberos
data structure, at least in NT 5.0-and-later
server replies? */
- len = tvb_reported_length_remaining(tvb, offset);
- if(len){
+ if(bc){
proto_tree_add_item(tree, hf_smb_security_blob,
- tvb, offset, len, TRUE);
- offset += len;
+ tvb, offset, bc, TRUE);
+ COUNT_BYTES(bc);
}
}
break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, bc,
- "Bytes for unknown response format");
- offset += bc;
- goto endofcommand;
}
END_OF_SMB
@@ -1578,15 +1631,18 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* dir name */
dn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &dn_len,
- FALSE, FALSE);
+ FALSE, FALSE, &bc);
+ if (dn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
dn);
- offset += dn_len;
+ COUNT_BYTES(dn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Directory: %s", dn);
@@ -1627,9 +1683,11 @@ dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
BYTE_COUNT;
- /* echo data */
- proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
- offset += bc;
+ if (bc != 0) {
+ /* echo data */
+ proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
+ COUNT_BYTES(bc);
+ }
END_OF_SMB
@@ -1650,9 +1708,11 @@ dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
BYTE_COUNT;
- /* echo data */
- proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
- offset += bc;
+ if (bc != 0) {
+ /* echo data */
+ proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
+ COUNT_BYTES(bc);
+ }
END_OF_SMB
@@ -1660,29 +1720,6 @@ dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
}
static int
-dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
-{
- guint8 wc;
- guint16 bc;
-
- WORD_COUNT;
-
- /* Maximum Buffer Size */
- proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
- offset += 2;
-
- /* tid */
- proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
- offset += 2;
-
- BYTE_COUNT;
-
- END_OF_SMB
-
- return offset;
-}
-
-static int
dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
int an_len, pwlen;
@@ -1695,56 +1732,87 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* Path */
an = get_unicode_or_ascii_string_tvb(tvb, &offset,
- pinfo, &an_len, FALSE, FALSE);
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_path, tvb,
offset, an_len, an);
- offset += an_len;
-
+ COUNT_BYTES(an_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", an);
}
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* password, ANSI */
+ /* XXX - what if this runs past bc? */
pwlen = tvb_strsize(tvb, offset);
+ CHECK_BYTE_COUNT(pwlen);
proto_tree_add_item(tree, hf_smb_password,
tvb, offset, pwlen, TRUE);
- offset += pwlen;
+ COUNT_BYTES(pwlen);
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* Service */
an = get_unicode_or_ascii_string_tvb(tvb, &offset,
- pinfo, &an_len, FALSE, FALSE);
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_service, tvb,
offset, an_len, an);
- offset += an_len;
+ COUNT_BYTES(an_len);
END_OF_SMB
return offset;
}
+static int
+dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc;
+ guint16 bc;
+
+ WORD_COUNT;
+
+ /* Maximum Buffer Size */
+ proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* tid */
+ proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ return offset;
+}
+
static const true_false_string tfs_of_create = {
- "CREATE file if it does not exist",
- "FAIL if file does not exist"
+ "Create file if it does not exist",
+ "Fail if file does not exist"
};
static const value_string of_open[] = {
- { 0x00, "Fail if file exists"},
- { 0x01, "Open file if it exists"},
- { 0x02, "Truncate file if it exists"},
+ { 0, "Fail if file exists"},
+ { 1, "Open file if it exists"},
+ { 2, "Truncate file if it exists"},
{0, NULL}
};
static int
@@ -1838,28 +1906,36 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
fn_len, fn, "Old File Name: %s", fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Old Name: %s", fn);
}
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
fn_len, fn, "New File Name: %s", fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", New Name: %s", fn);
@@ -1887,14 +1963,18 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
END_OF_SMB
@@ -1920,14 +2000,18 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2008,14 +2092,18 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* File Name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2064,14 +2152,18 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2098,28 +2190,36 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* old file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Old Name: %s", fn);
}
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", New Name: %s", fn);
@@ -2143,14 +2243,18 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
BYTE_COUNT;
/* Buffer Format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* File Name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2214,14 +2318,18 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2283,28 +2391,26 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
- bc -= 1;
+ COUNT_BYTES(1);
/* data len */
- if (bc < 2)
- return offset;
+ CHECK_BYTE_COUNT(2);
proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
- offset += 2;
- bc -= 2;
+ COUNT_BYTES(2);
if (bc != 0) {
/* file data */
- if(bc>tvb_length_remaining(tvb, offset)){
- int len;
- len = tvb_length_remaining(tvb, offset);
+ int len = tvb_length_remaining(tvb, offset);
+ if(bc>len){
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_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
offset += bc;
}
+ bc = 0;
}
END_OF_SMB
@@ -2332,13 +2438,14 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
- bc -= 1;
+ COUNT_BYTES(1);
/* data len */
+ CHECK_BYTE_COUNT(2);
proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
- offset += 2;
+ COUNT_BYTES(2);
END_OF_SMB
@@ -2374,28 +2481,26 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
- bc -= 1;
+ COUNT_BYTES(1);
/* data len */
- if (bc < 2)
- return offset;
+ CHECK_BYTE_COUNT(2);
proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
- offset += 2;
- bc -= 2;
+ COUNT_BYTES(2);
if (bc != 0) {
/* file data */
- if(bc>tvb_length_remaining(tvb, offset)){
- int len;
- len = tvb_length_remaining(tvb, offset);
+ int len = tvb_length_remaining(tvb, offset);
+ if(bc>len){
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_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
offset += bc;
}
+ bc = 0;
}
END_OF_SMB
@@ -2469,14 +2574,18 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* directory name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
@@ -2504,14 +2613,18 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, FALSE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
END_OF_SMB
@@ -2595,7 +2708,7 @@ dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
/* last write time */
offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
- hf_smb_last_write_date,
+ hf_smb_last_write_time,
hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
BYTE_COUNT;
@@ -2625,7 +2738,7 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
/* last write time */
offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
- hf_smb_last_write_date,
+ hf_smb_last_write_time,
hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
/* data size */
@@ -2653,6 +2766,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
guint8 wc;
guint16 cnt=0;
guint16 bc;
+ int len;
WORD_COUNT;
@@ -2681,21 +2795,22 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
BYTE_COUNT;
/* 1 pad byte */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/*XXX Do we have to do something like in dissect_read_file_response()?
Must check some captures. */
/* file data */
- if(cnt>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),"Incomplete data. Only %d of %d bytes", len, cnt);
+ len = tvb_length_remaining(tvb, offset);
+ if(cnt>len){
+ 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, cnt);
offset += len;
} else {
proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, cnt, TRUE);
offset += cnt;
}
+ bc = 0; /* XXX */
END_OF_SMB
@@ -2843,8 +2958,9 @@ dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
static int
dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- guint16 len=0, bc;
+ guint16 datalen=0, bc;
guint8 wc;
+ int tvblen;
WORD_COUNT;
@@ -2869,8 +2985,8 @@ dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
offset += 2;
/* data len */
- len = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
+ datalen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
offset += 2;
/* data offset */
@@ -2880,23 +2996,23 @@ dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
BYTE_COUNT;
/* file data */
- if(bc>len){
+ if(bc>datalen){
/* We have some initial padding bytes. */
/* XXX - use the data offset here instead? */
- proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-len,
+ proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
TRUE);
- offset += bc-len;
- bc = len;
+ offset += bc-datalen;
+ bc = datalen;
}
- 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;
+ tvblen = tvb_length_remaining(tvb, offset);
+ if(bc>tvblen){
+ proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %d bytes", tvblen, bc);
+ offset += tvblen;
} else {
proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
offset += bc;
}
+ bc = 0;
END_OF_SMB
@@ -2952,8 +3068,9 @@ static int
dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
guint32 to;
- guint16 len=0, bc;
+ guint16 datalen=0, bc;
guint8 wc;
+ int tvblen;
WORD_COUNT;
@@ -2986,8 +3103,8 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
offset += 4;
/* data len */
- len = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
+ datalen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
offset += 2;
/* data offset */
@@ -2997,23 +3114,23 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
BYTE_COUNT;
/* file data */
- if(bc>len){
+ if(bc>datalen){
/* We have some initial padding bytes. */
/* XXX - use the data offset here instead? */
- proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-len,
+ proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
TRUE);
- offset += bc-len;
- bc = len;
+ offset += bc-datalen;
+ bc = datalen;
}
- 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;
+ tvblen = tvb_length_remaining(tvb, offset);
+ if(bc>tvblen){
+ proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %d bytes", tvblen, bc);
+ offset += tvblen;
} else {
proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
offset += bc;
}
+ bc = 0;
END_OF_SMB
@@ -3062,8 +3179,9 @@ static int
dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
guint32 to;
- guint16 len=0, bc;
+ guint16 datalen=0, bc;
guint8 wc;
+ int tvblen;
WORD_COUNT;
@@ -3096,8 +3214,8 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
offset += 4;
/* data len */
- len = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
+ datalen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
offset += 2;
/* data offset */
@@ -3107,23 +3225,23 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
BYTE_COUNT;
/* file data */
- if(bc>len){
+ if(bc>datalen){
/* We have some initial padding bytes. */
/* XXX - use the data offset here instead? */
- proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-len,
+ proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
TRUE);
- offset += bc-len;
- bc = len;
+ offset += bc-datalen;
+ bc = datalen;
}
- 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;
+ tvblen = tvb_length_remaining(tvb, offset);
+ if(bc>tvblen){
+ proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %d bytes", tvblen, bc);
+ offset += tvblen;
} else {
proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
offset += bc;
}
+ bc = 0;
END_OF_SMB
@@ -3149,9 +3267,9 @@ dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, pro
return offset;
}
-
static int
-dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *parent_tree, int offset, guint16 *bc, gboolean *trunc)
{
proto_item *item = NULL;
proto_tree *tree = NULL;
@@ -3166,32 +3284,55 @@ dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
}
/* reserved byte */
+ if (*bc < 1) {
+ *trunc = TRUE;
+ return offset;
+ }
proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
offset += 1;
+ *bc -= 1;
/* file name */
fn_len = 11;
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, TRUE, TRUE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ TRUE, TRUE, bc);
+ if (fn == NULL) {
+ *trunc = TRUE;
+ return offset;
+ }
/* ensure that it's null-terminated */
strncpy(fname, fn, 11);
fname[11] = '\0';
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
fname);
offset += fn_len;
+ *bc -= fn_len;
/* server cookie */
+ if (*bc < 5) {
+ *trunc = TRUE;
+ return offset;
+ }
proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
offset += 5;
+ *bc -= 5;
/* client cookie */
+ if (*bc < 4) {
+ *trunc = TRUE;
+ return offset;
+ }
proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
offset += 4;
+ *bc -= 4;
+ *trunc = FALSE;
return offset;
}
static int
-dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *parent_tree, int offset, guint16 *bc, gboolean *trunc)
{
proto_item *item = NULL;
proto_tree *tree = NULL;
@@ -3206,31 +3347,55 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
}
/* resume key */
- offset = dissect_search_resume_key(tvb, pinfo, tree, offset);
+ offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bc, trunc);
+ if (*trunc)
+ return offset;
/* File Attributes */
+ if (*bc < 1) {
+ *trunc = TRUE;
+ return offset;
+ }
offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
+ *bc -= 1;
/* last write time */
+ if (*bc < 4) {
+ *trunc = TRUE;
+ return offset;
+ }
offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
- hf_smb_last_write_date,
+ hf_smb_last_write_time,
hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
TRUE);
+ *bc -= 4;
/* File Size */
+ if (*bc < 4) {
+ *trunc = TRUE;
+ return offset;
+ }
proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
offset += 4;
+ *bc -= 4;
/* file name */
fn_len = 13;
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, TRUE, TRUE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ TRUE, TRUE, bc);
+ if (fn == NULL) {
+ *trunc = TRUE;
+ return offset;
+ }
/* ensure that it's null-terminated */
strncpy(fname, fn, 13);
fname[13] = '\0';
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fname);
offset += fn_len;
+ *bc -= fn_len;
+ *trunc = FALSE;
return offset;
}
@@ -3243,6 +3408,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint16 rkl;
guint8 wc;
guint16 bc;
+ gboolean trunc;
WORD_COUNT;
@@ -3256,31 +3422,40 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* file name */
- fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len, TRUE, FALSE);
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ TRUE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
fn);
- offset += fn_len;
+ COUNT_BYTES(fn_len);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO, ", File: %s", fn);
}
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* resume key length */
+ CHECK_BYTE_COUNT(2);
rkl = tvb_get_letohs(tvb, offset);
proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
- offset += 2;
+ COUNT_BYTES(2);
/* resume key */
if(rkl){
- offset = dissect_search_resume_key(tvb, pinfo, tree, offset);
+ offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
+ &bc, &trunc);
+ if (trunc)
+ goto endofcommand;
}
END_OF_SMB
@@ -3294,6 +3469,7 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint16 count=0;
guint8 wc;
guint16 bc;
+ gboolean trunc;
WORD_COUNT;
@@ -3305,19 +3481,1340 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
BYTE_COUNT;
/* buffer format */
+ CHECK_BYTE_COUNT(1);
proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
- offset += 1;
+ COUNT_BYTES(1);
/* data len */
+ CHECK_BYTE_COUNT(2);
proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
- offset += 2;
+ COUNT_BYTES(2);
while(count--){
- offset = dissect_search_dir_info(tvb, pinfo, tree, offset);
+ offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
+ &bc, &trunc);
+ if (trunc)
+ goto endofcommand;
+ }
+
+ END_OF_SMB
+
+ return offset;
+}
+
+static const value_string locking_ol_vals[] = {
+ {0, "Client is not holding oplock on this file"},
+ {1, "Level 2 oplock currently held by client"},
+ {0, NULL}
+};
+
+static const true_false_string tfs_lock_type_large = {
+ "Large file locking format requested",
+ "Large file locking format not requested"
+};
+static const true_false_string tfs_lock_type_cancel = {
+ "Cancel outstanding lock request",
+ "Don't cancel outstanding lock request"
+};
+static const true_false_string tfs_lock_type_change = {
+ "Change lock type",
+ "Don't change lock type"
+};
+static const true_false_string tfs_lock_type_oplock = {
+ "This is an oplock break notification/response",
+ "This is not an oplock break notification/response"
+};
+static const true_false_string tfs_lock_type_shared = {
+ "This is a shared lock",
+ "This is an exclusive lock"
+};
+static int
+dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff, lt=0;
+ guint16 andxoffset=0, un=0, ln=0, bc;
+ guint32 to;
+ proto_item *litem = NULL;
+ proto_tree *ltree = NULL;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* fid */
+ proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* lock type */
+ lt = tvb_get_guint8(tvb, offset);
+ if(tree){
+ litem = proto_tree_add_text(tree, tvb, offset, 1,
+ "Lock Type: 0x%02x", lt);
+ ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
+ }
+ proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
+ tvb, offset, 1, lt);
+ proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
+ tvb, offset, 1, lt);
+ proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
+ tvb, offset, 1, lt);
+ proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
+ tvb, offset, 1, lt);
+ proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
+ tvb, offset, 1, lt);
+ offset += 1;
+
+ /* oplock level */
+ proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* timeout */
+ to = tvb_get_letohl(tvb, offset);
+ if (to == 0)
+ proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
+ else if (to == 0xffffffff)
+ proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
+ else
+ proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
+ offset += 4;
+
+ /* number of unlocks */
+ un = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
+ offset += 2;
+
+ /* number of locks */
+ ln = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ /* unlocks */
+ if(un){
+ proto_item *it = NULL;
+ proto_tree *tr = NULL;
+ int old_offset = offset;
+
+ it = proto_tree_add_text(tree, tvb, offset, 0,
+ "Unlocks");
+ tr = proto_item_add_subtree(it, ett_smb_unlocks);
+ while(un--){
+ proto_item *litem = NULL;
+ proto_tree *ltree = NULL;
+ if(lt&0x10){
+ /* large lock format */
+ litem = proto_tree_add_text(tr, tvb, offset, 20,
+ "Unlock");
+ ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+
+ /* PID */
+ proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* 2 reserved bytes */
+ proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
+ offset += 8;
+
+ /* length */
+ proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
+ offset += 8;
+ } else {
+ /* normal lock format */
+ litem = proto_tree_add_text(tr, tvb, offset, 10,
+ "Unlock");
+ ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+
+ /* PID */
+ proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* lock count */
+ proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
+ offset += 4;
+ }
+ }
+ proto_item_set_len(it, offset-old_offset);
+ }
+
+ /* locks */
+ if(ln){
+ proto_item *it = NULL;
+ proto_tree *tr = NULL;
+ int old_offset = offset;
+
+ it = proto_tree_add_text(tree, tvb, offset, 0,
+ "Locks");
+ tr = proto_item_add_subtree(it, ett_smb_locks);
+ while(ln--){
+ proto_item *litem = NULL;
+ proto_tree *ltree = NULL;
+ if(lt&0x10){
+ /* large lock format */
+ litem = proto_tree_add_text(tr, tvb, offset, 20,
+ "Lock");
+ ltree = proto_item_add_subtree(litem, ett_smb_lock);
+
+ /* PID */
+ proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* 2 reserved bytes */
+ proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
+ offset += 8;
+
+ /* length */
+ proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
+ offset += 8;
+ } else {
+ /* normal lock format */
+ litem = proto_tree_add_text(tr, tvb, offset, 10,
+ "Unlock");
+ ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+
+ /* PID */
+ proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* lock count */
+ proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
+ offset += 4;
+ }
+ }
+ proto_item_set_len(it, offset-old_offset);
+ }
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static int
+dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0;
+ guint16 bc;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+
+static const value_string oa_open_vals[] = {
+ { 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}
+};
+static const true_false_string tfs_oa_lock = {
+ "File is currently opened only by this user",
+ "File is opened by another user (or mode not supported by server)"
+};
+static int
+dissect_open_action(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,
+ "Action: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_open_action);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_open_action_lock,
+ tvb, offset, 2, mask);
+ proto_tree_add_uint(tree, hf_smb_open_action_open,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+static const true_false_string tfs_open_flags_add_info = {
+ "Additional information requested",
+ "Additional information not requested"
+};
+static const true_false_string tfs_open_flags_ex_oplock = {
+ "Exclusive oplock requested",
+ "Exclusive oplock not requested"
+};
+static const true_false_string tfs_open_flags_batch_oplock = {
+ "Batch oplock requested",
+ "Batch oplock not requested"
+};
+static const true_false_string tfs_open_flags_ealen = {
+ "Total length of EAs requested",
+ "Total length of EAs not requested"
+};
+static int
+dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
+{
+ 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,
+ "Flags: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_open_flags);
+ }
+
+ if(bm&0x0001){
+ proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
+ tvb, offset, 2, mask);
+ }
+ if(bm&0x0002){
+ proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
+ tvb, offset, 2, mask);
+ }
+ if(bm&0x0004){
+ proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
+ tvb, offset, 2, mask);
+ }
+ if(bm&0x0008){
+ proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
+ tvb, offset, 2, mask);
+ }
+
+ offset += 2;
+
+ return offset;
+}
+
+static const value_string filetype_vals[] = {
+ { 0, "Disk file or directory"},
+ { 1, "Named pipe in byte mode"},
+ { 2, "Named pipe in message mode"},
+ { 3, "Spooled printer"},
+ {0, NULL}
+};
+static int
+dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0, bc;
+ int fn_len;
+ const char *fn;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* open flags */
+ offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
+
+ /* desired access */
+ offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+
+ /* Search Attributes */
+ offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+
+ /* File Attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+ /* creation time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+
+ /* open function */
+ offset = dissect_open_function(tvb, pinfo, tree, offset);
+
+ /* allocation size */
+ proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* 8 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
+ offset += 8;
+
+ BYTE_COUNT;
+
+ /* file name */
+ fn = get_unicode_or_ascii_string_tvb(tvb, &offset, pinfo, &fn_len,
+ FALSE, FALSE, &bc);
+ if (fn == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+ fn);
+ COUNT_BYTES(fn_len);
+
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
+ }
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static int
+dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0, bc;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* fid */
+ proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* File Attributes */
+ offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+ /* last write time */
+ offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+
+ /* File Size */
+ proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* granted access */
+ offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+
+ /* File Type */
+ proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* Device State */
+ /*
+ * XXX - dissect this according to the stuff on page 67 of
+ *
+ * ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
+ */
+ proto_tree_add_item(tree, hf_smb_device_state, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* open_action */
+ offset = dissect_open_action(tvb, pinfo, tree, offset);
+
+ /* server fid */
+ proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* 2 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static int
+dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0, bc;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* fid */
+ proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* offset */
+ proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* max count */
+ proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* min count */
+ proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* 4 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* remaining */
+ proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ if(wc==12){
+ /* high offset */
+ proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
+ offset += 4;
+ }
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static int
+dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0, bc, cnt=0;
+ int len;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* remaining */
+ proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* data compaction mode */
+ proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* 2 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* data len */
+ cnt = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
+ offset += 2;
+
+ /* data offset */
+ proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* 10 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
+ offset += 10;
+
+ BYTE_COUNT;
+
+ /* file data */
+ if(bc>cnt){
+ /* We have some initial padding bytes. */
+ /* XXX - use the data offset here instead? */
+ proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-cnt, TRUE);
+ offset += bc-cnt;
+ bc = cnt;
+ }
+ len = tvb_length_remaining(tvb, offset);
+ if(bc>len){
+ 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_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
+ offset += bc;
+ }
+ bc = 0;
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static const true_false_string tfs_setup_action_guest = {
+ "Logged in as GUEST",
+ "Not logged in as GUEST"
+};
+static int
+dissect_setup_action(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,
+ "Action: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_setup_action);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+
+static int
+dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 bc;
+ guint16 andxoffset=0;
+ int an_len;
+ const char *an;
+ int dn_len;
+ const char *dn;
+ guint16 pwlen=0;
+ guint16 sbloblen=0;
+ guint16 apwlen=0, upwlen=0;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* Maximum Buffer Size */
+ proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* Maximum Multiplex Count */
+ proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* VC Number */
+ proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
+ offset += 2;
+
+ /* session key */
+ proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ switch (wc) {
+ case 10:
+ /* password length, ASCII*/
+ pwlen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_password_len,
+ tvb, offset, 2, pwlen);
+ offset += 2;
+
+ /* 4 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ break;
+
+ case 12:
+ /* security blob length */
+ sbloblen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
+ offset += 2;
+
+ /* 4 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* capabilities */
+ dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+ offset += 4;
+
+ break;
+
+ case 13:
+ /* password length, ANSI*/
+ apwlen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_ansi_password_len,
+ tvb, offset, 2, apwlen);
+ offset += 2;
+
+ /* password length, Unicode*/
+ upwlen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_unicode_password_len,
+ tvb, offset, 2, upwlen);
+ offset += 2;
+
+ /* 4 reserved bytes */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+ offset += 4;
+
+ /* capabilities */
+ dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+ offset += 4;
+
+ break;
+ }
+
+ BYTE_COUNT;
+
+ if (wc==12) {
+ /* security blob */
+ /* XXX - is this ASN.1-encoded? Is it a Kerberos
+ data structure, at least in NT 5.0-and-later
+ server replies? */
+ if(sbloblen){
+ CHECK_BYTE_COUNT(sbloblen);
+ proto_tree_add_item(tree, hf_smb_security_blob,
+ tvb, offset, sbloblen, TRUE);
+ COUNT_BYTES(sbloblen);
+ }
+
+ /* OS */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_os, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ /* LANMAN */
+ /* 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....
+ */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_lanman, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ /* 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?
+ */
+ dn = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &dn_len, FALSE, FALSE, &bc);
+ if (dn == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
+ offset, dn_len, dn);
+ COUNT_BYTES(dn_len);
+ } else {
+ switch (wc) {
+
+ case 10:
+ if(pwlen){
+ /* password, ASCII */
+ CHECK_BYTE_COUNT(pwlen);
+ proto_tree_add_item(tree, hf_smb_password,
+ tvb, offset, pwlen, TRUE);
+ COUNT_BYTES(pwlen);
+ }
+
+ break;
+
+ case 13:
+ if(apwlen){
+ /* password, ANSI */
+ CHECK_BYTE_COUNT(apwlen);
+ proto_tree_add_item(tree, hf_smb_ansi_password,
+ tvb, offset, apwlen, TRUE);
+ COUNT_BYTES(apwlen);
+ }
+
+ if(upwlen){
+ /* password, Unicode */
+ CHECK_BYTE_COUNT(upwlen);
+ proto_tree_add_item(tree, hf_smb_unicode_password,
+ tvb, offset, upwlen, TRUE);
+ COUNT_BYTES(upwlen);
+ }
+
+ break;
+ }
+
+ /* Account Name */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
+ an);
+ COUNT_BYTES(an_len);
+
+ /* 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?
+ */
+ dn = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &dn_len, FALSE, FALSE, &bc);
+ if (dn == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
+ offset, dn_len, dn);
+ COUNT_BYTES(dn_len);
+
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", User: %s@%s",
+ an,dn);
+ }
+
+ /* OS */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_os, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ /* LANMAN */
+ /* 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....
+ */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_lanman, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+ }
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+static int
+dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0, bc;
+ guint16 sbloblen=0;
+ int an_len;
+ const char *an;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* flags */
+ offset = dissect_setup_action(tvb, pinfo, tree, offset);
+
+ if(wc==4){
+ /* security blob length */
+ sbloblen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
+ offset += 2;
+ }
+
+ BYTE_COUNT;
+
+ if(wc==4) {
+ /* security blob */
+ /* XXX - is this ASN.1-encoded? Is it a Kerberos
+ data structure, at least in NT 5.0-and-later
+ server replies? */
+ if(sbloblen){
+ CHECK_BYTE_COUNT(sbloblen);
+ proto_tree_add_item(tree, hf_smb_security_blob,
+ tvb, offset, sbloblen, TRUE);
+ COUNT_BYTES(sbloblen);
+ }
+ }
+
+ /* OS */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_os, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ /* LANMAN */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_lanman, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ if(wc==3) {
+ /* Primary domain */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+ }
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+
+static int
+dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 andxoffset=0;
+ guint16 bc;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+
+static const true_false_string tfs_connect_support_search = {
+ "Exclusive search bits supported",
+ "Exclusive search bits not supported"
+};
+static const true_false_string tfs_connect_support_in_dfs = {
+ "Share is in Dfs",
+ "Share isn't in Dfs"
+};
+
+static int
+dissect_connect_support_bits(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,
+ "Optional Support: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_connect_support_search,
+ tvb, offset, 2, mask);
+ proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+static const true_false_string tfs_disconnect_tid = {
+ "DISCONNECT TID",
+ "Do NOT disconnect TID"
+};
+
+static int
+dissect_connect_flags(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,
+ "Flags: 0x%04x", mask);
+ tree = proto_item_add_subtree(item, ett_smb_connect_flags);
+ }
+
+ proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
+ tvb, offset, 2, mask);
+
+ offset += 2;
+
+ return offset;
+}
+
+static int
+dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, cmd=0xff;
+ guint16 bc;
+ guint16 andxoffset=0, pwlen=0;
+ int an_len;
+ const char *an;
+
+ WORD_COUNT;
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+
+ /* flags */
+ offset = dissect_connect_flags(tvb, pinfo, tree, offset);
+
+ /* password length*/
+ pwlen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
+ offset += 2;
+
+ BYTE_COUNT;
+
+ /* password */
+ CHECK_BYTE_COUNT(pwlen);
+ proto_tree_add_item(tree, hf_smb_password,
+ tvb, offset, pwlen, TRUE);
+ COUNT_BYTES(pwlen);
+
+ /* Path */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_path, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ if (check_col(pinfo->fd, COL_INFO)) {
+ col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", an);
+ }
+
+ /*
+ * NOTE: the Service string is always ASCII, even if the
+ * "strings are Unicode" bit is set in the flags2 field
+ * of the SMB.
+ */
+
+ /* Service */
+ /* XXX - what if this runs past bc? */
+ an_len = tvb_strsize(tvb, offset);
+ CHECK_BYTE_COUNT(an_len);
+ an = tvb_get_ptr(tvb, offset, an_len);
+ proto_tree_add_string(tree, hf_smb_service, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ END_OF_SMB
+
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
+ return offset;
+}
+
+
+static int
+dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+ guint8 wc, wleft, cmd=0xff;
+ guint16 andxoffset=0;
+ guint16 bc;
+ int an_len;
+ const char *an;
+
+ WORD_COUNT;
+
+ wleft = wc; /* this is at least 1 */
+
+ /* next smb command */
+ cmd = tvb_get_guint8(tvb, offset);
+ if(cmd!=0xff){
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+ } else {
+ proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
+ }
+ offset += 1;
+
+ /* reserved byte */
+ proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ wleft--;
+ if (wleft == 0)
+ goto bytecount;
+
+ /* andxoffset */
+ andxoffset = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+ offset += 2;
+ wleft--;
+ if (wleft == 0)
+ goto bytecount;
+
+ /* flags */
+ offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
+ wleft--;
+
+ /* XXX - I've seen captures where this is 7, but I have no
+ idea how to dissect it. I'm guessing the third word
+ contains connect support bits, which looks plausible
+ from the values I've seen. */
+
+ while (wleft != 0) {
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
+ offset += 2;
+ wleft--;
+ }
+
+ BYTE_COUNT;
+
+ /*
+ * NOTE: even though the SNIA CIFS spec doesn't say there's
+ * a "Service" string if there's a word count of 2, the
+ * document at
+ *
+ * ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
+ *
+ * (it's in an ugly format - text intended to be sent to a
+ * printer, with backspaces and overstrikes used for boldfacing
+ * and underlining; UNIX "col -b" can be used to strip the
+ * overstrikes out) says there's a "Service" string there, and
+ * some network traffic has it.
+ */
+
+ /*
+ * NOTE: the Service string is always ASCII, even if the
+ * "strings are Unicode" bit is set in the flags2 field
+ * of the SMB.
+ */
+
+ /* Service */
+ /* XXX - what if this runs past bc? */
+ an_len = tvb_strsize(tvb, offset);
+ CHECK_BYTE_COUNT(an_len);
+ an = tvb_get_ptr(tvb, offset, an_len);
+ proto_tree_add_string(tree, hf_smb_service, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+
+ if(wc==3){
+ if (bc != 0) {
+ /*
+ * Sometimes this isn't present.
+ */
+
+ /* Native FS */
+ an = get_unicode_or_ascii_string_tvb(tvb, &offset,
+ pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
+ if (an == NULL)
+ goto endofcommand;
+ proto_tree_add_string(tree, hf_smb_fs, tvb,
+ offset, an_len, an);
+ COUNT_BYTES(an_len);
+ }
}
END_OF_SMB
+ /* call AndXCommand (if there are any) */
+ dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+
return offset;
}
@@ -3368,7 +4865,7 @@ smb_function smb_dissector[256] = {
/* 0x21 */ {NULL, NULL},
/* 0x22 Set Info2*/ {dissect_set_information2_request, dissect_empty},
/* 0x23 Query Info2*/ {dissect_fid, dissect_query_information2_response},
- /* 0x24 */ {NULL, NULL},
+ /* 0x24 Locking And X*/ {dissect_locking_andx_request, dissect_locking_andx_response},
/* 0x25 */ {NULL, NULL},
/* 0x26 */ {NULL, NULL},
/* 0x27 */ {NULL, NULL},
@@ -3377,8 +4874,8 @@ smb_function smb_dissector[256] = {
/* 0x2a Move File*/ {dissect_move_request, dissect_move_response},
/* 0x2b Echo*/ {dissect_echo_request, dissect_echo_response},
/* 0x2c Write And Close*/ {dissect_write_and_close_request, dissect_write_and_close_response},
- /* 0x2d */ {NULL, NULL},
- /* 0x2e */ {NULL, NULL},
+ /* 0x2d Open And X*/ {dissect_open_andx_request, dissect_open_andx_response},
+ /* 0x2e Read And X*/ {dissect_read_andx_request, dissect_read_andx_response},
/* 0x2f */ {NULL, NULL},
/* 0x30 */ {NULL, NULL},
@@ -3452,9 +4949,9 @@ smb_function smb_dissector[256] = {
/* 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},
+ /* 0x73 Session Setup And X*/ {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
+ /* 0x74 Logoff And X*/ {dissect_empty_andx, dissect_empty_andx},
+ /* 0x75 Tree Connect And X*/ {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
/* 0x76 */ {NULL, NULL},
/* 0x77 */ {NULL, NULL},
/* 0x78 */ {NULL, NULL},
@@ -4368,47 +5865,6 @@ smb_init_protocol(void)
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;
-static proto_tree *our_tree;
-
-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((si->request)? smb_dissector[cmd].request :
- smb_dissector[cmd].response){
- /* call smb command dissector */
- our_pinfo->private_data = si;
- dissect_smb_command(our_tvb, our_pinfo, top_tree, offset, our_tree, cmd);
- } else {
- proto_item *cmd_item;
- proto_tree *cmd_tree;
-
- 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");
- }
-
- cmd_item = proto_tree_add_text(our_tree, NullTVB, offset,
- 0, "%s %s (0x%02x)",
- decode_smb_name(cmd),
- (si->request)?"Request":"Response",
- cmd);
- smb_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
-
- (dissect[cmd])(pd, offset, our_pinfo->fd, top_tree, smb_tree, *si,
- max_data, SMB_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)
{
@@ -4422,52 +5878,6 @@ dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *pa
}
-/*
- * Dissect a UNIX like date ...
- */
-
-struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
- conflict with /usr/include/time.h on some NetBSD
- systems */
-
-static char *
-dissect_smbu_date(guint16 date, guint16 time)
-
-{
- static char datebuf[4+2+2+2+1+10];
- time_t ltime = (date << 16) + time;
-
- _gtime = gmtime(&ltime);
-
- 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;
-
-}
-
-/*
- * Relies on time
- */
-static char *
-dissect_smbu_time(guint16 date, guint16 time)
-
-{
- static char timebuf[2+2+2+2+1+10];
-
- if (_gtime)
- sprintf(timebuf, "%02d:%02d:%02d",
- _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
- else
- sprintf(timebuf, "Bad time format");
-
- return timebuf;
-
-}
-
/* Max string length for displaying Unicode strings. */
#define MAX_UNICODE_STR_LEN 256
@@ -4518,9 +5928,14 @@ unicode_to_str(const guint8 *us, int *us_lenp) {
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 !
+ bc specifies the number of bytes in the byte parameters; Windows 2000,
+ at least, appears, in some cases, to put only 1 byte of 0 at the end
+ of a Unicode string if the byte count
*/
static gchar *
-unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen) {
+unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
+ guint16 bc)
+{
static gchar str[3][MAX_UNICODE_STR_LEN+3+1];
static gchar *cur;
gchar *p;
@@ -4539,7 +5954,20 @@ unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen) {
p = cur;
len = MAX_UNICODE_STR_LEN;
us_len = 0;
- while ((uchar = tvb_get_letohs(tvb, offset)) != 0) {
+ for (;;) {
+ if (bc == 0)
+ break;
+ if (bc == 1) {
+ /* XXX - explain this */
+ if (!exactlen)
+ us_len += 1; /* this is a one-byte null terminator */
+ break;
+ }
+ uchar = tvb_get_letohs(tvb, offset);
+ if (uchar == 0) {
+ us_len += 2; /* this is a two-byte null terminator */
+ break;
+ }
if (len > 0) {
if ((uchar & 0xFF00) == 0)
*p++ = uchar; /* ISO 8859-1 */
@@ -4549,6 +5977,7 @@ unicode_to_str_tvb(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen) {
} else
overflow = 1;
offset += 2;
+ bc -= 2;
us_len += 2;
if(exactlen){
if(us_len>= *us_lenp){
@@ -4603,15 +6032,23 @@ get_unicode_or_ascii_string(const u_char *pd, int *offsetp, int SMB_offset,
/* nopad == TRUE : Do not add any padding before this string
* exactlen == TRUE : len contains the exact len of the string in bytes.
+ * bc: pointer to variable with amount of data left in the byte parameters
+ * region
*/
static const gchar *
-get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen)
+get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp,
+ packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
+ guint16 *bc)
{
int offset = *offsetp;
const gchar *string;
int string_len;
smb_info_t *si;
+ if (*bc == 0) {
+ /* Not enough data in buffer */
+ return NULL;
+ }
si = pinfo->private_data;
if (si->unicode) {
if ((!nopad) && (*offsetp % 2)) {
@@ -4622,13 +6059,17 @@ get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo,
* the beginning of the frame will give the wrong answer.
*/
(*offsetp)++; /* Looks like a pad byte there sometimes */
+ (*bc)--;
+ if (*bc == 0) {
+ /* Not enough data in buffer */
+ return NULL;
+ }
}
if(exactlen){
string_len = *len;
- string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
+ string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen, *bc);
} else {
- string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen);
- string_len += 2;
+ string = unicode_to_str_tvb(tvb, *offsetp, &string_len, exactlen, *bc);
}
} else {
if(exactlen){
@@ -4650,1895 +6091,6 @@ get_unicode_or_ascii_string_tvb(tvbuff_t *tvb, int *offsetp, packet_info *pinfo,
-/* 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 (BCC): %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);
-
- }
-
- 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: ANSI Account Password Length */
-
- ANSIAccountPasswordLength = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
-
- }
-
- offset += 2; /* Skip ANSI Account Password Length */
-
- /* Build display for: UNICODE Account Password Length */
-
- UNICODEAccountPasswordLength = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
-
- }
-
- offset += 2; /* Skip UNICODE Account Password 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 (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- if (ByteCount > 0) {
-
- /* Build display for: ANSI Password */
-
- ANSIPassword = pd + offset;
-
- if (ANSIAccountPasswordLength > 0) {
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
-
- }
-
- offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
- }
-
- /* Build display for: UNICODE Password */
-
- UNICODEPassword = pd + offset;
-
- if (UNICODEAccountPasswordLength > 0) {
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
-
- }
-
- offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
-
- }
-
- /* Build display for: Account Name */
-
- AccountName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Account Name: %s", AccountName);
-
- }
-
- 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?
- */
-
- 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 */
-
- /* 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 */
-
- /*
- * 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);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
-
- }
-
- offset += string_len; /* Skip Native LanMan Type */
-
- }
-
- break;
-
- default:
-
- /* XXX - dump the parameter words, one word at a time? */
-
- offset += WordCount;
-
- /* 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) */
-
- break;
-
- }
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- } 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) */
-
- 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 */
-
- /* 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: 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) {
-
- 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 += 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 */
-
- }
-
- break;
-
- default:
-
- /* XXX - dump the parameter words, one word at a time? */
-
- offset += WordCount;
-
- /* 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) */
-
- break;
-
- }
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_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)
-
-{
- 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;
-
- wct = pd[offset];
-
- /* Now figure out what format we are talking about, 2, 3, or 4 response
- * words ...
- */
-
- if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
- !(!si.request && (wct == 3)) && !(wct == 0)) {
-
- 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, END_OF_FRAME, "Data");
-
- return;
-
- }
-
- }
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
-
- }
-
- offset += 1;
-
- if (wct > 0) {
-
- andxcmd = 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]);
-
- }
-
- offset += 2;
-
- andxoffs = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
-
- }
-
- offset += 2;
-
- }
-
- switch (wct) {
-
- case 0:
-
- bcc = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
-
- }
-
- break;
-
- case 4:
-
- flags = GSHORT(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"));
-
- }
-
- offset += 2;
-
- passwdlen = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
-
- }
-
- offset += 2;
-
- bcc = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
-
- }
-
- offset += 2;
-
- str = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
-
- }
-
- offset += passwdlen;
-
- str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, string_len, "Path: %s", str);
-
- }
-
- offset += string_len;
-
- str = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
-
- }
-
- break;
-
- case 2:
-
- bcc = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
-
- }
-
- offset += 2;
-
- str = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
- str);
-
- }
-
- offset += strlen(str) + 1;
-
- break;
-
- case 3:
-
- optionsup = GSHORT(pd, offset);
-
- 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;
-
- bcc = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
-
- }
-
- 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.
- */
-
- str = pd + offset;
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
-
- }
-
- offset += strlen(str) + 1;
-
- str = 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 File System: %s", str);
-
- }
-
- offset += string_len;
-
-
- break;
-
- 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)
-
-{
- 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;
-
- 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: 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: Flags */
-
- Flags = GSHORT(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) {
-
- 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);
-
- if (tree) {
-
- 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 Search */
-
- /* Build display for: File */
-
- File = GSHORT(pd, offset);
-
- 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 File */
-
- /* Build display for: Creation Time */
-
- CreationTime = GSHORT(pd, offset);
-
- if (tree) {
-
-
- }
-
- offset += 2; /* Skip Creation Time */
-
- /* Build display for: Creation Date */
-
- CreationDate = GSHORT(pd, offset);
-
- if (tree) {
-
- 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 Creation Date */
-
- /* Build display for: Open Function */
-
- OpenFunction = GSHORT(pd, 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"));
-
- }
-
- offset += 2; /* Skip Open Function */
-
- /* Build display for: Allocated Size */
-
- AllocatedSize = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
-
- }
-
- offset += 4; /* Skip Allocated Size */
-
- /* Build display for: Reserved1 */
-
- Reserved1 = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
-
- }
-
- offset += 4; /* Skip Reserved1 */
-
- /* Build display for: Reserved2 */
-
- Reserved2 = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
-
- }
-
- offset += 4; /* Skip Reserved2 */
-
- /* Build display for: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
- /* 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 */
-
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- } 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: 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: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: 0x%04x", 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 */
-
- DataSize = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
-
- }
-
- offset += 4; /* Skip Data Size */
-
- /* Build display for: Granted Access */
-
- GrantedAccess = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
-
- }
-
- offset += 2; /* Skip Granted Access */
-
- /* Build display for: File Type */
-
- FileType = 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"));
-
- }
-
- offset += 2; /* Skip File Type */
-
- /* Build display for: Device State */
-
- DeviceState = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
-
- }
-
- offset += 2; /* Skip Device State */
-
- /* Build display for: Action */
-
- Action = 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"));
-
- }
-
- offset += 2; /* Skip Action */
-
- /* Build display for: Server FID */
-
- ServerFID = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: 0x%04x", ServerFID);
-
- }
-
- offset += 4; /* Skip Server FID */
-
- /* 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 */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- }
-
-}
void
@@ -6686,509 +6238,6 @@ dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_
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)
-
-{
- 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;
-
- 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: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", 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: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: 0x%04x", 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 */
-
- Reserved = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
-
- }
-
- offset += 4; /* Skip Reserved */
-
- /* 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 */
-
- if (WordCount == 12) {
-
- /* Build display for: Offset High */
-
- OffsetHigh = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
-
- }
-
- offset += 4; /* Skip Offset High */
- }
-
- /* 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 (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- } 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: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", 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: 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: 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: 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;
- }
-
- /* 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 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);
-
- }
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- }
-
-}
-
-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 */
-
- /* 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: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", 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: 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 (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- } 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: AndXCommand */
-
- AndXCommand = GBYTE(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", 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: 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 (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- }
-
-}
-
-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)
{
@@ -7337,259 +6386,6 @@ dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_
}
-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 = 0;
-
- 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: 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: FID */
-
- FID = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "FID: 0x%04x", FID);
-
- }
-
- offset += 2; /* Skip FID */
-
- /* Build display for: Lock Type */
-
- LockType = GBYTE(pd, offset);
-
- if (tree) {
-
- 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 OplockLevel */
-
- /* Build display for: Timeout */
-
- Timeout = GWORD(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %s", time_msecs_to_str(Timeout));
-
- }
-
- offset += 4; /* Skip Timeout */
-
- /* Build display for: Number Of Unlocks */
-
- NumberOfUnlocks = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
-
- }
-
- offset += 2; /* Skip Number Of Unlocks */
-
- /* Build display for: Number of Locks */
-
- NumberofLocks = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
-
- }
-
- offset += 2; /* Skip Number of Locks */
-
- /* 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 (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_offset);
-
- }
-
- } 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: 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: Byte Count */
-
- ByteCount = GSHORT(pd, offset);
-
- if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
- }
-
- offset += 2; /* Skip Byte Count */
-
-
- if (AndXCommand != 0xFF) {
-
- wrap_dissect_smb_command(parent, pd, AndXOffset, tree, AndXCommand,
- &si, max_data, SMB_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)
@@ -9291,7 +8087,7 @@ static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, pro
dissect_unknown_smb, /* unknown SMB 0x21 */
dissect_unknown_smb,
dissect_unknown_smb,
- dissect_locking_andx_smb, /* SMBlockingX lock/unlock byte ranges and X */
+ dissect_unknown_smb,
dissect_transact_smb, /* SMBtrans transaction - name, bytes in/out */
dissect_unknown_smb,
dissect_unknown_smb,
@@ -9300,8 +8096,8 @@ static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, pro
dissect_unknown_smb,
dissect_unknown_smb,
dissect_unknown_smb,
- dissect_open_andx_smb, /* SMBopenX open and X */
- dissect_read_andx_smb, /* SMBreadX read and X */
+ dissect_unknown_smb,
+ dissect_unknown_smb,
dissect_unknown_smb, /* SMBwriteX write and X */
dissect_unknown_smb, /* unknown SMB 0x30 */
@@ -9375,9 +8171,9 @@ static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, pro
dissect_unknown_smb,
dissect_unknown_smb,
dissect_unknown_smb,
- dissect_ssetup_andx_smb, /* SMBsesssetupX Session Set Up & X (including User Logon) */
- dissect_logoff_andx_smb, /* SMBlogof Logoff & X */
- dissect_tcon_andx_smb, /* SMBtconX tree connect and X */
+ dissect_unknown_smb,
+ dissect_unknown_smb,
+ dissect_unknown_smb,
dissect_unknown_smb, /* unknown SMB 0x76 */
dissect_unknown_smb, /* unknown SMB 0x77 */
dissect_unknown_smb, /* unknown SMB 0x78 */
@@ -10763,9 +9559,6 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
sip->mid);
offset += 2;
- our_tvb = tvb;
- our_pinfo = pinfo;
- our_tree = tree;
if((sip->request)? smb_dissector[sip->cmd].request :
smb_dissector[sip->cmd].response){
/* call smb command dissector */
@@ -10985,8 +9778,12 @@ proto_register_smb(void)
{ "Server GUID", "smb.server.guid", FT_BYTES, BASE_HEX,
NULL, 0, "Globally unique identifier for this server", HFILL }},
+ { &hf_smb_security_blob_len,
+ { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
+ NULL, 0, "Security blob length", HFILL }},
+
{ &hf_smb_security_blob,
- { "Security Blob", "smb.security.blob", FT_BYTES, BASE_HEX,
+ { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
NULL, 0, "Security blob", HFILL }},
{ &hf_smb_sm_mode16,
@@ -11149,6 +9946,14 @@ proto_register_smb(void)
{ "Password", "smb.password", FT_BYTES, BASE_NONE,
NULL, 0, "Password", HFILL }},
+ { &hf_smb_ansi_password,
+ { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
+ NULL, 0, "ANSI Password", HFILL }},
+
+ { &hf_smb_unicode_password,
+ { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
+ NULL, 0, "Unicode Password", HFILL }},
+
{ &hf_smb_move_flags_file,
{ "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
@@ -11174,7 +9979,7 @@ proto_register_smb(void)
TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
{ &hf_smb_open_function_open,
- { "Open", "smb.open.function.open", FT_UINT16, BASE_HEX,
+ { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
{ &hf_smb_fid,
@@ -11269,10 +10074,6 @@ proto_register_smb(void)
{ "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 }},
@@ -11298,15 +10099,15 @@ proto_register_smb(void)
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,
+ { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
{ &hf_smb_access_sharing,
- { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_HEX,
+ { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
{ &hf_smb_access_locality,
- { "Locality", "smb.access.locality", FT_UINT16, BASE_HEX,
+ { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
{ &hf_smb_access_caching,
@@ -11329,9 +10130,9 @@ proto_register_smb(void)
{ "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
NULL, 0, "Create Time, SMB_TIME format", 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_time,
+ { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
+ NULL, 0, "Time this file was last written to", HFILL }},
{ &hf_smb_last_write_dos_date,
{ "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
@@ -11465,6 +10266,134 @@ proto_register_smb(void)
{ "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
NULL, 0, "Cookie, must not be modified by the server", HFILL }},
+ { &hf_smb_andxoffset,
+ { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
+ NULL, 0, "Offset to next command in this SMB packet", HFILL }},
+
+ { &hf_smb_lock_type_large,
+ { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
+ TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
+
+ { &hf_smb_lock_type_cancel,
+ { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
+ TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
+
+ { &hf_smb_lock_type_change,
+ { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
+ TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
+
+ { &hf_smb_lock_type_oplock,
+ { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
+ TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
+
+ { &hf_smb_lock_type_shared,
+ { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
+ TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
+
+ { &hf_smb_locking_ol,
+ { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
+ VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
+
+ { &hf_smb_number_of_locks,
+ { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
+ NULL, 0, "Number of lock requests in this request", HFILL }},
+
+ { &hf_smb_number_of_unlocks,
+ { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
+ NULL, 0, "Number of unlock requests in this request", HFILL }},
+
+ { &hf_smb_lock_long_length,
+ { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
+ NULL, 0, "Length of lock/unlock region", HFILL }},
+
+ { &hf_smb_lock_long_offset,
+ { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
+ NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
+
+ { &hf_smb_file_type,
+ { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
+ VALS(filetype_vals), 0, "Type of file", HFILL }},
+
+ { &hf_smb_device_state,
+ { "Device State", "smb.device_state", FT_UINT16, BASE_HEX,
+ NULL, 0, "Device State", HFILL }},
+
+ { &hf_smb_server_fid,
+ { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
+ NULL, 0, "Server unique File ID", HFILL }},
+
+ { &hf_smb_open_flags_add_info,
+ { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
+ TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
+
+ { &hf_smb_open_flags_ex_oplock,
+ { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
+ TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
+
+ { &hf_smb_open_flags_batch_oplock,
+ { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
+ TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
+
+ { &hf_smb_open_flags_ealen,
+ { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
+ TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
+
+ { &hf_smb_open_action_open,
+ { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
+ VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
+
+ { &hf_smb_open_action_lock,
+ { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
+ TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
+
+ { &hf_smb_vc_num,
+ { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
+ NULL, 0, "VC Number", HFILL }},
+
+ { &hf_smb_password_len,
+ { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
+ NULL, 0, "Length of password", HFILL }},
+
+ { &hf_smb_ansi_password_len,
+ { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
+ NULL, 0, "Length of ANSI password", HFILL }},
+
+ { &hf_smb_unicode_password_len,
+ { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
+ NULL, 0, "Length of Unicode password", HFILL }},
+
+ { &hf_smb_account,
+ { "Account", "smb.account", FT_STRING, BASE_NONE,
+ NULL, 0, "Account, username", HFILL }},
+
+ { &hf_smb_os,
+ { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
+ NULL, 0, "Which OS we are running", HFILL }},
+
+ { &hf_smb_lanman,
+ { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
+ NULL, 0, "Which LANMAN protocol we are running", HFILL }},
+
+ { &hf_smb_setup_action_guest,
+ { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
+ TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
+
+ { &hf_smb_fs,
+ { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
+ NULL, 0, "Native File System", HFILL }},
+
+ { &hf_smb_connect_flags_dtid,
+ { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
+ TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
+
+ { &hf_smb_connect_support_search,
+ { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
+ TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
+
+ { &hf_smb_connect_support_in_dfs,
+ { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
+ TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
+
};
static gint *ett[] = {
@@ -11496,6 +10425,15 @@ proto_register_smb(void)
&ett_smb_file_attributes,
&ett_smb_search_resume_key,
&ett_smb_search_dir_info,
+ &ett_smb_unlocks,
+ &ett_smb_unlock,
+ &ett_smb_locks,
+ &ett_smb_lock,
+ &ett_smb_open_flags,
+ &ett_smb_open_action,
+ &ett_smb_setup_action,
+ &ett_smb_connect_flags,
+ &ett_smb_connect_support_bits,
};
proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",