aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-smb2.c378
1 files changed, 376 insertions, 2 deletions
diff --git a/epan/dissectors/packet-smb2.c b/epan/dissectors/packet-smb2.c
index 1990427578..a265241dcb 100644
--- a/epan/dissectors/packet-smb2.c
+++ b/epan/dissectors/packet-smb2.c
@@ -43,11 +43,21 @@ static int hf_smb2_cmd = -1;
static int hf_smb2_mpxid = -1;
static int hf_smb2_tid = -1;
static int hf_smb2_flags_response = -1;
+static int hf_smb2_security_blob_len = -1;
+static int hf_smb2_security_blob = -1;
static int hf_smb2_unknown = -1;
static gint ett_smb2 = -1;
+static gint ett_smb2_command = -1;
+static gint ett_smb2_secblob = -1;
+static dissector_handle_t gssapi_handle = NULL;
+
+typedef struct _smb2_function {
+ int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+ int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+} smb2_function;
#define SMB2_FLAGS_RESPONSE 0x01
@@ -56,6 +66,63 @@ static const true_false_string tfs_flags_response = {
"This is a REQUEST"
};
+
+static int
+dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ proto_item *blob_item;
+ proto_tree *blob_tree;
+ tvbuff_t *blob_tvb;
+ guint16 sbloblen;
+
+ /* some unknown bytes */
+ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 14, FALSE);
+ offset += 14;
+
+ /* length of security blob */
+ sbloblen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb2_security_blob_len, tvb, offset, 2, sbloblen);
+ offset += 2;
+
+ /* the security blob itself */
+ blob_item = proto_tree_add_item(tree, hf_smb2_security_blob, tvb, offset, sbloblen, TRUE);
+ blob_tree = proto_item_add_subtree(blob_item, ett_smb2_secblob);
+
+ blob_tvb = tvb_new_subset(tvb, offset, sbloblen, sbloblen);
+ call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
+ offset += sbloblen;
+
+ return offset;
+}
+
+static int
+dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ proto_item *blob_item;
+ proto_tree *blob_tree;
+ tvbuff_t *blob_tvb;
+ guint16 sbloblen;
+
+ /* some unknown bytes */
+ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, FALSE);
+ offset += 6;
+
+ /* length of security blob */
+ sbloblen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb2_security_blob_len, tvb, offset, 2, sbloblen);
+ offset += 2;
+
+ /* the security blob itself */
+ blob_item = proto_tree_add_item(tree, hf_smb2_security_blob, tvb, offset, sbloblen, TRUE);
+ blob_tree = proto_item_add_subtree(blob_item, ett_smb2_secblob);
+
+ blob_tvb = tvb_new_subset(tvb, offset, sbloblen, sbloblen);
+ call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
+ offset += sbloblen;
+
+ return offset;
+}
+
/* names here are just until we find better names for these functions */
const value_string smb2_cmd_vals[] = {
{ 0x00, "NegotiateProtocol" },
@@ -321,8 +388,296 @@ static const char *decode_smb2_name(guint8 cmd)
return(smb2_cmd_vals[cmd].strptr);
}
+static smb2_function smb2_dissector[256] = {
+ /* 0x00 */ {NULL, NULL},
+ /* 0x01 SessionSetup*/
+ {dissect_smb2_session_setup_request,
+ dissect_smb2_session_setup_response},
+ /* 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 */ {NULL, NULL},
+ /* 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},
+};
+static int
+dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint8 cmd, guint8 response)
+{
+ int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+ proto_item *cmd_item;
+ proto_tree *cmd_tree;
+
+
+ cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
+ "%s %s (0x%02x)",
+ decode_smb2_name(cmd),
+ response?"Response":"Request",
+ cmd);
+ cmd_tree = proto_item_add_subtree(cmd_item, ett_smb2_command);
+
+
+ cmd_dissector=response?
+ smb2_dissector[cmd&0xff].response:
+ smb2_dissector[cmd&0xff].request;
+ if(cmd_dissector){
+ offset=(*cmd_dissector)(tvb, pinfo, cmd_tree, offset);
+ } else {
+ proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, FALSE);
+ offset=tvb_length(tvb);
+ }
+
+ return offset;
+}
static void
dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
@@ -330,7 +685,7 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
proto_item *item=NULL;
proto_tree *tree=NULL;
int offset=0;
- int cmd, response;
+ guint8 cmd, response;
if (check_col(pinfo->cinfo, COL_PROTOCOL)){
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
@@ -384,6 +739,14 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 1, FALSE);
offset += 1;
+ /* some unknown bytes */
+ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 15, FALSE);
+ offset += 15;
+
+ /* some unknown bytes */
+ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 12, FALSE);
+ offset += 12;
+
if (check_col(pinfo->cinfo, COL_INFO)){
col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
decode_smb2_name(cmd),
@@ -391,7 +754,7 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
/* Decode the payload */
- /* ... */
+ dissect_smb2_command(pinfo, tree, tvb, offset, cmd, response);
}
static gboolean
@@ -428,6 +791,14 @@ proto_register_smb2(void)
{ &hf_smb2_flags_response,
{ "Response", "smb2.flags.response", FT_BOOLEAN, 8,
TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }},
+ { &hf_smb2_security_blob_len,
+ { "Security Blob Length", "smb2.security_blob_len", FT_UINT16, BASE_DEC,
+ NULL, 0, "Security blob length", HFILL }},
+
+ { &hf_smb2_security_blob,
+ { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_HEX,
+ NULL, 0, "Security blob", HFILL }},
+
{ &hf_smb2_unknown,
{ "unknown", "smb2.unknown", FT_BYTES, BASE_HEX,
NULL, 0, "Unknown bytes", HFILL }},
@@ -435,6 +806,8 @@ proto_register_smb2(void)
static gint *ett[] = {
&ett_smb2,
+ &ett_smb2_command,
+ &ett_smb2_secblob,
};
proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
@@ -446,5 +819,6 @@ proto_register_smb2(void)
void
proto_reg_handoff_smb2(void)
{
+ gssapi_handle = find_dissector("gssapi");
heur_dissector_add("netbios", dissect_smb2_heur, proto_smb2);
}