Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-pvfs2.c
Line
Count
Source
1
/* packet-pvfs2.c
2
 * Routines for pvfs2 packet dissection
3
 * By Mike Frisch <mfrisch@platform.com>
4
 * Joint and Several Copyright 2005, Mike Frisch and Platform Computing Inc.
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * Dissector for Parallel Virtual File System (PVFS) version 2.
11
 * https://web.archive.org/web/20160701052501/http://www.pvfs.org/
12
 *
13
 * Copied from packet-smb.c and others
14
 *
15
 * TODO
16
 *
17
 *    - Add filename snooping (match file handles with file names),
18
 *      similar to how packet-rpc.c/packet-nfs.c implements it
19
 *
20
 * SPDX-License-Identifier: GPL-2.0-or-later
21
 */
22
23
#include "config.h"
24
25
26
#include <epan/packet.h>
27
#include <epan/exceptions.h>
28
#include <epan/prefs.h>
29
#include <epan/strutil.h>
30
#include <epan/expert.h>
31
#include <epan/charsets.h>
32
#include <wsutil/ws_roundup.h>
33
#include "packet-tcp.h"
34
35
16
#define TCP_PORT_PVFS2 3334 /* Not IANA registered */
36
37
0
#define PVFS2_FH_LENGTH 8
38
39
/* Header incl. magic number, mode, tag, size */
40
0
#define BMI_HEADER_SIZE 24
41
42
/* desegmentation of PVFS over TCP */
43
static bool pvfs_desegment = true;
44
45
/* Forward declaration we need below */
46
void proto_register_pvfs(void);
47
void proto_reg_handoff_pvfs(void);
48
49
static dissector_handle_t pvfs_handle;
50
51
/* Initialize the protocol and registered fields */
52
static int proto_pvfs;
53
static int hf_pvfs_magic_nr;
54
static int hf_pvfs_uid;
55
static int hf_pvfs_gid;
56
static int hf_pvfs_mode;
57
static int hf_pvfs_tag;
58
static int hf_pvfs_size;
59
static int hf_pvfs_release_number;
60
static int hf_pvfs_encoding;
61
static int hf_pvfs_server_op;
62
/* static int hf_pvfs_handle; */
63
static int hf_pvfs_fs_id;
64
static int hf_pvfs_attrmask;
65
static int hf_pvfs_attr;
66
static int hf_pvfs_ds_type;
67
static int hf_pvfs_error;
68
static int hf_pvfs_atime;
69
static int hf_pvfs_atime_sec;
70
static int hf_pvfs_atime_nsec;
71
static int hf_pvfs_mtime;
72
static int hf_pvfs_mtime_sec;
73
static int hf_pvfs_mtime_nsec;
74
static int hf_pvfs_ctime;
75
static int hf_pvfs_ctime_sec;
76
static int hf_pvfs_ctime_nsec;
77
static int hf_pvfs_parent_atime;
78
static int hf_pvfs_parent_atime_sec;
79
static int hf_pvfs_parent_atime_nsec;
80
static int hf_pvfs_parent_mtime;
81
static int hf_pvfs_parent_mtime_sec;
82
static int hf_pvfs_parent_mtime_nsec;
83
static int hf_pvfs_parent_ctime;
84
static int hf_pvfs_parent_ctime_sec;
85
static int hf_pvfs_parent_ctime_nsec;
86
static int hf_pvfs_distribution;
87
static int hf_pvfs_dfile_count;
88
static int hf_pvfs_dirent_count;
89
static int hf_pvfs_directory_version;
90
static int hf_pvfs_path;
91
static int hf_pvfs_total_completed;
92
static int hf_pvfs_io_dist;
93
static int hf_pvfs_aggregate_size;
94
static int hf_pvfs_io_type;
95
static int hf_pvfs_flowproto_type;
96
static int hf_pvfs_server_param;
97
static int hf_pvfs_prev_value;
98
/* static int hf_pvfs_ram_free_bytes; */
99
static int hf_pvfs_bytes_available;
100
static int hf_pvfs_bytes_total;
101
static int hf_pvfs_ram_bytes_total;
102
static int hf_pvfs_ram_bytes_free;
103
static int hf_pvfs_load_average_1s;
104
static int hf_pvfs_load_average_5s;
105
static int hf_pvfs_load_average_15s;
106
static int hf_pvfs_uptime_seconds;
107
static int hf_pvfs_handles_available;
108
static int hf_pvfs_handles_total;
109
static int hf_pvfs_unused;
110
static int hf_pvfs_context_id;
111
static int hf_pvfs_offset;
112
static int hf_pvfs_stride;
113
static int hf_pvfs_lb;
114
static int hf_pvfs_ub;
115
static int hf_pvfs_end_time_ms;
116
static int hf_pvfs_cur_time_ms;
117
static int hf_pvfs_start_time_ms;
118
static int hf_pvfs_bytes_written;
119
static int hf_pvfs_bytes_read;
120
static int hf_pvfs_metadata_write;
121
static int hf_pvfs_metadata_read;
122
static int hf_pvfs_b_size;
123
static int hf_pvfs_k_size;
124
static int hf_pvfs_id_gen_t;
125
static int hf_pvfs_attribute_key;
126
static int hf_pvfs_attribute_value;
127
static int hf_pvfs_strip_size;
128
static int hf_pvfs_ereg;
129
static int hf_pvfs_sreg;
130
static int hf_pvfs_num_eregs;
131
static int hf_pvfs_num_blocks;
132
static int hf_pvfs_num_contig_chunks;
133
static int hf_pvfs_server_nr;
134
static int hf_pvfs_server_count;
135
static int hf_pvfs_fh_length;
136
static int hf_pvfs_fh_hash;
137
static int hf_pvfs_permissions;
138
static int hf_pvfs_server_mode;
139
static int hf_pvfs_depth;
140
static int hf_pvfs_num_nested_req;
141
static int hf_pvfs_committed;
142
static int hf_pvfs_refcount;
143
static int hf_pvfs_numreq;
144
static int hf_pvfs_truncate_request_flags;
145
static int hf_pvfs_ds_position;
146
static int hf_pvfs_dirent_limit;
147
static int hf_pvfs_flush_request_flags;
148
static int hf_pvfs_next_id;
149
static int hf_pvfs_mgmt_perf_mon_request_count;
150
static int hf_pvfs_mgmt_perf_mon_request_event_count;
151
static int hf_pvfs_lookup_path_response_handle_count;
152
static int hf_pvfs_getconfig_response_total_bytes;
153
static int hf_pvfs_getconfig_response_lines;
154
static int hf_pvfs_getconfig_response_config_bytes;
155
static int hf_pvfs_mgmt_perf_mon_response_suggested_next_id;
156
static int hf_pvfs_mgmt_perf_stat_valid_flag;
157
static int hf_pvfs_mgmt_perf_stat_id;
158
static int hf_pvfs_mgmt_perf_mon_response_perf_array_count;
159
static int hf_pvfs_mgmt_iterate_handles_response_ds_position;
160
static int hf_pvfs_mgmt_iterate_handles_response_handle_count;
161
static int hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count;
162
static int hf_pvfs_mgmt_event_mon_response_api;
163
static int hf_pvfs_mgmt_event_mon_response_operation;
164
static int hf_pvfs_mgmt_event_mon_response_value;
165
static int hf_pvfs_mgmt_event_mon_response_flags;
166
static int hf_pvfs_mgmt_event_mon_response_tv_sec;
167
static int hf_pvfs_mgmt_event_mon_response_tv_usec;
168
static int hf_pvfs_fill_bytes;
169
static int hf_pvfs_target_path_len;
170
static int hf_pvfs_version2;
171
static int hf_pvfs_flow_data;
172
static int hf_pvfs_getconfig_response_entry;
173
static int hf_fhandle_data;
174
static int hf_pvfs_opaque_length;
175
176
/* Initialize the subtree pointers */
177
static int ett_pvfs;
178
static int ett_pvfs_hdr;
179
static int ett_pvfs_credentials;
180
static int ett_pvfs_server_config;
181
static int ett_pvfs_server_config_branch;
182
static int ett_pvfs_attrmask;
183
static int ett_pvfs_time;
184
static int ett_pvfs_extent_array_tree;
185
static int ett_pvfs_extent_item;
186
static int ett_pvfs_string;
187
static int ett_pvfs_attr_tree;
188
static int ett_pvfs_distribution;
189
static int ett_pvfs_mgmt_perf_stat;
190
static int ett_pvfs_mgmt_dspace_info;
191
static int ett_pvfs_attr;
192
static int ett_pvfs_fh;
193
194
static expert_field ei_pvfs_malformed;
195
196
1.18k
#define BMI_MAGIC_NR 51903
197
198
static const value_string names_pvfs_mode[] =
199
{
200
0
#define TCP_MODE_IMMED 1
201
  { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
202
0
#define TCP_MODE_UNEXP 2
203
  { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
204
0
#define TCP_MODE_EAGER 4
205
  { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
206
0
#define TCP_MODE_REND 8
207
  { TCP_MODE_REND,  "TCP_MODE_REND" },
208
  { 0, NULL }
209
};
210
211
static const value_string names_pvfs_encoding[] =
212
{
213
#define PVFS_ENCODING_DIRECT 1
214
  { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
215
#define PVFS_ENCODING_LE_BFIELD 2
216
  { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
217
#define PVFS_ENCODING_XDR 3
218
  { PVFS_ENCODING_XDR, "ENCODING_XDR" },
219
  { 0, NULL }
220
};
221
222
static const value_string names_pvfs_io_type[] =
223
{
224
#define PVFS_IO_READ 1
225
  { PVFS_IO_READ, "PVFS_IO_READ" },
226
#define PVFS_IO_WRITE 2
227
  { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
228
  { 0, NULL }
229
};
230
231
static const value_string names_pvfs_flowproto_type[] =
232
{
233
#define FLOWPROTO_DUMP_OFFSETS 1
234
  { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
235
#define FLOWPROTO_BMI_CACHE 2
236
  { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
237
#define FLOWPROTO_MULTIQUEUE 3
238
  { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
239
  { 0, NULL }
240
};
241
242
static const value_string names_pvfs_server_param[] =
243
{
244
#define PVFS_SERV_PARAM_INVALID 0
245
  { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
246
#define PVFS_SERV_PARAM_GOSSIP_MASK 1
247
  { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
248
0
#define PVFS_SERV_PARAM_FSID_CHECK 2
249
  { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
250
0
#define PVFS_SERV_PARAM_ROOT_CHECK 3
251
  { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
252
0
#define PVFS_SERV_PARAM_MODE 4
253
  { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
254
#define PVFS_SERV_PARAM_EVENT_ON 5
255
  { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
256
#define PVFS_SERV_PARAM_EVENT_MASKS 6
257
  { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
258
  { 0, NULL }
259
};
260
261
static const value_string names_pvfs_server_mode[] =
262
{
263
#define PVFS_SERVER_NORMAL_MODE 1
264
  { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
265
#define PVFS_SERVER_ADMIN_MODE 2
266
  { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
267
  { 0, NULL }
268
};
269
270
/* Forward declaration */
271
static bool
272
dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
273
    bool dissect_other_as_continuation);
274
275
276
static int dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
277
0
{
278
0
  dissect_pvfs_common(tvb, pinfo, tree, false);
279
0
  return tvb_reported_length(tvb);
280
0
}
281
282
static unsigned get_pvfs_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
283
                              int offset, void *data _U_)
284
0
{
285
0
  uint32_t plen;
286
287
  /*
288
   * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
289
   */
290
0
  plen = tvb_get_letohl(tvb, offset + 16);
291
292
0
  return plen+24;
293
0
}
294
295
static int
296
dissect_pvfs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
297
2.03k
{
298
2.03k
  uint32_t magic_nr, mode;
299
2.03k
  uint64_t size;
300
301
  /* verify that this is indeed PVFS and that it looks sane */
302
2.03k
  if(tvb_reported_length(tvb)<24){
303
    /* too few bytes remaining to verify the header */
304
856
    return 0;
305
856
  }
306
307
  /* validate the magic number */
308
1.18k
  magic_nr = tvb_get_letohl(tvb, 0);
309
1.18k
  if(magic_nr!=BMI_MAGIC_NR){
310
1.18k
    return 0;
311
1.18k
  }
312
313
  /* Validate the TCP message mode (32-bit) */
314
0
  mode = tvb_get_letohl(tvb, 4);
315
0
  switch(mode){
316
0
  case TCP_MODE_IMMED:
317
0
  case TCP_MODE_UNEXP:
318
0
  case TCP_MODE_EAGER:
319
0
  case TCP_MODE_REND:
320
0
    break;
321
0
  default:
322
    /* invalid mode, not a PVFS packet */
323
0
    return 0;
324
0
  }
325
326
  /* validate the size : assume size must be >0 and less than 1000000 */
327
0
  size=tvb_get_letohl(tvb, 20);
328
0
  size<<=32;
329
0
  size|=tvb_get_letohl(tvb, 16);
330
0
  if((size>1000000)||(size==0)){
331
0
    return 0;
332
0
  }
333
334
0
  tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
335
0
    dissect_pvfs_pdu, data);
336
337
0
  return tvb_reported_length(tvb);
338
0
}
339
340
static bool
341
dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
342
2.03k
{
343
2.03k
    return dissect_pvfs(tvb, pinfo, tree, data) > 0;
344
2.03k
}
345
346
static const value_string names_pvfs_server_op[] =
347
{
348
#define PVFS_SERV_INVALID 0
349
  { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
350
0
#define PVFS_SERV_CREATE 1
351
  { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
352
0
#define PVFS_SERV_REMOVE 2
353
  { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
354
0
#define PVFS_SERV_IO 3
355
  { PVFS_SERV_IO, "PVFS_SERV_IO" },
356
0
#define PVFS_SERV_GETATTR 4
357
  { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
358
0
#define PVFS_SERV_SETATTR 5
359
  { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
360
0
#define PVFS_SERV_LOOKUP_PATH 6
361
  { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
362
0
#define PVFS_SERV_CRDIRENT 7
363
  { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
364
0
#define PVFS_SERV_RMDIRENT 8
365
  { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
366
0
#define PVFS_SERV_CHDIRENT 9
367
  { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
368
0
#define PVFS_SERV_TRUNCATE 10
369
  { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
370
0
#define PVFS_SERV_MKDIR 11
371
  { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
372
0
#define PVFS_SERV_READDIR 12
373
  { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
374
0
#define PVFS_SERV_GETCONFIG 13
375
  { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
376
0
#define PVFS_SERV_WRITE_COMPLETION 14
377
  { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
378
0
#define PVFS_SERV_FLUSH 15
379
  { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
380
0
#define PVFS_SERV_MGMT_SETPARAM 16
381
  { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
382
#define PVFS_SERV_MGMT_NOOP 17
383
  { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
384
0
#define PVFS_SERV_STATFS 18
385
  { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
386
#define PVFS_SERV_PERF_UPDATE 19  /* not a real protocol request */
387
  { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
388
0
#define PVFS_SERV_MGMT_PERF_MON 20
389
  { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
390
0
#define PVFS_SERV_MGMT_ITERATE_HANDLES 21
391
  { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
392
0
#define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
393
  { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
394
0
#define PVFS_SERV_MGMT_EVENT_MON 23
395
  { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
396
0
#define PVFS_SERV_MGMT_REMOVE_OBJECT 24
397
  { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
398
0
#define PVFS_SERV_MGMT_REMOVE_DIRENT 25
399
  { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
400
0
#define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
401
  { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
402
#define PVFS_SERV_JOB_TIMER 27    /* not a real protocol request */
403
  { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
404
0
#define PVFS_SERV_PROTO_ERROR 28
405
  { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
406
0
#define PVFS_SERV_GETEATTR 29
407
  { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
408
0
#define PVFS_SERV_SETEATTR 30
409
  { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
410
0
#define PVFS_SERV_DELEATTR 31
411
  { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
412
  { 0, NULL }
413
};
414
415
/* special bits used to differentiate PVFS error codes from system
416
 *  * errno values
417
 *   */
418
#define PVFS_ERROR_BIT           (1 << 30)
419
420
/* a shorthand to make the error code definitions more readable */
421
#define E(num) (num|PVFS_ERROR_BIT)
422
423
static const value_string names_pvfs_error[] = {
424
  { 0, "Success" },
425
#define PVFS_EPERM            E(1) /* Operation not permitted */
426
  { PVFS_EPERM, "PVFS_EPERM" },
427
#define PVFS_ENOENT           E(2) /* No such file or directory */
428
  { PVFS_ENOENT, "PVFS_ENOENT" },
429
#define PVFS_EINTR            E(3) /* Interrupted system call */
430
  { PVFS_EINTR, "PVFS_EINTR" },
431
#define PVFS_EIO              E(4) /* I/O error */
432
  { PVFS_EIO, "PVFS_EIO" },
433
#define PVFS_ENXIO            E(5) /* No such device or address */
434
  { PVFS_ENXIO, "PVFS_ENXIO" },
435
#define PVFS_EBADF            E(6) /* Bad file number */
436
  { PVFS_EBADF, "PVFS_EBADF" },
437
#define PVFS_EAGAIN           E(7) /* Try again */
438
  { PVFS_EAGAIN, "PVFS_EAGAIN" },
439
#define PVFS_ENOMEM           E(8) /* Out of memory */
440
  { PVFS_ENOMEM, "PVFS_ENOMEM" },
441
#define PVFS_EFAULT           E(9) /* Bad address */
442
  { PVFS_EFAULT, "PVFS_EFAULT" },
443
#define PVFS_EBUSY           E(10) /* Device or resource busy */
444
  { PVFS_EBUSY, "PVFS_EBUSY" },
445
#define PVFS_EEXIST          E(11) /* File exists */
446
  { PVFS_EEXIST, "PVFS_EEXIST" },
447
#define PVFS_ENODEV          E(12) /* No such device */
448
  { PVFS_ENODEV, "PVFS_ENODEV" },
449
#define PVFS_ENOTDIR         E(13) /* Not a directory */
450
  { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
451
#define PVFS_EISDIR          E(14) /* Is a directory */
452
  { PVFS_EISDIR, "PVFS_EISDIR" },
453
#define PVFS_EINVAL          E(15) /* Invalid argument */
454
  { PVFS_EINVAL, "PVFS_EINVAL" },
455
#define PVFS_EMFILE          E(16) /* Too many open files */
456
  { PVFS_EMFILE, "PVFS_EMFILE" },
457
#define PVFS_EFBIG           E(17) /* File too large */
458
  { PVFS_EFBIG, "PVFS_EFBIG" },
459
#define PVFS_ENOSPC          E(18) /* No space left on device */
460
  { PVFS_ENOSPC, "PVFS_ENOSPC" },
461
#define PVFS_EROFS           E(19) /* Read-only file system */
462
  { PVFS_EROFS, "PVFS_EROFS" },
463
#define PVFS_EMLINK          E(20) /* Too many links */
464
  { PVFS_EMLINK, "PVFS_EMLINK" },
465
#define PVFS_EPIPE           E(21) /* Broken pipe */
466
  { PVFS_EPIPE, "PVFS_EPIPE" },
467
#define PVFS_EDEADLK         E(22) /* Resource deadlock would occur */
468
  { PVFS_EDEADLK, "PVFS_EDEADLK" },
469
#define PVFS_ENAMETOOLONG    E(23) /* File name too long */
470
  { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
471
#define PVFS_ENOLCK          E(24) /* No record locks available */
472
  { PVFS_ENOLCK, "PVFS_ENOLCK" },
473
#define PVFS_ENOSYS          E(25) /* Function not implemented */
474
  { PVFS_ENOSYS, "PVFS_ENOSYS" },
475
#define PVFS_ENOTEMPTY       E(26) /* Directory not empty */
476
  { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
477
#define PVFS_ELOOP           E(27) /* Too many symbolic links encountered */
478
  { PVFS_ELOOP, "PVFS_ELOOP" },
479
#define PVFS_EWOULDBLOCK     E(28) /* Operation would block */
480
  { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
481
#define PVFS_ENOMSG          E(29) /* No message of desired type */
482
  { PVFS_ENOMSG, "PVFS_ENOMSG" },
483
#define PVFS_EUNATCH         E(30) /* Protocol driver not attached */
484
  { PVFS_EUNATCH, "PVFS_EUNATCH" },
485
#define PVFS_EBADR           E(31) /* Invalid request descriptor */
486
  { PVFS_EBADR, "PVFS_EBADR" },
487
#define PVFS_EDEADLOCK       E(32)
488
  { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
489
#define PVFS_ENODATA         E(33) /* No data available */
490
  { PVFS_ENODATA, "PVFS_ENODATA" },
491
#define PVFS_ETIME           E(34) /* Timer expired */
492
  { PVFS_ETIME, "PVFS_ETIME" },
493
#define PVFS_ENONET          E(35) /* Machine is not on the network */
494
  { PVFS_ENONET, "PVFS_ENONET" },
495
#define PVFS_EREMOTE         E(36) /* Object is remote */
496
  { PVFS_EREMOTE, "PVFS_EREMOTE" },
497
#define PVFS_ECOMM           E(37) /* Communication error on send */
498
  { PVFS_ECOMM, "PVFS_ECOMM" },
499
#define PVFS_EPROTO          E(38) /* Protocol error */
500
  { PVFS_EPROTO, "PVFS_EPROTO" },
501
#define PVFS_EBADMSG         E(39) /* Not a data message */
502
  { PVFS_EBADMSG, "PVFS_EBADMSG" },
503
#define PVFS_EOVERFLOW       E(40) /* Value too large for defined data type */
504
  { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
505
#define PVFS_ERESTART        E(41) /* Interrupted system call should be restarted */
506
  { PVFS_ERESTART, "PVFS_ERESTART" },
507
#define PVFS_EMSGSIZE        E(42) /* Message too long */
508
  { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
509
#define PVFS_EPROTOTYPE      E(43) /* Protocol wrong type for socket */
510
  { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
511
#define PVFS_ENOPROTOOPT     E(44) /* Protocol not available */
512
  { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
513
#define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
514
  { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
515
#define PVFS_EOPNOTSUPP      E(46) /* Operation not supported on transport endpoint */
516
  { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
517
#define PVFS_EADDRINUSE      E(47) /* Address already in use */
518
  { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
519
#define PVFS_EADDRNOTAVAIL   E(48) /* Cannot assign requested address */
520
  { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
521
#define PVFS_ENETDOWN        E(49) /* Network is down */
522
  { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
523
#define PVFS_ENETUNREACH     E(50) /* Network is unreachable */
524
  { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
525
#define PVFS_ENETRESET       E(51) /* Network dropped connection because of reset */
526
  { PVFS_ENETRESET, "PVFS_ENETRESET" },
527
#define PVFS_ENOBUFS         E(52) /* No buffer space available */
528
  { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
529
#define PVFS_ETIMEDOUT       E(53) /* Connection timed out */
530
  { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
531
#define PVFS_ECONNREFUSED    E(54) /* Connection refused */
532
  { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
533
#define PVFS_EHOSTDOWN       E(55) /* Host is down */
534
  { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
535
#define PVFS_EHOSTUNREACH    E(56) /* No route to host */
536
  { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
537
#define PVFS_EALREADY        E(57) /* Operation already in progress */
538
  { PVFS_EALREADY, "PVFS_EALREADY" },
539
#define PVFS_EACCES          E(58) /* Operation already in progress */
540
  { PVFS_EACCES, "PVFS_EACCES" },
541
  { 0, NULL }
542
};
543
544
static unsigned
545
dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
546
    packet_info *pinfo)
547
0
{
548
0
  int32_t err;
549
0
  const char *errmsg = NULL;
550
551
0
  err = tvb_get_letohl(tvb, offset);
552
0
  proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
553
0
  offset += 4;
554
555
0
  if (err != 0)
556
0
  {
557
0
    errmsg = val_to_str(pinfo->pool, -err, names_pvfs_error, "Unknown error: %u");
558
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
559
0
  }
560
561
0
  return offset;
562
0
}
563
564
static unsigned
565
dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
566
    unsigned offset)
567
0
{
568
0
  proto_tree *hcred_tree;
569
0
  uint32_t uid, gid;
570
571
0
  uid = tvb_get_letohl(tvb, offset);
572
0
  gid = tvb_get_letohl(tvb, offset + 4);
573
574
0
  hcred_tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, 8,
575
0
      ett_pvfs_credentials, NULL, "Credentials (UID: %d, GID: %d)", uid, gid);
576
577
  /* UID */
578
0
  proto_tree_add_item(hcred_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
579
0
  offset += 4;
580
581
  /* GID */
582
0
  proto_tree_add_item(hcred_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
583
0
  offset += 4;
584
585
0
  return offset;
586
0
}
587
588
static const value_string names_pvfs_attr[] =
589
{
590
#define PVFS_ATTR_COMMON_UID   (1 << 0)
591
#define PVFS_ATTR_BIT_COMMON_UID 0
592
  { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
593
594
#define PVFS_ATTR_COMMON_GID   (1 << 1)
595
#define PVFS_ATTR_BIT_COMMON_GID 1
596
  { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
597
598
#define PVFS_ATTR_COMMON_PERM  (1 << 2)
599
#define PVFS_ATTR_BIT_COMMON_PERM 2
600
  { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
601
602
#define PVFS_ATTR_COMMON_ATIME (1 << 3)
603
#define PVFS_ATTR_BIT_COMMON_ATIME 3
604
  { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
605
606
#define PVFS_ATTR_COMMON_CTIME (1 << 4)
607
#define PVFS_ATTR_BIT_COMMON_CTIME 4
608
  { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
609
610
#define PVFS_ATTR_COMMON_MTIME (1 << 5)
611
#define PVFS_ATTR_BIT_COMMON_MTIME 5
612
  { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
613
614
#define PVFS_ATTR_COMMON_TYPE  (1 << 6)
615
#define PVFS_ATTR_BIT_COMMON_TYPE 6
616
  { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
617
618
#if 0
619
#define PVFS_ATTR_COMMON_ALL                       \
620
  (PVFS_ATTR_COMMON_UID   | PVFS_ATTR_COMMON_GID   | \
621
    PVFS_ATTR_COMMON_PERM  | PVFS_ATTR_COMMON_ATIME | \
622
    PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
623
    PVFS_ATTR_COMMON_TYPE)
624
#endif
625
626
/* internal attribute masks for metadata objects */
627
0
#define PVFS_ATTR_META_DIST    (1 << 10)
628
#define PVFS_ATTR_BIT_META_DIST 10
629
  { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
630
631
0
#define PVFS_ATTR_META_DFILES  (1 << 11)
632
#define PVFS_ATTR_BIT_META_DFILES 11
633
  { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
634
635
#if 0
636
#define PVFS_ATTR_META_ALL \
637
  (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
638
#endif
639
640
/* internal attribute masks for datafile objects */
641
0
#define PVFS_ATTR_DATA_SIZE            (1 << 15)
642
#define PVFS_ATTR_BIT_DATA_SIZE 15
643
  { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
644
645
#if 0
646
#define PVFS_ATTR_DATA_ALL   PVFS_ATTR_DATA_SIZE
647
#endif
648
649
/* internal attribute masks for symlink objects */
650
0
#define PVFS_ATTR_SYMLNK_TARGET            (1 << 18)
651
#define PVFS_ATTR_BIT_SYMLINK_TARGET 18
652
  { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
653
654
#if 0
655
#define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
656
#endif
657
658
/* internal attribute masks for directory objects */
659
0
#define PVFS_ATTR_DIR_DIRENT_COUNT         (1 << 19)
660
#define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
661
  { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
662
663
#if 0
664
#define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
665
#endif
666
667
/* attribute masks used by system interface callers */
668
#define PVFS_ATTR_SYS_SIZE                  (1 << 20)
669
#define PVFS_ATTR_BIT_SYS_SIZE 20
670
  { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
671
672
#define PVFS_ATTR_SYS_LNK_TARGET            (1 << 24)
673
#define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
674
  { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
675
676
#define PVFS_ATTR_SYS_DFILE_COUNT           (1 << 25)
677
#define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
678
  { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
679
680
#define PVFS_ATTR_SYS_DIRENT_COUNT          (1 << 26)
681
#define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
682
  { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
683
684
#if 0
685
#define PVFS_ATTR_SYS_UID        PVFS_ATTR_COMMON_UID
686
#define PVFS_ATTR_SYS_GID        PVFS_ATTR_COMMON_GID
687
#define PVFS_ATTR_SYS_PERM       PVFS_ATTR_COMMON_PERM
688
#define PVFS_ATTR_SYS_ATIME      PVFS_ATTR_COMMON_ATIME
689
#define PVFS_ATTR_SYS_CTIME      PVFS_ATTR_COMMON_CTIME
690
#define PVFS_ATTR_SYS_MTIME      PVFS_ATTR_COMMON_MTIME
691
#define PVFS_ATTR_SYS_TYPE       PVFS_ATTR_COMMON_TYPE
692
#endif
693
  { 0, NULL }
694
};
695
696
#if 0
697
#define PVFS_ATTR_SYS_ALL                    \
698
  (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
699
    PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
700
    PVFS_ATTR_SYS_DIRENT_COUNT)
701
702
#define PVFS_ATTR_SYS_ALL_NOSIZE                   \
703
  (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
704
    PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
705
706
#define PVFS_ATTR_SYS_ALL_SETABLE \
707
  (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
708
#endif
709
710
711
static unsigned
712
dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
713
    uint32_t *pattrmask)
714
0
{
715
0
  uint32_t attrmask, i;
716
0
  proto_item *attritem;
717
0
  proto_tree *attrtree;
718
719
0
  attrmask = tvb_get_letohl(tvb, offset);
720
721
0
  attritem = proto_tree_add_uint(tree, hf_pvfs_attrmask, tvb, offset, 4, attrmask);
722
0
  attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
723
724
0
  for (i = 0; i < 32; i++)
725
0
  {
726
0
    if (attrmask & (1u << i))
727
0
      proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
728
0
  }
729
730
0
  offset += 4;
731
732
0
  if (pattrmask)
733
0
    *pattrmask = attrmask;
734
735
0
  return offset;
736
0
}
737
738
static const value_string names_pvfs_ds_type[] = {
739
#define PVFS_TYPE_NONE 0
740
  { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
741
#define PVFS_TYPE_METAFILE (1 << 0)
742
  { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
743
#define PVFS_TYPE_DATAFILE (1 << 1)
744
  { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
745
#define PVFS_TYPE_DIRECTORY (1 << 2)
746
  { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
747
#define PVFS_TYPE_SYMLINK (1 << 3)
748
  { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
749
#define PVFS_TYPE_DIRDATA (1 << 4)
750
  { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
751
  { 0, NULL }
752
};
753
754
static unsigned
755
dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
756
    int *pds_type)
757
0
{
758
0
  uint32_t ds_type;
759
760
0
  ds_type = tvb_get_letohl(tvb, offset);
761
762
0
  proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
763
764
0
  offset += 4;
765
766
0
  if (pds_type)
767
0
    *pds_type = ds_type;
768
769
0
  return offset;
770
0
}
771
772
static unsigned
773
dissect_pvfs_opaque_data(tvbuff_t *tvb, unsigned offset,
774
  proto_tree *tree,
775
  packet_info *pinfo,
776
  int hfindex,
777
  bool fixed_length, uint32_t length,
778
  bool string_data, const char **string_buffer_ret)
779
0
{
780
0
  int data_offset;
781
0
  proto_item *string_item = NULL;
782
0
  proto_tree *string_tree = NULL;
783
784
0
  uint32_t string_length;
785
0
  uint32_t string_length_full;
786
0
  uint32_t string_length_packet;
787
0
  uint32_t string_length_captured;
788
0
  uint32_t string_length_copy;
789
790
0
  int fill_truncated;
791
0
  uint32_t fill_length;
792
0
  uint32_t fill_length_packet;
793
0
  uint32_t fill_length_captured;
794
0
  uint32_t fill_length_copy;
795
796
0
  int exception = 0;
797
798
0
  char *string_buffer = NULL;
799
0
  const char *string_buffer_print = NULL;
800
801
0
  if (fixed_length) {
802
0
    string_length = length;
803
0
    data_offset = offset;
804
0
  } else {
805
0
    string_length = tvb_get_letohl(tvb,offset+0);
806
0
    data_offset = offset + 4;
807
808
    /*
809
     * Variable-length strings include NULL terminator on-the-wire but
810
     * NULL terminator is not included in string length.
811
     */
812
813
0
    if (string_data)
814
0
      string_length += 1;
815
0
  }
816
817
0
  string_length_captured = tvb_captured_length_remaining(tvb, data_offset);
818
0
  string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
819
820
  /*
821
   * Strangeness...  the protocol basically says that the length plus
822
   * the string must be padded out to an 8-byte boundary.
823
   */
824
825
0
  if (!string_data)
826
0
    string_length_full = WS_ROUNDUP_4(string_length);
827
0
  else
828
0
    string_length_full = WS_ROUNDUP_8(4 + string_length);
829
830
0
  if (string_length_captured < string_length) {
831
    /* truncated string */
832
0
    string_length_copy = string_length_captured;
833
0
    fill_truncated = 2;
834
0
    fill_length = 0;
835
0
    fill_length_copy = 0;
836
837
0
    if (string_length_packet < string_length)
838
0
      exception = ReportedBoundsError;
839
0
    else
840
0
      exception = BoundsError;
841
0
  }
842
0
  else {
843
    /* full string data */
844
0
    string_length_copy = string_length;
845
846
0
    if (!string_data)
847
0
      fill_length = string_length_full - string_length;
848
0
    else
849
0
      fill_length = string_length_full - string_length - 4;
850
851
0
    fill_length_captured = tvb_captured_length_remaining(tvb,
852
0
        data_offset + string_length);
853
0
    fill_length_packet = tvb_reported_length_remaining(tvb,
854
0
        data_offset + string_length);
855
856
0
    if (fill_length_captured < fill_length) {
857
      /* truncated fill bytes */
858
0
      fill_length_copy = fill_length_packet;
859
0
      fill_truncated = 1;
860
0
      if (fill_length_packet < fill_length)
861
0
        exception = ReportedBoundsError;
862
0
      else
863
0
        exception = BoundsError;
864
0
    }
865
0
    else {
866
      /* full fill bytes */
867
0
      fill_length_copy = fill_length;
868
0
      fill_truncated = 0;
869
0
    }
870
0
  }
871
872
0
  if (string_data) {
873
0
    string_buffer = (char*)tvb_get_string_enc(pinfo->pool, tvb, data_offset, string_length_copy, ENC_ASCII);
874
0
  } else {
875
0
    string_buffer = (char *) tvb_memcpy(tvb,
876
0
        wmem_alloc(pinfo->pool, string_length_copy+1), data_offset, string_length_copy);
877
0
    string_buffer[string_length_copy] = '\0';
878
0
  }
879
880
  /* calculate a nice printable string */
881
0
  if (string_length) {
882
0
    if (string_length != strlen(string_buffer)) {
883
0
      if (string_data) {
884
0
        char *formatted;
885
0
        size_t string_buffer_size = 0;
886
0
        char *string_buffer_temp;
887
888
0
        formatted = format_text(pinfo->pool, string_buffer,
889
0
            (int)strlen(string_buffer));
890
891
0
        string_buffer_size = strlen(formatted) + 12 + 1;
892
893
        /* alloc maximum data area */
894
0
        string_buffer_temp = (char*) wmem_alloc(pinfo->pool, string_buffer_size);
895
        /* copy over the data */
896
0
        snprintf(string_buffer_temp, string_buffer_size,
897
0
            "%s<TRUNCATED>", formatted);
898
        /* append <TRUNCATED> */
899
        /* This way, we get the TRUNCATED even
900
           in the case of totally wrong packets,
901
           where \0 are inside the string.
902
           TRUNCATED will appear at the
903
           first \0 or at the end (where we
904
           put the securing \0).
905
        */
906
0
        string_buffer_print = string_buffer_temp;
907
0
      } else {
908
0
        string_buffer_print="<DATA><TRUNCATED>";
909
0
      }
910
0
    } else {
911
0
      if (string_data) {
912
0
        string_buffer_print = format_text(pinfo->pool, string_buffer,
913
0
                 (int)strlen(string_buffer));
914
0
      } else {
915
0
        string_buffer_print="<DATA>";
916
0
      }
917
0
    }
918
0
  } else {
919
0
    string_buffer_print="<EMPTY>";
920
0
  }
921
922
0
  string_item = proto_tree_add_string(tree, hfindex, tvb, offset+0, -1,
923
0
        string_buffer_print);
924
925
0
  string_tree = proto_item_add_subtree(string_item,
926
0
          ett_pvfs_string);
927
928
0
  if (!fixed_length) {
929
0
    proto_tree_add_uint_format_value(string_tree, hf_pvfs_opaque_length, tvb, offset, 4,
930
0
        string_length - 1, "%u (excl. NULL terminator)", string_length - 1);
931
0
    offset += 4;
932
0
  }
933
934
0
  if (string_data) {
935
0
    proto_tree_add_string_format(string_tree,
936
0
      hfindex, tvb, offset, string_length_copy,
937
0
      string_buffer,
938
0
      "contents: %s", string_buffer_print);
939
0
  } else {
940
0
    proto_tree_add_bytes_format(string_tree,
941
0
      hfindex, tvb, offset, string_length_copy,
942
0
      (uint8_t *) string_buffer,
943
0
      "contents: %s", string_buffer_print);
944
0
  }
945
946
0
  offset += string_length_copy;
947
948
0
  if (fill_length) {
949
0
    if (string_tree) {
950
0
      if (fill_truncated) {
951
0
        proto_tree_add_bytes_format_value(string_tree, hf_pvfs_fill_bytes, tvb,
952
0
        offset, fill_length_copy, NULL,
953
0
        "opaque data <TRUNCATED>");
954
0
      }
955
0
      else {
956
0
        proto_tree_add_bytes_format_value(string_tree, hf_pvfs_fill_bytes, tvb,
957
0
        offset, fill_length_copy, NULL,
958
0
        "opaque data");
959
0
      }
960
0
    }
961
0
    offset += fill_length_copy;
962
0
  }
963
964
0
  if (string_item)
965
0
    proto_item_set_end(string_item, tvb, offset);
966
967
0
  if (string_buffer_ret != NULL)
968
0
    *string_buffer_ret = string_buffer_print;
969
970
  /*
971
   * If the data was truncated, throw the appropriate exception,
972
   * so that dissection stops and the frame is properly marked.
973
   */
974
0
  if (exception != 0)
975
0
    THROW(exception);
976
977
0
  return offset;
978
0
}
979
980
static unsigned
981
dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
982
    unsigned offset, packet_info *pinfo, const char **string_buffer_ret)
983
0
{
984
0
  return dissect_pvfs_opaque_data(tvb, offset, tree, pinfo, hfindex,
985
0
      false, 0, true, string_buffer_ret);
986
0
}
987
988
static void
989
dissect_fhandle_data_unknown(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
990
0
{
991
0
  unsigned bytes_left  = PVFS2_FH_LENGTH;
992
993
0
  proto_tree_add_item(tree, hf_fhandle_data, tvb, offset, bytes_left, ENC_NA);
994
0
}
995
996
static void
997
dissect_fhandle_data(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_,
998
         proto_tree *tree, uint32_t *hash)
999
0
{
1000
0
  uint32_t fhhash;
1001
0
  uint32_t i;
1002
1003
  /* Not all bytes there. Any attempt to deduce the type would be
1004
    senseless. */
1005
0
  if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
1006
0
    goto type_ready;
1007
1008
  /* create a semiunique hash value for the filehandle */
1009
0
  for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
1010
0
    uint32_t val;
1011
0
    val = tvb_get_ntohl(tvb, offset+i);
1012
0
    fhhash ^= val;
1013
0
    fhhash += val;
1014
0
  }
1015
1016
0
  proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
1017
0
      fhhash);
1018
1019
0
  if (hash)
1020
0
    *hash = fhhash;
1021
1022
  /* TODO: add file name snooping code here */
1023
1024
0
type_ready:
1025
0
  dissect_fhandle_data_unknown(tvb, offset, tree);
1026
0
}
1027
1028
static unsigned
1029
dissect_pvfs_fh(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
1030
    proto_tree *tree, const char *name, uint32_t *hash)
1031
0
{
1032
0
  proto_tree* ftree;
1033
1034
0
  ftree = proto_tree_add_subtree(tree, tvb, offset, PVFS2_FH_LENGTH,
1035
0
      ett_pvfs_fh, NULL, name);
1036
1037
  /* TODO: add fh to file name snooping code here */
1038
1039
0
  proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
1040
0
      PVFS2_FH_LENGTH);
1041
1042
0
  dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
1043
1044
0
  offset += PVFS2_FH_LENGTH;
1045
1046
0
  return offset;
1047
0
}
1048
1049
static unsigned
1050
dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1051
    packet_info *pinfo, uint32_t nCount)
1052
0
{
1053
0
  proto_tree *extent_tree;
1054
1055
0
  extent_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
1056
0
      ett_pvfs_extent_item, NULL, "Item %d", nCount);
1057
1058
  /* first handle */
1059
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
1060
0
      NULL);
1061
1062
  /* last handle */
1063
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
1064
0
      NULL);
1065
1066
0
  return offset;
1067
0
}
1068
1069
static unsigned
1070
dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1071
    packet_info *pinfo)
1072
0
{
1073
0
  uint32_t extent_count;
1074
0
  uint32_t nCount;
1075
0
  proto_tree *extent_array_tree;
1076
1077
  /* extent count */
1078
0
  extent_count = tvb_get_letohl(tvb, offset);
1079
1080
0
  extent_array_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
1081
0
          ett_pvfs_extent_array_tree, NULL, "Handle Extent Array (count = %d)", extent_count);
1082
1083
0
  offset += 4;
1084
1085
0
  if (extent_count > 0)
1086
0
  {
1087
    /* Add extent array items */
1088
0
    for (nCount = 0; nCount < extent_count; nCount++)
1089
0
      offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
1090
0
          pinfo, nCount);
1091
0
  }
1092
1093
0
  return offset;
1094
0
}
1095
1096
static unsigned
1097
dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1098
    int hf_time, int hf_time_sec, int hf_time_nsec)
1099
0
{
1100
0
  uint32_t seconds;
1101
0
  uint32_t nseconds;
1102
0
  nstime_t ts;
1103
0
  proto_item *time_item;
1104
0
  proto_tree *time_tree;
1105
1106
0
  ts.secs = seconds = tvb_get_letohl(tvb, offset);
1107
0
  ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
1108
1109
0
  time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
1110
0
  time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
1111
1112
0
  proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
1113
0
  proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4, nseconds);
1114
1115
0
  offset += 8;
1116
0
  return offset;
1117
0
}
1118
1119
static
1120
int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1121
    int hfindex, uint64_t *pvalue)
1122
0
{
1123
0
  uint64_t val;
1124
1125
0
  val = tvb_get_letoh64(tvb, offset);
1126
0
  proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
1127
1128
0
  if (pvalue)
1129
0
    *pvalue = val;
1130
1131
0
  return offset + 8;
1132
0
}
1133
1134
/* Taken from pvfs2-dist-simple-stripe.h */
1135
0
#define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
1136
0
#define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
1137
1138
static unsigned
1139
dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1140
    packet_info *pinfo)
1141
0
{
1142
0
  proto_item *dist_item;
1143
0
  proto_tree *dist_tree;
1144
0
  uint32_t distlen;
1145
0
  char *tmpstr;
1146
0
  uint8_t issimplestripe = 0;
1147
0
  uint32_t total_len;
1148
1149
  /* Get distribution name length */
1150
0
  distlen = tvb_get_letohl(tvb, offset);
1151
1152
  /* Get distribution name */
1153
0
  tmpstr = (char *) tvb_get_string_enc(pinfo->pool, tvb, offset + 4, distlen, ENC_ASCII);
1154
1155
  /* 'distlen' does not include the NULL terminator */
1156
0
  total_len = WS_ROUNDUP_8(4 + distlen + 1);
1157
1158
0
  if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
1159
0
      (g_ascii_strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
1160
0
               distlen) == 0))
1161
0
  {
1162
    /* Parameter for 'simple_stripe' is 8 bytes */
1163
0
    total_len += 8;
1164
1165
0
    issimplestripe = 1;
1166
0
  }
1167
1168
0
  dist_item = proto_tree_add_string(tree, hf_pvfs_distribution,
1169
0
      tvb, offset, total_len + 8, tmpstr);
1170
0
  dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
1171
1172
  /* io_dist */
1173
0
  offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
1174
0
      pinfo, NULL);
1175
1176
  /* TODO: only one distribution type is currently supported */
1177
0
  if (issimplestripe)
1178
0
    offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
1179
0
        hf_pvfs_strip_size, NULL);
1180
1181
0
  offset += 8;
1182
1183
0
  return offset;
1184
0
}
1185
1186
static unsigned
1187
dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1188
    packet_info *pinfo)
1189
0
{
1190
0
  uint32_t dfile_count, i;
1191
1192
  /* dfile_count */
1193
0
  dfile_count = tvb_get_letohl(tvb, offset);
1194
0
  proto_tree_add_uint(tree, hf_pvfs_dfile_count, tvb, offset, 4, dfile_count);
1195
1196
0
  offset += 4;
1197
1198
0
  for (i = 0; i < dfile_count; i++)
1199
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1200
1201
0
  return offset;
1202
0
}
1203
1204
static unsigned
1205
dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1206
    packet_info *pinfo)
1207
0
{
1208
0
  int32_t ds_type = 0;
1209
0
  uint32_t attrmask = 0;
1210
0
  proto_tree *attr_tree;
1211
1212
0
  attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_pvfs_attr_tree, NULL, "Attributes");
1213
1214
  /* UID */
1215
0
  proto_tree_add_item(attr_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1216
0
  offset += 4;
1217
1218
  /* GID */
1219
0
  proto_tree_add_item(attr_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1220
0
  offset += 4;
1221
1222
  /* Permissions */
1223
0
  proto_tree_add_item(attr_tree, hf_pvfs_permissions, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1224
0
  offset += 4;
1225
1226
0
  offset += 4;
1227
1228
  /* atime */
1229
0
  offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
1230
0
      hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1231
1232
  /* mtime */
1233
0
  offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
1234
0
      hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1235
1236
  /* ctime */
1237
0
  offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
1238
0
      hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1239
1240
  /* attrmask */
1241
0
  offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
1242
1243
  /* objtype */
1244
0
  offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
1245
1246
0
  if (attrmask & PVFS_ATTR_META_DIST)
1247
0
  {
1248
0
    offset = dissect_pvfs_distribution(tvb, attr_tree, offset, pinfo);
1249
1250
0
    offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1251
0
  }
1252
0
  else
1253
0
  {
1254
0
    if (attrmask & PVFS_ATTR_META_DFILES)
1255
0
    {
1256
0
      offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1257
0
    }
1258
0
    else
1259
0
    {
1260
0
      if (attrmask & PVFS_ATTR_DATA_SIZE)
1261
0
      {
1262
0
        offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
1263
0
            NULL);
1264
0
      }
1265
0
      else
1266
0
      {
1267
0
        if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
1268
0
        {
1269
          /* target_path_len */
1270
0
          proto_tree_add_item(attr_tree, hf_pvfs_target_path_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1271
0
          offset += 4;
1272
1273
0
          offset += 4;
1274
1275
          /* target_path */
1276
0
          offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
1277
0
              offset, pinfo, NULL);
1278
0
        }
1279
0
        else
1280
0
        {
1281
0
          if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
1282
0
          {
1283
0
            offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
1284
0
                hf_pvfs_size, NULL);
1285
0
          }
1286
0
        }
1287
0
      }
1288
0
    }
1289
0
  }
1290
1291
0
  return offset;
1292
0
}
1293
1294
static unsigned
1295
dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1296
0
{
1297
0
  proto_tree_add_item(tree, hf_pvfs_io_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1298
0
  offset += 4;
1299
1300
0
  return offset;
1301
0
}
1302
1303
static unsigned
1304
dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1305
0
{
1306
0
  proto_tree_add_item(tree, hf_pvfs_flowproto_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1307
0
  offset += 4;
1308
1309
0
  return offset;
1310
0
}
1311
1312
static unsigned
1313
dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1314
    packet_info *pinfo)
1315
0
{
1316
0
  uint32_t server_param;
1317
0
  proto_item* ti;
1318
1319
  /* server_param */
1320
0
  server_param = tvb_get_letohl(tvb, offset);
1321
0
  proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
1322
0
      server_param);
1323
0
  offset += 4;
1324
1325
0
  switch (server_param)
1326
0
  {
1327
0
    case PVFS_SERV_PARAM_MODE:
1328
0
      ti = proto_tree_add_item(tree, hf_pvfs_server_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1329
0
      proto_item_set_len(ti, 8);
1330
0
      break;
1331
1332
0
    case PVFS_SERV_PARAM_FSID_CHECK:
1333
0
      proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1334
0
      proto_tree_add_item(tree, hf_pvfs_unused, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1335
0
      break;
1336
1337
0
    case PVFS_SERV_PARAM_ROOT_CHECK:
1338
0
      offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1339
0
      break;
1340
0
  }
1341
1342
0
  offset += 8;
1343
1344
0
  return offset;
1345
0
}
1346
1347
static unsigned
1348
dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1349
0
{
1350
0
  proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1351
0
  offset += 4;
1352
1353
0
  return offset;
1354
0
}
1355
1356
/*
1357
 * =======================================================================
1358
 * Request handlers
1359
 * =======================================================================
1360
 */
1361
1362
static unsigned
1363
dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1364
    packet_info *pinfo)
1365
0
{
1366
  /* fs_id */
1367
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1368
1369
  /* type */
1370
0
  offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
1371
1372
0
  offset += 4;
1373
1374
0
  offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
1375
1376
0
  return offset;
1377
0
}
1378
1379
static unsigned
1380
dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1381
    packet_info *pinfo)
1382
0
{
1383
  /* handle */
1384
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1385
1386
  /* fs_id */
1387
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1388
1389
0
  return offset;
1390
0
}
1391
1392
static unsigned
1393
dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1394
0
{
1395
  /* offset */
1396
0
  proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1397
0
  offset += 8;
1398
1399
  /* TODO: num_eregs */
1400
0
  proto_tree_add_item(tree, hf_pvfs_num_eregs, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1401
0
  offset += 4;
1402
1403
  /* TODO: num_blocks */
1404
0
  proto_tree_add_item(tree, hf_pvfs_num_blocks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1405
0
  offset += 4;
1406
1407
  /* TODO: stride */
1408
0
  proto_tree_add_item(tree, hf_pvfs_stride, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1409
0
  offset += 8;
1410
1411
  /* TODO: ub */
1412
0
  proto_tree_add_item(tree, hf_pvfs_ub, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1413
0
  offset += 8;
1414
1415
  /* TODO: lb */
1416
0
  proto_tree_add_item(tree, hf_pvfs_lb, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1417
0
  offset += 8;
1418
1419
  /* TODO: aggregate size */
1420
0
  proto_tree_add_item(tree, hf_pvfs_aggregate_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1421
0
  offset += 8;
1422
1423
  /* num_contig_chunks */
1424
0
  proto_tree_add_item(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1425
0
  offset += 4;
1426
1427
  /* depth */
1428
0
  proto_tree_add_item(tree, hf_pvfs_depth, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1429
0
  offset += 4;
1430
1431
  /* num_nested_req */
1432
0
  proto_tree_add_item(tree, hf_pvfs_num_nested_req, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1433
0
  offset += 4;
1434
1435
  /* committed */
1436
0
  proto_tree_add_item(tree, hf_pvfs_committed, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1437
0
  offset += 4;
1438
1439
  /* refcount */
1440
0
  proto_tree_add_item(tree, hf_pvfs_refcount, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1441
0
  offset += 4;
1442
1443
  /* documented */
1444
0
  offset += 4;
1445
1446
  /* ereg */
1447
0
  proto_tree_add_item(tree, hf_pvfs_ereg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1448
0
  offset += 4;
1449
1450
  /* sreg */
1451
0
  proto_tree_add_item(tree, hf_pvfs_sreg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1452
0
  offset += 4;
1453
1454
0
  return offset;
1455
0
}
1456
1457
static unsigned
1458
dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1459
    packet_info *pinfo)
1460
0
{
1461
  /* handle */
1462
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1463
1464
  /* fs_id */
1465
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1466
1467
  /* skip4 as per source code */
1468
0
  offset += 4;
1469
1470
  /* io_type */
1471
0
  offset = dissect_pvfs_io_type(tvb, tree, offset);
1472
1473
  /* flow_type */
1474
0
  offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
1475
1476
  /* server_nr */
1477
0
  proto_tree_add_item(tree, hf_pvfs_server_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1478
0
  offset += 4;
1479
1480
  /* server_ct */
1481
0
  proto_tree_add_item(tree, hf_pvfs_server_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1482
0
  offset += 4;
1483
1484
  /* Distribution */
1485
0
  offset = dissect_pvfs_distribution(tvb, tree, offset, pinfo);
1486
1487
0
  proto_tree_add_item(tree, hf_pvfs_numreq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1488
0
  offset += 4;
1489
1490
  /* */
1491
0
  offset += 4;
1492
1493
  /*offset = */dissect_pvfs_pint_request(tvb, tree, offset);
1494
1495
  /* TODO: remove this!!! */
1496
0
  offset = tvb_reported_length(tvb) - 16;
1497
1498
  /* offset */
1499
0
  proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1500
0
  offset += 8;
1501
1502
  /* size */
1503
0
  proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1504
0
  offset += 8;
1505
1506
0
  return offset;
1507
0
}
1508
1509
static unsigned
1510
dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1511
    packet_info *pinfo)
1512
0
{
1513
  /* handle */
1514
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1515
1516
  /* fs_id */
1517
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1518
1519
  /* attrmask */
1520
0
  offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1521
1522
0
  return offset;
1523
0
}
1524
1525
static unsigned
1526
dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1527
    packet_info *pinfo)
1528
0
{
1529
  /* handle */
1530
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1531
1532
  /* parent_ref: fs_id */
1533
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1534
1535
0
  offset += 4;
1536
1537
0
  offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1538
1539
0
  return offset;
1540
0
}
1541
1542
/* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
1543
static unsigned
1544
dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
1545
    unsigned offset, packet_info *pinfo)
1546
0
{
1547
  /* Path */
1548
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1549
1550
  /* fs_id */
1551
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1552
1553
0
  offset += 4;
1554
1555
  /* starting_handle */
1556
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1557
1558
  /* attribute mask */
1559
0
  offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1560
1561
0
  return offset;
1562
0
}
1563
1564
static unsigned
1565
dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1566
    packet_info *pinfo)
1567
0
{
1568
  /* Filename */
1569
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1570
1571
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
1572
1573
  /* parent_handle */
1574
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1575
1576
  /* fs_id */
1577
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1578
1579
0
  offset += 4;
1580
1581
  /* atime */
1582
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1583
0
      hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1584
1585
  /* mtime */
1586
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1587
0
      hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1588
1589
  /* ctime */
1590
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1591
0
      hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1592
1593
0
  return offset;
1594
0
}
1595
1596
/* TODO: incomplete */
1597
static unsigned
1598
dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1599
    packet_info *pinfo)
1600
0
{
1601
  /* path */
1602
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1603
1604
  /* handle */
1605
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1606
1607
  /* fs_id */
1608
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1609
1610
0
  offset += 4;
1611
1612
  /* atime */
1613
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1614
0
      hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1615
1616
  /* mtime */
1617
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1618
0
      hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1619
1620
  /* ctime */
1621
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1622
0
      hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1623
1624
0
  return offset;
1625
0
}
1626
1627
static unsigned
1628
dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1629
    packet_info *pinfo)
1630
0
{
1631
  /* path */
1632
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1633
1634
  /* New directory entry handle */
1635
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
1636
0
      NULL);
1637
1638
  /* Parent handle */
1639
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1640
1641
  /* fs_id */
1642
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1643
1644
  /* Parent atime */
1645
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
1646
0
      hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
1647
1648
  /* Parent mtime */
1649
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
1650
0
      hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
1651
1652
  /* Parent ctime */
1653
0
  offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
1654
0
      hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
1655
1656
0
  return offset;
1657
0
}
1658
1659
static unsigned
1660
dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1661
    packet_info *pinfo)
1662
0
{
1663
  /* handle */
1664
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1665
1666
  /* fs_id */
1667
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1668
1669
0
  offset += 4;
1670
1671
  /* size */
1672
0
  proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1673
0
  offset += 8;
1674
1675
  /* TODO: flags */
1676
0
  proto_tree_add_item(tree, hf_pvfs_truncate_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1677
0
  offset += 4;
1678
1679
0
  return offset;
1680
0
}
1681
1682
static unsigned
1683
dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1684
    packet_info *pinfo)
1685
0
{
1686
0
  unsigned count, i;
1687
1688
  /* fs_id */
1689
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1690
1691
0
  offset += 4;
1692
1693
  /* attr */
1694
0
  offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1695
1696
  /* handle_extent_array */
1697
0
  count = tvb_get_letohl(tvb, offset);
1698
0
  offset += 4;
1699
1700
0
  for (i = 0; i < count; i++)
1701
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1702
1703
0
  return offset;
1704
0
}
1705
1706
static unsigned
1707
dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1708
    packet_info *pinfo)
1709
0
{
1710
  /* object_ref: handle */
1711
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1712
1713
  /* object_ref: fs_id */
1714
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1715
1716
  /* ds_position */
1717
0
  proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1718
0
  offset += 4;
1719
1720
  /* dirent_limit */
1721
0
  proto_tree_add_item(tree, hf_pvfs_dirent_limit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1722
0
  offset += 4;
1723
1724
0
  return offset;
1725
0
}
1726
1727
static unsigned
1728
dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
1729
    unsigned offset, packet_info *pinfo)
1730
0
{
1731
  /* handle */
1732
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1733
1734
  /* fs_id */
1735
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1736
1737
  /* flags */
1738
0
  proto_tree_add_item(tree, hf_pvfs_flush_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1739
0
  offset += 4;
1740
1741
0
  return offset;
1742
0
}
1743
1744
static unsigned
1745
dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
1746
    unsigned offset, packet_info *pinfo)
1747
0
{
1748
  /* fs_id */
1749
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1750
1751
  /* server_param */
1752
0
  offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
1753
1754
0
  return offset;
1755
0
}
1756
1757
static unsigned
1758
dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1759
    packet_info *pinfo _U_)
1760
0
{
1761
  /* fs_id */
1762
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1763
1764
0
  return offset;
1765
0
}
1766
1767
static unsigned
1768
dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
1769
    unsigned offset, packet_info *pinfo _U_)
1770
0
{
1771
  /* TODO: next_id */
1772
0
  proto_tree_add_item(tree, hf_pvfs_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1773
0
  offset += 4;
1774
1775
  /* TODO: count */
1776
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1777
0
  offset += 4;
1778
1779
0
  return offset;
1780
0
}
1781
1782
static unsigned
1783
dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
1784
    unsigned offset, packet_info *pinfo)
1785
0
{
1786
  /* fs_id */
1787
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1788
1789
  /* handle */
1790
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1791
1792
0
  return offset;
1793
0
}
1794
1795
static unsigned
1796
dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
1797
    proto_tree *tree, unsigned offset, packet_info *pinfo)
1798
0
{
1799
0
  uint32_t handle_count, i;
1800
1801
  /* fs_id */
1802
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1803
1804
  /* handle count */
1805
0
  handle_count = tvb_get_letohl(tvb, offset);
1806
0
  offset += 4;
1807
1808
0
  for (i = 0; i < handle_count; i++)
1809
0
  {
1810
    /* handle */
1811
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1812
0
  }
1813
1814
0
  return offset;
1815
0
}
1816
1817
static unsigned
1818
dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
1819
    unsigned offset, packet_info *pinfo _U_)
1820
0
{
1821
  /* event_count */
1822
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_event_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1823
0
  offset += 4;
1824
1825
0
  return offset;
1826
0
}
1827
1828
static unsigned
1829
dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
1830
    unsigned offset, packet_info *pinfo)
1831
0
{
1832
  /* Handle */
1833
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1834
1835
  /* fs_id */
1836
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1837
1838
0
  return offset;
1839
0
}
1840
1841
static unsigned
1842
dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
1843
    proto_tree *tree, unsigned offset, packet_info *pinfo)
1844
0
{
1845
  /* Handle */
1846
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1847
1848
  /* fs_id */
1849
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1850
1851
  /* */
1852
0
  offset += 4;
1853
1854
  /* entry */
1855
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1856
1857
0
  return offset;
1858
0
}
1859
1860
static unsigned
1861
dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
1862
    proto_tree *tree, unsigned offset, packet_info *pinfo)
1863
0
{
1864
  /* Handle */
1865
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1866
1867
  /* fs_id */
1868
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1869
1870
0
  return offset;
1871
0
}
1872
1873
/* TODO: untested/incomplete */
1874
static unsigned
1875
dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, unsigned offset, packet_info *pinfo)
1876
0
{
1877
  /* attribute key */
1878
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
1879
0
      pinfo, NULL);
1880
1881
  /* attribute value */
1882
0
  offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
1883
0
      pinfo, NULL);
1884
1885
0
  return offset;
1886
0
}
1887
1888
/* TODO: incomplete/untested */
1889
static unsigned
1890
dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, unsigned offset, packet_info *pinfo)
1891
0
{
1892
0
  uint32_t nKey, i;
1893
1894
  /* number of keys and vals */
1895
0
  nKey = tvb_get_letohl(tvb, offset);
1896
0
  offset += 4;
1897
1898
0
  for (i = 0; i < nKey; i++)
1899
0
    offset = dissect_pvfs_ds_keyval(tvb, tree, offset, pinfo);
1900
1901
0
  return offset;
1902
0
}
1903
1904
/* TODO: incomplete/untested */
1905
static unsigned
1906
dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
1907
    unsigned offset, packet_info *pinfo)
1908
0
{
1909
  /* handle */
1910
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1911
1912
  /* fs_id */
1913
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1914
1915
0
  offset += 4;
1916
1917
0
  offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
1918
1919
0
  return offset;
1920
0
}
1921
1922
/* TODO: incomplete/untested */
1923
static unsigned
1924
dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
1925
    unsigned offset, packet_info *pinfo)
1926
0
{
1927
  /* handle */
1928
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1929
1930
  /* fs_id */
1931
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1932
1933
0
  offset += 4;
1934
1935
0
  offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
1936
1937
0
  return offset;
1938
0
}
1939
1940
/* TODO: untested */
1941
static unsigned
1942
dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
1943
    unsigned offset, packet_info *pinfo)
1944
0
{
1945
  /* handle */
1946
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1947
1948
  /* fs_id */
1949
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
1950
1951
  /* key */
1952
0
  offset = dissect_pvfs_ds_keyval(tvb, tree, offset, pinfo);
1953
1954
0
  return offset;
1955
0
}
1956
1957
static void
1958
pvfc_fmt_release_num(char *result, uint32_t release_nr)
1959
0
{
1960
0
  snprintf( result, ITEM_LABEL_LENGTH, "%d (%d.%d.%d)",
1961
0
      release_nr,
1962
0
      release_nr / 10000,
1963
0
      (release_nr % 10000) / 100,
1964
0
      (release_nr % 10000) % 100);
1965
0
}
1966
1967
static unsigned
1968
dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1969
0
{
1970
  /* PVFS release number */
1971
0
  proto_tree_add_item(tree, hf_pvfs_release_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1972
0
  offset += 4;
1973
1974
  /* wire encoding type */
1975
0
  proto_tree_add_item(tree, hf_pvfs_encoding, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1976
0
  offset += 4;
1977
1978
  /* server op */
1979
0
  proto_tree_add_item(tree, hf_pvfs_server_op, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1980
0
  offset += 4;
1981
1982
0
  return offset;
1983
0
}
1984
1985
static unsigned
1986
dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
1987
    packet_info *pinfo, uint32_t server_op)
1988
0
{
1989
  /* context_id */
1990
0
  proto_tree_add_item(tree, hf_pvfs_context_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1991
0
  offset += 4;
1992
1993
  /* credentials */
1994
0
  offset = dissect_pvfs_credentials(tvb, tree, offset);
1995
1996
0
  switch (server_op)
1997
0
  {
1998
0
    case  PVFS_SERV_CREATE:
1999
0
      offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
2000
0
      break;
2001
2002
0
    case  PVFS_SERV_REMOVE:
2003
0
      offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
2004
0
      break;
2005
2006
0
    case  PVFS_SERV_IO:
2007
0
      offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
2008
0
      break;
2009
2010
0
    case PVFS_SERV_GETATTR:
2011
0
      offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
2012
0
      break;
2013
2014
0
    case PVFS_SERV_SETATTR:
2015
0
      offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
2016
0
      break;
2017
2018
0
    case PVFS_SERV_LOOKUP_PATH:
2019
0
      offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
2020
0
      break;
2021
2022
0
    case PVFS_SERV_CRDIRENT:
2023
0
      offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
2024
0
      break;
2025
2026
0
    case PVFS_SERV_RMDIRENT:
2027
0
      offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
2028
0
      break;
2029
2030
0
    case  PVFS_SERV_CHDIRENT:
2031
0
      offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
2032
0
      break;
2033
2034
0
    case  PVFS_SERV_TRUNCATE:
2035
0
      offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
2036
0
      break;
2037
2038
0
    case  PVFS_SERV_MKDIR:
2039
0
      offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
2040
0
      break;
2041
2042
0
    case  PVFS_SERV_READDIR:
2043
0
      offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
2044
0
      break;
2045
2046
#if 0
2047
    case PVFS_SERV_GETCONFIG:
2048
      /* No parameters in request */
2049
      break;
2050
#endif
2051
2052
#if 0
2053
    case  PVFS_SERV_WRITE_COMPLETION:
2054
      /* No parameters in request */
2055
      break;
2056
#endif
2057
2058
0
    case  PVFS_SERV_FLUSH:
2059
0
      offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
2060
0
      break;
2061
2062
0
    case  PVFS_SERV_MGMT_SETPARAM:
2063
0
      offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
2064
0
          pinfo);
2065
0
      break;
2066
2067
#if 0
2068
    case  PVFS_SERV_MGMT_NOOP:
2069
      /* No parameters in request */
2070
      break;
2071
#endif
2072
2073
0
    case  PVFS_SERV_STATFS:
2074
0
      offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
2075
0
      break;
2076
2077
#if 0
2078
    case  PVFS_SERV_PERF_UPDATE:
2079
      /* No parameters in request */
2080
      break;
2081
#endif
2082
2083
0
    case  PVFS_SERV_MGMT_PERF_MON:
2084
0
      offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
2085
0
          pinfo);
2086
0
      break;
2087
2088
0
    case  PVFS_SERV_MGMT_ITERATE_HANDLES:
2089
0
      offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
2090
0
          offset, pinfo);
2091
0
      break;
2092
2093
0
    case  PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2094
0
      offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
2095
0
          offset, pinfo);
2096
0
      break;
2097
2098
0
    case  PVFS_SERV_MGMT_EVENT_MON:
2099
0
      offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
2100
0
          pinfo);
2101
0
      break;
2102
2103
0
    case  PVFS_SERV_MGMT_REMOVE_OBJECT:
2104
0
      offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
2105
0
          pinfo);
2106
0
      break;
2107
2108
0
    case  PVFS_SERV_MGMT_REMOVE_DIRENT:
2109
0
      offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
2110
0
          pinfo);
2111
0
      break;
2112
2113
0
    case  PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2114
0
      offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
2115
0
          offset, pinfo);
2116
0
      break;
2117
2118
#if 0
2119
    case  PVFS_SERV_JOB_TIMER:
2120
      /* No parameters in request */
2121
      break;
2122
#endif
2123
2124
0
    case  PVFS_SERV_PROTO_ERROR:
2125
      /* TODO: is this necessary? */
2126
0
      break;
2127
2128
0
    case  PVFS_SERV_GETEATTR:
2129
0
      offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
2130
0
      break;
2131
2132
0
    case  PVFS_SERV_SETEATTR:
2133
0
      offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
2134
0
      break;
2135
2136
0
    case  PVFS_SERV_DELEATTR:
2137
0
      offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
2138
0
      break;
2139
2140
0
    default:
2141
      /* TODO: what should we do here? */
2142
0
      break;
2143
0
  }
2144
2145
0
  return offset;
2146
0
}
2147
2148
/*
2149
 * =======================================================================
2150
 * Response handlers
2151
 * =======================================================================
2152
 */
2153
2154
static unsigned
2155
dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2156
    packet_info *pinfo)
2157
0
{
2158
  /* Handle */
2159
0
  return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2160
0
}
2161
2162
static unsigned
2163
dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
2164
0
{
2165
0
  return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
2166
0
}
2167
2168
static unsigned
2169
dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
2170
    unsigned offset, packet_info *pinfo)
2171
0
{
2172
0
  offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
2173
2174
0
  return offset;
2175
0
}
2176
2177
static unsigned
2178
dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
2179
    unsigned offset, packet_info *pinfo)
2180
0
{
2181
0
  uint32_t nCount = 0;
2182
0
  uint32_t handle_count = 0;
2183
0
  uint32_t attr_count = 0;
2184
0
  proto_tree *attr_tree;
2185
2186
0
  offset += 4;
2187
2188
  /* handle_count */
2189
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_lookup_path_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &handle_count);
2190
0
  offset += 4;
2191
2192
  /* TODO: add bounds checking */
2193
0
  for (nCount = 0; nCount < handle_count; nCount++)
2194
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2195
2196
0
  offset += 4;
2197
2198
  /* array of attributes */
2199
0
  attr_count = tvb_get_letohl(tvb, offset);
2200
2201
0
  attr_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
2202
0
        ett_pvfs_attr, NULL, "Attribute array (total items: %d)", attr_count);
2203
2204
0
  offset += 4;
2205
2206
  /* Array of attributes */
2207
0
  for (nCount = 0; nCount < attr_count; nCount++)
2208
0
    offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
2209
2210
0
  return offset;
2211
0
}
2212
2213
static unsigned
2214
dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2215
    packet_info *pinfo)
2216
0
{
2217
  /* Handle */
2218
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2219
2220
0
  return offset;
2221
0
}
2222
2223
static unsigned
2224
dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2225
    packet_info *pinfo)
2226
0
{
2227
  /* Handle */
2228
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2229
2230
0
  return offset;
2231
0
}
2232
2233
static unsigned
2234
dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2235
    packet_info *pinfo)
2236
0
{
2237
  /* Handle */
2238
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2239
2240
0
  return offset;
2241
0
}
2242
2243
static unsigned
2244
dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2245
    packet_info *pinfo)
2246
0
{
2247
0
  uint32_t dirent_count = 0;
2248
0
  uint32_t nCount = 0;
2249
2250
  /* ds_position */
2251
0
  proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2252
0
  offset += 4;
2253
2254
0
  offset += 4;
2255
2256
  /* directory_version */
2257
0
  proto_tree_add_item(tree, hf_pvfs_directory_version, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2258
0
  offset += 8;
2259
2260
0
  offset += 4;
2261
2262
  /* dirent_count */
2263
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_dirent_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &dirent_count);
2264
0
  offset += 4;
2265
2266
0
  for (nCount = 0; nCount < dirent_count; nCount++)
2267
0
  {
2268
0
    offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
2269
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2270
0
  }
2271
2272
0
  return offset;
2273
0
}
2274
2275
/*
2276
 * TODO: this code needs work!  Not finished yet!
2277
 */
2278
static unsigned
2279
dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
2280
    unsigned offset, packet_info *pinfo)
2281
0
{
2282
0
  uint32_t i;
2283
0
  uint32_t total_bytes = 0, total_config_bytes = 0, total_lines = 0;
2284
0
  uint32_t bytes_processed = 0;
2285
0
  uint32_t length_remaining = 0;
2286
0
  const char *ptr = NULL;
2287
0
  proto_tree *tree, *config_tree = NULL;
2288
  /*uint8_t truncated = 0;*/
2289
2290
0
  tree = proto_tree_add_subtree(parent_tree, tvb, offset, 12,
2291
0
        ett_pvfs_server_config, NULL, "Server Config");
2292
2293
  /* Total number of bytes in server config (incl. entry count) */
2294
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_getconfig_response_total_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN, &total_bytes);
2295
0
  offset += 4;
2296
2297
  /* There must be at least 4 bytes of data returned to determine the
2298
   * size of the server config data
2299
   */
2300
0
  if (total_bytes < 4)
2301
0
  {
2302
    /* Server config not returned, bail out */
2303
0
    return offset;
2304
0
  }
2305
2306
  /* Number of entries in server config */
2307
0
  total_lines = tvb_get_letohl(tvb, offset);
2308
0
  proto_tree_add_item(tree, hf_pvfs_getconfig_response_lines, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2309
0
  offset += 4;
2310
2311
  /* Number of bytes in server config */
2312
0
  total_config_bytes = tvb_get_letohl(tvb, offset);
2313
0
  proto_tree_add_item(tree, hf_pvfs_getconfig_response_config_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2314
0
  offset += 4;
2315
2316
  /* Get pointer to server config data */
2317
0
  ptr = (const char*)tvb_get_ptr(tvb, offset, total_config_bytes);
2318
2319
0
  if (!ptr)
2320
0
  {
2321
    /* Not enough data. Bail out. */
2322
0
    return offset;
2323
0
  }
2324
2325
  /* Check if all data is available */
2326
0
  length_remaining = tvb_captured_length_remaining(tvb, offset);
2327
2328
0
  if (length_remaining < total_config_bytes)
2329
0
  {
2330
0
    total_config_bytes = length_remaining;
2331
2332
    /*truncated = 1;*/
2333
0
  }
2334
2335
0
  bytes_processed = 0;
2336
2337
0
  for (i = 0; i < total_lines; i++)
2338
0
  {
2339
0
    uint8_t entry[256], *pentry = entry;
2340
0
    char *tmp_entry = NULL;
2341
0
    uint32_t entry_length = 0, tmp_entry_length = 0;
2342
0
    uint32_t bufsiz = sizeof(entry);
2343
2344
0
    while ((bytes_processed < total_config_bytes) &&
2345
0
        (entry_length < bufsiz) &&
2346
0
        (*ptr != '\n') && (*ptr != '\0'))
2347
0
    {
2348
0
      *pentry++ = *ptr++;
2349
2350
0
      bytes_processed++;
2351
0
      entry_length++;
2352
0
    }
2353
2354
0
    if ((entry_length == bufsiz) &&
2355
0
        ((entry[entry_length - 1] != '\n') &&
2356
0
         (entry[entry_length - 1] != '\0')))
2357
0
    {
2358
      /*
2359
       * Single line of config data doesn't fit into provided buffer,
2360
       * config data is malformed.
2361
       */
2362
2363
0
      break;
2364
0
    }
2365
2366
0
    if (bytes_processed == total_config_bytes)
2367
0
    {
2368
      /* Oops...  ran out of data before we could complete the entry */
2369
0
      break;
2370
0
    }
2371
2372
0
    *pentry= '\0';
2373
2374
0
    tmp_entry = (char*)get_ascii_string(pinfo->pool, entry, entry_length);
2375
0
    tmp_entry_length = (uint32_t)strlen(tmp_entry);
2376
2377
    /* Remove all whitespace from front of entry */
2378
0
    while ((tmp_entry_length > 0) && (!g_ascii_isalnum(*tmp_entry)) &&
2379
0
        (*tmp_entry != '<'))
2380
0
    {
2381
0
      tmp_entry++;
2382
0
      tmp_entry_length--;
2383
0
    }
2384
2385
0
    if (tmp_entry[0] == '<')
2386
0
    {
2387
0
      if (tmp_entry[tmp_entry_length - 1] == '>')
2388
0
      {
2389
        /* Token */
2390
0
        if (tmp_entry[1] != '/')
2391
0
        {
2392
          /* Opening token, create new tree root */
2393
0
          config_tree = proto_tree_add_subtree(tree, tvb, offset,
2394
0
              tmp_entry_length, ett_pvfs_server_config_branch, NULL, tmp_entry);
2395
0
        }
2396
0
        else
2397
0
        {
2398
          /* Closing token */
2399
0
          config_tree = NULL;
2400
0
        }
2401
0
      }
2402
0
      else
2403
0
      {
2404
        /* Malformed token */
2405
0
        break;
2406
0
      }
2407
0
    }
2408
0
    else
2409
0
    {
2410
      /* Insert items into the root config tree if there's no subtree
2411
       * defined.
2412
       */
2413
0
      if (config_tree == NULL)
2414
0
        config_tree = tree;
2415
2416
0
      if (tmp_entry_length > 0)
2417
0
      {
2418
0
        proto_tree_add_string_format(config_tree, hf_pvfs_getconfig_response_entry, tvb, offset, tmp_entry_length,
2419
0
            tmp_entry, "%s", tmp_entry);
2420
0
      }
2421
0
    }
2422
2423
0
    offset += entry_length + 1;
2424
2425
0
    ptr++;
2426
0
    bytes_processed++;
2427
0
  }
2428
2429
0
  if (bytes_processed < total_config_bytes)
2430
0
  {
2431
    /* We ran out of server config data */
2432
0
    proto_tree_add_expert_remaining(config_tree, pinfo, &ei_pvfs_malformed, tvb, offset);
2433
0
  }
2434
2435
0
  return offset;
2436
0
}
2437
2438
static unsigned
2439
dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
2440
    unsigned offset)
2441
0
{
2442
  /* size */
2443
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
2444
0
      NULL);
2445
2446
0
  return offset;
2447
0
}
2448
2449
static unsigned
2450
dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
2451
    unsigned offset)
2452
0
{
2453
  /* old_value */
2454
0
  proto_tree_add_item(tree, hf_pvfs_prev_value, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2455
2456
0
  offset += 8;
2457
2458
0
  return offset;
2459
0
}
2460
2461
static unsigned
2462
dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
2463
0
{
2464
0
  offset += 4;
2465
2466
  /* fs_id */
2467
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
2468
2469
  /* bytes_available */
2470
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
2471
0
      NULL);
2472
2473
  /* bytes_total */
2474
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
2475
0
      NULL);
2476
2477
  /* RAM bytes total */
2478
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
2479
0
      NULL);
2480
2481
  /* RAM bytes free */
2482
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
2483
0
      NULL);
2484
2485
  /* load average (1s) */
2486
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
2487
0
      NULL);
2488
2489
  /* load average (5s) */
2490
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
2491
0
      NULL);
2492
2493
  /* load average (15s) */
2494
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
2495
0
      NULL);
2496
2497
  /* uptime (seconds) */
2498
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
2499
0
      NULL);
2500
2501
  /* handles_available_count */
2502
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
2503
0
      NULL);
2504
2505
  /* handles_total_count */
2506
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
2507
0
      NULL);
2508
2509
0
  return offset;
2510
0
}
2511
2512
static unsigned
2513
dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2514
    int nItem)
2515
0
{
2516
0
  proto_tree *stat_tree;
2517
2518
0
  stat_tree = proto_tree_add_subtree_format(tree, tvb, offset, 48,
2519
0
        ett_pvfs_mgmt_perf_stat, NULL, "Stat Array - Element %d", nItem);
2520
2521
  /* TODO: valid_flag */
2522
0
  proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_valid_flag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2523
0
  offset += 4;
2524
2525
  /* TODO: id */
2526
0
  proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2527
0
  offset += 4;
2528
2529
0
  offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
2530
0
      NULL);
2531
0
  offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
2532
0
      NULL);
2533
0
  offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
2534
0
      NULL);
2535
0
  offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
2536
0
      NULL);
2537
0
  offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
2538
0
      NULL);
2539
2540
0
  return offset;
2541
0
}
2542
2543
static unsigned
2544
dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
2545
    unsigned offset)
2546
0
{
2547
0
  uint32_t perf_array_count, i;
2548
2549
  /* suggested_next_id */
2550
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_response_suggested_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2551
0
  offset += 4;
2552
2553
0
  offset += 4;
2554
2555
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms, NULL);
2556
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms, NULL);
2557
2558
0
  offset += 4;
2559
2560
  /* perf_array_count */
2561
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_mgmt_perf_mon_response_perf_array_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &perf_array_count);
2562
0
  offset += 4;
2563
2564
0
  for (i = 0; i < perf_array_count; i++)
2565
0
    offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
2566
2567
0
  return offset;
2568
0
}
2569
2570
static unsigned
2571
dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
2572
    unsigned offset, packet_info *pinfo)
2573
0
{
2574
0
  uint32_t handle_count, i;
2575
2576
  /* ds_position */
2577
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_iterate_handles_response_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2578
0
  offset += 4;
2579
2580
  /* handle_count */
2581
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_mgmt_iterate_handles_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &handle_count);
2582
0
  offset += 4;
2583
2584
  /* TODO: this could be improved */
2585
0
  for (i = 0; i < handle_count; i++)
2586
0
    offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2587
2588
0
  return offset;
2589
0
}
2590
2591
static unsigned
2592
dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2593
    packet_info *pinfo)
2594
0
{
2595
0
  offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2596
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2597
0
  offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
2598
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
2599
0
      NULL);
2600
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
2601
0
      NULL);
2602
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2603
2604
0
  return offset;
2605
0
}
2606
2607
static unsigned
2608
dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
2609
    unsigned offset, packet_info *pinfo)
2610
0
{
2611
0
  uint32_t dspace_info_count, i;
2612
0
  proto_tree *arr_tree = NULL;
2613
2614
0
  offset += 4;
2615
2616
  /* dspace_info_count */
2617
0
  proto_tree_add_item_ret_uint(tree, hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &dspace_info_count);
2618
2619
0
  offset += 4;
2620
2621
0
  if ((dspace_info_count > 0) && (tree))
2622
0
  {
2623
0
    arr_tree = proto_tree_add_subtree_format(tree, tvb, offset,
2624
0
        (dspace_info_count > (uint32_t)(INT_MAX / 40)) ? -1 : (int)(dspace_info_count * 40),
2625
0
        ett_pvfs_mgmt_dspace_info, NULL, "dspace_info Array (%u items)",
2626
0
        dspace_info_count);
2627
0
  }
2628
2629
0
  for (i = 0; i < dspace_info_count; i++)
2630
0
    offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
2631
2632
0
  return offset;
2633
0
}
2634
2635
static unsigned
2636
dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
2637
    unsigned offset)
2638
0
{
2639
  /* api */
2640
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_api, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2641
0
  offset += 4;
2642
2643
  /* operation */
2644
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_operation, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2645
0
  offset += 4;
2646
2647
  /* value */
2648
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_value, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2649
0
  offset += 4;
2650
2651
  /* id */
2652
0
  offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
2653
0
      NULL);
2654
2655
  /* flags */
2656
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2657
0
  offset += 4;
2658
2659
  /* tv_sec */
2660
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_sec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2661
0
  offset += 4;
2662
2663
  /* tv_usec */
2664
0
  proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_usec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2665
0
  offset += 4;
2666
2667
0
  offset += 4;
2668
2669
0
  return offset;
2670
0
}
2671
2672
static unsigned
2673
dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
2674
    unsigned offset, packet_info *pinfo)
2675
0
{
2676
  /* handle */
2677
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2678
2679
  /* fs_id */
2680
0
  offset = dissect_pvfs_fs_id(tvb, tree, offset);
2681
2682
0
  return offset;
2683
0
}
2684
2685
static unsigned
2686
dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
2687
    proto_tree *tree, unsigned offset, packet_info *pinfo)
2688
0
{
2689
  /* handle */
2690
0
  offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2691
2692
0
  return offset;
2693
0
}
2694
2695
/* TODO: untested */
2696
static unsigned
2697
dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2698
    packet_info *pinfo _U_)
2699
0
{
2700
0
  offset += 4;
2701
2702
  /* Dissect nKey & ds_keyval array */
2703
0
  offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
2704
2705
0
  return offset;
2706
0
}
2707
2708
static unsigned
2709
dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
2710
    packet_info *pinfo, uint32_t server_op)
2711
0
{
2712
  /* error code */
2713
0
  offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2714
2715
0
  switch (server_op)
2716
0
  {
2717
0
    case PVFS_SERV_CREATE:
2718
0
      offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
2719
0
      break;
2720
2721
#if 0
2722
    case PVFS_SERV_REMOVE:
2723
      /* No result data */
2724
      break;
2725
#endif
2726
2727
0
    case PVFS_SERV_IO:
2728
0
      offset = dissect_pvfs2_io_response(tvb, tree, offset);
2729
0
      break;
2730
2731
0
    case PVFS_SERV_GETATTR:
2732
0
      offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
2733
0
      break;
2734
2735
0
    case PVFS_SERV_SETATTR:
2736
      /* No result data */
2737
0
      break;
2738
2739
0
    case PVFS_SERV_LOOKUP_PATH:
2740
0
      offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
2741
0
      break;
2742
2743
#if 0
2744
    case PVFS_SERV_CRDIRENT:
2745
      /* No result data */
2746
      break;
2747
#endif
2748
2749
0
    case PVFS_SERV_RMDIRENT:
2750
0
      offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
2751
0
      break;
2752
2753
0
    case PVFS_SERV_CHDIRENT:
2754
0
      offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
2755
0
      break;
2756
2757
#if 0
2758
    case PVFS_SERV_TRUNCATE:
2759
      /* No result data */
2760
      break;
2761
#endif
2762
2763
0
    case PVFS_SERV_MKDIR:
2764
0
      offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
2765
0
      break;
2766
2767
0
    case PVFS_SERV_READDIR:
2768
0
      offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
2769
0
      break;
2770
2771
0
    case PVFS_SERV_GETCONFIG:
2772
0
      offset = dissect_pvfs2_getconfig_response(tvb, tree, offset, pinfo);
2773
0
      break;
2774
2775
0
    case PVFS_SERV_WRITE_COMPLETION:
2776
0
      offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
2777
0
      break;
2778
2779
#if 0
2780
    case PVFS_SERV_FLUSH:
2781
      /* No result data */
2782
      break;
2783
#endif
2784
2785
0
    case PVFS_SERV_MGMT_SETPARAM:
2786
0
      offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
2787
0
      break;
2788
2789
#if 0
2790
    case PVFS_SERV_MGMT_NOOP:
2791
      /* No result data */
2792
      break;
2793
#endif
2794
2795
0
    case PVFS_SERV_STATFS:
2796
0
      offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
2797
0
      break;
2798
2799
#if 0
2800
    case PVFS_SERV_PERF_UPDATE:
2801
      /* No result data */
2802
      break;
2803
#endif
2804
2805
0
    case PVFS_SERV_MGMT_PERF_MON:
2806
0
      offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
2807
0
      break;
2808
2809
0
    case PVFS_SERV_MGMT_ITERATE_HANDLES:
2810
0
      offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
2811
0
          offset, pinfo);
2812
0
      break;
2813
2814
0
    case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2815
0
      offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
2816
0
          offset, pinfo);
2817
0
      break;
2818
2819
0
    case PVFS_SERV_MGMT_EVENT_MON:
2820
0
      offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
2821
0
      break;
2822
2823
0
    case PVFS_SERV_MGMT_REMOVE_OBJECT:
2824
0
      offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
2825
0
          pinfo);
2826
0
      break;
2827
2828
#if 0
2829
    case PVFS_SERV_MGMT_REMOVE_DIRENT:
2830
      /* No result data */
2831
      break;
2832
#endif
2833
2834
0
    case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2835
0
      offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
2836
0
          offset, pinfo);
2837
0
      break;
2838
2839
#if 0
2840
    case PVFS_SERV_JOB_TIMER:
2841
      /* No result data */
2842
      break;
2843
#endif
2844
2845
0
    case PVFS_SERV_PROTO_ERROR:
2846
      /* No result data */
2847
0
      break;
2848
2849
      /* TODO: untested */
2850
0
    case PVFS_SERV_GETEATTR:
2851
0
      offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
2852
0
      break;
2853
2854
#if 0
2855
    case PVFS_SERV_SETEATTR:
2856
      /* No result data */
2857
      break;
2858
#endif
2859
2860
#if 0
2861
    case PVFS_SERV_DELEATTR:
2862
      /* No result data */
2863
      break;
2864
#endif
2865
2866
0
    default:
2867
      /* TODO: what do we do here? */
2868
0
      break;
2869
0
  }
2870
2871
0
  return offset;
2872
0
}
2873
2874
static wmem_map_t *pvfs2_io_tracking_value_table;
2875
2876
typedef struct pvfs2_io_tracking_key
2877
{
2878
  uint64_t tag;
2879
} pvfs2_io_tracking_key_t;
2880
2881
typedef struct pvfs2_io_tracking_value
2882
{
2883
  uint32_t request_frame_num;
2884
  uint32_t response_frame_num;
2885
  uint32_t flow_frame_num;
2886
2887
} pvfs2_io_tracking_value_t;
2888
2889
static int
2890
pvfs2_io_tracking_equal(const void *k1, const void *k2)
2891
0
{
2892
0
  const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
2893
0
  const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
2894
2895
0
  return (key1->tag == key2->tag);
2896
0
}
2897
2898
static unsigned
2899
pvfs2_io_tracking_hash(const void *k)
2900
0
{
2901
0
  const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
2902
2903
0
  return (unsigned) ((key->tag >> 32) ^ ((uint32_t) key->tag));
2904
0
}
2905
2906
static pvfs2_io_tracking_value_t *
2907
pvfs2_io_tracking_new_with_tag(uint64_t tag, uint32_t num)
2908
0
{
2909
0
  pvfs2_io_tracking_value_t *value;
2910
0
  pvfs2_io_tracking_key_t *newkey;
2911
2912
0
  newkey = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_key_t);
2913
0
  newkey->tag = tag;
2914
2915
0
  value = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_value_t);
2916
2917
0
  wmem_map_insert(pvfs2_io_tracking_value_table, newkey, value);
2918
2919
0
  value->request_frame_num = num;
2920
2921
0
  return value;
2922
0
}
2923
2924
static bool
2925
dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
2926
    bool dissect_other_as_continuation _U_)
2927
0
{
2928
0
  uint32_t mode = 0;
2929
0
  proto_item *item;
2930
0
  proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
2931
0
  unsigned offset = 0;
2932
0
  uint64_t tag;
2933
0
  uint32_t server_op;
2934
0
  pvfs2_io_tracking_value_t *val = NULL;
2935
2936
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
2937
2938
0
  col_clear(pinfo->cinfo, COL_INFO);
2939
2940
0
  item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, ENC_NA);
2941
0
  pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
2942
2943
0
  proto_tree_add_item(pvfs_tree, hf_pvfs_version2, tvb, 0, -1, ENC_NA);
2944
2945
  /* PVFS packet header is 24 bytes */
2946
0
  pvfs_htree = proto_tree_add_subtree(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
2947
0
      ett_pvfs_hdr, NULL, "BMI Header");
2948
2949
  /* Magic number */
2950
0
  proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2951
0
  offset += 4;
2952
2953
  /* TCP message mode (32-bit) */
2954
0
  mode = tvb_get_letohl(tvb, offset);
2955
0
  proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
2956
0
  offset += 4;
2957
2958
  /* tag (64-bit) */
2959
0
  offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
2960
2961
  /* size (64-bit) */
2962
0
  offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
2963
2964
  /* Lookahead to get server_op (invalid if frame contains flow data) */
2965
0
  server_op = tvb_get_letohl(tvb, offset + 8);
2966
2967
0
  if (mode == TCP_MODE_UNEXP)
2968
0
  {
2969
    /* Add entry to tracking table for PVFS_SERV_IO request */
2970
0
    if ((server_op == PVFS_SERV_IO) && !pinfo->fd->visited)
2971
0
      val = pvfs2_io_tracking_new_with_tag(tag, pinfo->num);
2972
0
  }
2973
0
  else
2974
0
  {
2975
0
    pvfs2_io_tracking_key_t key;
2976
2977
0
    memset(&key, 0, sizeof(key));
2978
0
    key.tag = tag;
2979
2980
0
    val = (pvfs2_io_tracking_value_t *)wmem_map_lookup(pvfs2_io_tracking_value_table, &key);
2981
2982
    /* If this frame contains a known PVFS_SERV_IO tag, track it */
2983
0
    if (val && !pinfo->fd->visited)
2984
0
    {
2985
      /* If response HAS NOT been seen, mark this frame as response */
2986
0
      if (val->response_frame_num == 0)
2987
0
        val->response_frame_num = pinfo->num;
2988
0
      else
2989
0
      {
2990
        /* If response HAS been seen, this frame is flow data */
2991
0
        if (val->flow_frame_num == 0)
2992
0
          val->flow_frame_num = pinfo->num;
2993
0
      }
2994
0
    }
2995
0
  }
2996
2997
0
  if (val && (val->flow_frame_num == pinfo->num))
2998
0
  {
2999
    /* This frame is marked as being flow data */
3000
0
    col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
3001
3002
0
    proto_tree_add_item(pvfs_tree, hf_pvfs_flow_data, tvb, offset, -1, ENC_NA);
3003
3004
0
    return true;
3005
0
  }
3006
3007
  /* Extract common part of packet found in requests and responses */
3008
0
  offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
3009
3010
  /* Update column info display */
3011
0
  col_add_str(pinfo->cinfo, COL_INFO,
3012
0
      val_to_str(pinfo->pool, server_op, names_pvfs_server_op, "%u (unknown)"));
3013
3014
0
  col_append_str(pinfo->cinfo, COL_INFO,
3015
0
      (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
3016
3017
  /* TODO: handle all modes */
3018
0
  if (mode == TCP_MODE_UNEXP)
3019
0
  {
3020
    /* Request */
3021
0
    /*offset = */dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
3022
0
  }
3023
0
  else
3024
0
  {
3025
    /* TODO: re-examine this! */
3026
#if 0
3027
    if (mode == TCP_MODE_REND)
3028
    {
3029
      /*
3030
       * TODO: move this code outside so it's common for requests and
3031
       * responses
3032
       */
3033
3034
      col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
3035
    }
3036
    else
3037
#endif
3038
0
    {
3039
      /* Response */
3040
0
      /*offset = */dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
3041
0
          server_op);
3042
0
    }
3043
0
  }
3044
3045
0
  return true;
3046
0
}
3047
3048
/* Register the protocol with Wireshark */
3049
void
3050
proto_register_pvfs(void)
3051
16
{
3052
16
  static hf_register_info hf[] = {
3053
16
    { &hf_pvfs_magic_nr,
3054
16
      { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
3055
16
        NULL, 0, NULL, HFILL }},
3056
3057
16
    { &hf_pvfs_uid,
3058
16
      { "UID", "pvfs.uid", FT_UINT32, BASE_DEC,
3059
16
        NULL, 0, NULL, HFILL }},
3060
3061
16
    { &hf_pvfs_gid,
3062
16
      { "GID", "pvfs.gid", FT_UINT32, BASE_DEC,
3063
16
        NULL, 0, NULL, HFILL }},
3064
3065
16
    { &hf_pvfs_mode,
3066
16
      { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
3067
16
        VALS(names_pvfs_mode), 0, NULL, HFILL }},
3068
3069
16
    { &hf_pvfs_tag,
3070
16
      { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
3071
16
        NULL, 0, NULL, HFILL }},
3072
3073
16
    { &hf_pvfs_size,
3074
16
      { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
3075
16
        NULL, 0, NULL, HFILL }},
3076
3077
16
    { &hf_pvfs_release_number,
3078
16
      { "Release Number", "pvfs.release_number", FT_UINT32, BASE_CUSTOM,
3079
16
        CF_FUNC(pvfc_fmt_release_num), 0, NULL, HFILL }},
3080
3081
16
    { &hf_pvfs_encoding,
3082
16
      { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
3083
16
        VALS(names_pvfs_encoding), 0, NULL, HFILL }},
3084
3085
16
    { &hf_pvfs_server_op,
3086
16
      { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
3087
16
        VALS(names_pvfs_server_op), 0, NULL, HFILL }},
3088
3089
#if 0
3090
    { &hf_pvfs_handle,
3091
      { "Handle", "pvfs.handle", FT_BYTES, BASE_NONE,
3092
        NULL, 0, NULL, HFILL }},
3093
#endif
3094
3095
16
    { &hf_pvfs_fs_id,
3096
16
      { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
3097
16
        NULL, 0, "File System ID", HFILL }},
3098
3099
16
    { &hf_pvfs_attrmask,
3100
16
      { "Attribute Mask", "pvfs.attrmask", FT_UINT32, BASE_DEC,
3101
16
        NULL, 0, NULL, HFILL }},
3102
3103
16
    { &hf_pvfs_attr,
3104
16
      { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
3105
16
        VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
3106
3107
16
    { &hf_pvfs_ds_type,
3108
16
      { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
3109
16
        VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
3110
3111
16
    { &hf_pvfs_error,
3112
16
      { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
3113
16
        VALS(names_pvfs_error), 0, NULL, HFILL }},
3114
3115
16
    { &hf_pvfs_atime,
3116
16
      { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3117
16
        NULL, 0, "Access Time", HFILL }},
3118
3119
16
    { &hf_pvfs_atime_sec,
3120
16
      { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
3121
16
        NULL, 0, "Access Time (seconds)", HFILL }},
3122
3123
16
    { &hf_pvfs_atime_nsec,
3124
16
      { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
3125
16
        NULL, 0, "Access Time (microseconds)", HFILL }},
3126
3127
16
    { &hf_pvfs_mtime,
3128
16
      { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3129
16
        NULL, 0, "Modify Time", HFILL }},
3130
3131
16
    { &hf_pvfs_mtime_sec,
3132
16
      { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
3133
16
        NULL, 0, "Modify Time (seconds)", HFILL }},
3134
3135
16
    { &hf_pvfs_mtime_nsec,
3136
16
      { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
3137
16
        NULL, 0, "Modify Time (microseconds)", HFILL }},
3138
3139
16
    { &hf_pvfs_ctime,
3140
16
      { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3141
16
        NULL, 0, "Creation Time", HFILL }},
3142
3143
16
    { &hf_pvfs_ctime_sec,
3144
16
      { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
3145
16
        NULL, 0, "Creation Time (seconds)", HFILL }},
3146
3147
16
    { &hf_pvfs_ctime_nsec,
3148
16
      { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
3149
16
        NULL, 0, "Creation Time (microseconds)", HFILL }},
3150
3151
16
    { &hf_pvfs_parent_atime,
3152
16
      { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3153
16
        NULL, 0, "Access Time", HFILL }},
3154
3155
16
    { &hf_pvfs_parent_atime_sec,
3156
16
      { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
3157
16
        NULL, 0, "Access Time (seconds)", HFILL }},
3158
3159
16
    { &hf_pvfs_parent_atime_nsec,
3160
16
      { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
3161
16
        NULL, 0, "Access Time (microseconds)", HFILL }},
3162
3163
16
    { &hf_pvfs_parent_mtime,
3164
16
      { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3165
16
        NULL, 0, "Modify Time", HFILL }},
3166
3167
16
    { &hf_pvfs_parent_mtime_sec,
3168
16
      { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
3169
16
        NULL, 0, "Modify Time (seconds)", HFILL }},
3170
3171
16
    { &hf_pvfs_parent_mtime_nsec,
3172
16
      { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
3173
16
        NULL, 0, "Modify Time (microseconds)", HFILL }},
3174
3175
16
    { &hf_pvfs_parent_ctime,
3176
16
      { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3177
16
        NULL, 0, "Creation Time", HFILL }},
3178
3179
16
    { &hf_pvfs_parent_ctime_sec,
3180
16
      { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
3181
16
        NULL, 0, "Creation Time (seconds)", HFILL }},
3182
3183
16
    { &hf_pvfs_parent_ctime_nsec,
3184
16
      { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
3185
16
        NULL, 0, "Creation Time (microseconds)", HFILL }},
3186
3187
16
    { &hf_pvfs_dfile_count,
3188
16
      { "dfile_count", "pvfs.dfile_count", FT_UINT32, BASE_DEC,
3189
16
        NULL, 0, NULL, HFILL }},
3190
3191
16
    { &hf_pvfs_distribution,
3192
16
      { "Distribution", "pvfs.distribution", FT_STRING, BASE_NONE,
3193
16
        NULL, 0, NULL, HFILL }},
3194
3195
16
    { &hf_pvfs_dirent_count,
3196
16
      { "Dir Entry Count", "pvfs.dirent_count", FT_UINT32, BASE_DEC,
3197
16
        NULL, 0, "Directory Entry Count", HFILL }},
3198
3199
16
    { &hf_pvfs_directory_version,
3200
16
      { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
3201
16
        NULL, 0, NULL, HFILL }},
3202
3203
16
    { &hf_pvfs_path,
3204
16
      { "Path", "pvfs.path", FT_STRING, BASE_NONE,
3205
16
        NULL, 0, NULL, HFILL }},
3206
3207
16
    { &hf_pvfs_total_completed,
3208
16
      { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
3209
16
        NULL, 0, NULL, HFILL }},
3210
3211
16
    { &hf_pvfs_io_dist,
3212
16
       { "Name", "pvfs.distribution.name", FT_STRING, BASE_NONE,
3213
16
         NULL, 0, "Distribution Name", HFILL }},
3214
3215
16
    { &hf_pvfs_aggregate_size,
3216
16
      { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
3217
16
        NULL, 0, NULL, HFILL }},
3218
3219
16
    { &hf_pvfs_io_type,
3220
16
      { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
3221
16
        VALS(names_pvfs_io_type), 0, NULL, HFILL }},
3222
3223
16
    { &hf_pvfs_flowproto_type,
3224
16
      { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
3225
16
        VALS(names_pvfs_flowproto_type), 0, NULL, HFILL }},
3226
3227
16
    { &hf_pvfs_server_param,
3228
16
      { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
3229
16
        VALS(names_pvfs_server_param), 0, NULL, HFILL }},
3230
3231
16
    { &hf_pvfs_prev_value,
3232
16
      { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
3233
16
        NULL, 0, NULL, HFILL }},
3234
3235
#if 0
3236
    { &hf_pvfs_ram_free_bytes,
3237
      { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
3238
        NULL, 0, NULL, HFILL }},
3239
#endif
3240
3241
16
    { &hf_pvfs_bytes_available,
3242
16
      { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
3243
16
        NULL, 0, NULL, HFILL }},
3244
3245
16
    { &hf_pvfs_bytes_total,
3246
16
      { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
3247
16
        NULL, 0, NULL, HFILL }},
3248
3249
16
    { &hf_pvfs_ram_bytes_total,
3250
16
      { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
3251
16
        NULL, 0, NULL, HFILL }},
3252
3253
16
    { &hf_pvfs_ram_bytes_free,
3254
16
      { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
3255
16
        NULL, 0, NULL, HFILL }},
3256
3257
16
    { &hf_pvfs_load_average_1s,
3258
16
      { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
3259
16
        NULL, 0, NULL, HFILL }},
3260
3261
16
    { &hf_pvfs_load_average_5s,
3262
16
      { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
3263
16
        NULL, 0, NULL, HFILL }},
3264
3265
16
    { &hf_pvfs_load_average_15s,
3266
16
      { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
3267
16
        NULL, 0, NULL, HFILL }},
3268
3269
16
    { &hf_pvfs_uptime_seconds,
3270
16
      { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
3271
16
        NULL, 0, NULL, HFILL }},
3272
3273
16
    { &hf_pvfs_handles_available,
3274
16
      { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
3275
16
        NULL, 0, NULL, HFILL }},
3276
3277
16
    { &hf_pvfs_handles_total,
3278
16
      { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
3279
16
        NULL, 0, NULL, HFILL }},
3280
3281
    /*
3282
     * This is used when the field returns 64-bits but we're only interested
3283
     * in the lower 32-bit bits.
3284
     */
3285
16
    { &hf_pvfs_unused,
3286
16
      { "Unused", "pvfs.unused", FT_UINT32, BASE_DEC,
3287
16
        NULL, 0, NULL, HFILL }},
3288
3289
16
    { &hf_pvfs_context_id,
3290
16
      { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
3291
16
        NULL, 0, NULL, HFILL }},
3292
3293
16
    { &hf_pvfs_offset,
3294
16
      { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
3295
16
        NULL, 0, NULL, HFILL }},
3296
3297
16
    { &hf_pvfs_stride,
3298
16
      { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
3299
16
        NULL, 0, NULL, HFILL }},
3300
3301
16
    { &hf_pvfs_ub,
3302
16
      { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
3303
16
        NULL, 0, NULL, HFILL }},
3304
3305
16
    { &hf_pvfs_lb,
3306
16
      { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
3307
16
        NULL, 0, NULL, HFILL }},
3308
3309
16
    { &hf_pvfs_end_time_ms,
3310
16
      { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
3311
16
        NULL, 0, NULL, HFILL }},
3312
3313
16
    { &hf_pvfs_cur_time_ms,
3314
16
      { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
3315
16
        NULL, 0, NULL, HFILL }},
3316
3317
16
    { &hf_pvfs_start_time_ms,
3318
16
      { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
3319
16
        NULL, 0, NULL, HFILL }},
3320
3321
16
    { &hf_pvfs_bytes_written,
3322
16
      { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
3323
16
        NULL, 0, NULL, HFILL }},
3324
3325
16
    { &hf_pvfs_bytes_read,
3326
16
      { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
3327
16
        NULL, 0, NULL, HFILL }},
3328
3329
16
    { &hf_pvfs_metadata_write,
3330
16
      { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
3331
16
        NULL, 0, NULL, HFILL }},
3332
3333
16
    { &hf_pvfs_metadata_read,
3334
16
      { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
3335
16
        NULL, 0, NULL, HFILL }},
3336
3337
16
    { &hf_pvfs_b_size,
3338
16
      { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
3339
16
        BASE_DEC, NULL, 0, NULL, HFILL }},
3340
3341
16
    { &hf_pvfs_k_size,
3342
16
      { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
3343
16
        BASE_DEC, NULL, 0, NULL, HFILL }},
3344
3345
16
    { &hf_pvfs_id_gen_t,
3346
16
      { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
3347
16
        NULL, 0, NULL, HFILL }},
3348
3349
16
    { &hf_pvfs_attribute_key,
3350
16
      { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_NONE,
3351
16
        NULL, 0, NULL, HFILL }},
3352
3353
16
    { &hf_pvfs_attribute_value,
3354
16
      { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_NONE,
3355
16
        NULL, 0, NULL, HFILL }},
3356
3357
16
    { &hf_pvfs_strip_size,
3358
16
      { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
3359
16
        NULL, 0, "Strip size (bytes)", HFILL }},
3360
3361
    /* TODO: need description */
3362
16
    { &hf_pvfs_ereg,
3363
16
      { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
3364
16
        NULL, 0, NULL, HFILL }},
3365
3366
    /* TODO: need description */
3367
16
    { &hf_pvfs_sreg,
3368
16
      { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
3369
16
        NULL, 0, NULL, HFILL }},
3370
3371
16
    { &hf_pvfs_num_eregs,
3372
16
      { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
3373
16
        NULL, 0, NULL, HFILL }},
3374
3375
16
    { &hf_pvfs_num_blocks,
3376
16
      { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
3377
16
        NULL, 0, NULL, HFILL }},
3378
3379
16
    { &hf_pvfs_num_contig_chunks,
3380
16
      { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
3381
16
        BASE_DEC, NULL, 0, NULL, HFILL }},
3382
3383
16
    { &hf_pvfs_server_nr,
3384
16
      { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
3385
16
        NULL, 0, NULL, HFILL }},
3386
3387
16
    { &hf_pvfs_server_count,
3388
16
      { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
3389
16
        NULL, 0, NULL, HFILL }},
3390
3391
16
    { &hf_pvfs_fh_length,
3392
16
      { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
3393
16
        NULL, 0, "file handle length", HFILL }},
3394
3395
16
    { &hf_pvfs_fh_hash,
3396
16
      { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
3397
16
        NULL, 0, "file handle hash", HFILL }},
3398
3399
16
    { &hf_pvfs_permissions,
3400
16
      { "Permissions", "pvfs.permissions", FT_UINT32, BASE_OCT,
3401
16
        NULL, 0, NULL, HFILL }},
3402
3403
16
    { &hf_pvfs_server_mode,
3404
16
      { "Server Mode", "pvfs.server_mode", FT_UINT32, BASE_DEC,
3405
16
        VALS(names_pvfs_server_mode), 0, NULL, HFILL }},
3406
3407
16
    { &hf_pvfs_depth,
3408
16
      { "depth", "pvfs.depth", FT_UINT32, BASE_DEC,
3409
16
        NULL, 0, NULL, HFILL }},
3410
3411
16
    { &hf_pvfs_num_nested_req,
3412
16
      { "num_nested_req", "pvfs.num_nested_req", FT_UINT32, BASE_DEC,
3413
16
        NULL, 0, NULL, HFILL }},
3414
3415
16
    { &hf_pvfs_committed,
3416
16
      { "committed", "pvfs.committed", FT_UINT32, BASE_DEC,
3417
16
        NULL, 0, NULL, HFILL }},
3418
3419
16
    { &hf_pvfs_refcount,
3420
16
      { "refcount", "pvfs.refcount", FT_UINT32, BASE_DEC,
3421
16
        NULL, 0, NULL, HFILL }},
3422
3423
16
    { &hf_pvfs_numreq,
3424
16
      { "numreq", "pvfs.numreq", FT_UINT32, BASE_DEC,
3425
16
        NULL, 0, NULL, HFILL }},
3426
3427
16
    { &hf_pvfs_truncate_request_flags,
3428
16
      { "flags", "pvfs.truncate_request_flags", FT_UINT32, BASE_DEC,
3429
16
        NULL, 0, NULL, HFILL }},
3430
3431
16
    { &hf_pvfs_ds_position,
3432
16
      { "ds_position", "pvfs.ds_position", FT_UINT32, BASE_DEC,
3433
16
        NULL, 0, NULL, HFILL }},
3434
3435
16
    { &hf_pvfs_dirent_limit,
3436
16
      { "dirent_limit", "pvfs.dirent_limit", FT_UINT32, BASE_DEC,
3437
16
        NULL, 0, NULL, HFILL }},
3438
3439
16
    { &hf_pvfs_flush_request_flags,
3440
16
      { "flags", "pvfs.flush_request_flags", FT_UINT32, BASE_DEC,
3441
16
        NULL, 0, NULL, HFILL }},
3442
3443
16
    { &hf_pvfs_next_id,
3444
16
      { "next_id", "pvfs.next_id", FT_UINT32, BASE_DEC,
3445
16
        NULL, 0, NULL, HFILL }},
3446
3447
16
    { &hf_pvfs_mgmt_perf_mon_request_count,
3448
16
      { "count", "pvfs.mgmt_perf_mon_request.count", FT_UINT32, BASE_DEC,
3449
16
        NULL, 0, NULL, HFILL }},
3450
3451
16
    { &hf_pvfs_mgmt_perf_mon_request_event_count,
3452
16
      { "Event count", "pvfs.mgmt_perf_mon_request.event_count", FT_UINT32, BASE_DEC,
3453
16
        NULL, 0, NULL, HFILL }},
3454
3455
16
    { &hf_pvfs_lookup_path_response_handle_count,
3456
16
      { "Handle Count", "pvfs.lookup_path_response.handle_count", FT_UINT32, BASE_DEC,
3457
16
        NULL, 0, NULL, HFILL }},
3458
3459
16
    { &hf_pvfs_getconfig_response_total_bytes,
3460
16
      { "Total Bytes", "pvfs.getconfig_response.total_bytes", FT_UINT32, BASE_DEC,
3461
16
        NULL, 0, NULL, HFILL }},
3462
3463
16
    { &hf_pvfs_getconfig_response_lines,
3464
16
      { "Lines", "pvfs.getconfig_response.lines", FT_UINT32, BASE_DEC,
3465
16
        NULL, 0, NULL, HFILL }},
3466
3467
16
    { &hf_pvfs_getconfig_response_config_bytes,
3468
16
      { "Config Bytes", "pvfs.getconfig_response.config_bytes", FT_UINT32, BASE_DEC,
3469
16
        NULL, 0, NULL, HFILL }},
3470
3471
16
    { &hf_pvfs_mgmt_perf_stat_valid_flag,
3472
16
      { "valid_flag", "pvfs.mgmt_perf_stat.valid_flag", FT_UINT32, BASE_DEC,
3473
16
        NULL, 0, NULL, HFILL }},
3474
3475
16
    { &hf_pvfs_mgmt_perf_stat_id,
3476
16
      { "id", "pvfs.mgmt_perf_stat.id", FT_UINT32, BASE_DEC,
3477
16
        NULL, 0, NULL, HFILL }},
3478
3479
16
    { &hf_pvfs_mgmt_perf_mon_response_suggested_next_id,
3480
16
      { "suggested_next_id", "pvfs.mgmt_perf_mon_response.suggested_next_id", FT_UINT32, BASE_DEC,
3481
16
        NULL, 0, NULL, HFILL }},
3482
3483
16
    { &hf_pvfs_mgmt_perf_mon_response_perf_array_count,
3484
16
      { "perf_array_count", "pvfs.mgmt_perf_mon_response.perf_array_count", FT_UINT32, BASE_DEC,
3485
16
        NULL, 0, NULL, HFILL }},
3486
3487
16
    { &hf_pvfs_mgmt_iterate_handles_response_ds_position,
3488
16
      { "ds_position", "pvfs.mgmt_iterate_handles_response.ds_position", FT_UINT32, BASE_DEC,
3489
16
        NULL, 0, NULL, HFILL }},
3490
3491
16
    { &hf_pvfs_mgmt_iterate_handles_response_handle_count,
3492
16
      { "handle_count", "pvfs.mgmt_iterate_handles_response.handle_count", FT_UINT32, BASE_DEC,
3493
16
        NULL, 0, NULL, HFILL }},
3494
3495
16
    { &hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count,
3496
16
      { "dspace_info_count", "pvfs.mgmt_dspace_info_list_response.dspace_info_count", FT_UINT32, BASE_DEC,
3497
16
        NULL, 0, NULL, HFILL }},
3498
3499
16
    { &hf_pvfs_mgmt_event_mon_response_api,
3500
16
      { "api", "pvfs.mgmt_event_mon_response.api", FT_UINT32, BASE_DEC,
3501
16
        NULL, 0, NULL, HFILL }},
3502
3503
16
    { &hf_pvfs_mgmt_event_mon_response_operation,
3504
16
      { "operation", "pvfs.mgmt_event_mon_response.operation", FT_UINT32, BASE_DEC,
3505
16
        NULL, 0, NULL, HFILL }},
3506
3507
16
    { &hf_pvfs_mgmt_event_mon_response_value,
3508
16
      { "value", "pvfs.mgmt_event_mon_response.value", FT_UINT32, BASE_DEC,
3509
16
        NULL, 0, NULL, HFILL }},
3510
3511
16
    { &hf_pvfs_mgmt_event_mon_response_flags,
3512
16
      { "flags", "pvfs.mgmt_event_mon_response.flags", FT_UINT32, BASE_DEC,
3513
16
        NULL, 0, NULL, HFILL }},
3514
3515
16
    { &hf_pvfs_mgmt_event_mon_response_tv_sec,
3516
16
      { "tv_sec", "pvfs.mgmt_event_mon_response.tv_sec", FT_UINT32, BASE_DEC,
3517
16
        NULL, 0, NULL, HFILL }},
3518
3519
16
    { &hf_pvfs_mgmt_event_mon_response_tv_usec,
3520
16
      { "tv_usec", "pvfs.mgmt_event_mon_response.tv_usec", FT_UINT32, BASE_DEC,
3521
16
        NULL, 0, NULL, HFILL }},
3522
3523
16
    { &hf_pvfs_fill_bytes,
3524
16
      { "fill_bytes", "pvfs.fill_bytes", FT_BYTES, BASE_NONE,
3525
16
        NULL, 0, NULL, HFILL }},
3526
3527
16
    { &hf_pvfs_target_path_len,
3528
16
      { "target_path_len", "pvfs.target_path_len", FT_UINT32, BASE_DEC,
3529
16
        NULL, 0, NULL, HFILL }},
3530
3531
16
    { &hf_pvfs_version2,
3532
16
      { "Version 2", "pvfs.version2", FT_NONE, BASE_NONE,
3533
16
        NULL, 0, NULL, HFILL }},
3534
3535
16
    { &hf_pvfs_flow_data,
3536
16
      { "PVFC Flow Data", "pvfs.flow_data", FT_BYTES, BASE_NONE,
3537
16
        NULL, 0, NULL, HFILL }},
3538
3539
16
    { &hf_pvfs_getconfig_response_entry,
3540
16
      { "GETCONFIG Response entry", "pvfs.getconfig_response_entry", FT_STRING, BASE_NONE,
3541
16
        NULL, 0, NULL, HFILL }},
3542
3543
16
    { &hf_fhandle_data,
3544
16
      { "data", "pvfs.fhandle_data", FT_BYTES, BASE_NONE,
3545
16
        NULL, 0, NULL, HFILL }},
3546
3547
16
    { &hf_pvfs_opaque_length,
3548
16
      { "length", "pvfs.opaque_length", FT_UINT32, BASE_DEC,
3549
16
        NULL, 0, NULL, HFILL }},
3550
16
  };
3551
3552
  /* Setup protocol subtree array */
3553
16
  static int *ett[] = {
3554
16
    &ett_pvfs,
3555
16
    &ett_pvfs_hdr,
3556
16
    &ett_pvfs_credentials,
3557
16
    &ett_pvfs_server_config,
3558
16
    &ett_pvfs_server_config_branch,
3559
16
    &ett_pvfs_attrmask,
3560
16
    &ett_pvfs_time,
3561
16
    &ett_pvfs_extent_array_tree,
3562
16
    &ett_pvfs_extent_item,
3563
16
    &ett_pvfs_string,
3564
16
    &ett_pvfs_attr_tree,
3565
16
    &ett_pvfs_distribution,
3566
16
    &ett_pvfs_mgmt_perf_stat,
3567
16
    &ett_pvfs_mgmt_dspace_info,
3568
16
    &ett_pvfs_attr,
3569
16
    &ett_pvfs_fh
3570
16
  };
3571
3572
16
  static ei_register_info ei[] = {
3573
16
    { &ei_pvfs_malformed, { "pvfs.malformed", PI_MALFORMED, PI_ERROR, "MALFORMED OR TRUNCATED DATA", EXPFILL }},
3574
16
  };
3575
3576
16
  module_t *pvfs_module;
3577
16
  expert_module_t* expert_pvfs;
3578
3579
  /* Register the protocol name and description */
3580
16
  proto_pvfs = proto_register_protocol("Parallel Virtual File System",
3581
16
      "PVFS", "pvfs");
3582
16
  pvfs_handle = register_dissector("pvfs", dissect_pvfs, proto_pvfs);
3583
3584
  /*
3585
   * Required function calls to register the header fields and
3586
   * subtrees used
3587
   */
3588
3589
16
  proto_register_field_array(proto_pvfs, hf, array_length(hf));
3590
16
  proto_register_subtree_array(ett, array_length(ett));
3591
16
  expert_pvfs = expert_register_protocol(proto_pvfs);
3592
16
  expert_register_field_array(expert_pvfs, ei, array_length(ei));
3593
3594
16
  pvfs2_io_tracking_value_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), pvfs2_io_tracking_hash, pvfs2_io_tracking_equal);
3595
3596
16
  pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
3597
16
  prefs_register_bool_preference(pvfs_module, "desegment",
3598
16
      "Reassemble PVFS messages spanning multiple TCP segments",
3599
16
      "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
3600
16
      "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3601
16
      &pvfs_desegment);
3602
16
}
3603
3604
void
3605
proto_reg_handoff_pvfs(void)
3606
16
{
3607
16
  dissector_add_uint_with_preference("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
3608
3609
16
  heur_dissector_add("tcp", dissect_pvfs_heur, "PVFS over TCP", "pvfs_tcp", proto_pvfs, HEURISTIC_ENABLE);
3610
16
}
3611
3612
/*
3613
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3614
 *
3615
 * Local variables:
3616
 * c-basic-offset: 8
3617
 * tab-width: 8
3618
 * indent-tabs-mode: t
3619
 * End:
3620
 *
3621
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3622
 * :indentSize=8:tabSize=8:noTabs=false:
3623
 */