Ethereal-dev: [Ethereal-dev] Re: [Ethrereal-dev] packet-smb.c
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
Hi list
Guy wrote:
>> @@ -11163,8 +10907,8 @@
>> {
>> static hf_register_info hf[] = {
>> { &hf_smb_cmd,
>> - { "SMB Command", "smb.cmd",
>> - FT_UINT8, BASE_HEX, VALS(smb_cmd_vals), 0x0, "", HFILL }}
>> + { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
>> + NULL, 0x0, "SMB Command", HFILL }}
>
>And the reason for removing the ability to compare SMB commands by name
>in a filter _expression_ is?
The reason was basically performance. Value_string searches are O(n) so instead of using it as a value_string with VALS(), it uses proto_tree_add_*_format() to print the value for that field. This makes the mapping cmd->string O(1).
I didnt think of the case where one uses the name in the display-filter.
Sorry, change it to use VALS().
Attached is another patch. This patch requires the previous smb patch.
(My tree starts to diverge from CVS now, time to try to download a nightly snapshot again)
This patch allows tvbuffification one-by-one of the command-dissectors in smb.c
As an example SMBnegprot has been tvbuffified in this patch.
(A lot of the other commands are much easier/quicker to implement).
I think it could be worth it to tvbuffify these dissectors manually, there are not really that many of them.
best regards
ronnie sahlberg
Get your FREE download of MSN Explorer at http://explorer.msn.com
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-common.c ethereal/packet-smb-common.c
--- ethereal-orig/packet-smb-common.c Tue Aug 7 08:45:14 2001 +++ ethereal/packet-smb-common.c Fri Aug 10 16:59:10 2001 @@ -26,6 +26,18 @@ */ #include "packet-smb-common.h" +#include "smb.h" ++int dissect_ascii_or_unicode_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_index)
+{ + struct smb_info *si = pinfo->private; + + if(si->unicode){ + return display_unicode_string(tvb, pinfo, tree, offset, hf_index); + } + + return display_ms_string(tvb, pinfo, tree, offset, hf_index); +}int display_ms_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_index)
{diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-common.h ethereal/packet-smb-common.h
--- ethereal-orig/packet-smb-common.h Tue Aug 7 08:45:14 2001 +++ ethereal/packet-smb-common.h Fri Aug 10 14:08:36 2001 @@ -53,6 +53,8 @@int dissect_smb_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+int dissect_ascii_or_unicode_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_index);
+ int display_unicode_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_index);diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb.c ethereal/packet-smb.c
--- ethereal-orig/packet-smb.c Fri Aug 10 08:34:54 2001 +++ ethereal/packet-smb.c Fri Aug 10 17:02:16 2001 @@ -51,15 +51,67 @@ #include "packet-smb-mailslot.h" #include "packet-smb-pipe.h" +#include "packet-smb-common.h" static int proto_smb = -1; static int hf_smb_cmd = -1; +static int hf_word_count = -1; +static int hf_byte_count = -1; +static int hf_dialect_buffer_format = -1; +static int hf_dialect_name = -1; +static int hf_dialect_index = -1; +static int hf_sm_mode = -1; +static int hf_sm_password = -1; +static int hf_sm_signatures = -1; +static int hf_sm_sig_required = -1; +static int hf_max_trans_buf_size = -1; +static int hf_max_raw_buf_size = -1; +static int hf_max_mpx_count = -1; +static int hf_max_vcs_num = -1; +static int hf_rm_read = -1; +static int hf_rm_write = -1; +static int hf_session_key = -1; +static int hf_current_server_date = -1; +static int hf_current_server_dos_date = -1; +static int hf_current_server_dos_time = -1; +static int hf_server_timezone = -1; +static int hf_encryption_key_length = -1; +static int hf_reserved = -1; +static int hf_encryption_key = -1; +static int hf_primary_domain = -1; +static int hf_oem_domain = -1; +static int hf_server_cap_raw_mode = -1; +static int hf_server_cap_mpx_mode = -1; +static int hf_server_cap_unicode = -1; +static int hf_server_cap_large_files = -1; +static int hf_server_cap_nt_smbs = -1; +static int hf_server_cap_rpc_remote_apis = -1; +static int hf_server_cap_status32 = -1; +static int hf_server_cap_level_ii_oplocks = -1; +static int hf_server_cap_lock_and_read = -1; +static int hf_server_cap_nt_find = -1; +static int hf_server_cap_dfs = -1; +static int hf_server_cap_infolevel_passthru = -1; +static int hf_server_cap_large_readx = -1; +static int hf_server_cap_large_writex = -1; +static int hf_server_cap_unix = -1; +static int hf_server_cap_reserved = -1; +static int hf_server_cap_bulk_transfer = -1; +static int hf_server_cap_compressed_data = -1; +static int hf_server_cap_extended_security = -1; +static int hf_system_time_low = -1; +static int hf_system_time_high = -1; +static int hf_server_guid = -1; +static int hf_security_blob = -1; + +/*xxxxx*/ static gint ett_smb = -1; static gint ett_smb_fileattributes = -1; static gint ett_smb_capabilities = -1; static gint ett_smb_aflags = -1; static gint ett_smb_dialects = -1; +static gint ett_smb_dialect = -1; static gint ett_smb_mode = -1; static gint ett_smb_rawmode = -1; static gint ett_smb_flags = -1; @@ -73,6 +125,838 @@ static gint ett_smb_writemode = -1; static gint ett_smb_lock_type = -1; static gint ett_smb_header = -1; +static gint ett_smb_command = -1; +static gint ett_smb_time_date = -1; + + +#define SERVER_CAP_RAW_MODE 0x00000001 +#define SERVER_CAP_MPX_MODE 0x00000002 +#define SERVER_CAP_UNICODE 0x00000004 +#define SERVER_CAP_LARGE_FILES 0x00000008 +#define SERVER_CAP_NT_SMBS 0x00000010 +#define SERVER_CAP_RPC_REMOTE_APIS 0x00000020 +#define SERVER_CAP_STATUS32 0x00000040 +#define SERVER_CAP_LEVEL_II_OPLOCKS 0x00000080 +#define SERVER_CAP_LOCK_AND_READ 0x00000100 +#define SERVER_CAP_NT_FIND 0x00000200 +#define SERVER_CAP_DFS 0x00001000 +#define SERVER_CAP_INFOLEVEL_PASSTHRU 0x00002000 +#define SERVER_CAP_LARGE_READX 0x00004000 +#define SERVER_CAP_LARGE_WRITEX 0x00008000 +#define SERVER_CAP_UNIX 0x00800000 +#define SERVER_CAP_RESERVED 0x02000000 +#define SERVER_CAP_BULK_TRANSFER 0x20000000 +#define SERVER_CAP_COMPRESSED_DATA 0x40000000 +#define SERVER_CAP_EXTENDED_SECURITY 0x80000000 +static const true_false_string tfs_server_cap_raw_mode = { + "RAW MODE capability is available", + "Raw mode capability is NOT available" +}; +static const true_false_string tfs_server_cap_mpx_mode = { + "MPX MODE capability is available", + "Mpx mode capability is NOT available" +}; +static const true_false_string tfs_server_cap_unicode = { + "UNICODE capability is available", + "Unicode capability is NOT available" +}; +static const true_false_string tfs_server_cap_large_files = { + "LARGE FILES capability is available", + "Large files capability is NOT available" +}; +static const true_false_string tfs_server_cap_nt_smbs = { + "NT SMBS capability is available", + "Nt smbs capability is NOT available" +}; +static const true_false_string tfs_server_cap_rpc_remote_apis = { + "RPC REMOTE APIS capability is available", + "Rpc remote apis capability is NOT available" +}; +static const true_false_string tfs_server_cap_status32 = { + "STATUS32 capability is available", + "Status32 capability is NOT available" +}; +static const true_false_string tfs_server_cap_level_ii_oplocks = { + "LEVEL II OPLOCKS capability is available", + "Level ii oplocks capability is NOT available" +}; +static const true_false_string tfs_server_cap_lock_and_read = { + "LOCK AND READ capability is available", + "Lock and read capability is NOT available" +}; +static const true_false_string tfs_server_cap_nt_find = { + "NT FIND capability is available", + "Nt find capability is NOT available" +}; +static const true_false_string tfs_server_cap_dfs = { + "DFS capability is available", + "Dfs capability is NOT available" +}; +static const true_false_string tfs_server_cap_infolevel_passthru = { + "INFOLEVEL PASSTHRU capability is available", + "Infolevel passthru capability is NOT available" +}; +static const true_false_string tfs_server_cap_large_readx = { + "LARGE READX capability is available", + "Large readx capability is NOT available" +}; +static const true_false_string tfs_server_cap_large_writex = { + "LARGE WRITEX capability is available", + "Large writex capability is NOT available" +}; +static const true_false_string tfs_server_cap_unix = { + "UNIX capability is available", + "Unix capability is NOT available" +}; +static const true_false_string tfs_server_cap_reserved = { + "Reserved", + "Reserved" +}; +static const true_false_string tfs_server_cap_bulk_transfer = { + "BULK TRANSFER capability is available", + "Bulk transfer capability is NOT available" +}; +static const true_false_string tfs_server_cap_compressed_data = { + "COMPRESSED DATA capability is available", + "Compressed data capability is NOT available" +}; +static const true_false_string tfs_server_cap_extended_security = { + "EXTENDED SECURITY capability is available", + "Extended security capability is NOT available" +}; + + +#define RAWMODE_READ 0x01 +#define RAWMODE_WRITE 0x02 +static const true_false_string tfs_rm_read = { + "READ raw supported", + "Read raw NOT supported" +}; +static const true_false_string tfs_rm_write = { + "WRITE raw supported", + "Write raw NOT supported" +}; + +#define SECURITY_MODE_MODE 0x01 +#define SECURITY_MODE_PASSWORD 0x02 +#define SECURITY_MODE_SIGNATURES 0x04 +#define SECURITY_MODE_SIG_REQUIRED 0x08 +static const true_false_string tfs_sm_mode = { + "USER security mode", + "SHARE security mode" +}; +static const true_false_string tfs_sm_password = { + "ENCRYPTED password. Use challenge response", + "PLAINTEXT password" +}; +static const true_false_string tfs_sm_signatures = { + "Security signatures ENABLED", + "Security signatures NOT enabled" +}; +static const true_false_string tfs_sm_sig_required = { + "Security signatures REQUIRED", + "Security signatures NOT required" +}; + +/*xxxxx*/ +static int+dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+{ + guint32 mask; + proto_item *item = NULL; + proto_tree *tree = NULL; + + mask = tvb_get_letohl(tvb, offset); + + if(parent_tree){+ item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%04x ", mask);
+ tree = proto_item_add_subtree(item, ett_smb_capabilities); + } + + proto_tree_add_boolean(tree, hf_server_cap_raw_mode, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_mpx_mode, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_unicode, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_large_files, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_nt_smbs, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_rpc_remote_apis, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_status32, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_level_ii_oplocks, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_lock_and_read, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_nt_find, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_dfs, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_infolevel_passthru, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_large_readx, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_large_writex, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_unix, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_reserved, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_bulk_transfer, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_compressed_data, + tvb, offset, 4, mask); + proto_tree_add_boolean(tree, hf_server_cap_extended_security, + tvb, offset, 4, mask); + + return mask; +} + +static int+dissect_time_date(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date, int hf_dos_date, int hf_dos_time)
+{ + guint16 dos_time, dos_date; + proto_item *item = NULL; + proto_tree *tree = NULL; + struct tm tm; + time_t t; + struct timeval tv; + char ts[256]; + + dos_time = tvb_get_letohs(tvb, offset); + dos_date = tvb_get_letohs(tvb, offset+2); + + tm.tm_sec = (dos_time&0x1f)*2; + tm.tm_min = (dos_time>>5)&0x3f; + tm.tm_hour = (dos_time>>11)&0x1f; + tm.tm_mday = dos_date&0x1f; + tm.tm_mon = (dos_date>>5)&0x0f; + tm.tm_year = ((dos_date>>9)&0x7f)+1980; + + t = mktime(&tm); + + tv.tv_sec = t; + tv.tv_usec = 0; + + if(parent_tree){ + strftime(ts, 256, "%d %d, %Y %H:%M:%S", &tm);+ item = proto_tree_add_text(parent_tree, tvb, offset, 4, "%s : %s", str, ts);
+ tree = proto_item_add_subtree(item, ett_smb_time_date); + } + + proto_tree_add_time(tree, hf_date, tvb, offset, 4, &tv); ++ proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "Dos Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
++ proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "Dos Date: %04d-%02d-%02d (0x%04x)", tm.tm_year, tm.tm_mon, tm.tm_mday, dos_date);
+ + offset += 4; + + return offset; +} + +static int+dissect_negprot_rawmode(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, "Rawmode: 0x%04x ", mask);
+ tree = proto_item_add_subtree(item, ett_smb_rawmode); + } + + proto_tree_add_boolean(tree, hf_rm_read, tvb, offset, 2, mask); + proto_tree_add_boolean(tree, hf_rm_write, tvb, offset, 2, mask); + + offset += 2; + + return offset; +} + +static int+dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int type)
+{ + guint16 mask = 0; + proto_item *item = NULL; + proto_tree *tree = NULL; + + + if(parent_tree){ + switch(type){ + case 0: + mask = tvb_get_letohs(tvb, offset);+ item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Security Mode: 0x%04x ", mask);
+ break; + case 1: + mask = tvb_get_guint8(tvb, offset);+ item = proto_tree_add_text(parent_tree, tvb, offset, 1, "Security Mode: 0x%02x ", mask);
+ break; + } + tree = proto_item_add_subtree(item, ett_smb_mode); + } + + proto_tree_add_boolean(tree, hf_sm_mode, tvb, offset, 2, mask); + proto_tree_add_boolean(tree, hf_sm_password, tvb, offset, 2, mask); + if(type==0){ + offset += 2; + return offset; + } + proto_tree_add_boolean(tree, hf_sm_signatures, tvb, offset, 2, mask); + proto_tree_add_boolean(tree, hf_sm_sig_required, tvb, offset, 2, mask); + if(type==1){ + offset +=1; + return offset; + } + + offset += 2; + return offset; +} + + +static int+dissect_smb_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{ + proto_item *it = NULL; + proto_tree *tr = NULL; + + int offset = 0; + int bc; + + /* word count */+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1; + + /* byte count */ + bc = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, bc); + offset += 2; + + if(tree){ + it = proto_tree_add_text(tree, tvb, offset, bc, "Requested Dialects"); + tr = proto_item_add_subtree(it, ett_smb_dialects); + } + + while(bc){ + int len; + int old_offset = offset; + const guint8 *str; + proto_item *dit = NULL; + proto_tree *dtr = NULL; + + len = tvb_strsize(tvb, offset+1); + str = tvb_get_ptr(tvb, offset+1, len); + + if(tr){ + dit = proto_tree_add_text(tr, tvb, offset, len+1, "Dialect: %s", str); + dtr = proto_item_add_subtree(dit, ett_smb_dialect); + } + + /* buffer format */+ proto_tree_add_uint(dtr, hf_dialect_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+ offset += 1; + bc -= 1; + + /*dialect name */ + proto_tree_add_string(dtr, hf_dialect_name, tvb, offset, len, str); + offset += len; + bc -= len; + } + + return offset; +} + +static int+dissect_smb_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{ + int wc; + int offset = 0; + + /* word count */ + wc = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, wc); + offset += 1; + + /* the server didnt understand any dialect so it must be + * "PC NETWORK PROGRAM 1.0" + */ + if(wc==1){ + guint16 dialect; + + /* dialect index */ + dialect = tvb_get_letohs(tvb, offset); + if(dialect==0xffff){ + proto_tree_add_uint_format(tree, hf_dialect_index, + tvb, offset, 2, dialect, + "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen"); + } else { + proto_tree_add_uint(tree, hf_dialect_index, + tvb, offset, 2, dialect); + } + offset += 2; + + /* byte count */+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2; + } + + + if(wc==13){ + guint16 ekl; + guint16 dialect; + gint16 tz; + + /* dialect index */ + dialect = tvb_get_letohs(tvb, offset); + proto_tree_add_uint_format(tree, hf_dialect_index,+ tvb, offset, 2, dialect, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
+ offset += 2; + + /* security mode */ + offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, 0); + + /* maximum transmit buffer size */ + proto_tree_add_uint(tree, hf_max_trans_buf_size, + tvb, offset, 2, tvb_get_letohs(tvb, offset)); + offset += 2; + + /* maximum multiplex count */ + proto_tree_add_uint(tree, hf_max_mpx_count, + tvb, offset, 2, tvb_get_letohs(tvb, offset)); + offset += 2; + + /* maximum vcs number */ + proto_tree_add_uint(tree, hf_max_vcs_num, + tvb, offset, 2, tvb_get_letohs(tvb, offset)); + offset += 2; + + /* raw mode */ + offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset); + + /* session key */ + proto_tree_add_uint(tree, hf_session_key, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* current time and date at server */+ offset = dissect_time_date(tvb, pinfo, tree, offset, "Current Time and Date at server", hf_current_server_date, hf_current_server_dos_date, hf_current_server_dos_time);
+ + /* time zone */ + tz = tvb_get_letohs(tvb, offset);+ proto_tree_add_int_format(tree, hf_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
+ offset += 2; + + /* encryption key length */ + ekl = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_encryption_key_length, tvb, offset, 2, ekl); + offset += 2; + + /* 2 reserved bytes */+ proto_tree_add_bytes(tree, hf_reserved, tvb, offset, 2, tvb_get_ptr(tvb, offset, 2));
+ offset += 2; + + + /* byte count */+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2; + + /* challange/ encryption key */ + if(ekl){+ proto_tree_add_bytes(tree, hf_encryption_key, tvb, offset, ekl, tvb_get_ptr(tvb, offset, ekl));
+ offset += ekl; + } + + /* is this string optional ? */ + /* primary domain */+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_primary_domain);
+ } + + if(wc==17){ + guint16 ekl, dialect; + guint32 caps; + gint16 tz; + + /* dialect index */ + dialect = tvb_get_letohs(tvb, offset); + proto_tree_add_uint_format(tree, hf_dialect_index,+ tvb, offset, 2, dialect, "Dialect Index: %u, greater than LANMAN2.1", dialect);
+ offset += 2; + + /* security mode */ + offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, 1); + + /* maximum multiplex count */ + proto_tree_add_uint(tree, hf_max_mpx_count, + tvb, offset, 2, tvb_get_letohs(tvb, offset)); + offset += 2; + + /* maximum vcs number */ + proto_tree_add_uint(tree, hf_max_vcs_num, + tvb, offset, 2, tvb_get_letohs(tvb, offset)); + offset += 2; + + /* maximum transmit buffer size */ + proto_tree_add_uint(tree, hf_max_trans_buf_size, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* maximum raw buffer size */ + proto_tree_add_uint(tree, hf_max_raw_buf_size, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* session key */ + proto_tree_add_uint(tree, hf_session_key, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* server capabilities */ + caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset); + offset += 4; + + /*XXX FIXME: how should these times be decoded?*/ + /* system time low */ + proto_tree_add_uint(tree, hf_system_time_low, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* system time high */ + proto_tree_add_uint(tree, hf_system_time_high, + tvb, offset, 4, tvb_get_letohl(tvb, offset)); + offset += 4; + + /* time zone */ + tz = tvb_get_letohs(tvb, offset);+ proto_tree_add_int_format(tree, hf_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
+ offset += 2; + + /* encryption key length */ + ekl = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tree, hf_encryption_key_length, tvb, offset, 1, ekl); + offset += 1; + + + /* byte count */+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+ offset += 2; + + if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){ + struct smb_info *si; + + /* challange/ encryption key */ + if(ekl){+ proto_tree_add_bytes(tree, hf_encryption_key, tvb, offset, ekl, tvb_get_ptr(tvb, offset, ekl));
+ offset += ekl; + } + + if(tvb_length_remaining(tvb, offset)){ + /* oem domain */ + /* this string is special, unicode is flagged in caps */ + si = pinfo->private; + si->unicode = (caps&SERVER_CAP_UNICODE);+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_oem_domain);
+ } + } else { + int len; + + /* guid */+ proto_tree_add_bytes(tree, hf_server_guid, tvb, offset, 16, tvb_get_ptr(tvb, offset, 16));
+ offset += 16; + + /* security blob */ + len = tvb_length_remaining(tvb, offset); + if(len){+ proto_tree_add_bytes(tree, hf_security_blob, tvb, offset, len, tvb_get_ptr(tvb, offset, len));
+ offset += len; + } + } + + } + + return offset; +} + + +/*xxxxx*/ + + +typedef struct _smb_function { + int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +} smb_function; + +smb_function smb_dissector[256] = { +/* 0x00 */ {NULL, NULL}, +/* 0x01 */ {NULL, NULL}, +/* 0x02 */ {NULL, NULL}, +/* 0x03 */ {NULL, NULL}, +/* 0x04 */ {NULL, NULL}, +/* 0x05 */ {NULL, NULL}, +/* 0x06 */ {NULL, NULL}, +/* 0x07 */ {NULL, NULL}, +/* 0x08 */ {NULL, NULL}, +/* 0x09 */ {NULL, NULL}, +/* 0x0a */ {NULL, NULL}, +/* 0x0b */ {NULL, NULL}, +/* 0x0c */ {NULL, NULL}, +/* 0x0d */ {NULL, NULL}, +/* 0x0e */ {NULL, NULL}, +/* 0x0f */ {NULL, NULL}, +/* 0x10 */ {NULL, NULL}, +/* 0x11 */ {NULL, NULL}, +/* 0x12 */ {NULL, NULL}, +/* 0x13 */ {NULL, NULL}, +/* 0x14 */ {NULL, NULL}, +/* 0x15 */ {NULL, NULL}, +/* 0x16 */ {NULL, NULL}, +/* 0x17 */ {NULL, NULL}, +/* 0x18 */ {NULL, NULL}, +/* 0x19 */ {NULL, NULL}, +/* 0x1a */ {NULL, NULL}, +/* 0x1b */ {NULL, NULL}, +/* 0x1c */ {NULL, NULL}, +/* 0x1d */ {NULL, NULL}, +/* 0x1e */ {NULL, NULL}, +/* 0x1f */ {NULL, NULL}, +/* 0x20 */ {NULL, NULL}, +/* 0x21 */ {NULL, NULL}, +/* 0x22 */ {NULL, NULL}, +/* 0x23 */ {NULL, NULL}, +/* 0x24 */ {NULL, NULL}, +/* 0x25 */ {NULL, NULL}, +/* 0x26 */ {NULL, NULL}, +/* 0x27 */ {NULL, NULL}, +/* 0x28 */ {NULL, NULL}, +/* 0x29 */ {NULL, NULL}, +/* 0x2a */ {NULL, NULL}, +/* 0x2b */ {NULL, NULL}, +/* 0x2c */ {NULL, NULL}, +/* 0x2d */ {NULL, NULL}, +/* 0x2e */ {NULL, NULL}, +/* 0x2f */ {NULL, NULL}, +/* 0x30 */ {NULL, NULL}, +/* 0x31 */ {NULL, NULL}, +/* 0x32 */ {NULL, NULL}, +/* 0x33 */ {NULL, NULL}, +/* 0x34 */ {NULL, NULL}, +/* 0x35 */ {NULL, NULL}, +/* 0x36 */ {NULL, NULL}, +/* 0x37 */ {NULL, NULL}, +/* 0x38 */ {NULL, NULL}, +/* 0x39 */ {NULL, NULL}, +/* 0x3a */ {NULL, NULL}, +/* 0x3b */ {NULL, NULL}, +/* 0x3c */ {NULL, NULL}, +/* 0x3d */ {NULL, NULL}, +/* 0x3e */ {NULL, NULL}, +/* 0x3f */ {NULL, NULL}, +/* 0x40 */ {NULL, NULL}, +/* 0x41 */ {NULL, NULL}, +/* 0x42 */ {NULL, NULL}, +/* 0x43 */ {NULL, NULL}, +/* 0x44 */ {NULL, NULL}, +/* 0x45 */ {NULL, NULL}, +/* 0x46 */ {NULL, NULL}, +/* 0x47 */ {NULL, NULL}, +/* 0x48 */ {NULL, NULL}, +/* 0x49 */ {NULL, NULL}, +/* 0x4a */ {NULL, NULL}, +/* 0x4b */ {NULL, NULL}, +/* 0x4c */ {NULL, NULL}, +/* 0x4d */ {NULL, NULL}, +/* 0x4e */ {NULL, NULL}, +/* 0x4f */ {NULL, NULL}, +/* 0x50 */ {NULL, NULL}, +/* 0x51 */ {NULL, NULL}, +/* 0x52 */ {NULL, NULL}, +/* 0x53 */ {NULL, NULL}, +/* 0x54 */ {NULL, NULL}, +/* 0x55 */ {NULL, NULL}, +/* 0x56 */ {NULL, NULL}, +/* 0x57 */ {NULL, NULL}, +/* 0x58 */ {NULL, NULL}, +/* 0x59 */ {NULL, NULL}, +/* 0x5a */ {NULL, NULL}, +/* 0x5b */ {NULL, NULL}, +/* 0x5c */ {NULL, NULL}, +/* 0x5d */ {NULL, NULL}, +/* 0x5e */ {NULL, NULL}, +/* 0x5f */ {NULL, NULL}, +/* 0x60 */ {NULL, NULL}, +/* 0x61 */ {NULL, NULL}, +/* 0x62 */ {NULL, NULL}, +/* 0x63 */ {NULL, NULL}, +/* 0x64 */ {NULL, NULL}, +/* 0x65 */ {NULL, NULL}, +/* 0x66 */ {NULL, NULL}, +/* 0x67 */ {NULL, NULL}, +/* 0x68 */ {NULL, NULL}, +/* 0x69 */ {NULL, NULL}, +/* 0x6a */ {NULL, NULL}, +/* 0x6b */ {NULL, NULL}, +/* 0x6c */ {NULL, NULL}, +/* 0x6d */ {NULL, NULL}, +/* 0x6e */ {NULL, NULL}, +/* 0x6f */ {NULL, NULL}, +/* 0x70 */ {NULL, NULL}, +/* 0x71 */ {NULL, NULL}, +/* 0x72 */ {dissect_smb_negprot_request, dissect_smb_negprot_response}, +/* 0x73 */ {NULL, NULL}, +/* 0x74 */ {NULL, NULL}, +/* 0x75 */ {NULL, NULL}, +/* 0x76 */ {NULL, NULL}, +/* 0x77 */ {NULL, NULL}, +/* 0x78 */ {NULL, NULL}, +/* 0x79 */ {NULL, NULL}, +/* 0x7a */ {NULL, NULL}, +/* 0x7b */ {NULL, NULL}, +/* 0x7c */ {NULL, NULL}, +/* 0x7d */ {NULL, NULL}, +/* 0x7e */ {NULL, NULL}, +/* 0x7f */ {NULL, NULL}, +/* 0x80 */ {NULL, NULL}, +/* 0x81 */ {NULL, NULL}, +/* 0x82 */ {NULL, NULL}, +/* 0x83 */ {NULL, NULL}, +/* 0x84 */ {NULL, NULL}, +/* 0x85 */ {NULL, NULL}, +/* 0x86 */ {NULL, NULL}, +/* 0x87 */ {NULL, NULL}, +/* 0x88 */ {NULL, NULL}, +/* 0x89 */ {NULL, NULL}, +/* 0x8a */ {NULL, NULL}, +/* 0x8b */ {NULL, NULL}, +/* 0x8c */ {NULL, NULL}, +/* 0x8d */ {NULL, NULL}, +/* 0x8e */ {NULL, NULL}, +/* 0x8f */ {NULL, NULL}, +/* 0x90 */ {NULL, NULL}, +/* 0x91 */ {NULL, NULL}, +/* 0x92 */ {NULL, NULL}, +/* 0x93 */ {NULL, NULL}, +/* 0x94 */ {NULL, NULL}, +/* 0x95 */ {NULL, NULL}, +/* 0x96 */ {NULL, NULL}, +/* 0x97 */ {NULL, NULL}, +/* 0x98 */ {NULL, NULL}, +/* 0x99 */ {NULL, NULL}, +/* 0x9a */ {NULL, NULL}, +/* 0x9b */ {NULL, NULL}, +/* 0x9c */ {NULL, NULL}, +/* 0x9d */ {NULL, NULL}, +/* 0x9e */ {NULL, NULL}, +/* 0x9f */ {NULL, NULL}, +/* 0xa0 */ {NULL, NULL}, +/* 0xa1 */ {NULL, NULL}, +/* 0xa2 */ {NULL, NULL}, +/* 0xa3 */ {NULL, NULL}, +/* 0xa4 */ {NULL, NULL}, +/* 0xa5 */ {NULL, NULL}, +/* 0xa6 */ {NULL, NULL}, +/* 0xa7 */ {NULL, NULL}, +/* 0xa8 */ {NULL, NULL}, +/* 0xa9 */ {NULL, NULL}, +/* 0xaa */ {NULL, NULL}, +/* 0xab */ {NULL, NULL}, +/* 0xac */ {NULL, NULL}, +/* 0xad */ {NULL, NULL}, +/* 0xae */ {NULL, NULL}, +/* 0xaf */ {NULL, NULL}, +/* 0xb0 */ {NULL, NULL}, +/* 0xb1 */ {NULL, NULL}, +/* 0xb2 */ {NULL, NULL}, +/* 0xb3 */ {NULL, NULL}, +/* 0xb4 */ {NULL, NULL}, +/* 0xb5 */ {NULL, NULL}, +/* 0xb6 */ {NULL, NULL}, +/* 0xb7 */ {NULL, NULL}, +/* 0xb8 */ {NULL, NULL}, +/* 0xb9 */ {NULL, NULL}, +/* 0xba */ {NULL, NULL}, +/* 0xbb */ {NULL, NULL}, +/* 0xbc */ {NULL, NULL}, +/* 0xbd */ {NULL, NULL}, +/* 0xbe */ {NULL, NULL}, +/* 0xbf */ {NULL, NULL}, +/* 0xc0 */ {NULL, NULL}, +/* 0xc1 */ {NULL, NULL}, +/* 0xc2 */ {NULL, NULL}, +/* 0xc3 */ {NULL, NULL}, +/* 0xc4 */ {NULL, NULL}, +/* 0xc5 */ {NULL, NULL}, +/* 0xc6 */ {NULL, NULL}, +/* 0xc7 */ {NULL, NULL}, +/* 0xc8 */ {NULL, NULL}, +/* 0xc9 */ {NULL, NULL}, +/* 0xca */ {NULL, NULL}, +/* 0xcb */ {NULL, NULL}, +/* 0xcc */ {NULL, NULL}, +/* 0xcd */ {NULL, NULL}, +/* 0xce */ {NULL, NULL}, +/* 0xcf */ {NULL, NULL}, +/* 0xd0 */ {NULL, NULL}, +/* 0xd1 */ {NULL, NULL}, +/* 0xd2 */ {NULL, NULL}, +/* 0xd3 */ {NULL, NULL}, +/* 0xd4 */ {NULL, NULL}, +/* 0xd5 */ {NULL, NULL}, +/* 0xd6 */ {NULL, NULL}, +/* 0xd7 */ {NULL, NULL}, +/* 0xd8 */ {NULL, NULL}, +/* 0xd9 */ {NULL, NULL}, +/* 0xda */ {NULL, NULL}, +/* 0xdb */ {NULL, NULL}, +/* 0xdc */ {NULL, NULL}, +/* 0xdd */ {NULL, NULL}, +/* 0xde */ {NULL, NULL}, +/* 0xdf */ {NULL, NULL}, +/* 0xe0 */ {NULL, NULL}, +/* 0xe1 */ {NULL, NULL}, +/* 0xe2 */ {NULL, NULL}, +/* 0xe3 */ {NULL, NULL}, +/* 0xe4 */ {NULL, NULL}, +/* 0xe5 */ {NULL, NULL}, +/* 0xe6 */ {NULL, NULL}, +/* 0xe7 */ {NULL, NULL}, +/* 0xe8 */ {NULL, NULL}, +/* 0xe9 */ {NULL, NULL}, +/* 0xea */ {NULL, NULL}, +/* 0xeb */ {NULL, NULL}, +/* 0xec */ {NULL, NULL}, +/* 0xed */ {NULL, NULL}, +/* 0xee */ {NULL, NULL}, +/* 0xef */ {NULL, NULL}, +/* 0xf0 */ {NULL, NULL}, +/* 0xf1 */ {NULL, NULL}, +/* 0xf2 */ {NULL, NULL}, +/* 0xf3 */ {NULL, NULL}, +/* 0xf4 */ {NULL, NULL}, +/* 0xf5 */ {NULL, NULL}, +/* 0xf6 */ {NULL, NULL}, +/* 0xf7 */ {NULL, NULL}, +/* 0xf8 */ {NULL, NULL}, +/* 0xf9 */ {NULL, NULL}, +/* 0xfa */ {NULL, NULL}, +/* 0xfb */ {NULL, NULL}, +/* 0xfc */ {NULL, NULL}, +/* 0xfd */ {NULL, NULL}, +/* 0xfe */ {NULL, NULL}, +/* 0xff */ {NULL, NULL} +}; + + + +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + * Everything tvbuffified above this line + * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + */ + /* @@ -1915,6 +2799,8 @@ } + + /* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */ voiddissect_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, int errcode)
@@ -2799,548 +3685,6 @@ } -void-dissect_negprot_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, int errcode)
-{ - guint8 wct, enckeylen; - guint16 bcc, mode, rawmode, dialect; - guint32 caps; - proto_tree *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree; - proto_item *ti; - const char *str; - char *ustr; - int ustr_len; - - wct = pd[offset]; /* Should be 0, 1 or 13 or 17, I think */ - - if (!((wct == 0) && si.request) && !((wct == 1) && !si.request) && - !((wct == 13) && !si.request) && !((wct == 17) && !si.request)) { - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., 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): %d", wct);
- - } - - if (!si.request && errcode != 0) return; /* No more info ... */ - - offset += 1; - - /* Now decode the various formats ... */ - - switch (wct) { - - case 0: /* A request */ - - bcc = GSHORT(pd, offset); - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
- - } - - offset += 2; - - if (tree) { -- ti = proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Dialects");
- dialects = proto_item_add_subtree(ti, ett_smb_dialects); - - } - - while (IS_DATA_IN_FRAME(offset)) { - const char *str; - - if (tree) { -- proto_tree_add_text(dialects, NullTVB, offset, 1, "Dialect Marker: %d", pd[offset]);
- - } - - offset += 1; - - str = pd + offset; - - if (tree) { -- proto_tree_add_text(dialects, NullTVB, offset, strlen(str)+1, "Dialect: %s", str);
- - } - - offset += strlen(str) + 1; - - } - break; - - case 1: /* PC NETWORK PROGRAM 1.0 */ - - dialect = GSHORT(pd, offset); - - if (tree) { /* Hmmmm, what if none of the dialects is recognized */ - - if (dialect == 0xFFFF) { /* Server didn't like them dialects */ -- proto_tree_add_text(tree, NullTVB, offset, 2, "Supplied dialects not recognized");
- - } - else { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, PC NETWORK PROTGRAM 1.0", dialect);
- - } - - } - - offset += 2; - - bcc = GSHORT(pd, offset); - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
- - } - - break; - - case 13: /* Greater than Core and up to and incl LANMAN2.1 */ - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
- - } - - /* Much of this is similar to response 17 below */ - - offset += 2; - - mode = GSHORT(pd, offset); - - if (tree) { -- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Security Mode: 0x%04x", mode);
- mode_tree = proto_item_add_subtree(ti, ett_smb_mode); - proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s", - decode_boolean_bitfield(mode, 0x0001, 16, - "Security = User", - "Security = Share")); - proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s", - decode_boolean_bitfield(mode, 0x0002, 16, - "Passwords = Encrypted", - "Passwords = Plaintext")); - - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size: %u", GSHORT(pd, offset));
- - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
- - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs: %u", GSHORT(pd, offset));
- - } - - offset += 2; - - rawmode = GSHORT(pd, offset); - - if (tree) { -- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Raw Mode: 0x%04x", rawmode);
- rawmode_tree = proto_item_add_subtree(ti, ett_smb_rawmode); - proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s", - decode_boolean_bitfield(rawmode, 0x01, 16, - "Read Raw supported", - "Read Raw not supported")); - proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s", - decode_boolean_bitfield(rawmode, 0x02, 16, - "Write Raw supported", - "Write Raw not supported")); - - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 4, "Session key: %08x", GWORD(pd, offset));
- - } - - offset += 4; - - /* Now the server time, two short parameters ... */ - - if (tree) { - - proto_tree_add_text(tree, NullTVB, offset, 2, "Server Time: %s", - dissect_dos_time(GSHORT(pd, offset))); - proto_tree_add_text(tree, NullTVB, offset + 2, 2, "Server Date: %s", - dissect_dos_date(GSHORT(pd, offset + 2))); - - } - - offset += 4; - - /* Server Time Zone, SHORT */ - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
- (signed short)GSSHORT(pd, offset)); - - } - - offset += 2; - - /* Challenge Length */ - - enckeylen = GSHORT(pd, offset); - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Challenge Length: %u", enckeylen);
- - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u (MBZ)", GSHORT(pd, offset));
- - } - - offset += 2; - - bcc = GSHORT(pd, offset); - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
- - } - - offset += 2; - - if (enckeylen) { /* only if non-zero key len */ - - str = pd + offset; - - if (tree) { - - proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge: %s", - bytes_to_str(str, enckeylen)); - } - - offset += enckeylen; - - } - - /* Primary Domain ... */ - - str = pd + offset; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "Primary Domain: %s", str);
- - } - - break; - - case 17: /* Greater than LANMAN2.1 */ - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than LANMAN2.1", GSHORT(pd, offset));
- - } - - offset += 2; - - mode = GBYTE(pd, offset); - - if (tree) { -- ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Security Mode: 0x%02x", mode);
- mode_tree = proto_item_add_subtree(ti, ett_smb_mode); - proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s", - decode_boolean_bitfield(mode, 0x01, 8, - "Security = User", - "Security = Share")); - proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s", - decode_boolean_bitfield(mode, 0x02, 8, - "Passwords = Encrypted", - "Passwords = Plaintext")); - proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s", - decode_boolean_bitfield(mode, 0x04, 8, - "Security signatures enabled", - "Security signatures not enabled")); - proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s", - decode_boolean_bitfield(mode, 0x08, 8, - "Security signatures required", - "Security signatures not required")); - - } - - offset += 1; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
- - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs: %u", GSHORT(pd, offset));
- - } - - offset += 2; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size: %u", GWORD(pd, offset));
- - } - - offset += 4; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 4, "Max raw size: %u", GWORD(pd, offset));
- - } - - offset += 4; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 4, "Session key: %08x", GWORD(pd, offset));
- - } - - offset += 4; - - caps = GWORD(pd, offset); - - if (tree) { -- ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", caps);
- caps_tree = proto_item_add_subtree(ti, ett_smb_capabilities); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0001, 32, - "Raw Mode supported", - "Raw Mode not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0002, 32, - "MPX Mode supported", - "MPX Mode not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0004, 32, - "Unicode supported", - "Unicode not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0008, 32, - "Large files supported", - "Large files not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0010, 32, - "NT LM 0.12 SMBs supported", - "NT LM 0.12 SMBs not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0020, 32, - "RPC remote APIs supported", - "RPC remote APIs not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0040, 32, - "NT status codes supported", - "NT status codes not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0080, 32, - "Level 2 OpLocks supported", - "Level 2 OpLocks not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0100, 32, - "Lock&Read supported", - "Lock&Read not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x0200, 32, - "NT Find supported", - "NT Find not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x1000, 32, - "DFS supported", - "DFS not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x4000, 32, - "Large READX supported", - "Large READX not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x8000, 32, - "Large WRITEX supported", - "Large WRITEX not supported")); - proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s", - decode_boolean_bitfield(caps, 0x80000000, 32, - "Extended security exchanges supported", - "Extended security exchanges not supported")); - } - - offset += 4; - - /* Server time, 2 WORDS */ - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 4, "System Time Low: 0x%08x", GWORD(pd, offset)); - proto_tree_add_text(tree, NullTVB, offset + 4, 4, "System Time High: 0x%08x", GWORD(pd, offset + 4));
- - } - - offset += 8; - - /* Server Time Zone, SHORT */ - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
- (signed short)GSSHORT(pd, offset)); - - } - - offset += 2; - - /* Encryption key len */ - - enckeylen = pd[offset]; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 1, "Encryption key len: %u", enckeylen);
- - } - - offset += 1; - - bcc = GSHORT(pd, offset); - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte count (BCC): %u", bcc);
- - } - - offset += 2; - - if (caps & 0x80000000) { - /* Extended security */ - - /* GUID */ - - if (tree) { - - /* XXX - show it in GUID form, with dashes or whatever */ - proto_tree_add_text(tree, NullTVB, offset, 16, "GUID: %s", - bytes_to_str(&pd[offset], 16)); - - } - - offset += 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? */ - - if (bcc > 16) { - bcc -= 16; - - if (tree) { - - proto_tree_add_text(tree, NullTVB, offset, bcc, "Security blob: %s", - bytes_to_str(&pd[offset], bcc)); - - } - } - } else { - /* Non-extended security */ - - if (enckeylen) { /* only if non-zero key len */ - - /* Encryption challenge key */ - - str = pd + offset; - - if (tree) { -- proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge encryption key: %s",
- bytes_to_str(str, enckeylen)); - - } - - offset += enckeylen; - - } - - /* The domain, a null terminated string; Unicode if "caps" has - the 0x0004 bit set, ASCII (OEM character set) otherwise. - XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */ - - str = pd + offset; - - if (tree) { - - if (caps & 0x0004) { - ustr = unicode_to_str(str, &ustr_len);- proto_tree_add_text(tree, NullTVB, offset, ustr_len+2, "OEM domain name: %s", ustr);
- } else {- proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "OEM domain name: %s", str);
- } - - } - } - - break; - - default: /* Baddd */ - - if (tree)- proto_tree_add_text(tree, NullTVB, offset, 1, "Bad format, should never get here");
- return; - - } - -} - voiddissect_deletedir_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, int errcode)
@@ -10291,7 +10635,7 @@ dissect_unknown_smb, /* unknown SMB 0x6f */ dissect_treecon_smb, /* SMBtcon tree connect */ dissect_tdis_smb, /* SMBtdis tree disconnect */ - dissect_negprot_smb, /* SMBnegprot negotiate a protocol */ + 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 */ @@ -10589,15 +10933,18 @@ #define SMB_FLAGS_DIRN 0x80 void-dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data) +dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent_tree, int max_data)
{ - proto_tree *smb_tree = tree, *flags_tree, *flags2_tree; - proto_item *ti, *tf; + proto_tree *smb_tree = NULL, *tree = NULL, *flags_tree, *flags2_tree; + proto_item *item = NULL, *ti = NULL, *tf = NULL; guint8 cmd, errcls, errcode1, flags; guint16 flags2, errcode, tid, pid, uid, mid; guint32 status; int SMB_offset = offset; + int old_offset = offset; struct smb_info si; + int (*new_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + OLD_CHECK_DISPLAY_AS_DATA(proto_smb, pd, offset, fd, tree); @@ -10617,20 +10964,29 @@ } + if (parent_tree) {+ item = proto_tree_add_item(parent_tree, proto_smb, NullTVB, offset, END_OF_FRAME, FALSE);
+ + tree = proto_item_add_subtree(item, ett_smb); + } + if (tree) { + ti = proto_tree_add_text(tree, NullTVB, offset, + END_OF_FRAME, "SMB Header : %s (0x%02x) %s", + decode_smb_name(cmd), cmd, + (pi.match_port==pi.destport)?"Request":"Response");- ti = proto_tree_add_item(tree, proto_smb, NullTVB, offset, END_OF_FRAME, FALSE);
- smb_tree = proto_item_add_subtree(ti, ett_smb); + smb_tree = proto_item_add_subtree(ti, ett_smb_header); /* 0xFFSMB is actually a 1 byte msg type and 3 byte server * component ... SMB is only one used */ - proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Message Type: 0xFF");- proto_tree_add_text(smb_tree, NullTVB, offset+1, 3, "Server Component: SMB");
- } + proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Message Type: 0xFF");+ proto_tree_add_text(smb_tree, NullTVB, offset+1, 3, "Server Component: SMB");
+ offset += 4; /* Skip the marker */ if (tree) { @@ -10789,7 +11145,9 @@ } - if (flags2 & 0x8000) si.unicode = TRUE; /* Mark them as Unicode */ + if (flags2 & 0x8000) { + si.unicode = TRUE; /* Mark them as Unicode */ + } offset += 2; @@ -10887,10 +11245,35 @@ offset += 2; + new_dissector = (pi.match_port==pi.destport)? + smb_dissector[cmd].request:smb_dissector[cmd].response; + /* Now vector through the table to dissect them */ - - (dissect[cmd])(pd, offset, fd, tree, smb_tree, si, max_data, - SMB_offset, errcode); + if(new_dissector){ + tvbuff_t *next_tvb; + proto_item *cmd_item = NULL; + proto_tree *cmd_tree = NULL; + + /* we need the unicode flag */ + pi.private = &si; + + proto_item_set_len(ti, offset-old_offset); + + next_tvb = tvb_create_from_top(offset); + if (tree) { + cmd_item = proto_tree_add_text(tree, NullTVB, offset, + END_OF_FRAME, "SMB Command : %s (0x%02x) %s", + decode_smb_name(cmd), cmd, + (pi.match_port==pi.destport)?"Request":"Response"); + + cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command); + } + (*new_dissector)(next_tvb, &pi, cmd_tree); + } else { + /* call old dissector */ + (dissect[cmd])(pd, offset, fd, tree, tree, si, max_data, + SMB_offset, errcode); + } } /*** External routines called during the registration process */ @@ -10908,7 +11291,201 @@ static hf_register_info hf[] = { { &hf_smb_cmd, { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX, - NULL, 0x0, "SMB Command", HFILL }} + NULL, 0x0, "SMB Command", HFILL }}, + + { &hf_word_count, + { "Word Count", "smb.word_count", FT_UINT8, BASE_DEC, + NULL, 0, "SMB Word Count", HFILL }}, + + { &hf_byte_count, + { "Byte Count", "smb.byte_count", FT_UINT16, BASE_DEC, + NULL, 0, "SMB Byte Count", HFILL }}, + + { &hf_dialect_buffer_format, + { "Buffer Format", "smb.dialect.buffer_format", FT_UINT8, BASE_HEX, + NULL, 0, "Buffer Format for this dialect", HFILL }}, + + { &hf_dialect_name, + { "Name", "smb.dialect.name", FT_STRING, BASE_NONE, + NULL, 0, "Name of dialect", HFILL }}, + + { &hf_dialect_index, + { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC, + NULL, 0, "Index of selected dialect", HFILL }}, + + { &hf_sm_mode, + { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,+ TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
+ + { &hf_sm_password, + { "Password", "smb.sm.password", FT_BOOLEAN, 16,+ TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
+ + { &hf_sm_signatures, + { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 16,+ TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
+ + { &hf_sm_sig_required, + { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 16,+ TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
+ + { &hf_max_trans_buf_size, + { "Max TBuffer", "smb.max_trans", FT_UINT32, BASE_DEC, + NULL, 0, "Max transmit buffer size", HFILL }}, + + { &hf_max_raw_buf_size, + { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC, + NULL, 0, "Max raw buffer size", HFILL }}, + + { &hf_max_mpx_count, + { "Max Mpx", "smb.max_mpx", FT_UINT16, BASE_DEC, + NULL, 0, "Max pending multiplexed requests", HFILL }}, + + { &hf_max_vcs_num, + { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC, + NULL, 0, "Max VCs between client and server", HFILL }}, + + { &hf_rm_read, + { "Read", "smb.rm.read", FT_BOOLEAN, 16, + TFS(&tfs_rm_read), RAWMODE_READ, "Is rawmode READ supported?", HFILL }}, + + { &hf_rm_write, + { "Write", "smb.rm.write", FT_BOOLEAN, 16,+ TFS(&tfs_rm_write), RAWMODE_WRITE, "Is rawmode WRITE supported?", HFILL }},
+ + { &hf_session_key, + { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX, + NULL, 0, "Unique token identifying this session", HFILL }}, + + { &hf_current_server_date, + { "Current Date", "smb.server.current.date", FT_ABSOLUTE_TIME, BASE_NONE, + NULL, 0, "Current date and time at server", HFILL }}, + + { &hf_current_server_dos_date, + { "Current Date", "smb.server.current.dos.date", FT_UINT16, BASE_HEX, + NULL, 0, "Current date at server, DOS format", HFILL }}, + + { &hf_current_server_dos_time, + { "Current Time", "smb.server.current.dos.time", FT_UINT16, BASE_HEX, + NULL, 0, "Current time at server, DOS format", HFILL }}, + + { &hf_server_timezone, + { "Time Zone", "smb.server.timezone", FT_INT16, BASE_DEC, + NULL, 0, "Current timezone at server.", HFILL }}, + + { &hf_encryption_key_length, + { "Key Length", "smb.encryption.key.length", FT_UINT16, BASE_DEC,+ NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
+ + { &hf_reserved, + { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX, + NULL, 0, "Reserved (MUST be zero)", HFILL }}, + + { &hf_encryption_key, + { "Encryption Key", "smb.encryption.key", FT_BYTES, BASE_HEX,+ NULL, 0, "Challange/Response Encryption Key (for LM2.1 dialect)", HFILL }},
+ + { &hf_primary_domain, + { "Primary Domain", "smb.primary.domain", FT_STRING, BASE_NONE, + NULL, 0, "The Server's Primary Domain", HFILL }}, + + { &hf_oem_domain, + { "OEM Domain", "smb.oem.domain", FT_STRING, BASE_NONE,+ NULL, 0, "The Server's OEM Domain (Present only for non-extended security)", HFILL }},
+ + { &hf_server_cap_raw_mode, + { "Raw Mode", "smb.server.cap.raw_mode", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Is RAW MODE capability supported?", HFILL }},
+ + { &hf_server_cap_mpx_mode, + { "MPX Mode", "smb.server.cap.mpx_mode", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Is MPX MODE capability supported?", HFILL }},
+ + { &hf_server_cap_unicode, + { "Unicode", "smb.server.cap.unicode", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Is UNICODE capability supported?", HFILL }},
+ + { &hf_server_cap_large_files, + { "Large Files", "smb.server.cap.large_files", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Is LARGE FILES capability supported?", HFILL }},
+ + { &hf_server_cap_nt_smbs, + { "NT Smbs", "smb.server.cap.nt_smbs", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Is NT SMBS capability supported?", HFILL }},
+ + { &hf_server_cap_rpc_remote_apis, + { "RPC Remote APIs", "smb.server.cap.rpc_remote_apis", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Is RPC REMOTE APIS capability supported?", HFILL }},
+ + { &hf_server_cap_status32, + { "Status32", "smb.server.cap.status32", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_status32), SERVER_CAP_STATUS32, "Is STATUS32 capability supported?", HFILL }},
+ + { &hf_server_cap_level_ii_oplocks, + { "Level 2 Oplocks", "smb.server.cap.level_2_oplocks", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Is LEVEL II OPLOCKS capability supported?", HFILL }},
+ + { &hf_server_cap_lock_and_read, + { "Lock and Read", "smb.server.cap.lock_and_read", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is LOCK AND READ capability supported?", HFILL }},
+ + { &hf_server_cap_nt_find, + { "NT Find", "smb.server.cap.nt_find", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT FIND capability supported?", HFILL }},
+ + { &hf_server_cap_dfs, + { "DFS", "smb.server.cap.dfs", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is DFS capability supported?", HFILL }},
+ + { &hf_server_cap_infolevel_passthru,+ { "Infolevel Passthru", "smb.server.cap.infolevel_passthru", FT_BOOLEAN, 32, + TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is INFOLEVEL PASSTHRU capability supported?", HFILL }},
+ + { &hf_server_cap_large_readx, + { "Large ReadX", "smb.server.cap.large_readx", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is LARGE READX capability supported?", HFILL }},
+ + { &hf_server_cap_large_writex, + { "Large WriteX", "smb.server.cap.large_writex", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is LARGE WRITEX capability supported?", HFILL }},
+ + { &hf_server_cap_unix, + { "Unix", "smb.server.cap.unix", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Is UNIX capability supported?", HFILL }},
+ + { &hf_server_cap_reserved, + { "Reserved", "smb.server.cap.reserved", FT_BOOLEAN, 32, + TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }}, + + { &hf_server_cap_bulk_transfer, + { "Bulk Transfer", "smb.server.cap.bulk_transfer", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Is BULK TRANSFER capability supported?", HFILL }},
+ + { &hf_server_cap_compressed_data, + { "Compressed Data", "smb.server.cap.compressed_data", FT_BOOLEAN, 32,+ TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is COMPRESSED DATA capability supported?", HFILL }},
+ + { &hf_server_cap_extended_security,+ { "Extended Security", "smb.server.cap.extended_security", FT_BOOLEAN, 32, + TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Is EXTENDED SECURITY capability supported?", HFILL }},
+ + { &hf_system_time_low, + { "System Time Low", "smb.system.time.low", FT_UINT32, BASE_HEX, + NULL, 0, "Low part of system time", HFILL }}, + + { &hf_system_time_high, + { "System Time High", "smb.system.time.high", FT_UINT32, BASE_HEX, + NULL, 0, "High part of system time", HFILL }}, + + { &hf_server_guid, + { "Server GUID", "smb.server.guid", FT_BYTES, BASE_HEX, + NULL, 0, "Globally unique identifier for this server", HFILL }}, + + { &hf_security_blob, + { "Security Blob", "smb.security.blob", FT_BYTES, BASE_HEX, + NULL, 0, "Security blob", HFILL }}, + +/*xxxxx*/ }; static gint *ett[] = { &ett_smb, @@ -10916,6 +11493,7 @@ &ett_smb_capabilities, &ett_smb_aflags, &ett_smb_dialects, + &ett_smb_dialect, &ett_smb_mode, &ett_smb_rawmode, &ett_smb_flags, @@ -10928,6 +11506,9 @@ &ett_smb_action, &ett_smb_writemode, &ett_smb_lock_type, + &ett_smb_header, + &ett_smb_command, + &ett_smb_time_date, }; proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
- Follow-Ups:
- Re: [Ethereal-dev] Re: [Ethrereal-dev] packet-smb.c
- From: Guy Harris
- Re: [Ethereal-dev] Re: [Ethrereal-dev] packet-smb.c
- Prev by Date: Re: [Ethereal-dev] asn.1 compiler used???
- Next by Date: [Ethereal-dev] patch - idl2eth - CORBA IDL Union support
- Previous by thread: [Ethereal-dev] Debug dissector
- Next by thread: Re: [Ethereal-dev] Re: [Ethrereal-dev] packet-smb.c
- Index(es):