aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-sftp.c
diff options
context:
space:
mode:
authorJerome-PS <jerome.hamm@planete-sciences.org>2022-01-18 13:09:06 +0000
committerA Wireshark GitLab Utility <6629907-ws-gitlab-utility@users.noreply.gitlab.com>2022-01-18 13:09:06 +0000
commit269e662442ec6262af7a60469774dff98a13c25d (patch)
tree3880c8d5f413c2cdd474efa9ba675d7b5a5c5a42 /epan/dissectors/packet-sftp.c
parentca61ee833ac886345ae5e6f4c239da7eae72f027 (diff)
Adding dissection for subsystem sftp.
Diffstat (limited to 'epan/dissectors/packet-sftp.c')
-rw-r--r--epan/dissectors/packet-sftp.c705
1 files changed, 705 insertions, 0 deletions
diff --git a/epan/dissectors/packet-sftp.c b/epan/dissectors/packet-sftp.c
new file mode 100644
index 0000000000..89e5da203e
--- /dev/null
+++ b/epan/dissectors/packet-sftp.c
@@ -0,0 +1,705 @@
+/* packet-sftp.c
+ * Routines for ssh packet dissection
+ *
+ * Jérôme Hamm
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from packet-ssh.c
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ *
+ * Note: support for SFTP.
+ *
+ */
+
+/* SFTP is defined in:
+ *
+ * draft-ietf-secsh-filexfer-02 - SSH File Transfer Protocol
+ *
+ */
+
+#include "config.h"
+
+/* Start with G_MESSAGES_DEBUG=sftp to see messages. */
+#define G_LOG_DOMAIN "sftp"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+
+void proto_register_sftp(void);
+
+static int proto_sftp = -1;
+
+static int hf_ssh_sftp_len = -1;
+static int hf_ssh_sftp_type = -1;
+static int hf_ssh_sftp_version = -1;
+static int hf_ssh_sftp_id = -1;
+static int hf_ssh_sftp_path_len = -1;
+static int hf_ssh_sftp_path = -1;
+static int hf_ssh_sftp_pflags = -1;
+static int hf_ssh_sftp_name_count = -1;
+static int hf_ssh_sftp_name_fn_len = -1;
+static int hf_ssh_sftp_name_fn = -1;
+static int hf_ssh_sftp_name_ln_len = -1;
+static int hf_ssh_sftp_name_ln = -1;
+static int hf_ssh_sftp_attrs_flags = -1;
+static int hf_ssh_sftp_attrs_size = -1;
+static int hf_ssh_sftp_attrs_uid = -1;
+static int hf_ssh_sftp_attrs_gid = -1;
+static int hf_ssh_sftp_attrs_permissions = -1;
+static int hf_ssh_sftp_attrs_atime = -1;
+static int hf_ssh_sftp_attrs_mtime = -1;
+static int hf_ssh_sftp_attrs_extended_count = -1;
+static int hf_ssh_sftp_handle_len = -1;
+static int hf_ssh_sftp_handle = -1;
+static int hf_ssh_sftp_status = -1;
+static int hf_ssh_sftp_error_message_len = -1;
+static int hf_ssh_sftp_error_message = -1;
+static int hf_ssh_sftp_offset = -1;
+static int hf_ssh_sftp_length = -1;
+static int hf_ssh_sftp_data_len = -1;
+static int hf_ssh_sftp_data = -1;
+static int hf_ssh_lang_tag_length = -1;
+static int hf_ssh_lang_tag = -1;
+
+static gint ett_sftp = -1;
+static gint ett_sftp_attrs = -1;
+
+static dissector_handle_t sftp_handle;
+
+#define SSH_FXP_INIT 1
+#define SSH_FXP_VERSION 2
+#define SSH_FXP_OPEN 3
+#define SSH_FXP_CLOSE 4
+#define SSH_FXP_READ 5
+#define SSH_FXP_WRITE 6
+#define SSH_FXP_LSTAT 7
+#define SSH_FXP_FSTAT 8
+#define SSH_FXP_SETSTAT 9
+#define SSH_FXP_FSETSTAT 10
+#define SSH_FXP_OPENDIR 11
+#define SSH_FXP_READDIR 12
+#define SSH_FXP_REMOVE 13
+#define SSH_FXP_MKDIR 14
+#define SSH_FXP_RMDIR 15
+#define SSH_FXP_REALPATH 16
+#define SSH_FXP_STAT 17
+#define SSH_FXP_RENAME 18
+#define SSH_FXP_READLINK 19
+#define SSH_FXP_LINK 21
+#define SSH_FXP_BLOCK 22
+#define SSH_FXP_UNBLOCK 23
+
+#define SSH_FXP_STATUS 101
+#define SSH_FXP_HANDLE 102
+#define SSH_FXP_DATA 103
+#define SSH_FXP_NAME 104
+#define SSH_FXP_ATTRS 105
+
+#define SSH_FXP_EXTENDED 200
+#define SSH_FXP_EXTENDED_REPLY 201
+
+#define SSH_FILEXFER_ATTR_SIZE 0x00000001
+#define SSH_FILEXFER_ATTR_UIDGID 0x00000002
+#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
+#define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
+#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
+
+static const value_string ssh2_sftp_vals[] = {
+ {SSH_FXP_INIT, "SSH_FXP_INIT"},
+ {SSH_FXP_VERSION, "SSH_FXP_VERSION"},
+ {SSH_FXP_OPEN, "SSH_FXP_OPEN"},
+ {SSH_FXP_CLOSE, "SSH_FXP_CLOSE"},
+ {SSH_FXP_READ, "SSH_FXP_READ"},
+ {SSH_FXP_WRITE, "SSH_FXP_WRITE"},
+ {SSH_FXP_LSTAT, "SSH_FXP_LSTAT"},
+ {SSH_FXP_FSTAT, "SSH_FXP_FSTAT"},
+ {SSH_FXP_SETSTAT, "SSH_FXP_SETSTAT"},
+ {SSH_FXP_FSETSTAT, "SSH_FXP_FSETSTAT"},
+ {SSH_FXP_OPENDIR, "SSH_FXP_OPENDIR"},
+ {SSH_FXP_READDIR, "SSH_FXP_READDIR"},
+ {SSH_FXP_REMOVE, "SSH_FXP_REMOVE"},
+ {SSH_FXP_MKDIR, "SSH_FXP_MKDIR"},
+ {SSH_FXP_RMDIR, "SSH_FXP_RMDIR"},
+ {SSH_FXP_REALPATH, "SSH_FXP_REALPATH"},
+ {SSH_FXP_STAT, "SSH_FXP_STAT"},
+ {SSH_FXP_RENAME, "SSH_FXP_RENAME"},
+ {SSH_FXP_READLINK, "SSH_FXP_READLINK"},
+ {SSH_FXP_LINK, "SSH_FXP_LINK"},
+ {SSH_FXP_BLOCK, "SSH_FXP_BLOCK"},
+ {SSH_FXP_UNBLOCK, "SSH_FXP_UNBLOCK"},
+ {SSH_FXP_STATUS, "SSH_FXP_STATUS"},
+ {SSH_FXP_HANDLE, "SSH_FXP_HANDLE"},
+ {SSH_FXP_DATA, "SSH_FXP_DATA"},
+ {SSH_FXP_NAME, "SSH_FXP_NAME"},
+ {SSH_FXP_ATTRS, "SSH_FXP_ATTRS"},
+ {SSH_FXP_EXTENDED, "SSH_FXP_EXTENDED"},
+ {SSH_FXP_EXTENDED_REPLY, "SSH_FXP_EXTENDED_REPLY"},
+ {0, NULL}
+};
+
+static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
+static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo,
+ int offset, proto_item *msg_type_tree);
+
+//static int dissect_sftp(tvbuff_t *packet_tvb, packet_info *pinfo,
+// int offset, proto_item *msg_type_tree)
+static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
+ guint plen;
+ guint slen;
+ plen = tvb_get_ntohl(tvb, offset) ;
+ wmem_strbuf_t *title = wmem_strbuf_new(wmem_packet_scope(), "SFTP");
+ proto_item * sftp_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_sftp, NULL, NULL);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 typ;
+ typ = tvb_get_guint8(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(typ, ssh2_sftp_vals, "Unknown (%u)"));
+ switch(typ){
+ case SSH_FXP_INIT:{
+ int ver = tvb_get_ntohl(tvb, offset) ;
+ wmem_strbuf_append_printf(title, " SSH_FXP_INIT (%d) version %d", typ, ver);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ }
+ case SSH_FXP_VERSION:{
+ int ver = tvb_get_ntohl(tvb, offset) ;
+ wmem_strbuf_append_printf(title, " SSH_FXP_VERSION (%d) version %d", typ, ver);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ }
+ case SSH_FXP_OPEN:{
+ int id = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+// int pflags = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_pflags, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_OPEN (%d) id=%d [%s]", typ, id, path);
+ break;
+ }
+ case SSH_FXP_CLOSE:{
+ int id = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_CLOSE (%d) id=%d {%s}", typ, id, handle);
+ break;
+ }
+ case SSH_FXP_READ:{
+ int id = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_length, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ wmem_strbuf_append_printf(title, " SSH_FXP_READ (%d) id=%d {%s}", typ, id, handle);
+ break;
+ }
+ case SSH_FXP_WRITE:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ int dlen = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA);
+ offset += dlen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_WRITE (%d) id=%d {%s} len=%d", typ, id, handle, dlen);
+ break;
+ }
+ case SSH_FXP_LSTAT:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ wmem_strbuf_append_printf(title, " SSH_FXP_LSTAT (%d) id=%d [%s]", typ, id, path);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ break;
+ }
+ case SSH_FXP_FSTAT:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_FSTAT (%d) id=%d {%s}", typ, id, handle);
+ break;
+ }
+ case SSH_FXP_SETSTAT:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
+ proto_item_set_len(sftp_tree, slen);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_SETSTAT (%d) id=%d [%s]", typ, id, path);
+ break;
+ }
+// case SSH_FXP_FSETSTAT):{
+// break;
+// }
+ case SSH_FXP_OPENDIR:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_OPENDIR (%d) id=%d [%s]", typ, id, path);
+ break;
+ }
+ case SSH_FXP_READDIR:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_READDIR (%d) id=%d {%s}", typ, id, handle);
+ break;
+ }
+ case SSH_FXP_REMOVE:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ wmem_strbuf_append_printf(title, " SSH_FXP_REMOVE (%d) id=%d [%s]", typ, id, path);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ break;
+ }
+// case SSH_FXP_MKDIR:{
+// break;
+// }
+// case SSH_FXP_RMDIR:{
+// break;
+// }
+ case SSH_FXP_REALPATH:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ wmem_strbuf_append_printf(title, " SSH_FXP_REALPATH (%d) id=%d [%s]", typ, id, path);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ break;
+ }
+ case SSH_FXP_STAT:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s]", typ, id, path);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ break;
+ }
+ case SSH_FXP_RENAME:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * oldpath = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * newpath = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s] > [%s]", typ, id, oldpath, newpath);
+ break;
+ }
+// case SSH_FXP_READLINK:{
+// break;
+// }
+// case SSH_FXP_SYMLINK:{
+// break;
+// }
+ case SSH_FXP_STATUS:{
+ int id = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ int code = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_status, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint8 * err_msg = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_lang_tag_length, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(sftp_tree, hf_ssh_lang_tag, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_STATUS (%d) id=%d code=%d [%s]", typ, id, code, err_msg);
+ break;
+ }
+ case SSH_FXP_HANDLE:{
+ int id = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
+ offset += slen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_HANDLE (%d) id=%d {%s}", typ, id, handle);
+ break;
+ }
+ case SSH_FXP_DATA:{
+ int id = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ int dlen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA);
+ offset += dlen;
+ wmem_strbuf_append_printf(title, " SSH_FXP_DATA (%d) id=%d len=%d", typ, id, dlen);
+ break;
+ }
+ case SSH_FXP_NAME:{
+ wmem_strbuf_append_printf(title, " SSH_FXP_NAME (%d)", typ);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint count = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_count, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ guint cnt;
+ for(cnt=0;cnt<count;cnt++){
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ slen = tvb_get_ntohl(tvb, offset) ;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln, tvb, offset, slen, ENC_UTF_8);
+ offset += slen;
+ slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
+ offset += slen;
+ }
+ break;
+ }
+ case SSH_FXP_ATTRS:{
+ int id = tvb_get_ntohl(tvb, offset);
+ wmem_strbuf_append_printf(title, " SSH_FXP_ATTRS (%d) id=%d", typ, id);
+ proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
+ proto_item_set_len(sftp_tree, slen);
+ offset += slen;
+ break;
+ }
+// case SSH_FXP_EXTENDED:{
+// break;
+// }
+// case SSH_FXP_EXTENDED_REPLY:{
+// break;
+// }
+ default:{
+ wmem_strbuf_append_printf(title, " unknown (%d)", typ);
+ offset += plen;
+ break;
+ }
+ }
+ proto_item_set_text(sftp_tree, "%s", wmem_strbuf_get_str(title));
+ proto_item_set_len(sftp_tree, plen+4);
+ return offset;
+}
+
+static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo,
+ int offset, proto_item *msg_type_tree)
+{
+ wmem_strbuf_t *title = wmem_strbuf_new(wmem_packet_scope(), "SFTP attributes");
+ proto_item * sftp_attrs_tree = proto_tree_add_subtree(msg_type_tree, packet_tvb, offset, -1, ett_sftp_attrs, NULL, NULL);
+
+ int offset0 = offset;
+ guint flags = tvb_get_ntohl(packet_tvb, offset) ;
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_flags, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ if(flags & SSH_FILEXFER_ATTR_SIZE){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_size, packet_tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+ if(flags & SSH_FILEXFER_ATTR_UIDGID){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_uid, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ if(flags & SSH_FILEXFER_ATTR_UIDGID){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_gid, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ if(flags & SSH_FILEXFER_ATTR_PERMISSIONS){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_permissions, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ if(flags & SSH_FILEXFER_ATTR_ACMODTIME){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_atime, packet_tvb, offset, 4, ENC_TIME_SECS);
+ offset += 4;
+ }
+ if(flags & SSH_FILEXFER_ATTR_ACMODTIME){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_mtime, packet_tvb, offset, 4, ENC_TIME_SECS);
+ offset += 4;
+ }
+ if(flags & SSH_FILEXFER_ATTR_EXTENDED){
+ proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_extended_count, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ proto_item_set_text(sftp_attrs_tree, "%s", wmem_strbuf_get_str(title));
+ proto_item_set_len(sftp_attrs_tree, offset - offset0);
+
+ return offset - offset0;
+
+(void)pinfo;
+}
+
+void
+proto_register_sftp(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_ssh_sftp_len,
+ { "SFTP packet length", "sftp.packet_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_type,
+ { "SFTP packet type", "sftp.packet_type",
+ FT_UINT8, BASE_DEC, VALS(ssh2_sftp_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_version,
+ { "SFTP version", "sftp.version",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_id,
+ { "SFTP id", "sftp.id",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_path_len,
+ { "SFTP path length", "sftp.path_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_path,
+ { "SFTP path", "sftp.path",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_pflags,
+ { "SFTP pflags", "sftp.pflags",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_name_count,
+ { "SFTP count", "sftp.name_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_name_fn_len,
+ { "SFTP name file name length", "sftp.name_fn_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_name_fn,
+ { "SFTP name file name", "sftp.name_fn",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_name_ln_len,
+ { "SFTP name long name length", "sftp.name_ln_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_name_ln,
+ { "SFTP name long name", "sftp.name_ln",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_flags,
+ { "SFTP attributes flags", "sftp.attrs.flags",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_size,
+ { "SFTP attributes file size", "sftp.attrs.size",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_uid,
+ { "SFTP attributes uid", "sftp.attrs.uid",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_gid,
+ { "SFTP attributes gid", "sftp.attrs.gid",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_permissions,
+ { "SFTP attributes permissions", "sftp.attrs.permissions",
+ FT_UINT32, BASE_OCT, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_atime,
+ { "SFTP attributes access time", "sftp.attrs.atime",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_mtime,
+ { "SFTP attributes modification time", "sftp.attrs.mtime",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_attrs_extended_count,
+ { "SFTP attributes extended count", "sftp.attrs.extended_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_offset,
+ { "SFTP offset", "sftp.offset",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_length,
+ { "SFTP length", "sftp.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_handle_len,
+ { "SFTP handle length", "sftp.handle_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_handle,
+ { "SFTP handle", "sftp.handle",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_status,
+ { "SFTP error/status code", "sftp.status",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_error_message_len,
+ { "SFTP error message length", "sftp.error_message_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_error_message,
+ { "SFTP error message", "sftp.error_message",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_data_len,
+ { "SFTP data length", "sftp.data_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_sftp_data,
+ { "SFTP data", "sftp.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_lang_tag_length,
+ { "Language tag length", "sftp.lang_tag_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_lang_tag,
+ { "Language tag", "sftp.lang_tag",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static gint *ett[] = {
+ &ett_sftp,
+ &ett_sftp_attrs,
+ };
+
+ proto_sftp = proto_register_protocol("SFTP Protocol", "SFTP", "sftp");
+ proto_register_field_array(proto_sftp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ sftp_handle = register_dissector("sftp", dissect_sftp, proto_sftp);
+}