2 * Routines for ssh packet dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copied from packet-ssh.c
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 * Note: support for SFTP.
19 /* SFTP is defined in:
21 * draft-ietf-secsh-filexfer-02 - SSH File Transfer Protocol
27 /* Start with WIRESHARK_LOG_DOMAINS=sftp and WIRESHARK_LOG_LEVEL=debug to see messages. */
28 #define WS_LOG_DOMAIN "sftp"
30 #include <epan/packet.h>
31 #include <epan/expert.h>
33 void proto_register_sftp(void);
35 static int proto_sftp
;
37 static int hf_ssh_sftp_len
;
38 static int hf_ssh_sftp_type
;
39 static int hf_ssh_sftp_version
;
40 static int hf_ssh_sftp_id
;
41 static int hf_ssh_sftp_path_len
;
42 static int hf_ssh_sftp_path
;
43 static int hf_ssh_sftp_pflags
;
44 static int hf_ssh_sftp_name_count
;
45 static int hf_ssh_sftp_name_fn_len
;
46 static int hf_ssh_sftp_name_fn
;
47 static int hf_ssh_sftp_name_ln_len
;
48 static int hf_ssh_sftp_name_ln
;
49 static int hf_ssh_sftp_attrs_flags
;
50 static int hf_ssh_sftp_attrs_size
;
51 static int hf_ssh_sftp_attrs_uid
;
52 static int hf_ssh_sftp_attrs_gid
;
53 static int hf_ssh_sftp_attrs_permissions
;
54 static int hf_ssh_sftp_attrs_atime
;
55 static int hf_ssh_sftp_attrs_mtime
;
56 static int hf_ssh_sftp_attrs_extended_count
;
57 static int hf_ssh_sftp_handle_len
;
58 static int hf_ssh_sftp_handle
;
59 static int hf_ssh_sftp_status
;
60 static int hf_ssh_sftp_error_message_len
;
61 static int hf_ssh_sftp_error_message
;
62 static int hf_ssh_sftp_offset
;
63 static int hf_ssh_sftp_length
;
64 static int hf_ssh_sftp_data_len
;
65 static int hf_ssh_sftp_data
;
66 static int hf_ssh_lang_tag_length
;
67 static int hf_ssh_lang_tag
;
70 static int ett_sftp_attrs
;
72 static dissector_handle_t sftp_handle
;
74 #define SSH_FXP_INIT 1
75 #define SSH_FXP_VERSION 2
76 #define SSH_FXP_OPEN 3
77 #define SSH_FXP_CLOSE 4
78 #define SSH_FXP_READ 5
79 #define SSH_FXP_WRITE 6
80 #define SSH_FXP_LSTAT 7
81 #define SSH_FXP_FSTAT 8
82 #define SSH_FXP_SETSTAT 9
83 #define SSH_FXP_FSETSTAT 10
84 #define SSH_FXP_OPENDIR 11
85 #define SSH_FXP_READDIR 12
86 #define SSH_FXP_REMOVE 13
87 #define SSH_FXP_MKDIR 14
88 #define SSH_FXP_RMDIR 15
89 #define SSH_FXP_REALPATH 16
90 #define SSH_FXP_STAT 17
91 #define SSH_FXP_RENAME 18
92 #define SSH_FXP_READLINK 19
93 #define SSH_FXP_LINK 21
94 #define SSH_FXP_BLOCK 22
95 #define SSH_FXP_UNBLOCK 23
97 #define SSH_FXP_STATUS 101
98 #define SSH_FXP_HANDLE 102
99 #define SSH_FXP_DATA 103
100 #define SSH_FXP_NAME 104
101 #define SSH_FXP_ATTRS 105
103 #define SSH_FXP_EXTENDED 200
104 #define SSH_FXP_EXTENDED_REPLY 201
106 #define SSH_FILEXFER_ATTR_SIZE 0x00000001
107 #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
108 #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
109 #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
110 #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
112 static const value_string ssh2_sftp_vals
[] = {
113 {SSH_FXP_INIT
, "SSH_FXP_INIT"},
114 {SSH_FXP_VERSION
, "SSH_FXP_VERSION"},
115 {SSH_FXP_OPEN
, "SSH_FXP_OPEN"},
116 {SSH_FXP_CLOSE
, "SSH_FXP_CLOSE"},
117 {SSH_FXP_READ
, "SSH_FXP_READ"},
118 {SSH_FXP_WRITE
, "SSH_FXP_WRITE"},
119 {SSH_FXP_LSTAT
, "SSH_FXP_LSTAT"},
120 {SSH_FXP_FSTAT
, "SSH_FXP_FSTAT"},
121 {SSH_FXP_SETSTAT
, "SSH_FXP_SETSTAT"},
122 {SSH_FXP_FSETSTAT
, "SSH_FXP_FSETSTAT"},
123 {SSH_FXP_OPENDIR
, "SSH_FXP_OPENDIR"},
124 {SSH_FXP_READDIR
, "SSH_FXP_READDIR"},
125 {SSH_FXP_REMOVE
, "SSH_FXP_REMOVE"},
126 {SSH_FXP_MKDIR
, "SSH_FXP_MKDIR"},
127 {SSH_FXP_RMDIR
, "SSH_FXP_RMDIR"},
128 {SSH_FXP_REALPATH
, "SSH_FXP_REALPATH"},
129 {SSH_FXP_STAT
, "SSH_FXP_STAT"},
130 {SSH_FXP_RENAME
, "SSH_FXP_RENAME"},
131 {SSH_FXP_READLINK
, "SSH_FXP_READLINK"},
132 {SSH_FXP_LINK
, "SSH_FXP_LINK"},
133 {SSH_FXP_BLOCK
, "SSH_FXP_BLOCK"},
134 {SSH_FXP_UNBLOCK
, "SSH_FXP_UNBLOCK"},
135 {SSH_FXP_STATUS
, "SSH_FXP_STATUS"},
136 {SSH_FXP_HANDLE
, "SSH_FXP_HANDLE"},
137 {SSH_FXP_DATA
, "SSH_FXP_DATA"},
138 {SSH_FXP_NAME
, "SSH_FXP_NAME"},
139 {SSH_FXP_ATTRS
, "SSH_FXP_ATTRS"},
140 {SSH_FXP_EXTENDED
, "SSH_FXP_EXTENDED"},
141 {SSH_FXP_EXTENDED_REPLY
, "SSH_FXP_EXTENDED_REPLY"},
145 static int dissect_sftp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
);
146 static int dissect_sftp_attrs(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
147 int offset
, proto_item
*msg_type_tree
);
149 static int dissect_sftp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
154 if (pinfo
->can_desegment
) {
155 if (tvb_captured_length_remaining(tvb
, offset
) < 4) {
156 pinfo
->desegment_offset
= offset
;
157 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
158 return tvb_captured_length(tvb
);
162 plen
= tvb_get_ntohl(tvb
, offset
);
163 if (pinfo
->can_desegment
) {
164 unsigned length_remaining
= tvb_captured_length_remaining(tvb
, offset
+ 4);
165 if (length_remaining
< plen
) {
166 pinfo
->desegment_offset
= offset
;
167 pinfo
->desegment_len
= plen
- length_remaining
;
168 return tvb_captured_length(tvb
);
172 wmem_strbuf_t
*title
= wmem_strbuf_new(pinfo
->pool
, "");
173 proto_item
*ti
= proto_tree_add_item(tree
, proto_sftp
, tvb
, offset
, -1, ENC_NA
);
174 proto_tree
*sftp_tree
= proto_item_add_subtree(ti
, ett_sftp
);
175 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
178 typ
= tvb_get_uint8(tvb
, offset
) ;
179 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
181 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(typ
, ssh2_sftp_vals
, "Unknown (%u)"));
184 int ver
= tvb_get_ntohl(tvb
, offset
) ;
185 wmem_strbuf_append_printf(title
, " SSH_FXP_INIT (%d) version %d", typ
, ver
);
186 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_version
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
190 case SSH_FXP_VERSION
:{
191 int ver
= tvb_get_ntohl(tvb
, offset
) ;
192 wmem_strbuf_append_printf(title
, " SSH_FXP_VERSION (%d) version %d", typ
, ver
);
193 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_version
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
198 int id
= tvb_get_ntohl(tvb
, offset
) ;
199 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
201 slen
= tvb_get_ntohl(tvb
, offset
) ;
202 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
204 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
205 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
207 // int pflags = tvb_get_ntohl(tvb, offset) ;
208 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_pflags
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
210 slen
= dissect_sftp_attrs(tvb
, pinfo
, offset
, sftp_tree
);
212 wmem_strbuf_append_printf(title
, " SSH_FXP_OPEN (%d) id=%d [%s]", typ
, id
, path
);
216 int id
= tvb_get_ntohl(tvb
, offset
) ;
217 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
219 slen
= tvb_get_ntohl(tvb
, offset
) ;
220 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
222 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
223 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
225 wmem_strbuf_append_printf(title
, " SSH_FXP_CLOSE (%d) id=%d {%s}", typ
, id
, handle
);
229 int id
= tvb_get_ntohl(tvb
, offset
) ;
230 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
232 slen
= tvb_get_ntohl(tvb
, offset
) ;
233 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
235 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
236 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
238 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_offset
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
240 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
242 wmem_strbuf_append_printf(title
, " SSH_FXP_READ (%d) id=%d {%s}", typ
, id
, handle
);
246 int id
= tvb_get_ntohl(tvb
, offset
);
247 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
249 slen
= tvb_get_ntohl(tvb
, offset
) ;
250 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
252 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
253 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
255 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_offset
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
257 int dlen
= tvb_get_ntohl(tvb
, offset
);
258 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_data_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
260 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_data
, tvb
, offset
, dlen
, ENC_NA
);
262 wmem_strbuf_append_printf(title
, " SSH_FXP_WRITE (%d) id=%d {%s} len=%d", typ
, id
, handle
, dlen
);
266 int id
= tvb_get_ntohl(tvb
, offset
);
267 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
269 slen
= tvb_get_ntohl(tvb
, offset
) ;
270 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
272 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
273 wmem_strbuf_append_printf(title
, " SSH_FXP_LSTAT (%d) id=%d [%s]", typ
, id
, path
);
274 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
279 int id
= tvb_get_ntohl(tvb
, offset
);
280 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
282 slen
= tvb_get_ntohl(tvb
, offset
) ;
283 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
285 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
286 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
288 wmem_strbuf_append_printf(title
, " SSH_FXP_FSTAT (%d) id=%d {%s}", typ
, id
, handle
);
291 case SSH_FXP_SETSTAT
:{
292 int id
= tvb_get_ntohl(tvb
, offset
);
293 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
295 slen
= tvb_get_ntohl(tvb
, offset
) ;
296 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
298 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
299 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
301 slen
= dissect_sftp_attrs(tvb
, pinfo
, offset
, sftp_tree
);
302 proto_item_set_len(sftp_tree
, slen
);
304 wmem_strbuf_append_printf(title
, " SSH_FXP_SETSTAT (%d) id=%d [%s]", typ
, id
, path
);
307 // case SSH_FXP_FSETSTAT):{
310 case SSH_FXP_OPENDIR
:{
311 int id
= tvb_get_ntohl(tvb
, offset
);
312 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
314 slen
= tvb_get_ntohl(tvb
, offset
) ;
315 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
317 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
318 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
320 wmem_strbuf_append_printf(title
, " SSH_FXP_OPENDIR (%d) id=%d [%s]", typ
, id
, path
);
323 case SSH_FXP_READDIR
:{
324 int id
= tvb_get_ntohl(tvb
, offset
);
325 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
327 slen
= tvb_get_ntohl(tvb
, offset
) ;
328 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
330 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
331 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
333 wmem_strbuf_append_printf(title
, " SSH_FXP_READDIR (%d) id=%d {%s}", typ
, id
, handle
);
336 case SSH_FXP_REMOVE
:{
337 int id
= tvb_get_ntohl(tvb
, offset
);
338 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
340 slen
= tvb_get_ntohl(tvb
, offset
) ;
341 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
343 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
344 wmem_strbuf_append_printf(title
, " SSH_FXP_REMOVE (%d) id=%d [%s]", typ
, id
, path
);
345 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
349 // case SSH_FXP_MKDIR:{
352 // case SSH_FXP_RMDIR:{
355 case SSH_FXP_REALPATH
:{
356 int id
= tvb_get_ntohl(tvb
, offset
);
357 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
359 slen
= tvb_get_ntohl(tvb
, offset
);
360 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
362 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
363 wmem_strbuf_append_printf(title
, " SSH_FXP_REALPATH (%d) id=%d [%s]", typ
, id
, path
);
364 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
369 int id
= tvb_get_ntohl(tvb
, offset
);
370 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
372 slen
= tvb_get_ntohl(tvb
, offset
) ;
373 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
375 uint8_t * path
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
376 wmem_strbuf_append_printf(title
, " SSH_FXP_STAT (%d) id=%d [%s]", typ
, id
, path
);
377 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
381 case SSH_FXP_RENAME
:{
382 int id
= tvb_get_ntohl(tvb
, offset
);
383 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
385 slen
= tvb_get_ntohl(tvb
, offset
) ;
386 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
388 uint8_t * oldpath
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
389 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
391 slen
= tvb_get_ntohl(tvb
, offset
) ;
392 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
394 uint8_t * newpath
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
395 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_path
, tvb
, offset
, slen
, ENC_UTF_8
);
397 wmem_strbuf_append_printf(title
, " SSH_FXP_STAT (%d) id=%d [%s] > [%s]", typ
, id
, oldpath
, newpath
);
400 // case SSH_FXP_READLINK:{
403 // case SSH_FXP_SYMLINK:{
406 case SSH_FXP_STATUS
:{
407 int id
= tvb_get_ntohl(tvb
, offset
) ;
408 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
410 int code
= tvb_get_ntohl(tvb
, offset
) ;
411 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_status
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
413 slen
= tvb_get_ntohl(tvb
, offset
) ;
414 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_error_message_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
416 uint8_t * err_msg
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, slen
, ENC_UTF_8
);
417 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_error_message
, tvb
, offset
, slen
, ENC_UTF_8
);
419 slen
= tvb_get_ntohl(tvb
, offset
) ;
420 proto_tree_add_item(sftp_tree
, hf_ssh_lang_tag_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
422 proto_tree_add_item(sftp_tree
, hf_ssh_lang_tag
, tvb
, offset
, slen
, ENC_UTF_8
);
424 wmem_strbuf_append_printf(title
, " SSH_FXP_STATUS (%d) id=%d code=%d [%s]", typ
, id
, code
, err_msg
);
427 case SSH_FXP_HANDLE
:{
428 int id
= tvb_get_ntohl(tvb
, offset
);
429 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
431 slen
= tvb_get_ntohl(tvb
, offset
) ;
432 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
434 char * handle
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, slen
);
435 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_handle
, tvb
, offset
, slen
, ENC_NA
);
437 wmem_strbuf_append_printf(title
, " SSH_FXP_HANDLE (%d) id=%d {%s}", typ
, id
, handle
);
441 int id
= tvb_get_ntohl(tvb
, offset
) ;
442 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
444 int dlen
= tvb_get_ntohl(tvb
, offset
) ;
445 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_data_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
447 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_data
, tvb
, offset
, dlen
, ENC_NA
);
449 wmem_strbuf_append_printf(title
, " SSH_FXP_DATA (%d) id=%d len=%d", typ
, id
, dlen
);
453 wmem_strbuf_append_printf(title
, " SSH_FXP_NAME (%d)", typ
);
454 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
456 unsigned count
= tvb_get_ntohl(tvb
, offset
) ;
457 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_name_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
460 for(cnt
=0;cnt
<count
;cnt
++){
461 slen
= tvb_get_ntohl(tvb
, offset
) ;
462 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_name_fn_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
464 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_name_fn
, tvb
, offset
, slen
, ENC_UTF_8
);
466 slen
= tvb_get_ntohl(tvb
, offset
) ;
467 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_name_ln_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
469 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_name_ln
, tvb
, offset
, slen
, ENC_UTF_8
);
471 slen
= dissect_sftp_attrs(tvb
, pinfo
, offset
, sftp_tree
);
477 int id
= tvb_get_ntohl(tvb
, offset
);
478 wmem_strbuf_append_printf(title
, " SSH_FXP_ATTRS (%d) id=%d", typ
, id
);
479 proto_tree_add_item(sftp_tree
, hf_ssh_sftp_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
481 slen
= dissect_sftp_attrs(tvb
, pinfo
, offset
, sftp_tree
);
482 proto_item_set_len(sftp_tree
, slen
);
486 // case SSH_FXP_EXTENDED:{
489 // case SSH_FXP_EXTENDED_REPLY:{
493 wmem_strbuf_append_printf(title
, " unknown (%d)", typ
);
498 proto_item_append_text(ti
, ",%s", wmem_strbuf_get_str(title
));
499 proto_item_set_len(sftp_tree
, plen
+4);
503 static int dissect_sftp_attrs(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
504 int offset
, proto_item
*msg_type_tree
)
506 wmem_strbuf_t
*title
= wmem_strbuf_new(pinfo
->pool
, "SFTP attributes");
507 proto_item
* sftp_attrs_tree
= proto_tree_add_subtree(msg_type_tree
, packet_tvb
, offset
, -1, ett_sftp_attrs
, NULL
, NULL
);
509 int offset0
= offset
;
510 unsigned flags
= tvb_get_ntohl(packet_tvb
, offset
) ;
511 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_flags
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
513 if(flags
& SSH_FILEXFER_ATTR_SIZE
){
514 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_size
, packet_tvb
, offset
, 8, ENC_BIG_ENDIAN
);
517 if(flags
& SSH_FILEXFER_ATTR_UIDGID
){
518 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_uid
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
521 if(flags
& SSH_FILEXFER_ATTR_UIDGID
){
522 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_gid
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
525 if(flags
& SSH_FILEXFER_ATTR_PERMISSIONS
){
526 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_permissions
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
529 if(flags
& SSH_FILEXFER_ATTR_ACMODTIME
){
530 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_atime
, packet_tvb
, offset
, 4, ENC_TIME_SECS
);
533 if(flags
& SSH_FILEXFER_ATTR_ACMODTIME
){
534 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_mtime
, packet_tvb
, offset
, 4, ENC_TIME_SECS
);
537 if(flags
& SSH_FILEXFER_ATTR_EXTENDED
){
538 proto_tree_add_item(sftp_attrs_tree
, hf_ssh_sftp_attrs_extended_count
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
542 proto_item_set_text(sftp_attrs_tree
, "%s", wmem_strbuf_get_str(title
));
543 proto_item_set_len(sftp_attrs_tree
, offset
- offset0
);
545 return offset
- offset0
;
549 proto_register_sftp(void)
551 static hf_register_info hf
[] = {
553 { "SFTP packet length", "sftp.packet_length",
554 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
558 { "SFTP packet type", "sftp.packet_type",
559 FT_UINT8
, BASE_DEC
, VALS(ssh2_sftp_vals
), 0x0,
562 { &hf_ssh_sftp_version
,
563 { "SFTP version", "sftp.version",
564 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
568 { "SFTP id", "sftp.id",
569 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
572 { &hf_ssh_sftp_path_len
,
573 { "SFTP path length", "sftp.path_len",
574 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
578 { "SFTP path", "sftp.path",
579 FT_STRING
, BASE_NONE
, NULL
, 0x0,
582 { &hf_ssh_sftp_pflags
,
583 { "SFTP pflags", "sftp.pflags",
584 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
587 { &hf_ssh_sftp_name_count
,
588 { "SFTP count", "sftp.name_count",
589 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
592 { &hf_ssh_sftp_name_fn_len
,
593 { "SFTP name file name length", "sftp.name_fn_len",
594 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
597 { &hf_ssh_sftp_name_fn
,
598 { "SFTP name file name", "sftp.name_fn",
599 FT_STRING
, BASE_NONE
, NULL
, 0x0,
602 { &hf_ssh_sftp_name_ln_len
,
603 { "SFTP name long name length", "sftp.name_ln_len",
604 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
607 { &hf_ssh_sftp_name_ln
,
608 { "SFTP name long name", "sftp.name_ln",
609 FT_STRING
, BASE_NONE
, NULL
, 0x0,
612 { &hf_ssh_sftp_attrs_flags
,
613 { "SFTP attributes flags", "sftp.attrs.flags",
614 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
617 { &hf_ssh_sftp_attrs_size
,
618 { "SFTP attributes file size", "sftp.attrs.size",
619 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
622 { &hf_ssh_sftp_attrs_uid
,
623 { "SFTP attributes uid", "sftp.attrs.uid",
624 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
627 { &hf_ssh_sftp_attrs_gid
,
628 { "SFTP attributes gid", "sftp.attrs.gid",
629 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
632 { &hf_ssh_sftp_attrs_permissions
,
633 { "SFTP attributes permissions", "sftp.attrs.permissions",
634 FT_UINT32
, BASE_OCT
, NULL
, 0x0,
637 { &hf_ssh_sftp_attrs_atime
,
638 { "SFTP attributes access time", "sftp.attrs.atime",
639 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
642 { &hf_ssh_sftp_attrs_mtime
,
643 { "SFTP attributes modification time", "sftp.attrs.mtime",
644 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
647 { &hf_ssh_sftp_attrs_extended_count
,
648 { "SFTP attributes extended count", "sftp.attrs.extended_count",
649 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
652 { &hf_ssh_sftp_offset
,
653 { "SFTP offset", "sftp.offset",
654 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
657 { &hf_ssh_sftp_length
,
658 { "SFTP length", "sftp.length",
659 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
662 { &hf_ssh_sftp_handle_len
,
663 { "SFTP handle length", "sftp.handle_len",
664 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
667 { &hf_ssh_sftp_handle
,
668 { "SFTP handle", "sftp.handle",
669 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
672 { &hf_ssh_sftp_status
,
673 { "SFTP error/status code", "sftp.status",
674 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
677 { &hf_ssh_sftp_error_message_len
,
678 { "SFTP error message length", "sftp.error_message_len",
679 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
682 { &hf_ssh_sftp_error_message
,
683 { "SFTP error message", "sftp.error_message",
684 FT_STRING
, BASE_NONE
, NULL
, 0x0,
687 { &hf_ssh_sftp_data_len
,
688 { "SFTP data length", "sftp.data_len",
689 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
693 { "SFTP data", "sftp.data",
694 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
697 { &hf_ssh_lang_tag_length
,
698 { "Language tag length", "sftp.lang_tag_length",
699 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
703 { "Language tag", "sftp.lang_tag",
704 FT_STRING
, BASE_NONE
, NULL
, 0x0,
709 static int *ett
[] = {
714 proto_sftp
= proto_register_protocol("SSH File Transfer Protocol", "SFTP", "sftp");
715 proto_register_field_array(proto_sftp
, hf
, array_length(hf
));
716 proto_register_subtree_array(ett
, array_length(ett
));
718 sftp_handle
= register_dissector("sftp", dissect_sftp
, proto_sftp
);