aboutsummaryrefslogtreecommitdiffstats
path: root/packet-smb.c
diff options
context:
space:
mode:
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)",