diff options
-rw-r--r-- | epan/dissectors/packet-smb2.c | 378 |
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); } |