Ethereal-dev: [ethereal-dev] NFS dissector continuation
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Uwe Girlich <Uwe.Girlich@xxxxxxxxxxx>
Date: Mon, 15 Nov 1999 10:12:28 +0100
Here comes the next part of my NFS dissector. It evolves very slowly but the NFS protocol is a really big one. I include some patches for packet-mount.[ch] (new mount protocol) and packet-portmap.[ch] (new portmapper protocol). To remove all incomplete dissectors, I provide a start for packet-nlm.[ch] (Network Lock Manager). roundup() in packet-rpc.c is called rpc_roundup() now. Then I include a small patch for packet-tcp.c, which may also call dissect_rpc().
Index: Makefile.am =================================================================== RCS file: /cvsroot/ethereal/Makefile.am,v retrieving revision 1.106 diff -u -r1.106 Makefile.am --- Makefile.am 1999/11/11 23:13:42 1.106 +++ Makefile.am 1999/11/15 09:05:45 @@ -84,6 +84,8 @@ packet-netbios.h \ packet-nfs.c \ packet-nfs.h \ + packet-nlm.c \ + packet-nlm.h \ packet-nntp.c \ packet-ntp.c \ packet-ntp.h \ Index: packet-mount.c =================================================================== RCS file: /cvsroot/ethereal/packet-mount.c,v retrieving revision 1.1 diff -u -r1.1 packet-mount.c --- packet-mount.c 1999/11/11 21:21:59 1.1 +++ packet-mount.c 1999/11/15 09:05:46 @@ -37,11 +37,12 @@ #include "packet-rpc.h" #include "packet-mount.h" + static int proto_mount = -1; static int hf_mount_path = -1; + -/* Dissect a unmount call */ -int dissect_unmount_call(const u_char *pd, int offset, frame_data *fd, +int dissect_mount_dirpath_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { if ( tree ) @@ -52,20 +53,45 @@ return offset; } + /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: take the generic one. */ - -const vsff mount_proc[] = { +/* Mount protocol version 1, RFC 1094 */ +const vsff mount1_proc[] = { { 0, "NULL", NULL, NULL }, - { MOUNTPROC_MOUNT, "MOUNT", + { MOUNTPROC_MNT, "MNT", + dissect_mount_dirpath_call, NULL }, + { MOUNTPROC_DUMP, "DUMP", + NULL, NULL }, + { MOUNTPROC_UMNT, "UMNT", + dissect_mount_dirpath_call, NULL }, + { MOUNTPROC_UMNTALL, "UMNTALL", + NULL, NULL }, + { MOUNTPROC_EXPORT, "EXPORT", NULL, NULL }, - { MOUNTPROC_UNMOUNT, "UNMOUNT", - dissect_unmount_call, NULL }, { 0, NULL, NULL, NULL } }; /* end of mount version 1 */ +/* Mount protocol version 3, RFC 1813 */ +const vsff mount3_proc[] = { + { 0, "NULL", NULL, NULL }, + { MOUNTPROC_MNT, "MNT", + dissect_mount_dirpath_call, NULL }, + { MOUNTPROC_DUMP, "DUMP", + NULL, NULL }, + { MOUNTPROC_UMNT, "UMNT", + dissect_mount_dirpath_call, NULL }, + { MOUNTPROC_UMNTALL, "UMNTALL", + NULL, NULL }, + { MOUNTPROC_EXPORT, "EXPORT", + NULL, NULL }, + { 0, NULL, NULL, NULL } +}; +/* end of Mount protocol version 3 */ + + void proto_register_mount(void) { @@ -81,6 +107,7 @@ /* Register the protocol as RPC */ rpc_init_prog(proto_mount, MOUNT_PROGRAM, ETT_MOUNT); /* Register the procedure tables */ - rpc_init_proc_table(MOUNT_PROGRAM, 1, mount_proc); + rpc_init_proc_table(MOUNT_PROGRAM, 1, mount1_proc); + rpc_init_proc_table(MOUNT_PROGRAM, 3, mount3_proc); } Index: packet-mount.h =================================================================== RCS file: /cvsroot/ethereal/packet-mount.h,v retrieving revision 1.1 diff -u -r1.1 packet-mount.h --- packet-mount.h 1999/11/11 21:21:59 1.1 +++ packet-mount.h 1999/11/15 09:05:46 @@ -6,8 +6,11 @@ #define MOUNT_PROGRAM 100005 -#define MOUNTPROC_NULL 0 -#define MOUNTPROC_MOUNT 1 -#define MOUNTPROC_UNMOUNT 3 +#define MOUNTPROC_NULL 0 +#define MOUNTPROC_MNT 1 +#define MOUNTPROC_DUMP 2 +#define MOUNTPROC_UMNT 3 +#define MOUNTPROC_UMNTALL 4 +#define MOUNTPROC_EXPORT 5 #endif Index: packet-nfs.c =================================================================== RCS file: /cvsroot/ethereal/packet-nfs.c,v retrieving revision 1.2 diff -u -r1.2 packet-nfs.c --- packet-nfs.c 1999/11/05 07:16:23 1.2 +++ packet-nfs.c 1999/11/15 09:05:51 @@ -94,7 +94,7 @@ if (tree) { proto_tree_add_text(tree, offset, 4, - "%s (stat): %s (%u)", name, stat_name, stat); + "%s: %s (%u)", name, stat_name, stat); } offset += 4; @@ -128,7 +128,7 @@ if (tree) { proto_tree_add_text(tree, offset, 4, - "%s (ftype): %s (%u)", name, ftype_name, ftype); + "%s: %s (%u)", name, ftype_name, ftype); } offset += 4; @@ -145,7 +145,7 @@ if (tree) { fitem = proto_tree_add_text(tree, offset, FHSIZE, - "%s (fhandle)", name); + "%s", name); if (fitem) ftree = proto_item_add_subtree(fitem, ETT_NFS_FHANDLE); } @@ -175,7 +175,7 @@ if (tree) { time_item = proto_tree_add_text(tree, offset, 8, - "%s (timeval): %u.%06u", name, seconds, mseconds); + "%s: %u.%06u", name, seconds, mseconds); if (time_item) time_tree = proto_item_add_subtree(time_item, ETT_NFS_TIMEVAL); } @@ -214,7 +214,7 @@ if (tree) { mode_item = proto_tree_add_text(tree, offset, 4, - "%s (mode): 0%o", name, mode); + "%s: 0%o", name, mode); if (mode_item) mode_tree = proto_item_add_subtree(mode_item, ETT_NFS_MODE); } @@ -264,7 +264,7 @@ if (tree) { fattr_item = proto_tree_add_text(tree, offset, - END_OF_FRAME, "%s (fattr)", name); + END_OF_FRAME, "%s", name); if (fattr_item) fattr_tree = proto_item_add_subtree(fattr_item, ETT_NFS_FATTR); } @@ -293,6 +293,38 @@ } +/* RFC 1094, Page 17 */ +int +dissect_sattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* sattr_item = NULL; + proto_tree* sattr_tree = NULL; + int old_offset = offset; + + if (tree) { + sattr_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (sattr_item) + sattr_tree = proto_item_add_subtree(sattr_item, ETT_NFS_SATTR); + } + + /* some how we should indicate here, that -1 means "do not set" */ + offset = dissect_mode (pd,offset,fd,sattr_tree,"mode"); + offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"uid"); + offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"gid"); + offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"size"); + offset = dissect_timeval (pd,offset,fd,sattr_tree,"atime"); + offset = dissect_timeval (pd,offset,fd,sattr_tree,"mtime"); + + /* now we know, that sattr is shorter */ + if (sattr_item) { + proto_item_set_len(sattr_item, offset - old_offset); + } + + return offset; +} + + /* generic NFS2 call dissector */ int dissect_nfs2_any_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) @@ -345,6 +377,39 @@ return offset; } + +/* RFC 1094, Page 6 */ +int +dissect_nfs2_setattr_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + offset = dissect_fhandle(pd, offset, fd, tree, "file" ); + offset = dissect_sattr (pd, offset, fd, tree, "attributes"); + + return offset; +} + + +/* RFC 1094, Page 6 */ +int +dissect_nfs2_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree) +{ + guint32 status; + + /* attrstat: RFC 1094, Page 17 */ + offset = dissect_stat(pd, offset, fd, tree, "status", &status); + switch (status) { + case 0: + offset = dissect_fattr(pd, offset, fd, tree, "attributes"); + break; + default: + /* do nothing */ + break; + } + + return offset; +} + + /* more to come here */ @@ -353,7 +418,7 @@ const vsff nfs2_proc[] = { { 0, "NULL", NULL, NULL }, { 1, "GETATTR", dissect_nfs2_getattr_call, dissect_nfs2_getattr_reply }, - { 2, "SETATTR", dissect_nfs2_any_call, dissect_nfs2_any_reply }, + { 2, "SETATTR", dissect_nfs2_any_call, dissect_nfs2_setattr_reply }, { 3, "ROOT", NULL, NULL }, { 4, "LOOKUP", dissect_nfs2_any_call, dissect_nfs2_any_reply }, { 5, "READLINK", dissect_nfs2_any_call, dissect_nfs2_any_reply }, @@ -453,7 +518,7 @@ if (tree) { mode3_item = proto_tree_add_text(tree, offset, 4, - "%s (mode3): 0%o", name, mode3); + "%s: 0%o", name, mode3); if (mode3_item) mode3_tree = proto_item_add_subtree(mode3_item, ETT_NFS_MODE3); } @@ -550,7 +615,7 @@ if (tree) { proto_tree_add_text(tree, offset, 4, - "%s (nfsstat3): %s (%u)", name, nfsstat3_name, nfsstat3); + "%s: %s (%u)", name, nfsstat3_name, nfsstat3); } offset += 4; @@ -588,7 +653,7 @@ if (tree) { proto_tree_add_text(tree, offset, 4, - "%s (ftype3): %s (%u)", name, ftype3_name, ftype3); + "%s: %s (%u)", name, ftype3_name, ftype3); } offset += 4; @@ -612,7 +677,7 @@ if (tree) { specdata3_item = proto_tree_add_text(tree, offset, 8, - "%s (specdata3) : %u,%u", name, specdata1, specdata2); + "%s: %u,%u", name, specdata1, specdata2); if (specdata3_item) specdata3_tree = proto_item_add_subtree(specdata3_item, ETT_NFS_SPECDATA3); @@ -641,12 +706,12 @@ proto_tree* ftree = NULL; fh_len = EXTRACT_UINT(pd, offset+0); - fh_len_full = roundup(fh_len); + fh_len_full = rpc_roundup(fh_len); fh_fill = fh_len_full - fh_len; if (tree) { fitem = proto_tree_add_text(tree, offset, 4+fh_len_full, - "%s (nfs_fh3)", name); + "%s", name); if (fitem) ftree = proto_item_add_subtree(fitem, ETT_NFS_FH3); } @@ -667,7 +732,7 @@ /* RFC 1813, Page 21 */ int -dissect_nfs3time(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name) +dissect_nfstime3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name) { guint32 seconds; guint32 nseconds; @@ -681,7 +746,7 @@ if (tree) { time_item = proto_tree_add_text(tree, offset, 8, - "%s (nfs3time): %u.%09u", name, seconds, nseconds); + "%s: %u.%09u", name, seconds, nseconds); if (time_item) time_tree = proto_item_add_subtree(time_item, ETT_NFS_NFSTIME3); } @@ -707,7 +772,7 @@ if (tree) { fattr3_item = proto_tree_add_text(tree, offset, - END_OF_FRAME, "%s (fattr3)", name); + END_OF_FRAME, "%s", name); if (fattr3_item) fattr3_tree = proto_item_add_subtree(fattr3_item, ETT_NFS_FATTR3); } @@ -722,9 +787,9 @@ offset = dissect_specdata3(pd,offset,fd,fattr3_tree,"rdev"); offset = dissect_uint64 (pd,offset,fd,fattr3_tree,"fsid"); offset = dissect_fileid3 (pd,offset,fd,fattr3_tree,"fileid"); - offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"atime"); - offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"mtime"); - offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"ctime"); + offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"atime"); + offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"mtime"); + offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"ctime"); /* now we know, that fattr3 is shorter */ if (fattr3_item) { @@ -735,6 +800,476 @@ } +const value_string value_follows[3] = + { + { 0, "no value" }, + { 1, "value follows"}, + { 0, NULL } + }; + + +/* RFC 1813, Page 23 */ +int +dissect_post_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* post_op_attr_item = NULL; + proto_tree* post_op_attr_tree = NULL; + int old_offset = offset; + guint32 attributes_follow; + + if (tree) { + post_op_attr_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (post_op_attr_item) + post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, ETT_NFS_POST_OP_ATTR); + } + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + attributes_follow = EXTRACT_UINT(pd, offset+0); + proto_tree_add_text(post_op_attr_tree, offset, 4, + "attributes_follow: %s (%u)", + val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow); + offset += 4; + switch (attributes_follow) { + case TRUE: + offset = dissect_fattr3(pd, offset, fd, post_op_attr_tree, + "attributes"); + break; + case FALSE: + /* void */ + break; + } + + /* now we know, that post_op_attr_tree is shorter */ + if (post_op_attr_item) { + proto_item_set_len(post_op_attr_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 24 */ +int +dissect_wcc_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* wcc_attr_item = NULL; + proto_tree* wcc_attr_tree = NULL; + int old_offset = offset; + + if (tree) { + wcc_attr_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (wcc_attr_item) + wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, ETT_NFS_WCC_ATTR); + } + + offset = dissect_size3 (pd, offset, fd, wcc_attr_tree, "size" ); + offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "mtime"); + offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "ctime"); + + /* now we know, that wcc_attr_tree is shorter */ + if (wcc_attr_item) { + proto_item_set_len(wcc_attr_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 24 */ +int +dissect_pre_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* pre_op_attr_item = NULL; + proto_tree* pre_op_attr_tree = NULL; + int old_offset = offset; + guint32 attributes_follow; + + if (tree) { + pre_op_attr_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (pre_op_attr_item) + pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, ETT_NFS_PRE_OP_ATTR); + } + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + attributes_follow = EXTRACT_UINT(pd, offset+0); + proto_tree_add_text(pre_op_attr_tree, offset, 4, + "attributes_follow: %s (%u)", + val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow); + offset += 4; + switch (attributes_follow) { + case TRUE: + offset = dissect_wcc_attr(pd, offset, fd, pre_op_attr_tree, + "attributes"); + break; + case FALSE: + /* void */ + break; + } + + /* now we know, that pre_op_attr_tree is shorter */ + if (pre_op_attr_item) { + proto_item_set_len(pre_op_attr_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 24 */ +int +dissect_wcc_data(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* wcc_data_item = NULL; + proto_tree* wcc_data_tree = NULL; + int old_offset = offset; + + if (tree) { + wcc_data_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (wcc_data_item) + wcc_data_tree = proto_item_add_subtree(wcc_data_item, ETT_NFS_WCC_DATA); + } + + offset = dissect_pre_op_attr (pd, offset, fd, wcc_data_tree, "before"); + offset = dissect_post_op_attr(pd, offset, fd, wcc_data_tree, "after" ); + + /* now we know, that wcc_data is shorter */ + if (wcc_data_item) { + proto_item_set_len(wcc_data_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 25 */ +int +dissect_set_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_mode3_item = NULL; + proto_tree* set_mode3_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,value_follows,"Unknown"); + + if (tree) { + set_mode3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", name, set_it_name); + if (set_mode3_item) + set_mode3_tree = proto_item_add_subtree(set_mode3_item, ETT_NFS_SET_MODE3); + } + + if (set_mode3_tree) + proto_tree_add_text(set_mode3_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case 1: + offset = dissect_mode3(pd, offset, fd, set_mode3_tree, + "mode"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_mode3 is shorter */ + if (set_mode3_item) { + proto_item_set_len(set_mode3_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 26 */ +int +dissect_set_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_uid3_item = NULL; + proto_tree* set_uid3_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,value_follows,"Unknown"); + + if (tree) { + set_uid3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", name, set_it_name); + if (set_uid3_item) + set_uid3_tree = proto_item_add_subtree(set_uid3_item, ETT_NFS_SET_UID3); + } + + if (set_uid3_tree) + proto_tree_add_text(set_uid3_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case 1: + offset = dissect_uid3(pd, offset, fd, set_uid3_tree, + "uid"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_uid3 is shorter */ + if (set_uid3_item) { + proto_item_set_len(set_uid3_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 26 */ +int +dissect_set_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_gid3_item = NULL; + proto_tree* set_gid3_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,value_follows,"Unknown"); + + if (tree) { + set_gid3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", name, set_it_name); + if (set_gid3_item) + set_gid3_tree = proto_item_add_subtree(set_gid3_item, ETT_NFS_SET_GID3); + } + + if (set_gid3_tree) + proto_tree_add_text(set_gid3_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case 1: + offset = dissect_gid3(pd, offset, fd, set_gid3_tree, + "gid"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_gid3 is shorter */ + if (set_gid3_item) { + proto_item_set_len(set_gid3_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 26 */ +int +dissect_set_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_size3_item = NULL; + proto_tree* set_size3_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,value_follows,"Unknown"); + + if (tree) { + set_size3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", name, set_it_name); + if (set_size3_item) + set_size3_tree = proto_item_add_subtree(set_size3_item, ETT_NFS_SET_SIZE3); + } + + if (set_size3_tree) + proto_tree_add_text(set_size3_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case 1: + offset = dissect_size3(pd, offset, fd, set_size3_tree, + "size"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_size3 is shorter */ + if (set_size3_item) { + proto_item_set_len(set_size3_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 25 */ +#define DONT_CHANGE 0 +#define SET_TO_SERVER_TIME 1 +#define SET_TO_CLIENT_TIME 2 + +const value_string time_how[] = + { + { DONT_CHANGE, "don't change" }, + { SET_TO_SERVER_TIME, "set to server time" }, + { SET_TO_CLIENT_TIME, "set to client time" }, + { 0, NULL } + }; + + +/* RFC 1813, Page 26 */ +int +dissect_set_atime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_atime_item = NULL; + proto_tree* set_atime_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,time_how,"Unknown"); + + if (tree) { + set_atime_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", + name, set_it_name, set_it); + if (set_atime_item) + set_atime_tree = proto_item_add_subtree(set_atime_item, ETT_NFS_SET_ATIME); + } + + if (set_atime_tree) + proto_tree_add_text(set_atime_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case SET_TO_CLIENT_TIME: + if (set_atime_item) + offset = dissect_nfstime3(pd, offset, fd, set_atime_tree, + "atime"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_atime is shorter */ + if (set_atime_item) { + proto_item_set_len(set_atime_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 26 */ +int +dissect_set_mtime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* set_mtime_item = NULL; + proto_tree* set_mtime_tree = NULL; + int old_offset = offset; + guint32 set_it; + char* set_it_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + set_it = EXTRACT_UINT(pd, offset+0); + set_it_name = val_to_str(set_it,time_how,"Unknown"); + + if (tree) { + set_mtime_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", + name, set_it_name, set_it); + if (set_mtime_item) + set_mtime_tree = proto_item_add_subtree(set_mtime_item, ETT_NFS_SET_MTIME); + } + + if (set_mtime_tree) + proto_tree_add_text(set_mtime_tree, offset, 4, + "set_it: %s (%u)", set_it_name, set_it); + + offset += 4; + + switch (set_it) { + case SET_TO_CLIENT_TIME: + if (set_mtime_item) + offset = dissect_nfstime3(pd, offset, fd, set_mtime_tree, + "atime"); + break; + default: + /* void */ + break; + } + + /* now we know, that set_mtime is shorter */ + if (set_mtime_item) { + proto_item_set_len(set_mtime_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 26 */ +int +dissect_sattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) +{ + proto_item* sattr3_item = NULL; + proto_tree* sattr3_tree = NULL; + int old_offset = offset; + + if (tree) { + sattr3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s", name); + if (sattr3_item) + sattr3_tree = proto_item_add_subtree(sattr3_item, ETT_NFS_SATTR3); + } + + offset = dissect_set_mode3(pd, offset, fd, sattr3_tree, "mode"); + offset = dissect_set_uid3 (pd, offset, fd, sattr3_tree, "uid"); + offset = dissect_set_gid3 (pd, offset, fd, sattr3_tree, "gid"); + offset = dissect_set_size3(pd, offset, fd, sattr3_tree, "size"); + offset = dissect_set_atime(pd, offset, fd, sattr3_tree, "atime"); + offset = dissect_set_mtime(pd, offset, fd, sattr3_tree, "mtime"); + + /* now we know, that sattr3 is shorter */ + if (sattr3_item) { + proto_item_set_len(sattr3_item, offset - old_offset); + } + + return offset; +} + + /* generic NFS3 call dissector */ int dissect_nfs3_any_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree) @@ -786,12 +1321,89 @@ } +/* RFC 1813, Page 33 */ +int +dissect_sattrguard3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, char *name) +{ + proto_item* sattrguard3_item = NULL; + proto_tree* sattrguard3_tree = NULL; + int old_offset = offset; + guint32 check; + char* check_name; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + check = EXTRACT_UINT(pd, offset+0); + check_name = val_to_str(check,value_follows,"Unknown"); + + if (tree) { + sattrguard3_item = proto_tree_add_text(tree, offset, + END_OF_FRAME, "%s: %s", name, check_name); + if (sattrguard3_item) + sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, ETT_NFS_SATTRGUARD3); + } + + if (sattrguard3_tree) + proto_tree_add_text(sattrguard3_tree, offset, 4, + "check: %s (%u)", check_name, check); + + offset += 4; + + switch (check) { + case TRUE: + offset = dissect_nfstime3(pd, offset, fd, sattrguard3_tree, + "obj_ctime"); + break; + case FALSE: + /* void */ + break; + } + + /* now we know, that sattrguard3 is shorter */ + if (sattrguard3_item) { + proto_item_set_len(sattrguard3_item, offset - old_offset); + } + + return offset; +} + + +/* RFC 1813, Page 33 */ +int +dissect_nfs3_setattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree) +{ + offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object"); + offset = dissect_sattr3 (pd, offset, fd, tree, "new_attributes"); + offset = dissect_sattrguard3(pd, offset, fd, tree, "guard"); + return offset; +} + + +/* RFC 1813, Page 33 */ +int +dissect_nfs3_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree) +{ + guint32 status; + + offset = dissect_nfsstat3(pd, offset, fd, tree, "status", &status); + switch (status) { + case 0: + offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc"); + break; + default: + offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc"); + break; + } + + return offset; +} + + /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: take the generic one. */ const vsff nfs3_proc[] = { { 0, "NULL", NULL, NULL }, { 1, "GETATTR", dissect_nfs3_getattr_call, dissect_nfs3_getattr_reply }, - { 2, "SETATTR", dissect_nfs3_any_call, dissect_nfs3_any_reply }, + { 2, "SETATTR", dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply }, { 3, "LOOKUP", dissect_nfs3_any_call, dissect_nfs3_any_reply }, { 4, "ACCESS", dissect_nfs3_any_call, dissect_nfs3_any_reply }, { 5, "READLINK", dissect_nfs3_any_call, dissect_nfs3_any_reply }, Index: packet-nfs.h =================================================================== RCS file: /cvsroot/ethereal/packet-nfs.h,v retrieving revision 1.1 diff -u -r1.1 packet-nfs.h --- packet-nfs.h 1999/10/29 01:11:23 1.1 +++ packet-nfs.h 1999/11/15 09:05:51 @@ -11,8 +11,8 @@ #define FHSIZE 32 /* the RPC mount protocol needs both function to decode a MNT reply */ -int dissect_fh2(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); -int dissect_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +int dissect_fhandle(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name); +int dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name); #endif /* packet-nfs.h */ Index: packet-portmap.c =================================================================== RCS file: /cvsroot/ethereal/packet-portmap.c,v retrieving revision 1.5 diff -u -r1.5 packet-portmap.c --- packet-portmap.c 1999/11/11 21:21:59 1.5 +++ packet-portmap.c 1999/11/15 09:05:52 @@ -186,6 +186,63 @@ /* end of Portmap version 2 */ +/* Portmapper version 3, RFC 1833, Page 7 */ +const vsff portmap3_proc[] = { + { RPCBPROC_NULL, "NULL", + NULL, NULL }, + { RPCBPROC_SET, "SET", + NULL, NULL }, + { RPCBPROC_UNSET, "UNSET", + NULL, NULL }, + { RPCBPROC_GETADDR, "GETADDR", + NULL, NULL}, + { RPCBPROC_DUMP, "DUMP", + NULL, NULL }, + { RPCBPROC_CALLIT, "CALLIT", + NULL, NULL }, + { RPCBPROC_GETTIME, "GETTIME", + NULL, NULL }, + { RPCBPROC_UADDR2TADDR, "UADDR2TADDR", + NULL, NULL }, + { RPCBPROC_TADDR2UADDR, "TADDR2UADDR", + NULL, NULL }, + { 0, NULL, NULL, NULL } +}; +/* end of Portmap version 3 */ + + +/* Portmapper version 4, RFC 1833, Page 8 */ +const vsff portmap4_proc[] = { + { RPCBPROC_NULL, "NULL", + NULL, NULL }, + { RPCBPROC_SET, "SET", + NULL, NULL }, + { RPCBPROC_UNSET, "UNSET", + NULL, NULL }, + { RPCBPROC_GETADDR, "GETADDR", + NULL, NULL}, + { RPCBPROC_DUMP, "DUMP", + NULL, NULL }, + { RPCBPROC_BCAST, "BCAST", + NULL, NULL }, + { RPCBPROC_GETTIME, "GETTIME", + NULL, NULL }, + { RPCBPROC_UADDR2TADDR, "UADDR2TADDR", + NULL, NULL }, + { RPCBPROC_TADDR2UADDR, "TADDR2UADDR", + NULL, NULL }, + { RPCBPROC_GETVERSADDR, "GETVERSADDR", + NULL, NULL }, + { RPCBPROC_INDIRECT, "INDIRECT", + NULL, NULL }, + { RPCBPROC_GETADDRLIST, "GETADDRLIST", + NULL, NULL }, + { RPCBPROC_GETSTAT, "GETSTAT", + NULL, NULL }, + { 0, NULL, NULL, NULL } +}; +/* end of Portmap version 4 */ + void proto_register_portmap(void) { @@ -218,5 +275,7 @@ /* Register the procedure tables */ rpc_init_proc_table(PORTMAP_PROGRAM, 1, portmap1_proc); rpc_init_proc_table(PORTMAP_PROGRAM, 2, portmap2_proc); + rpc_init_proc_table(PORTMAP_PROGRAM, 3, portmap3_proc); + rpc_init_proc_table(PORTMAP_PROGRAM, 4, portmap4_proc); } Index: packet-portmap.h =================================================================== RCS file: /cvsroot/ethereal/packet-portmap.h,v retrieving revision 1.2 diff -u -r1.2 packet-portmap.h --- packet-portmap.h 1999/11/10 21:05:10 1.2 +++ packet-portmap.h 1999/11/15 09:05:52 @@ -13,6 +13,24 @@ #define PORTMAPPROC_DUMP 4 #define PORTMAPPROC_CALLIT 5 +/* RFC 1833, Page 7 */ +#define RPCBPROC_NULL 0 +#define RPCBPROC_SET 1 +#define RPCBPROC_UNSET 2 +#define RPCBPROC_GETADDR 3 +#define RPCBPROC_DUMP 4 +#define RPCBPROC_CALLIT 5 +#define RPCBPROC_GETTIME 6 +#define RPCBPROC_UADDR2TADDR 7 +#define RPCBPROC_TADDR2UADDR 8 + +/* RFC 1833, Page 8 */ +#define RPCBPROC_BCAST RPCBPROC_CALLIT +#define RPCBPROC_GETVERSADDR 9 +#define RPCBPROC_INDIRECT 10 +#define RPCBPROC_GETADDRLIST 11 +#define RPCBPROC_GETSTAT 12 + struct pmap { guint32 pm_prog; guint32 pm_vers; Index: packet-rpc.c =================================================================== RCS file: /cvsroot/ethereal/packet-rpc.c,v retrieving revision 1.11 diff -u -r1.11 packet-rpc.c --- packet-rpc.c 1999/11/14 21:16:58 1.11 +++ packet-rpc.c 1999/11/15 09:05:56 @@ -221,22 +221,6 @@ /*--------------------------------------*/ -/* Placeholder for future dissectors. -It should vanish, if they are finally present. Up to this point, this -minimal variant serves as a detector for RPC services and can even find -request/reply pairs. */ - -#define NLM_PROGRAM 100021 - -static int proto_nlm = -1; - -void init_incomplete_dissect(void) -{ - proto_nlm = proto_register_protocol("Network Lock Manager", "NLM"); - rpc_init_prog(proto_nlm, NLM_PROGRAM, ETT_NLM); -} - - /* * Init the hash tables. It will be called from ethereal_proto_init(). * ethereal_proto_init() calls later proto_init(), which calls @@ -305,7 +289,7 @@ unsigned int -roundup(unsigned int a) +rpc_roundup(unsigned int a) { unsigned int mod = a % 4; return a + ((mod)? 4-mod : 0); @@ -323,7 +307,7 @@ if (tree) { proto_tree_add_text(tree, offset, 4, - "%s (%s): %u", name, type, value); + "%s: %u", name, value); } offset += 4; @@ -345,10 +329,10 @@ if (tree) { if (value_high) proto_tree_add_text(tree, offset, 8, - "%s (%s): %x%08x", name, type, value_high, value_low); + "%s: %x%08x", name, value_high, value_low); else proto_tree_add_text(tree, offset, 8, - "%s (%s): %u", name, type, value_low); + "%s: %u", name, value_low); } offset += 8; @@ -373,7 +357,7 @@ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; string_length = EXTRACT_UINT(pd,offset+0); - string_length_full = roundup(string_length); + string_length_full = rpc_roundup(string_length); string_fill = string_length_full - string_length; if (!BYTES_ARE_IN_FRAME(offset+4,string_length_full)) return offset; if (string_length>=sizeof(string_buffer)) return offset; @@ -414,7 +398,7 @@ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; string_length = EXTRACT_UINT(pd,offset+0); - string_length_full = roundup(string_length); + string_length_full = rpc_roundup(string_length); string_fill = string_length_full - string_length; if (!BYTES_ARE_IN_FRAME(offset+4,string_length_full)) return offset; if (string_length>=sizeof(string_buffer)) return offset; @@ -456,7 +440,7 @@ /* if (!BYTES_ARE_IN_FRAME(offset,8)) return; */ flavor = EXTRACT_UINT(pd,offset+0); length = EXTRACT_UINT(pd,offset+4); - length_full = roundup(length); + length_full = rpc_roundup(length); /* if (!BYTES_ARE_IN_FRAME(offset+8,full_length)) return; */ if (tree) { @@ -553,7 +537,7 @@ if (!BYTES_ARE_IN_FRAME(offset,8)) return offset; length = EXTRACT_UINT(pd,offset+4); - length_full = roundup(length); + length_full = rpc_roundup(length); if (!BYTES_ARE_IN_FRAME(offset+8,length_full)) return offset; if (tree) { @@ -578,7 +562,7 @@ if (!BYTES_ARE_IN_FRAME(offset,8)) return offset; length = EXTRACT_UINT(pd,offset+4); - length_full = roundup(length); + length_full = rpc_roundup(length); if (!BYTES_ARE_IN_FRAME(offset+8,length_full)) return offset; if (tree) { @@ -1047,7 +1031,4 @@ proto_register_rpc(void) { proto_rpc = proto_register_protocol("Remote Procedure Call", "rpc"); - - /* please remove this, if all specific dissectors are ready */ - init_incomplete_dissect(); } Index: packet-rpc.h =================================================================== RCS file: /cvsroot/ethereal/packet-rpc.h,v retrieving revision 1.4 diff -u -r1.4 packet-rpc.h --- packet-rpc.h 1999/11/11 21:22:00 1.4 +++ packet-rpc.h 1999/11/15 09:05:57 @@ -96,7 +96,7 @@ extern void init_dissect_rpc(); extern void cleanup_dissect_rpc(); -extern unsigned int roundup(unsigned int a); +extern unsigned int rpc_roundup(unsigned int a); extern int dissect_rpc_string(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name); extern int dissect_rpc_string_item(const u_char *pd, int offset, frame_data *fd, Index: packet-tcp.c =================================================================== RCS file: /cvsroot/ethereal/packet-tcp.c,v retrieving revision 1.42 diff -u -r1.42 packet-tcp.c --- packet-tcp.c 1999/11/11 23:13:43 1.42 +++ packet-tcp.c 1999/11/15 09:05:59 @@ -470,6 +470,13 @@ /* Check the packet length to see if there's more data (it could be an ACK-only packet) */ if (packet_max > offset) { + + /* ONC RPC. We can't base this on anything in the UDP header; we have + to look at the payload. If "dissect_rpc()" returns TRUE, it was + an RPC packet, otherwise it's some other type of packet. */ + if (dissect_rpc(pd, offset, fd, tree)) + goto reas; + /* XXX - this should be handled the way UDP handles this, with a table of port numbers to which stuff can be added */ #define PORT_IS(port) (th.th_sport == port || th.th_dport == port) @@ -529,6 +536,8 @@ } } } + +reas: if( data_out_file ) { reassemble_tcp( th.th_seq, /* sequence number */ Index: packet.h =================================================================== RCS file: /cvsroot/ethereal/packet.h,v retrieving revision 1.140 diff -u -r1.140 packet.h --- packet.h 1999/11/14 20:44:52 1.140 +++ packet.h 1999/11/15 09:06:03 @@ -455,11 +455,25 @@ ETT_NFS_TIMEVAL, ETT_NFS_MODE, ETT_NFS_FATTR, + ETT_NFS_SATTR, ETT_NFS_MODE3, ETT_NFS_SPECDATA3, ETT_NFS_FH3, ETT_NFS_NFSTIME3, ETT_NFS_FATTR3, + ETT_NFS_POST_OP_ATTR, + ETT_NFS_WCC_ATTR, + ETT_NFS_PRE_OP_ATTR, + ETT_NFS_WCC_DATA, + ETT_NFS_SET_MODE3, + ETT_NFS_SET_UID3, + ETT_NFS_SET_GID3, + ETT_NFS_SET_SIZE3, + ETT_NFS_SET_ATIME, + ETT_NFS_SET_MTIME, + ETT_NFS_SATTR3, + ETT_NFS_SATTRGUARD3, + ETT_BOOT, ETT_NLM, ETT_PORTMAP, ETT_STAT,
/* packet-nlm.c * Routines for nlm dissection * * $Id: $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxx> * Copyright 1998 Gerald Combs * * Copied from packet-mount.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif #include "packet-rpc.h" #include "packet-nlm.h" static int proto_nlm = -1; /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: take the generic one. */ /* NLM protocol version 3 */ const vsff nlm3_proc[] = { { 0, "NULL", NULL, NULL }, { 1, "TEST", NULL, NULL }, { 2, "LOCK", NULL, NULL }, { 3, "CANCEL", NULL, NULL }, { 4, "UNLOCK", NULL, NULL }, { 5, "GRANTED", NULL, NULL }, { 6, "TEST_MSG", NULL, NULL }, { 7, "LOCK_MSG", NULL, NULL }, { 8, "CANCEL_MSG", NULL, NULL }, { 9, "UNLOCK_MSG", NULL, NULL }, { 10, "GRANTED_MSG", NULL, NULL }, { 11, "TEST_RES", NULL, NULL }, { 12, "LOCK_RES", NULL, NULL }, { 13, "CANCEL_RES", NULL, NULL }, { 14, "UNLOCK_RES", NULL, NULL }, { 15, "GRANTED_RES", NULL, NULL }, { 20, "SHARE", NULL, NULL }, { 21, "UNSHARE", NULL, NULL }, { 22, "NM_LOCK", NULL, NULL }, { 23, "FREE_ALL", NULL, NULL }, { 0, NULL, NULL, NULL } }; /* end of NLM protocol version 3 */ void proto_register_nlm(void) { proto_nlm = proto_register_protocol("Network Lock Manager Protocol", "NLM"); /* Register the protocol as RPC */ rpc_init_prog(proto_nlm, NLM_PROGRAM, ETT_NLM); /* Register the procedure table */ rpc_init_proc_table(NLM_PROGRAM, 3, nlm3_proc); }
/* packet-nlm.h (c) 1999 Uwe Girlich */ /* $Id: $ */ #ifndef __PACKET_NLM_H__ #define __PACKET_NLM_H__ #define NLM_PROGRAM 100021 #endif /* packet-nlm.h */
- Prev by Date: [ethereal-dev] Antwort: Re: [ethereal-users] Reading AIX-iptrace on at0
- Next by Date: Re: [ethereal-dev] plugins support
- Previous by thread: Re: [ethereal-dev] Antwort: Re: [ethereal-users] Reading AIX-iptrace on at0
- Next by thread: RE: [ethereal-dev] NFS dissector continuation
- Index(es):