From Didier Gautheron:
[obnox/wireshark/wip.git] / epan / dissectors / packet-fmp.c
1 /* packet-fmp.c
2  * Routines for fmp dissection
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_SYS_TYPES_H
26 #include <sys/types.h>
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <glib.h>
35 #include <gmodule.h>
36 #include <epan/packet.h>
37 #include <epan/prefs.h>
38 #include <epan/strutil.h>
39 #include "packet-fmp.h" 
40 #include "packet-rpc.h"
41
42
43 int hf_fmp_procedure = -1;
44 int hf_fmp_fsID = -1;
45 int hf_fmp_fsBlkSz = -1;
46 int hf_fmp_sessionHandle = -1;
47 int hf_fmp_fmpFHandle = -1;
48 int hf_fmp_msgNum = -1;
49 int hf_fmp_fileSize = -1;
50 int hf_fmp_cookie = -1;
51 int hf_fmp_firstLogBlk = -1;
52 int hf_fmp_numBlksReq = -1;
53
54 static int proto_fmp = -1;
55 static int hf_fmp_hostID = -1;
56 static int hf_fmp_status = -1;
57 static int hf_fmp_btime = -1;
58 static int hf_fmp_time_sec = -1;
59 static int hf_fmp_time_nsec = -1;
60 static int hf_fmp_notifyPort = -1;
61 static int hf_fmp_minBlks = -1;
62 static int hf_fmp_eof = -1;
63 static int hf_fmp_path = -1;
64 static int hf_fmp_plugInID = -1;
65 static int hf_fmp_plugInBuf = -1;
66 static int hf_fmp_nfsFHandle = -1;
67 static int hf_fmp_extentList_len = -1;
68 static int hf_fmp_extent_state = -1;
69 static int hf_fmp_numBlks = -1;
70 static int hf_fmp_volID = -1;
71 static int hf_fmp_startOffset = -1;
72 static int hf_fmp_volHandle = -1;
73 static int hf_fmp_devSignature = -1;
74 static int hf_fmp_dskSigEnt_val = -1;
75 static int hf_fmp_mount_path = -1;
76 static int hf_fmp_sig_offset = -1;
77 static int hf_fmp_os_major = -1;
78 static int hf_fmp_os_minor = -1;
79 static int hf_fmp_os_name = -1;
80 static int hf_fmp_os_patch = -1;
81 static int hf_fmp_os_build = -1;
82 static int hf_fmp_server_version_string = -1;
83 static int hf_fmp_description = -1;
84 static int hf_fmp_nfsv3Attr_type = -1;
85 static int hf_fmp_nfsv3Attr_mode = -1;
86 static int hf_fmp_nfsv3Attr_nlink = -1;
87 static int hf_fmp_nfsv3Attr_uid = -1;
88 static int hf_fmp_nfsv3Attr_gid = -1;
89 static int hf_fmp_nfsv3Attr_used = -1;
90 static int hf_fmp_nfsv3Attr_rdev = -1;
91 static int hf_fmp_nfsv3Attr_fsid = -1;
92 static int hf_fmp_nfsv3Attr_fileid = -1;
93 static int hf_fmp_cmd = -1;
94 static int hf_fmp_topVolumeId = -1;
95 static int hf_fmp_cursor = -1;
96 static int hf_fmp_offset64 = -1;
97 static int hf_fmp_start_offset64 = -1;
98 static int hf_fmp_slice_size = -1;
99 static int hf_fmp_volume = -1;
100 static int hf_fmp_stripeSize = -1;
101 static int hf_fmp_firstLogBlk64 =-1;
102
103
104 static gint ett_fmp = -1;
105 static gint ett_fmp_timeval = -1;
106 static gint ett_fmp_extList = -1;
107 static gint ett_fmp_ext = -1;
108 static gint ett_fmp_fileHandle = -1;
109 static gint ett_capabilities = -1;
110 static gint ett_HierVolumeDescription = -1;
111 static gint ett_attrs = -1;
112
113 gboolean fmp_fhandle_reqrep_matching = FALSE;
114
115 int
116 dissect_fmp_genString(tvbuff_t *tvb, int offset, proto_tree *tree)
117 {
118         encoding mode;
119
120         mode = tvb_get_ntohl(tvb, offset);
121
122         switch (mode) {
123         case FMP_ASCII:
124                 proto_tree_add_text(tree, tvb, offset, 4, 
125                                     "Encoding Mode: ASCII (%d)", mode);
126                 break;
127         
128         case FMP_UTF8:
129                 proto_tree_add_text(tree, tvb, offset, 4,
130                                     "Encoding Mode: UTF8 (%d)", mode);
131                 break;
132         
133         case FMP_UNICODE1:
134                 proto_tree_add_text(tree, tvb, offset, 4, 
135                                     "Encoding Mode: UNICODE (%d)", mode);
136                 break;
137
138         default:
139                 proto_tree_add_text(tree, tvb, offset, 4, 
140                                     "Encoding Mode: UNKNOWN (%d)", mode);
141                 offset += 4;
142                 return offset;
143         }
144         offset += 4;
145         offset = dissect_rpc_string(tvb, tree, hf_fmp_path,
146                                    offset, NULL);
147
148         return offset;
149 }
150
151 static int
152 get_fileHandleSrc_size(tvbuff_t *tvb, int offset)
153 {
154         int length;
155         nativeProtocol np;
156
157         np = tvb_get_ntohl(tvb, offset);
158
159         switch (np) {
160         case FMP_PATH:
161                 length =  4 + FMP_MAX_PATH_LEN;
162                 break;
163         case FMP_NFS:
164                 length =  8 + tvb_get_ntohl(tvb, offset + 4);
165                 break;
166         case FMP_CIFS:
167                 length =  10;
168                 break;
169         case FMP_FMP:
170                 length =  8 + tvb_get_ntohl(tvb, offset + 4);
171                 break;
172         case FMP_FS_ONLY:
173                 length =  8;
174                 break;
175         case FMP_SHARE:
176                 /* FALLTHROUGH */
177         case FMP_MOUNT:
178                 length =  8 + FMP_MAX_PATH_LEN;
179                 break;
180         default:
181                 length =  4;
182                 break;
183         }
184
185         return length;
186 }
187
188 int
189 dissect_fmp_fileHandleSrc(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
190                           proto_tree *tree)
191 {
192         nativeProtocol  np;
193
194         proto_item *fileHandleItem;
195         proto_tree *fileHandleTree;
196         int length;
197         
198         length = get_fileHandleSrc_size(tvb, offset);
199
200         np = tvb_get_ntohl(tvb, offset);
201
202         fileHandleItem =  proto_tree_add_text(tree, tvb, offset, length, 
203                                               "Source File Handle");
204         fileHandleTree = proto_item_add_subtree(fileHandleItem, 
205                                                 ett_fmp_fileHandle);
206
207         switch (np) {
208         case FMP_PATH:
209                 proto_tree_add_text(fileHandleTree, tvb, offset, 4, 
210                                     "Native Protocol: PATH (%d)", np);
211                 offset += 4;
212         
213                 offset = dissect_rpc_string(tvb, fileHandleTree,
214                                            hf_fmp_mount_path, offset, NULL);
215                 break;
216
217         case FMP_NFS:
218                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
219                                     "Native Protocol: NFS (%d)", np);
220                 offset += 4;
221
222                 offset = dissect_rpc_data(tvb, fileHandleTree, 
223                                           hf_fmp_nfsFHandle, offset);   
224                 break;
225
226         case FMP_CIFS:
227                 proto_tree_add_text(fileHandleTree, tvb, offset, 4, 
228                                     "Native Protocol: CIFS (%d)", np);
229                 offset += 4;
230
231                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "fid: %d",
232                                     tvb_get_ntohs(tvb, offset));
233                 offset += 2;
234
235                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "tid: %d",
236                                     tvb_get_ntohs(tvb, offset));
237                 offset += 2;
238
239                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "uid: %d",
240                                     tvb_get_ntohs(tvb, offset));
241                 offset += 2;
242                 break;
243
244         case FMP_FMP:
245                 proto_tree_add_text(fileHandleTree, tvb, offset, 4, 
246                                     "Native Protocol: FMP (%d)", np);
247                 offset += 4;
248
249                 offset = dissect_rpc_string(tvb, fileHandleTree,
250                                             hf_fmp_fmpFHandle, offset, NULL);  
251                 break;
252
253         case FMP_FS_ONLY:
254                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
255                                     "Native Protocol: FS_ONLY (%d)", np);
256                 offset += 4;
257
258                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
259                                     "FsID: %d", tvb_get_ntohl(tvb, offset));
260                 offset += 4;
261                 break;
262
263         case FMP_SHARE:
264                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
265                                     "Native Protocol: SHARE (%d)", np);
266                 offset += 4;
267
268                 offset = dissect_fmp_genString(tvb, offset, fileHandleTree);
269                 break;
270
271         case FMP_MOUNT:
272                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
273                                     "Native Protocol: MOUNT (%d)", np);
274                 offset += 4;
275
276                 offset = dissect_fmp_genString(tvb, offset, fileHandleTree);
277                 break;
278
279         case FMP_CIFSV2:
280                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
281                                     "Native Protocol: CIFSV2: (%d)", np);
282                 offset += 4;
283                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "fid     : %d",
284                                     tvb_get_ntohs(tvb, offset));
285                 offset += 2;
286
287                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "tid     : %d",
288                                     tvb_get_ntohs(tvb, offset));
289                 offset += 2;
290
291                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "uid     : %d",
292                                     tvb_get_ntohs(tvb, offset));
293                 offset += 2;
294         
295                 proto_tree_add_text(fileHandleTree, tvb, offset, 2, "cifsPort: %d",
296                                     tvb_get_ntohs(tvb, offset));
297                 offset += 2;
298                 break;
299         case FMP_UNC:
300                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
301                                     "Native Protocol: UNC: (%d)", np);
302                 offset += 4;
303
304                 offset = dissect_fmp_genString(tvb, offset, fileHandleTree);
305                 break;
306         
307
308         default:
309                 proto_tree_add_text(fileHandleTree, tvb, offset, 4,
310                                     "Native Protocol: UNKNOWN (%d)", np);
311                 offset += 4;
312                 break;
313         }
314
315         return offset;
316 }
317
318 int
319 dissect_fmp_extentState(tvbuff_t *tvb, int offset, proto_tree *tree)
320 {
321         extentState state;
322
323         if (!tree) {
324                 return offset;
325         }
326
327         state = tvb_get_ntohl(tvb, offset);
328         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_extent_state,
329                                     offset);
330
331         return offset;
332 }
333
334 int
335 dissect_fmp_extent(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 ext_num)
336 {
337         proto_item *extItem;
338         proto_tree *extTree;
339
340         if (!tree) {
341                 return offset;
342         }
343
344         extItem = proto_tree_add_text(tree, tvb, offset, 20 ,
345                                       "Extent (%u)", (guint32) ext_num);
346
347         extTree = proto_item_add_subtree(extItem, ett_fmp_ext);
348
349         offset = dissect_rpc_uint32(tvb,  extTree, hf_fmp_firstLogBlk,
350                                     offset);
351         offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_numBlks,
352                                     offset);
353         offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_volID, offset);
354         offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_startOffset,
355                                     offset);
356         offset = dissect_fmp_extentState(tvb, offset, extTree);
357
358         return offset;
359 }
360
361 int
362 dissect_fmp_extentList(tvbuff_t *tvb, int offset, packet_info *pinfo,
363                        proto_tree *tree)
364 {
365         guint32 numExtents;
366         guint32 totalLength;
367         proto_item *extListItem;
368         proto_tree *extListTree;
369         guint32 i;
370
371         if (!tree) {
372                 return offset;
373         }
374
375         numExtents = tvb_get_ntohl(tvb, offset);
376         totalLength = 4 + (20 * numExtents); 
377
378         extListItem =  proto_tree_add_text(tree, tvb, offset, totalLength,
379                                            "Extent List");
380         extListTree = proto_item_add_subtree(extListItem, ett_fmp_extList);
381
382         offset = dissect_rpc_uint32(tvb, extListTree,
383                                     hf_fmp_extentList_len, offset);
384
385         for (i = 1; i <= numExtents; i++) {
386                 offset = dissect_fmp_extent(tvb, offset, pinfo, extListTree, i);
387         }
388
389         return offset;
390 }
391
392
393 int
394 dissect_fmp_extentListEx(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
395                        proto_tree *tree)
396 {
397         guint32 numExtents;
398         proto_item *extListItem;
399         proto_tree *extListTree;
400         guint32 i;
401
402         if (!tree) {
403                 return offset;
404         }
405
406         numExtents = tvb_get_ntohl(tvb, offset);
407
408
409         offset += 4;
410
411         for (i = 1; i <= numExtents; i++) {
412                 extListItem =  proto_tree_add_text(tree, tvb, offset, 28,
413                                            "Extent List");
414                 extListTree = proto_item_add_subtree(extListItem, ett_fmp_extList);
415
416
417                 offset = dissect_rpc_uint64(tvb,extListTree , hf_fmp_firstLogBlk64,  offset);
418
419                 offset = dissect_rpc_uint32(tvb,extListTree , hf_fmp_numBlksReq,
420                                     offset);
421
422                 offset = dissect_rpc_uint32(tvb,extListTree , hf_fmp_volID, offset);
423
424                 offset = dissect_rpc_uint64(tvb,extListTree , hf_fmp_start_offset64, offset);
425
426                 offset = dissect_fmp_extentState(tvb, offset, extListTree);
427
428         }
429
430         return offset;
431 }
432
433
434 int
435 dissect_plugInID(tvbuff_t *tvb, int offset, proto_tree *tree)
436 {
437         const guint8 *plugInID;
438         
439         if (!tree) {
440                 return offset;
441         }
442
443         plugInID = tvb_get_ptr(tvb, offset, FMP_PLUG_IN_ID_SZ);
444         proto_tree_add_bytes(tree, hf_fmp_plugInID, tvb, offset, FMP_PLUG_IN_ID_SZ,
445                              plugInID);
446         return offset;
447 }
448
449 int
450 dissect_fmp_flushCmd(tvbuff_t *tvb, int offset,  proto_tree *tree)
451 {
452         guint32 cmd;
453         char msg[MAX_MSG_SIZE];
454         guint32 bitValue;
455         int i;
456
457         if (!tree) {
458                 return offset;
459         }
460
461         cmd = tvb_get_ntohl(tvb, offset);
462
463         /* Initialize the message for an empty string */
464         msg[0] = '\0';
465
466         for (i = 0; cmd != 0 && i < 32; i++) {
467
468                 bitValue = 1 << i;
469
470                 if (cmd & bitValue) {
471                         switch (bitValue) {
472                         case FMP_COMMIT_SPECIFIED:
473                                 g_strlcat(msg, "COMMIT_SPECIFIED", MAX_MSG_SIZE);
474                                 break;
475                         case FMP_RELEASE_SPECIFIED:
476                                 g_strlcat(msg, "RELEASE_SPECIFIED", MAX_MSG_SIZE);
477                                 break;
478                         case FMP_RELEASE_ALL:
479                                 g_strlcat(msg, "RELEASE_ALL", MAX_MSG_SIZE);
480                                 break;
481                         case FMP_CLOSE_FILE:
482                                 g_strlcat(msg, "CLOSE_FILE", MAX_MSG_SIZE);
483                                 break;
484                         case FMP_UPDATE_TIME:
485                                 g_strlcat(msg, "UPDATE_TIME", MAX_MSG_SIZE);
486                                 break;
487                         case FMP_ACCESS_TIME:
488                                 g_strlcat(msg, "ACCESS_TIME", MAX_MSG_SIZE);
489                                 break;
490                         default:
491                                 g_strlcat(msg, "UNKNOWN", MAX_MSG_SIZE);
492                                 break;
493                         }
494
495                         /* clear the bit that we processed */
496                         cmd &= ~bitValue;
497         
498                         /* add a "bitwise inclusive OR" symbol between cmds */
499                         if (cmd) {
500                                 g_strlcat(msg, " | ", MAX_MSG_SIZE);
501                         }
502                 }
503         }
504
505         if (strlen(msg) == 0) {
506           g_strlcpy(msg, "No command specified", MAX_MSG_SIZE);
507         }
508
509         proto_tree_add_text(tree, tvb, offset, 4, "Cmd: %s", msg);
510         offset += 4;
511         return offset;
512 }
513 int
514 dissect_InterpretVolMgtStuff(tvbuff_t *tvb, int offset, proto_tree *tree)
515 {
516         int length,numdisks,i,j;
517
518         numdisks = tvb_get_ntohl(tvb, offset);
519         proto_tree_add_text(tree, tvb, offset, 4, "Number of Disk: %d", numdisks);
520         offset += 4;
521
522         for(i=0;i<numdisks;i++){
523                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_sig_offset,  offset);
524                 length = tvb_get_ntohl(tvb, offset);
525                 proto_tree_add_text(tree, tvb, offset, 4, "Length of List  : %d", length);
526                 offset += 4;
527                 
528                 for(j=0;j<length;j++){
529                         proto_tree_add_text(tree, tvb, offset, 4, "sigOffset: 0x%x",
530                                                 tvb_get_ntohl(tvb, offset));
531                         offset += 4;
532                         offset = dissect_rpc_string(tvb, tree, hf_fmp_dskSigEnt_val,
533                                     offset, NULL);   
534                                 
535                 }
536         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_volID, offset);
537         
538         }
539         return offset;
540         
541         
542 }
543 int
544 dissect_fmp_capability(tvbuff_t *tvb, int offset, proto_tree *tree)
545 {
546         int vmType;
547
548         if (!tree) {
549                 return offset;
550         }
551
552         vmType = tvb_get_ntohl(tvb, offset);
553
554         switch (vmType) {
555         case FMP_SERVER_BASED:
556                 proto_tree_add_text(tree, tvb, offset, 4,
557                            "Volume Mgmt Capability: SERVER_BASED (%d)", vmType);
558                 break;
559
560         case FMP_THIRD_PARTY:
561                 proto_tree_add_text(tree, tvb, offset, 4,
562                            "Volume Mgmt Capability: THIRD_PARTY (%d)", vmType);
563                 break;
564
565         case FMP_CLIENT_BASED_DART:
566                 proto_tree_add_text(tree, tvb, offset, 4,
567                            "Volume Mgmt Capability: CLIENT_BASED_DART (%d)",
568                            vmType);
569                 break;
570
571         case FMP_CLIENT_BASED_SIMPLE:
572                 proto_tree_add_text(tree, tvb, offset, 4,
573                            "Volume Mgmt Capability: CLIENT_BASED_SIMPLE (%d)",
574                            vmType);
575                 break;
576         case FMP_HIERARCHICAL_VOLUME:
577                proto_tree_add_text(tree, tvb, offset, 4,
578                           "Volume Mgmt Capability: FMP_HIERARCHICAL_VOLUME (%d)",
579                           vmType);
580                break;
581
582
583                 
584
585         default:
586                 proto_tree_add_text(tree, tvb, offset, 4,
587                            "Volume Mgmt Capability: UNKNOWN (%d)", vmType);
588                 break;
589         }
590
591         offset += 4;
592         return offset;
593 }
594
595 int
596 dissect_fmp_timeval(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
597                     proto_tree *tree, int hf_time, int hf_time_sec,
598                     int hf_time_nsec)
599 {
600         nstime_t ts;
601
602         proto_item* time_item;
603         proto_tree* time_tree = NULL;
604
605         if (!tree) {
606                 return offset;
607         }
608
609         ts.secs = tvb_get_ntohl(tvb, offset+0);
610         ts.nsecs = tvb_get_ntohl(tvb, offset+4);
611
612         time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
613         if (time_item) {
614                 time_tree = proto_item_add_subtree(time_item, ett_fmp_timeval);
615         }
616
617         if (time_tree) {
618                 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
619                                     (guint32) ts.secs);
620                 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset+4, 4,
621                                     ts.nsecs);
622         }
623
624         offset += 8;
625         return offset;
626 }
627
628 int
629 dissect_fmp_heartBeatIntv(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
630                           proto_tree *tree)
631 {
632         if (!tree) {
633                 return offset;
634         }
635
636         proto_tree_add_text(tree, tvb, offset, 8, 
637                             "Heart Beat Interval: %d.%d seconds",
638                             tvb_get_ntohl(tvb, offset),
639                             tvb_get_ntohl(tvb, offset+4));
640         offset += 8;
641         return offset;
642 }
643
644 int
645 dissect_fmp_status(tvbuff_t *tvb, int offset, proto_tree *tree, int *rval)
646 {
647         fmpStat status;
648
649         if (!tree) {
650                 return offset;
651         }
652
653         status = tvb_get_ntohl(tvb, offset);
654
655         switch (status) {
656         case FMP_OK:
657                 *rval = 0;
658                 break;
659         case FMP_IOERROR:
660                 *rval = 1;
661                 break;
662         case FMP_NOMEM:
663                 *rval = 1;
664                 break;
665         case FMP_NOACCESS:
666                 *rval = 1;
667                 break;
668         case FMP_INVALIDARG:
669                 
670                 *rval = 1;
671                 break;
672         case FMP_FSFULL:
673                 *rval = 0;
674                 break;
675         case FMP_QUEUE_FULL:
676         case FMP_NOTIFY_ERROR:
677         case FMP_WRITER_LOST_BLK:
678         case FMP_WRONG_MSG_NUM:
679         case FMP_SESSION_LOST:
680         case FMP_REQUEST_CANCELLED:
681                 *rval = 1;
682                 break;
683         case FMP_HOT_SESSION:
684                 *rval = 0;
685                 break;
686         case FMP_COLD_SESSION:
687                 *rval = 0;
688                 break;
689         case FMP_CLIENT_TERMINATED:
690                 *rval = 0;
691                 break;
692         case FMP_REQUEST_QUEUED:
693                 *rval = 0;
694                 break;
695         case FMP_FALL_BACK:
696                 *rval = 0;
697                 break;
698         case FMP_WRITER_ZEROED_BLK:
699                 *rval = 0;
700                 break;
701         case FMP_WRONG_HANDLE:
702                 *rval = 0;
703                 break;
704         case FMP_DUPLICATE_OPEN:
705                 *rval = 1;
706                 break;
707         case FMP_PLUGIN_NOFUNC:
708                 *rval = 1;
709                 break;
710         default:
711                 *rval = 1;
712                 break;
713         }
714    
715         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_status , offset);
716         return offset;
717 }
718
719 int
720 dissect_fmp_devSerial(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
721                       proto_tree *tree)
722 {
723         queryCmd qc;
724
725         if (!tree) {
726                 return offset;
727         }
728
729         qc = tvb_get_ntohl(tvb, offset);
730
731         switch (qc) {
732         case FMP_SCSI_INQUIRY:
733                 proto_tree_add_text(tree, tvb, offset, 4,
734                                    "Query Command: SCSI_INQUIRY (%d)", qc);
735                 break;
736         case FMP_DART_STAMP:
737                 proto_tree_add_text(tree, tvb, offset, 4,
738                                     "Query Command: DART_STAMP (%d)", qc);
739                 break;
740         default:
741                 proto_tree_add_text(tree, tvb, offset, 4,
742                                     "Query Command: UNKNOWN (%d)", qc);
743                 break;
744         }
745         offset += 4;
746
747         proto_tree_add_text(tree, tvb, offset, 4, "sigOffset: 0x%x",
748                             tvb_get_ntohl(tvb, offset));
749         offset += 4;
750
751         offset = dissect_rpc_string(tvb, tree, hf_fmp_devSignature,
752                                     offset, NULL);   
753         return offset;
754 }
755
756
757
758
759 int dissect_fmp_VolumeDescription(tvbuff_t *tvb, int offset, proto_tree * tree)
760 {
761         int i,length;
762         proto_tree *Hietree,*hieTree;
763         fmpVolumeType volumeType;
764         fmpDiskIdentifierType diskIdentifierType;
765                 volumeType = tvb_get_ntohl(tvb, offset);
766                 switch(volumeType){
767
768                 case FMP_VOLUME_DISK:
769                         hieTree =  proto_tree_add_text(tree, tvb, offset, 4,
770                                                    "VOLUME: DISK(%d)", volumeType );
771                         Hietree = proto_item_add_subtree(hieTree,
772                                                 ett_HierVolumeDescription);
773                         offset += 4;
774                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volID, offset);
775                         offset += 8; /* blockIndex64 */
776                         diskIdentifierType = tvb_get_ntohl(tvb, offset);
777
778
779                         switch(diskIdentifierType){
780                                 case FMP_DISK_IDENTIFIER_SIGNATURE:
781                                         proto_tree_add_text(Hietree, tvb, offset, 4,
782                                                     "DISK IDENTIFIER: SIGNATURE(%d)", diskIdentifierType);
783                                         offset += 4;
784                                         offset = dissect_rpc_uint64(tvb, Hietree, hf_fmp_sig_offset,  offset);
785                                         length = tvb_get_ntohl(tvb, offset);
786                                         proto_tree_add_text(Hietree, tvb, offset, 4, "Length of List  : %d", length);
787                                         offset += 4;
788
789                                         for(i=0;i<length;i++){
790                                                 proto_tree_add_text(Hietree, tvb, offset, 4, "sigOffset: 0x%x",
791                                                                                 tvb_get_ntohl(tvb, offset));
792                                                 offset += 4;
793                                                 offset = dissect_rpc_string(tvb, Hietree, hf_fmp_dskSigEnt_val,  offset, NULL);
794
795
796                                          }
797
798                                         break;
799
800                                 case FMP_DISK_IDENTIFIER_SERIAL:
801                                         proto_tree_add_text(Hietree, tvb, offset, 4,
802                                                             "DISK IDENTIFIER: SERIAL(%d)", diskIdentifierType);
803                                         dissect_fmp_devSerial(tvb, offset, NULL, Hietree);
804                                         break;
805                         }
806
807                         break;
808                 case FMP_VOLUME_SLICE:
809                         hieTree =  proto_tree_add_text(tree, tvb, offset, 4,
810                                                    "VOLUME: SLICE(%d)", volumeType );
811                         Hietree = proto_item_add_subtree(hieTree,
812                                                 ett_HierVolumeDescription);
813                         offset += 4;
814                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volID, offset);
815
816                         offset = dissect_rpc_uint64(tvb, Hietree, hf_fmp_offset64, offset);
817
818                         offset = dissect_rpc_uint64(tvb, Hietree, hf_fmp_slice_size, offset);
819
820                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volume, offset);
821
822                         break;
823
824                 case FMP_VOLUME_STRIPE:
825                         hieTree =  proto_tree_add_text(tree, tvb, offset, 4,
826                                                    "VOLUME: STRIPE(%d)", volumeType );
827                         Hietree = proto_item_add_subtree(hieTree,
828                                                 ett_HierVolumeDescription);
829                         offset += 4;
830                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volID, offset);
831
832                         offset = dissect_rpc_uint64(tvb, Hietree, hf_fmp_stripeSize, offset);
833                         length = tvb_get_ntohl(tvb, offset);
834                         proto_tree_add_text(Hietree, tvb, offset, 4, "Length of List  : %d", length);
835                         offset += 4;
836
837                         for(i=0;i<length;i++){
838                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volume, offset); /* FIXME: Size or length not know */
839
840                         }
841                         break;
842
843                 case FMP_VOLUME_META:
844                         hieTree =  proto_tree_add_text(tree, tvb, offset, 4,
845                                                    "VOLUME: META(%d)", volumeType );
846                         Hietree = proto_item_add_subtree(hieTree,
847                                                 ett_HierVolumeDescription);
848                         offset += 4;
849                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volID, offset);
850
851                         length = tvb_get_ntohl(tvb, offset);
852                         proto_tree_add_text(Hietree, tvb, offset, 4, "Length of List  : %d", length);
853                         offset += 4;
854                         for(i=0;i<length;i++){
855                         offset = dissect_rpc_uint32(tvb, Hietree, hf_fmp_volume, offset); /* FIXME: Size or length not know */
856                         }
857                         break;
858                 default:
859                         proto_tree_add_text(tree, tvb, offset, 4,
860                                            "VOLUME: UNKNOWN (%d)",volumeType);
861                         offset += 4;
862 }
863         return offset;
864 }
865
866
867 int dissect_fmp_Hiervolume(tvbuff_t *tvb, int offset, proto_tree * tree)
868
869 {
870
871         int vollength;
872         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_topVolumeId, offset);
873         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cursor, offset);
874         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie, offset);
875
876         /* hierarchical description of volume.  Each volume describes a
877      piece of the entire hierarchy and is guarenteed to only refer to
878      volumes that have already been described by the data structure up
879      to this point in time.  In some extreme cases, the number of
880      volumes and their descriptions may be to large to fit in a single
881      RPC reply.  In this case, the application may send getVolumeInfo
882      requests for the specific topVolumeId -- specifying the number of
883      volumes already recieved by the client, and the cookie.  The
884      server is then responsible for sending another message containing
885      additional volumes.  These RPCs exchanges may continue multiple
886      times, until the client has fetched the entire hierarchical
887      volume description.  If the volume hierarchy changes duing a
888      multiple RPC sequence, the server will return an
889      FMP_VOLUME_CHANGED error, and the client must discard all
890      information already received and restart the request with
891      FMP_Mount.
892      */
893
894         vollength = tvb_get_ntohl(tvb, offset);
895         proto_tree_add_text(tree, tvb, offset, 4, "Length of volume List  : %d", vollength);
896         offset += 4;
897         while(vollength){
898                 offset =  dissect_fmp_VolumeDescription(tvb, offset, tree);
899                 vollength--;
900         }
901         
902         return offset;
903
904 }
905
906
907
908 int
909 dissect_fmp_vmInfo(tvbuff_t *tvb, int offset, packet_info *pinfo,
910                    proto_tree *tree)
911 {
912         int vmType;
913         guint32 phyVolList_len;
914         guint32 volIndex;
915
916         if (!tree) {
917                 return offset;
918         }
919
920         vmType = tvb_get_ntohl(tvb, offset);
921
922         switch (vmType) {
923         case FMP_SERVER_BASED:
924                 /*
925                  * Need to finish
926                  */
927                 proto_tree_add_text(tree, tvb, offset, 4,
928                                     "Volume Mgmt Type: SERVER_BASED (%d)",
929                                     vmType);
930                 offset += 4;
931
932                 phyVolList_len = tvb_get_ntohl(tvb, offset);
933                 offset += 4;
934
935                 /*
936                  * Loop through and print all of the devInfo 
937                  * structures.
938                  */
939                 while (phyVolList_len) {
940                         offset = 
941                                 dissect_fmp_devSerial(tvb, offset, pinfo, tree);
942                         volIndex = tvb_get_ntohl(tvb, offset);
943                         proto_tree_add_text(tree, tvb, offset, 4, "0x%x",
944                                             volIndex);
945                         offset += 4;
946                         phyVolList_len--;
947                 }
948                 break;
949
950         case FMP_THIRD_PARTY:
951                 proto_tree_add_text(tree, tvb, offset, 4,
952                                     "Volume Mgmt Type: THIRD_PARTY (%d)",
953                                     vmType);
954                 offset += 4;
955
956                 offset = dissect_rpc_string(tvb, tree, hf_fmp_volHandle,
957                                             offset, NULL);   
958                 break;
959
960         case FMP_CLIENT_BASED_DART:
961                 proto_tree_add_text(tree, tvb, offset, 4,
962                                     "Volume Mgmt Type: CLIENT_BASED_DART (%d)",
963                                     vmType);
964                 offset += 4;
965
966                 offset = dissect_rpc_string(tvb,  tree, hf_fmp_volHandle,
967                                             offset, NULL); 
968                 break;
969
970         case FMP_CLIENT_BASED_SIMPLE:
971                 proto_tree_add_text(tree, tvb, offset, 4,
972                                    "Volume Mgmt Type: CLIENT_BASED_SIMPLE (%d)",
973                                    vmType);
974                 offset += 4;
975
976                 /*
977                  * Decoding simpleVolInfo
978                  */
979                 offset = dissect_fmp_devSerial(tvb, offset, pinfo, tree);
980
981                 proto_tree_add_text(tree, tvb, offset, 4, "blockIndex: 0x%x",
982                                     tvb_get_ntohl(tvb, offset));
983                 offset += 4;
984                 break;
985
986         case FMP_DISK_SIGNATURE:
987                 proto_tree_add_text(tree, tvb, offset, 4,
988                            "Volume Mgmt Type: DISK_SIGNATURE: (%d)",
989                            vmType);
990                 offset += 4;
991                 offset = dissect_InterpretVolMgtStuff(tvb, offset, tree);
992                 break;
993
994         case FMP_HIERARCHICAL_VOLUME:
995                 proto_tree_add_text(tree, tvb, offset, 4,
996                            "Volume Mgmt Type: FMP_HIERARCHICAL_VOLUME: (%d)",
997                            vmType);
998                 offset += 4;
999                 
1000                 dissect_fmp_Hiervolume(tvb, offset, tree);
1001                 break;
1002
1003         default:
1004                 proto_tree_add_text(tree, tvb, offset, 4,
1005                                     "Volume Mgmt Type: UNKNOWN (%d)", vmType);
1006                 offset += 4;
1007                 break;
1008         }
1009
1010         return offset;
1011 }
1012
1013 int
1014 dissect_fmp_notifyProtocol(tvbuff_t *tvb, int offset, proto_tree *tree)
1015 {
1016
1017         int proto;
1018
1019         if (!tree) {
1020                 return offset;
1021         }
1022
1023         proto = tvb_get_ntohl(tvb, offset);
1024
1025         switch(proto){
1026         case FMP_TCP:
1027                 proto_tree_add_text(tree, tvb, offset, 4,
1028                                     "Protocol: TCP (%d)",
1029                                     proto);
1030                 break;
1031         case FMP_UDP:
1032                 proto_tree_add_text(tree, tvb, offset, 4,
1033                                     "Protocol: UDP (%d)",
1034                                     proto);
1035                 break;
1036         default:
1037                 proto_tree_add_text(tree, tvb, offset, 4,
1038                                     "Protocol: UNKNOWN (%d)",
1039                                     proto);
1040                 break;
1041         }
1042
1043         return (offset+4);
1044
1045
1046 }
1047
1048
1049 int
1050 dissect_fmp_capabilities(tvbuff_t *tvb, int offset, proto_tree *tree)
1051 {
1052
1053         int cap_val ;
1054         proto_tree *capTree;
1055         proto_tree *captree;
1056         if (!tree) {
1057                 return offset;
1058         }
1059
1060         cap_val = tvb_get_ntohl(tvb, offset);
1061         captree =  proto_tree_add_text(tree, tvb, offset, 4,
1062                                               "Capabilities: ");
1063
1064         capTree = proto_item_add_subtree(captree,
1065                                                 ett_capabilities);
1066
1067         if (cap_val & FMP_CAP_REVOKE_HANDLE_LIST ){
1068                 proto_tree_add_text(capTree, tvb, offset, 4,
1069                                     "CAP_REVOKE_HANDLE_LIST (%x)",
1070                                     cap_val);
1071         }
1072         if (cap_val & FMP_CAP_UNC_NAMES ){
1073                 proto_tree_add_text(capTree, tvb, offset, 4,
1074                                     "CAP_UNC_NAMES (%x)",
1075                                     cap_val);
1076         }
1077         if (cap_val & FMP_CAP_CIFSV2 ){
1078                 proto_tree_add_text(capTree, tvb, offset, 4,
1079                                     "CAP_CIFSV2  (%x)",
1080                                     cap_val);
1081         }
1082
1083         return (offset+4);
1084 }
1085
1086
1087 int
1088 dissect_fmp_cerrInfo(tvbuff_t *tvb, int offset, proto_tree *tree)
1089 {
1090                 int rval;
1091         clientErrorNum  errorNum;
1092         errorNum = tvb_get_ntohl(tvb, offset);
1093
1094         switch(errorNum){
1095         case FMP_CE_GENERIC:
1096                 proto_tree_add_text(tree, tvb, offset, 4,
1097                                     "CLIENT Error Number:  FMP_CE_GENERIC  (%d)",
1098                                     errorNum);
1099                 break;
1100
1101         case FMP_CE_DISK_ERROR:
1102                 proto_tree_add_text(tree, tvb, offset, 4,
1103                                     "CLIENT Error Number: FMP_CE_DISK_ERROR (%d)",
1104                                     errorNum);
1105                 break;
1106
1107         default:
1108                 proto_tree_add_text(tree, tvb, offset, 4,
1109                                     "CLIENT Error Number:  Unknown Error Number  (%d)",
1110                                     errorNum);
1111                 break;
1112         }
1113
1114
1115         offset += 4;
1116         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1117
1118         return offset;
1119 }
1120
1121 int
1122 dissect_fmp_attrs(tvbuff_t *tvb, int offset, proto_tree *tree)
1123 {
1124         int attrs;
1125         proto_tree *attrstree;
1126         proto_tree *attrsTree;
1127
1128         attrstree =  proto_tree_add_text(tree, tvb, offset, 84,
1129                                               "Attribute: ");
1130         attrsTree = proto_item_add_subtree(attrstree,
1131                                                 ett_attrs );
1132         attrs = tvb_get_ntohl(tvb, offset);
1133         offset = dissect_rpc_uint32(tvb, attrsTree, hf_fmp_nfsv3Attr_type, offset);
1134         offset = dissect_rpc_uint32(tvb, attrsTree, hf_fmp_nfsv3Attr_mode, offset);
1135         offset = dissect_rpc_uint32(tvb, attrsTree, hf_fmp_nfsv3Attr_nlink, offset);
1136         offset = dissect_rpc_uint32(tvb, attrsTree, hf_fmp_nfsv3Attr_uid, offset);
1137         offset = dissect_rpc_uint32(tvb, attrsTree, hf_fmp_nfsv3Attr_gid, offset);
1138         offset = dissect_rpc_uint64(tvb, attrsTree, hf_fmp_fileSize, offset);
1139                         /* Here hf_fmp_fileSize is used in
1140                          * place of size
1141                          */
1142         offset = dissect_rpc_uint64(tvb, attrsTree, hf_fmp_nfsv3Attr_used,   offset);
1143         offset = dissect_rpc_uint64(tvb, attrsTree, hf_fmp_nfsv3Attr_rdev,   offset);
1144         offset = dissect_rpc_uint64(tvb, attrsTree, hf_fmp_nfsv3Attr_fsid,   offset);
1145         offset = dissect_rpc_uint64(tvb, attrsTree, hf_fmp_nfsv3Attr_fileid, offset);
1146         proto_tree_add_text(tree, tvb, offset, 8,"atime: %d.%d seconds",
1147                             tvb_get_ntohl(tvb, offset),tvb_get_ntohl(tvb, offset+4));
1148         offset +=8;
1149         proto_tree_add_text(tree, tvb, offset, 8,"mtime: %d.%d seconds",
1150                             tvb_get_ntohl(tvb, offset),tvb_get_ntohl(tvb, offset+4));
1151         offset +=8;
1152         proto_tree_add_text(tree, tvb, offset, 8,"ctime: %d.%d seconds",
1153                             tvb_get_ntohl(tvb, offset),tvb_get_ntohl(tvb, offset+4));
1154         offset +=8;
1155         return offset;
1156 }
1157
1158
1159
1160 static int
1161 dissect_FMP_SessionCreate_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1162                                   proto_tree *tree)
1163 {
1164         offset = dissect_rpc_string(tvb, tree, hf_fmp_hostID,
1165                                     offset, NULL); 
1166         offset = dissect_fmp_timeval(tvb, offset, pinfo, tree, hf_fmp_btime,
1167                                      hf_fmp_time_sec, hf_fmp_time_nsec);
1168         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_notifyPort,
1169                                     offset);
1170         return offset;
1171 }
1172
1173 static int
1174 dissect_FMP_SessionCreate_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1175                                 proto_tree *tree)
1176 {
1177         int rval;
1178
1179         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1180         if (rval == 0) {
1181                 offset = dissect_rpc_data(tvb, tree,
1182                                           hf_fmp_sessionHandle, offset); 
1183                 offset = dissect_rpc_string(tvb,  tree, hf_fmp_hostID,
1184                                             offset, NULL);
1185                 offset = dissect_fmp_timeval(tvb, offset, pinfo, tree,
1186                                              hf_fmp_btime, hf_fmp_time_sec,
1187                                              hf_fmp_time_nsec);
1188                 offset = dissect_fmp_heartBeatIntv(tvb, offset, pinfo, tree);
1189         }
1190
1191         return offset;
1192 }
1193
1194 static int
1195 dissect_FMP_HeartBeat_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1196                               proto_tree *tree)
1197 {
1198         offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
1199                                   offset);  
1200
1201         return offset;
1202 }
1203
1204 static int
1205 dissect_FMP_HeartBeat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1206                             proto_tree *tree)
1207 {
1208         int rval;
1209         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1210         return offset;
1211 }
1212
1213 static int
1214 dissect_FMP_Mount_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1215                           proto_tree *tree)
1216 {
1217         offset = dissect_rpc_data(tvb,  tree, hf_fmp_sessionHandle,
1218                                   offset);
1219         offset = dissect_fmp_capability(tvb, offset, tree);
1220         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1221         return offset;
1222 }
1223
1224 static int
1225 dissect_FMP_Mount_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1226                         proto_tree *tree)
1227 {
1228         int rval;
1229
1230         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1231         if (rval == 0) {
1232                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_fsID,
1233                                             offset);
1234                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_fsBlkSz,
1235                                             offset);
1236                 offset = dissect_fmp_vmInfo(tvb, offset, pinfo, tree);
1237         }
1238
1239         return offset;
1240 }
1241
1242 static int
1243 dissect_FMP_Open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1244                          proto_tree *tree)
1245 {
1246         offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
1247                                   offset); 
1248         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1249         return offset;
1250
1251
1252 static int
1253 dissect_FMP_Open_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1254                        proto_tree *tree)
1255 {
1256         int rval;
1257
1258         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1259         if (rval == 0) {
1260                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
1261                                           offset); 
1262                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1263                                             offset);
1264                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1265                                             offset);   
1266
1267                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID,
1268                                             offset);
1269         }
1270         return offset;
1271 }
1272
1273 static int
1274 dissect_FMP_Close_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1275                           proto_tree *tree)
1276 {
1277         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);  
1278         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1279         return offset;
1280 }
1281
1282 static int
1283 dissect_FMP_Close_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1284                         proto_tree *tree)
1285 {
1286         int rval;
1287
1288         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1289         if (rval == 0) {
1290                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1291                                             offset);
1292         }
1293
1294         return offset;
1295 }
1296
1297 static int
1298 dissect_FMP_OpenGetMap_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1299 {
1300         offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
1301                                   offset);  
1302
1303         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1304         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_firstLogBlk,
1305                                     offset);
1306         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1307                                     offset);
1308         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1309         return offset;
1310 }
1311
1312 static int
1313 dissect_FMP_OpenGetMap_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1314                              proto_tree *tree)
1315 {
1316         int rval;
1317
1318         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1319         if (rval == 0) {
1320                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
1321                                           offset);   
1322                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1323                                             offset);
1324                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1325                                             offset);
1326                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1327                                             offset);
1328                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID,
1329                                             offset);
1330                 offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1331         }
1332
1333         return offset;
1334 }
1335
1336 static int
1337 dissect_FMP_OpenAllocSpace_request(tvbuff_t *tvb, int offset,
1338                                    packet_info *pinfo, proto_tree *tree)
1339 {
1340         offset = dissect_rpc_data(tvb , tree, hf_fmp_sessionHandle,
1341                                   offset);  
1342         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1343         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_firstLogBlk,
1344                                     offset);
1345         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1346                                     offset);
1347         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1348         return offset;
1349 }
1350
1351 static int
1352 dissect_FMP_OpenAllocSpace_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1353                                  proto_tree *tree)
1354 {
1355         int rval;
1356
1357         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1358         if (rval == 0) {
1359                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
1360                                           offset);      
1361                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1362                                             offset);
1363                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1364                                             offset);
1365                 offset = dissect_rpc_uint64(tvb,  tree, hf_fmp_fileSize,
1366                                             offset);
1367                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID,
1368                                             offset);
1369                 offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1370         }
1371         return offset;
1372 }
1373
1374 static int
1375 dissect_FMP_GetMap_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1376                            proto_tree *tree)
1377 {
1378         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);   
1379         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum, offset);
1380         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_firstLogBlk,
1381                                     offset);
1382         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1383                                     offset);
1384         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1385         return offset;
1386 }
1387
1388 static int
1389 dissect_FMP_GetMap_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1390                          proto_tree *tree)
1391 {
1392         int rval;
1393
1394         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1395         if (rval == 0) {
1396                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1397                                             offset);
1398                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1399                                             offset);
1400                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1401                                             offset);
1402                 offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1403         }
1404
1405         return offset;
1406 }
1407
1408 static int
1409 dissect_FMP_AllocSpace_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1410                                proto_tree *tree)
1411 {
1412         offset = dissect_rpc_data(tvb,  tree, hf_fmp_fmpFHandle, offset);  
1413         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1414         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_firstLogBlk,
1415                                     offset);
1416         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_numBlksReq,
1417                                     offset);
1418         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_minBlks, offset);
1419         return offset;
1420 }
1421
1422 static int
1423 dissect_FMP_AllocSpace_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1424                              proto_tree *tree)
1425 {
1426         int rval;
1427
1428         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1429         if (rval == 0) {
1430                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum,
1431                                             offset);
1432                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie,
1433                                             offset);
1434                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1435                                             offset);
1436                 offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1437         }
1438
1439         return offset;
1440 }
1441
1442 static int
1443 dissect_FMP_Flush_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1444                           proto_tree *tree)
1445 {
1446         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);  
1447         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1448         offset = dissect_fmp_flushCmd(tvb, offset, tree);
1449         offset = dissect_rpc_uint64(tvb,tree, hf_fmp_eof, offset);
1450         offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1451         return offset;
1452 }
1453
1454 static int
1455 dissect_FMP_Flush_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1456                         proto_tree *tree)
1457 {
1458         int rval;
1459
1460         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1461         if (rval == 0) {
1462                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, 
1463                                             offset);
1464         }
1465         return offset;
1466 }
1467
1468 static int
1469 dissect_FMP_CancelReq_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1470                               proto_tree *tree)
1471 {
1472         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);  
1473         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1474         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie, offset);
1475         return offset;
1476 }
1477
1478 static int
1479 dissect_FMP_CancelReq_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1480                             proto_tree *tree)
1481 {
1482         int rval;
1483
1484         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1485         if (rval == 0) {
1486                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum,
1487                                             offset);
1488         }
1489         return offset;
1490 }
1491
1492 static int
1493 dissect_FMP_PlugIn_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1494                            proto_tree *tree)
1495 {
1496         offset = dissect_plugInID(tvb, offset, tree);
1497         offset = dissect_rpc_data(tvb, tree, hf_fmp_plugInBuf, offset); 
1498         return offset;
1499 }
1500
1501 static int
1502 dissect_FMP_PlugIn_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1503                          proto_tree *tree)
1504 {
1505         int rval;
1506
1507         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1508         if (rval == 0) {
1509                 offset = dissect_rpc_data(tvb,  tree, hf_fmp_plugInBuf,
1510                                           offset);  
1511         }
1512         return offset;
1513 }
1514
1515 static int
1516 dissect_FMP_SessionTerminate_request(tvbuff_t *tvb, int offset,
1517                                      packet_info *pinfo _U_, proto_tree *tree)
1518 {
1519         offset = dissect_rpc_data(tvb,  tree, hf_fmp_sessionHandle,
1520                                   offset);   
1521         return offset;
1522 }
1523
1524 static int
1525 dissect_FMP_SessionTerminate_reply(tvbuff_t *tvb, int offset,
1526                                    packet_info *pinfo _U_, proto_tree *tree)
1527 {
1528         int rval;
1529
1530         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1531         return offset;
1532 }
1533
1534 static int
1535 dissect_FMP_SessionCreateEx_request(tvbuff_t *tvb, int offset,packet_info *pinfo,  proto_tree *tree)
1536 {
1537
1538         offset = dissect_rpc_string(tvb, tree, hf_fmp_hostID,
1539                                     offset, NULL);  
1540         offset = dissect_fmp_timeval(tvb, offset, pinfo ,tree, hf_fmp_btime,
1541                                      hf_fmp_time_sec, hf_fmp_time_nsec);
1542         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_notifyPort,
1543                                     offset);
1544         offset = dissect_fmp_notifyProtocol(tvb, offset, tree);
1545
1546         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_major,
1547                                     offset);
1548         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_minor,
1549                                     offset);
1550
1551         offset = dissect_rpc_string(tvb, tree, hf_fmp_os_name,
1552                                     offset, NULL);   
1553
1554         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_patch,
1555                                     offset);
1556
1557         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_build,
1558                                     offset);
1559
1560         offset = dissect_fmp_capabilities(tvb, offset, tree);
1561
1562         return offset;
1563 }
1564
1565
1566 static int
1567 dissect_FMP_SessionCreateEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1568 {
1569
1570         int rval;
1571
1572         offset = dissect_fmp_status(tvb, offset, tree, &rval);
1573         if (rval == 0) {
1574                 offset = dissect_rpc_data(tvb, tree,
1575                                           hf_fmp_sessionHandle, offset); 
1576                 offset = dissect_rpc_string(tvb,  tree, hf_fmp_hostID,
1577                                             offset, NULL);  
1578                 offset = dissect_fmp_timeval(tvb, offset, pinfo ,tree,
1579                                              hf_fmp_btime, hf_fmp_time_sec,
1580                                              hf_fmp_time_nsec);
1581                 offset = dissect_fmp_heartBeatIntv(tvb, offset, pinfo , tree);
1582
1583                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_major,
1584                                             offset);
1585
1586                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_minor,
1587                                             offset);
1588
1589                 offset = dissect_rpc_string(tvb, tree, hf_fmp_server_version_string,
1590                                             offset, NULL);   
1591
1592                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_patch,
1593                                             offset);
1594
1595                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_os_build,
1596                                           offset);
1597
1598                 offset = dissect_fmp_capabilities(tvb, offset, tree);
1599         }
1600
1601         return offset;
1602 }
1603
1604
1605 static int
1606 dissect_FMP_ReportClientError_request(tvbuff_t *tvb, int offset, 
1607                                         packet_info *pinfo _U_, proto_tree *tree)
1608 {
1609         offset = dissect_rpc_string(tvb, tree, hf_fmp_description,
1610                                     offset, NULL);
1611
1612         offset = dissect_fmp_cerrInfo(tvb, offset, tree);
1613         return offset;
1614 }
1615
1616 static int
1617 dissect_FMP_ReportClientError_reply(tvbuff_t *tvb, int offset, 
1618                                 packet_info *pinfo _U_, proto_tree *tree)
1619 {
1620      int rval;
1621      offset = dissect_fmp_status(tvb, offset,tree, &rval);
1622
1623      return offset;
1624 }
1625
1626 static int
1627 dissect_FMP_GetAttr_request(tvbuff_t *tvb, int offset,
1628                             packet_info *pinfo _U_, proto_tree *tree)
1629 {
1630      offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
1631
1632      offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1633
1634      return offset;
1635 }
1636
1637
1638 static int
1639 dissect_FMP_GetAttr_reply(tvbuff_t *tvb, int offset,
1640                            packet_info *pinfo _U_, proto_tree *tree)
1641 {
1642         int rval;
1643         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1644         if(rval == 0){
1645                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1646
1647                 offset = dissect_fmp_attrs(tvb, offset, tree);
1648         }
1649
1650         return offset;
1651 }
1652
1653 static int
1654 dissect_FMP_OpenGetAttr_request(tvbuff_t *tvb, int offset,
1655                                 packet_info *pinfo, proto_tree *tree)
1656 {
1657
1658         offset = dissect_rpc_data(tvb,  tree, hf_fmp_sessionHandle,
1659                                   offset);
1660
1661         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1662
1663         return offset;
1664 }
1665
1666
1667 static int
1668 dissect_FMP_OpenGetAttr_reply(tvbuff_t *tvb, int offset,
1669                                packet_info *pinfo _U_, proto_tree *tree)
1670 {
1671         int rval;
1672
1673         offset = dissect_fmp_status(tvb, offset, tree, &rval);
1674
1675         if (rval == 0){
1676                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
1677         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1678                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize, offset);
1679                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID, offset);
1680         offset = dissect_fmp_attrs(tvb, offset, tree);
1681         }
1682
1683
1684         return offset;
1685 }
1686
1687
1688 static int
1689 dissect_FMP_FlushGetAttr_request(tvbuff_t *tvb, int offset,
1690                                 packet_info *pinfo, proto_tree *tree)
1691 {
1692
1693         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1694         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1695         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cmd, offset);
1696         offset = dissect_rpc_uint64(tvb,tree, hf_fmp_eof, offset);
1697
1698     proto_tree_add_text(tree, tvb, offset, 8,"mtime: %d.%d seconds",
1699                      tvb_get_ntohl(tvb, offset),tvb_get_ntohl(tvb, offset+4));
1700         offset += 8;
1701         offset = dissect_fmp_extentList(tvb, offset, pinfo, tree);
1702
1703         return offset;
1704 }
1705
1706
1707 static int
1708 dissect_FMP_FlushGetAttr_reply(tvbuff_t *tvb, int offset,
1709                                 packet_info *pinfo _U_, proto_tree *tree)
1710 {
1711         int rval;
1712
1713         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1714         if(rval == 0){
1715          offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1716
1717     offset = dissect_fmp_attrs(tvb, offset, tree);
1718         }
1719         
1720         return offset;
1721 }
1722
1723
1724 static int
1725 dissect_FMP_GetVolumeInfo_request(tvbuff_t *tvb, int offset,
1726                                 packet_info *pinfo _U_, proto_tree *tree)
1727 {
1728         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_topVolumeId, offset);
1729         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cursor, offset);
1730         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie, offset);
1731         return offset;
1732 }
1733
1734
1735
1736 static int
1737 dissect_FMP_GetVolumeInfo_reply(tvbuff_t *tvb, int offset,
1738                                 packet_info *pinfo _U_, proto_tree *tree)
1739 {
1740         int rval;
1741
1742         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1743         if (rval == 0) {
1744                 /* FIXME: I don't know size of this volumes */
1745                 offset = dissect_fmp_Hiervolume(tvb,offset, tree);
1746         }
1747     return offset;
1748
1749 }
1750
1751 static int
1752 dissect_FMP_OpenGetMapEx_request(tvbuff_t *tvb, int offset,
1753                                 packet_info *pinfo, proto_tree *tree)
1754 {
1755         offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
1756                                           offset);
1757         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1758         offset = dissect_rpc_uint64(tvb, tree, hf_fmp_firstLogBlk64,  offset);
1759     offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1760                                 offset);
1761         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1762         return offset;
1763 }
1764
1765
1766 static int
1767 dissect_FMP_OpenGetMapEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1768                              proto_tree *tree)
1769 {
1770         int rval;
1771         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1772         if (rval == 0) {
1773                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
1774                                   offset);   
1775                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1776                                       offset);
1777                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1778                                       offset);
1779                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1780                                       offset);
1781                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID,
1782                                       offset);
1783                 offset = dissect_fmp_extentListEx(tvb, offset, pinfo, tree);
1784         }
1785
1786         return offset;
1787 }
1788
1789
1790 static int
1791 dissect_FMP_OpenAllocSpaceEx_request(tvbuff_t *tvb, int offset,
1792                                    packet_info *pinfo, proto_tree *tree)
1793 {
1794         offset = dissect_rpc_data(tvb , tree, hf_fmp_sessionHandle,
1795                                   offset);  
1796         offset = dissect_fmp_fileHandleSrc(tvb, offset, pinfo, tree);
1797         offset = dissect_rpc_uint64(tvb, tree, hf_fmp_firstLogBlk64,  offset);
1798         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1799                                     offset);
1800         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1801         return offset;
1802 }
1803
1804
1805 static int
1806 dissect_FMP_OpenAllocSpaceEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1807                                  proto_tree *tree)
1808 {
1809         int rval;
1810
1811         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1812         if (rval == 0) {
1813                 offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
1814                                           offset);      
1815                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1816                                             offset);
1817                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1818                                             offset);
1819                 offset = dissect_rpc_uint64(tvb,  tree, hf_fmp_fileSize,
1820                                             offset);
1821                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_fsID,
1822                                             offset);
1823                 offset = dissect_fmp_extentListEx(tvb, offset, pinfo, tree);
1824         }
1825         return offset;
1826 }
1827
1828 static int
1829 dissect_FMP_GetMapEx_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1830                            proto_tree *tree)
1831 {
1832         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);   
1833         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum, offset);
1834         offset = dissect_rpc_uint64(tvb, tree, hf_fmp_firstLogBlk64,  offset);
1835         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_numBlksReq,
1836                                     offset);
1837         offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_minBlks, offset);
1838         return offset;
1839 }
1840
1841
1842 static int
1843 dissect_FMP_GetMapEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1844                          proto_tree *tree)
1845 {
1846         int rval;
1847
1848         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1849         if (rval == 0) {
1850                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_msgNum,
1851                                             offset);
1852                 offset = dissect_rpc_uint32(tvb,  tree, hf_fmp_cookie,
1853                                             offset);
1854                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1855                                             offset);
1856                 offset = dissect_fmp_extentListEx(tvb, offset, pinfo, tree);
1857         }
1858
1859         return offset;
1860 }
1861
1862
1863 static int
1864 dissect_FMP_AllocSpaceEx_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1865                                proto_tree *tree)
1866 {
1867         offset = dissect_rpc_data(tvb,  tree, hf_fmp_fmpFHandle, offset);  
1868         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1869         offset = dissect_rpc_uint64(tvb, tree, hf_fmp_firstLogBlk64,  offset);
1870         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_numBlksReq,
1871                                     offset);
1872         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_minBlks, offset);
1873         return offset;
1874 }
1875
1876
1877 static int
1878 dissect_FMP_AllocSpaceEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1879                              proto_tree *tree)
1880 {
1881         int rval;
1882
1883         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1884         if (rval == 0) {
1885                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum,
1886                                             offset);
1887                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie,
1888                                             offset);
1889                 offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize,
1890                                             offset);
1891                 offset = dissect_fmp_extentListEx(tvb, offset, pinfo, tree);
1892         }
1893
1894         return offset;
1895 }
1896
1897 static int
1898 dissect_FMP_FlushEx_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1899                           proto_tree *tree)
1900 {
1901         offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);  
1902         offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
1903         offset = dissect_fmp_flushCmd(tvb, offset, tree);
1904         offset = dissect_rpc_uint64(tvb,tree, hf_fmp_eof, offset);
1905         offset = dissect_fmp_extentListEx(tvb, offset, pinfo, tree);
1906         return offset;
1907 }
1908
1909 static int
1910 dissect_FMP_FlushEx_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1911                         proto_tree *tree)
1912 {
1913         int rval;
1914
1915         offset = dissect_fmp_status(tvb, offset,tree, &rval);
1916         if (rval == 0) {
1917                 offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, 
1918                                             offset);
1919         }
1920         return offset;
1921 }
1922 /*
1923  * proc number, "proc name", dissect_request, dissect_reply
1924  * NULL as function pointer means: type of arguments is "void".
1925  */
1926 static const vsff fmp3_proc[] = {
1927
1928 { 1,                    "SessionCreate",
1929   dissect_FMP_SessionCreate_request,    dissect_FMP_SessionCreate_reply },
1930
1931 { 2,                    "HeartBeat",
1932   dissect_FMP_HeartBeat_request,        dissect_FMP_HeartBeat_reply },
1933
1934 { 3,                            "Mount",
1935   dissect_FMP_Mount_request,            dissect_FMP_Mount_reply },
1936
1937 { 4,                            "Open",
1938   dissect_FMP_Open_request,             dissect_FMP_Open_reply },
1939
1940 { 5,                            "Close",
1941   dissect_FMP_Close_request,            dissect_FMP_Close_reply },
1942
1943 { 6,                    "OpenGetMap",
1944   dissect_FMP_OpenGetMap_request,       dissect_FMP_OpenGetMap_reply },
1945
1946 { 7,                    "OpenAllocSpace",
1947   dissect_FMP_OpenAllocSpace_request,   dissect_FMP_OpenAllocSpace_reply },
1948
1949 { 8,                            "GetMap",
1950   dissect_FMP_GetMap_request,           dissect_FMP_GetMap_reply },
1951
1952 { 9,                    "AllocSpace",
1953   dissect_FMP_AllocSpace_request,       dissect_FMP_AllocSpace_reply },
1954
1955 { 10,                           "Flush",
1956   dissect_FMP_Flush_request,            dissect_FMP_Flush_reply },
1957
1958 { 11,                   "CancelReq",
1959   dissect_FMP_CancelReq_request,        dissect_FMP_CancelReq_reply },
1960
1961 { 12,                           "PlugIn",
1962   dissect_FMP_PlugIn_request,           dissect_FMP_PlugIn_reply },
1963
1964 { 13,                    "SessionTerminate",
1965   dissect_FMP_SessionTerminate_request, dissect_FMP_SessionTerminate_reply },
1966
1967 { 14,                  "SessionCreateEx",
1968   dissect_FMP_SessionCreateEx_request,  dissect_FMP_SessionCreateEx_reply },
1969
1970 { 15,                "ReportClientError",
1971   dissect_FMP_ReportClientError_request,        dissect_FMP_ReportClientError_reply },
1972
1973 { 16           ,               "Get Attribute",
1974   dissect_FMP_GetAttr_request,          dissect_FMP_GetAttr_reply },
1975
1976 { 17               ,       "Open Get Attribute",
1977   dissect_FMP_OpenGetAttr_request,      dissect_FMP_OpenGetAttr_reply },
1978
1979 { 18               ,       "Flush Get Attribute",
1980   dissect_FMP_FlushGetAttr_request,      dissect_FMP_FlushGetAttr_reply },
1981
1982 { 19               ,       "OpenGetMapEx",
1983   dissect_FMP_OpenGetMapEx_request,      dissect_FMP_OpenGetMapEx_reply },
1984
1985 { 20               ,       "OpenAllocSpaceEx",
1986   dissect_FMP_OpenAllocSpaceEx_request,      dissect_FMP_OpenAllocSpaceEx_reply },
1987
1988 { 21               ,       "GetMapEx",
1989   dissect_FMP_GetMapEx_request,      dissect_FMP_GetMapEx_reply },
1990
1991 { 22               ,       "AllocSpaceEx",
1992   dissect_FMP_AllocSpaceEx_request,      dissect_FMP_AllocSpaceEx_reply },
1993
1994 { 23               ,       "FMP_FlushEx",
1995   dissect_FMP_FlushEx_request,      dissect_FMP_FlushEx_reply },
1996 #if 0
1997
1998 { 24               ,       "FlushGetAttrEx",
1999   dissect_FMP_FlushGetAttrEx_request,      dissect_FMP_FlushGetAttrEx_reply },
2000
2001 #endif 
2002
2003 { 25               ,       "GetVolumeInfo",
2004   dissect_FMP_GetVolumeInfo_request,      dissect_FMP_GetVolumeInfo_reply },
2005
2006
2007 {0 , NULL , NULL , NULL }
2008
2009 };
2010
2011
2012 static const value_string fmp_proc_vals[] = {
2013         { 1,    "SessionCreate" },
2014         { 2,    "HeartBeat" },
2015         { 3,    "Mount" },
2016         { 4,    "Open" },
2017         { 5,    "Close" },
2018         { 6,    "OpenGetMap" },
2019         { 7,    "OpenAllocSpace" },
2020         { 8,    "GetMap" },
2021         { 9,    "AllocSpace " },
2022         { 10,    "Flush" },
2023         { 11,   "CancelReq" },
2024         { 12,   "PlugIn" },
2025         { 13,   "SessionTerminate" },
2026         { 14,   "SessionCreateEx" },
2027         { 15,   "ReportClientError" },
2028         { 16,   "GetAttr " },
2029         { 17,   "OpenGetAttr" },
2030         { 18,   "FlushGetAttr"},
2031         { 19,   "OpenGetMapEx"},
2032         { 20,   "OpenAllocSpaceEx"},
2033         { 21,   "GetMapEx"},
2034         { 22,   "AllocSpaceEx"},
2035         { 23,   "FlushEx"},
2036         { 24,   "FlushGetAttrEx"},
2037         { 25,   "GetVolumeInfo"},
2038         { 0,    "NULL" },
2039         { 0,NULL }
2040 };
2041
2042
2043 static const value_string fmp_status_vals[] = {
2044         {0,"OK"},
2045         {5,"IOERROR"},
2046         {12,"NOMEM"},
2047         {13,"NOACCESS"},
2048         {22,"INVALIDARG"},
2049         {28,"FSFULL"},
2050         {79,"QUEUE_FULL"},
2051         {500,"WRONG_MSG_NUM"},
2052         {501,"SESSION_LOST"},
2053         {502,"HOT_SESSION"},
2054         {503,"COLD_SESSION"},
2055         {504,"CLIENT_TERMINATED"},
2056         {505,"WRITER_LOST_BLK"},
2057         {506,"FMP_REQUEST_QUEUED"},
2058         {507,"FMP_FALL_BACK"},
2059         {508,"REQUEST_CANCELLED"},
2060         {509,"WRITER_ZEROED_BLK"},
2061         {510,"NOTIFY_ERROR"},
2062         {511,"FMP_WRONG_HANDLE"},
2063         {512,"DUPLICATE_OPEN"},
2064         {600,"PLUGIN_NOFUNC"},
2065         {0,NULL}
2066 };
2067
2068
2069 static const value_string fmp_extentState_vals[] = {
2070         {0,"VALID_DATA"},
2071         {1,"INVALID_DATA"},
2072         {2,"NONE_DATA"},
2073         {0,NULL}
2074 };
2075
2076
2077
2078 void
2079 proto_register_fmp(void)
2080 {
2081         static hf_register_info hf[] = {
2082                  { &hf_fmp_procedure, {
2083                         "Procedure", "fmp.procedure", FT_UINT32, BASE_DEC,
2084                        VALS(fmp_proc_vals) , 0, NULL, HFILL }},        /* New addition */
2085
2086                 { &hf_fmp_hostID, {
2087                         "Host ID", "fmp.hostID", FT_STRING, BASE_NONE,
2088                         NULL, 0, NULL, HFILL }},
2089
2090                 { &hf_fmp_btime, {
2091                         "Boot Time", "fmp.btime", FT_ABSOLUTE_TIME, BASE_NONE,
2092                         NULL, 0, "Machine Boot Time", HFILL }},
2093
2094                 { &hf_fmp_time_sec, {
2095                         "seconds", "fmp.btime.sec", FT_UINT32, BASE_DEC,
2096                         NULL, 0, "Seconds", HFILL }},
2097
2098                 { &hf_fmp_time_nsec, {
2099                         "nanoseconds", "fmp.btime.nsec", FT_UINT32, BASE_DEC,
2100                         NULL, 0, "Nanoseconds", HFILL }},
2101
2102                 { &hf_fmp_notifyPort, {
2103                         "Notify Port", "fmp.notifyPort", FT_UINT32, BASE_DEC,
2104                         NULL, 0, "FMP Notify Port", HFILL }},
2105
2106                 { &hf_fmp_sessionHandle, {
2107                         "Session Handle", "fmp.sessHandle", FT_BYTES, BASE_NONE,
2108                         NULL, 0, "FMP Session Handle", HFILL }},
2109
2110                 { &hf_fmp_fmpFHandle, {
2111                         "FMP File Handle", "fmp.fmpFHandle",
2112                         FT_BYTES, BASE_NONE, NULL, 0, NULL,
2113                         HFILL }},
2114
2115                 { &hf_fmp_nfsFHandle, {
2116                         "NFS File Handle", "fmp.nfsFHandle", FT_BYTES,
2117                         BASE_NONE, NULL, 0, NULL, HFILL }},
2118
2119                 { &hf_fmp_fsID, {
2120                         "File System ID", "fmp.fsID", FT_UINT32, BASE_HEX,
2121                         NULL, 0, NULL, HFILL }},
2122                 { &hf_fmp_status, {
2123                         "Status", "fmp.status", FT_UINT32, BASE_DEC,
2124                         VALS(fmp_status_vals), 0, "Reply Status", HFILL }},
2125
2126                 { &hf_fmp_fsBlkSz, {
2127                         "FS Block Size", "fmp.fsBlkSz", FT_UINT32, BASE_DEC,
2128                         NULL, 0, "File System Block Size", HFILL }},
2129
2130                 { &hf_fmp_volHandle, {
2131                         "Volume Handle", "fmp.volHandle", FT_STRING, BASE_NONE,
2132                         NULL, 0, "FMP Volume Handle", HFILL }},
2133
2134                 { &hf_fmp_dskSigEnt_val, {
2135                         "Celerra Signature", "fmp.dsi.ds.dsList.dskSigLst_val.dse.dskSigEnt_val", FT_STRING, BASE_NONE,
2136                         NULL, 0, NULL, HFILL }},
2137                 { &hf_fmp_devSignature, {
2138                         "Signature DATA", "fmp.devSig", FT_STRING, BASE_NONE,
2139                         NULL, 0, NULL, HFILL }},
2140                 { &hf_fmp_mount_path, {
2141                        "Native Protocol: PATH", "fmp.mount_path", FT_STRING, BASE_NONE,
2142                        NULL, 0, "Absolute path from the root on the server side", HFILL }},
2143                 { &hf_fmp_sig_offset, {
2144                         "Sig Offset", "fmp.dsi.ds.sig_offset", FT_UINT64, BASE_DEC,
2145                         NULL, 0, NULL, HFILL }},
2146
2147                 { &hf_fmp_numBlksReq, {
2148                         "Extent Length", "fmp.numBlksReq", FT_UINT32,
2149                         BASE_DEC, NULL, 0, NULL, HFILL }},
2150
2151                 { &hf_fmp_minBlks, {
2152                         "Minimum Blocks to Grant", "fmp.minBlks", FT_UINT32,
2153                         BASE_DEC, NULL, 0, NULL, HFILL }},
2154
2155                 { &hf_fmp_msgNum, {
2156                         "Message Number", "fmp.msgNum", FT_UINT32, BASE_DEC,
2157                         NULL, 0, "FMP Message Number", HFILL }},
2158
2159                 { &hf_fmp_cookie, {
2160                         "Cookie", "fmp.cookie", FT_UINT32, BASE_HEX,
2161                         NULL, 0, "Cookie for FMP_REQUEST_QUEUED Resp", HFILL }},
2162
2163                 { &hf_fmp_fileSize, {
2164                         "File Size", "fmp.fileSize", FT_UINT64, BASE_DEC,
2165                         NULL, 0, NULL, HFILL }},
2166
2167                 { &hf_fmp_extentList_len, {
2168                         "Extent List Length", "fmp.extentList_len", FT_UINT32,
2169                         BASE_DEC, NULL, 0, "FMP Extent List Length", HFILL }},
2170
2171                 { &hf_fmp_extent_state, {
2172                         "Extent State", "fmp.extentState", FT_UINT32,BASE_DEC, 
2173                         VALS(fmp_extentState_vals), 0, "FMP Extent State", HFILL }},
2174
2175                 { &hf_fmp_firstLogBlk, {
2176                         "firstLogBlk", "fmp.firstLogBlk", FT_UINT32,
2177                         BASE_DEC, NULL, 0, "First Logical File Block", HFILL }},
2178
2179                 { &hf_fmp_numBlks, {
2180                         "Number Blocks", "fmp.numBlks", FT_UINT32, BASE_DEC,
2181                         NULL, 0, "Number of Blocks", HFILL }},
2182
2183                 { &hf_fmp_volID, {
2184                         "Volume ID inside DART", "fmp.volID", FT_UINT32, BASE_HEX,
2185                         NULL, 0, "FMP Volume ID inside DART", HFILL }},
2186         
2187                 { &hf_fmp_startOffset, {
2188                         "Start Offset", "fmp.startOffset", FT_UINT32, BASE_DEC,
2189                         NULL, 0, "FMP Start Offset", HFILL }},
2190
2191                 { &hf_fmp_start_offset64, {
2192                         "Start offset", "fmp.start_offset64", FT_UINT64, BASE_DEC,
2193                         NULL, 0, "Start Offset of extentEx", HFILL }},
2194
2195                 { &hf_fmp_eof, {
2196                         "EOF", "fmp.eof", FT_UINT64, BASE_DEC,
2197                         NULL, 0, "End Of File", HFILL }},
2198
2199                 { &hf_fmp_plugInID, {
2200                         "Plug In Cmd ID", "fmp.plugInID",  FT_BYTES, BASE_NONE,
2201                         NULL, 0, "Plug In Command ID", HFILL }},
2202
2203                 { &hf_fmp_plugInBuf, {
2204                         "Plug In Args", "fmp.plugIn", FT_BYTES, BASE_NONE,
2205                         NULL, 0, "FMP Plug In Arguments", HFILL }},
2206                 { &hf_fmp_os_major, {
2207                         "OS Major", "fmp.os_major", FT_UINT32, BASE_DEC,
2208                         NULL, 0, "FMP OS Major", HFILL }},
2209                 { &hf_fmp_os_minor, {
2210                         "OS Minor", "fmp.os_minor", FT_UINT32, BASE_DEC,
2211                         NULL, 0, "FMP OS Minor", HFILL }},
2212                 { &hf_fmp_os_name, {
2213                         "OS Name", "fmp.os_name", FT_STRING, BASE_NONE,
2214                         NULL, 0, NULL, HFILL }},
2215                  { &hf_fmp_path, {
2216                         "Mount Path", "fmp.Path", FT_STRING, BASE_NONE,
2217                         NULL, 0, NULL, HFILL }},
2218                 { &hf_fmp_os_patch, {
2219                         "OS Path", "fmp.os_patch", FT_UINT32, BASE_DEC,
2220                         NULL, 0, NULL, HFILL }},
2221                 { &hf_fmp_os_build, {
2222                         "OS Build", "fmp.os_build", FT_UINT32, BASE_DEC,
2223                         NULL, 0, NULL, HFILL }},
2224                 { &hf_fmp_server_version_string, {
2225                         "Server Version String", "fmp.server_version_string", FT_STRING, BASE_NONE,
2226                         NULL, 0, NULL, HFILL }},
2227                 { &hf_fmp_description, {
2228                         "Error Description", "fmp.description", FT_STRING, BASE_NONE,
2229                         NULL, 0, "Client Error Description", HFILL }},
2230                 { &hf_fmp_nfsv3Attr_type, {
2231                         "Type", "fmp.nfsv3Attr_type", FT_UINT32, BASE_DEC,
2232                         NULL, 0, "NFSV3 Attr Type", HFILL }},
2233                  { &hf_fmp_nfsv3Attr_mode, {
2234                         "Mode", "fmp.nfsv3Attr_mod", FT_UINT32, BASE_DEC,
2235                         NULL, 0, NULL, HFILL }},
2236                 { &hf_fmp_nfsv3Attr_nlink, {
2237                         "nlink", "fmp.nfsv3Attr_nlink", FT_UINT32, BASE_DEC,
2238                         NULL, 0, NULL, HFILL }},
2239                 { &hf_fmp_nfsv3Attr_uid, {
2240                         "uid", "fmp.nfsv3Attr_uid", FT_UINT32, BASE_DEC,
2241                         NULL, 0, "UID", HFILL }},
2242                 { &hf_fmp_nfsv3Attr_gid, {
2243                         "gid", "fmp.nfsv3Attr_gid", FT_UINT32, BASE_DEC,
2244                         NULL, 0, "GID", HFILL }},
2245                 /* for nfsv3Attr_size use hf_fmp_fileSize */
2246                 { &hf_fmp_nfsv3Attr_used, {
2247                         "Used", "fmp.nfsv3Attr_used", FT_UINT64, BASE_DEC,
2248                         NULL, 0, "used", HFILL }},
2249                 { &hf_fmp_nfsv3Attr_rdev, {
2250                         "rdev", "fmp.nfsv3Attr_rdev", FT_UINT64, BASE_DEC,
2251                         NULL, 0, NULL, HFILL }},
2252                 { &hf_fmp_nfsv3Attr_fsid, {
2253                         "fsid", "fmp.nfsv3Attr_fsid", FT_UINT64, BASE_DEC,
2254                         NULL, 0, NULL, HFILL }},
2255                 { &hf_fmp_nfsv3Attr_fileid, {
2256                         "File ID", "fmp.nfsv3Attr_fileid", FT_UINT64, BASE_DEC,
2257                         NULL, 0, "fileid", HFILL }},
2258                 { &hf_fmp_cmd, {
2259                         "Command", "fmp.cmd", FT_UINT32, BASE_DEC,
2260                         NULL, 0, "command", HFILL }},
2261                 { &hf_fmp_topVolumeId, {
2262                         "Top Volume ID", "fmp.topVolumeId", FT_UINT32, BASE_HEX,
2263                         NULL, 0, NULL, HFILL }},
2264                 { &hf_fmp_cursor, {
2265                         "number of volumes", "fmp.cursor", FT_UINT32, BASE_DEC,
2266                         NULL, 0, NULL, HFILL }},
2267                 { &hf_fmp_offset64, {
2268                         "offset", "fmp.offset64", FT_UINT64, BASE_DEC,
2269                         NULL, 0, NULL, HFILL }},
2270                 { &hf_fmp_slice_size, {
2271                         "size of the slice", "fmp.slice_size", FT_UINT64, BASE_DEC,
2272                         NULL, 0, NULL, HFILL }},
2273                 { &hf_fmp_volume, {
2274                         "Volume ID's", "fmp.volume", FT_UINT32, BASE_HEX,
2275                         NULL, 0, "FMP Volume ID's", HFILL }},
2276                 { &hf_fmp_stripeSize, {
2277                         "size of the stripe", "fmp.stripeSize", FT_UINT64, BASE_DEC,
2278                         NULL, 0, NULL, HFILL }},
2279                 { &hf_fmp_firstLogBlk64, {
2280                         "First Logical Block", "fmp.firstLogBlk64", FT_UINT64, BASE_DEC,
2281                         NULL, 0, NULL, HFILL }},
2282
2283         };
2284
2285         static gint *ett[] = {
2286                 &ett_fmp,
2287                 &ett_fmp_timeval,
2288                 &ett_fmp_extList,
2289                 &ett_fmp_ext,
2290                 &ett_fmp_fileHandle,
2291                 &ett_capabilities,
2292                 &ett_HierVolumeDescription,
2293                 &ett_attrs
2294         };
2295         
2296         module_t *fmp_module;
2297         proto_fmp = proto_register_protocol("File Mapping Protocol", "FMP",
2298                                             "fmp");
2299         
2300         proto_register_field_array(proto_fmp, hf, array_length(hf));
2301         proto_register_subtree_array(ett, array_length(ett));
2302
2303         fmp_module=prefs_register_protocol(proto_fmp, NULL);    
2304         
2305         prefs_register_bool_preference(fmp_module, "fhandle_find_both_reqrep",
2306                                        "Fhandle filters finds both request/response",
2307                                        "With this option display filters for fmp fhandle a RPC call, even if the actual fhandle is only present in one of the packets" 
2308       , &fmp_fhandle_reqrep_matching);
2309
2310 }
2311
2312 void
2313 proto_reg_handoff_fmp(void)
2314 {
2315         /* Register the protocol as RPC */
2316         rpc_init_prog(proto_fmp, FMP_PROGRAM, ett_fmp);
2317
2318         /* Register the procedure tables */
2319         rpc_init_proc_table(FMP_PROGRAM, FMP_VERSION_3, fmp3_proc,hf_fmp_procedure);
2320 }