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):





