Ethereal-dev: [ethereal-dev] some new RPC changes
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: Fri, 19 Nov 1999 11:34:39 +0100
Here comes again an update in the RPC field: * packet-mount.c New function: program MOUNT version 3 reply MNT * packet-nfs.c dissect_nfs_fh3(), fh_len (and others) renamed because of AIX problems. * packet-portmap.c Some unsigned %d -> %u changed. New function: program PORTMAP version 3,4 call getaddr New function: program PORTMAP version 3,4 reply getaddr New function: program PORTMAP version 3,4 reply dump * packet-rpc.c dissect_rpc() can handle record marking (used in RPC over TCP). dissect_rpc_string() can cope with truncated packets (anywhere in the string) much better. * packet-rpc.h prototype for flavor names (mount needs it). * packet-tcp.c Typo in comment on dissect_rpc() corrected. I provide a gzipped tcpdump file with many new protocols in it (mount v3, portmapper v3, nfs v2, nfs v3, RPC over TCP etc. etc.)
Index: packet-mount.c =================================================================== RCS file: /cvsroot/ethereal/packet-mount.c,v retrieving revision 1.4 diff -u -r1.4 packet-mount.c --- packet-mount.c 1999/11/16 11:42:38 1.4 +++ packet-mount.c 1999/11/19 10:27:54 @@ -36,10 +36,14 @@ #include "packet-rpc.h" #include "packet-mount.h" +#include "packet-nfs.h" static int proto_mount = -1; static int hf_mount_path = -1; +static int hf_mount_status = -1; +static int hf_mount_flavors = -1; +static int hf_mount_flavor = -1; static gint ett_mount = -1; @@ -75,11 +79,82 @@ /* end of mount version 1 */ +/* RFC 1813, Page 107 */ +const value_string mount3_mountstat3[] = +{ + { 0, "OK" }, + { 1, "ERR_PERM" }, + { 2, "ERR_NOENT" }, + { 5, "ERR_IO" }, + { 13, "ERR_ACCESS" }, + { 20, "ERR_NOTDIR" }, + { 22, "ERR_INVAL" }, + { 63, "ERR_NAMETOOLONG" }, + { 10004, "ERR_NOTSUPP" }, + { 10006, "ERR_SERVERFAULT" }, + { 0, NULL } +}; + + +/* RFC 1813, Page 107 */ +int +dissect_mountstat3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, + int hfindex, guint32* status) +{ + guint32 mountstat3; + + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + mountstat3 = EXTRACT_UINT(pd, offset+0); + + if (tree) { + proto_tree_add_item(tree, hfindex, offset, 4, mountstat3); + } + + offset += 4; + *status = mountstat3; + return offset; +} + + +/* RFC 1831, Page 109 */ +int dissect_mount3_mnt_reply(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree) +{ + guint32 status; + guint32 auth_flavors; + guint32 auth_flavor; + guint32 auth_flavor_i; + + offset = dissect_mountstat3(pd, offset, fd, tree, hf_mount_status, &status); + switch (status) { + case 0: + offset = dissect_nfs_fh3(pd,offset,fd,tree,"fhandle"); + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + auth_flavors = EXTRACT_UINT(pd,offset+0); + proto_tree_add_item(tree,hf_mount_flavors, + offset, 4, auth_flavors); + offset += 4; + for (auth_flavor_i = 0 ; auth_flavor_i < hf_mount_flavors ; auth_flavor_i++) { + if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; + auth_flavor = EXTRACT_UINT(pd,offset+0); + proto_tree_add_item(tree,hf_mount_flavor, + offset, 4, auth_flavor); + offset += 4; + } + break; + default: + /* void */ + break; + } + + return offset; +} + /* Mount protocol version 3, RFC 1813 */ const vsff mount3_proc[] = { { 0, "NULL", NULL, NULL }, { MOUNTPROC_MNT, "MNT", - dissect_mount_dirpath_call, NULL }, + dissect_mount_dirpath_call, dissect_mount3_mnt_reply }, { MOUNTPROC_DUMP, "DUMP", NULL, NULL }, { MOUNTPROC_UMNT, "UMNT", @@ -100,6 +175,15 @@ { &hf_mount_path, { "Path", "mount.path", FT_STRING, BASE_DEC, NULL, 0, "Path" }}, + { &hf_mount_status, { + "Status", "mount.status", FT_UINT32, BASE_DEC, + mount3_mountstat3, 0, "Status" }}, + { &hf_mount_flavors, { + "Flavors", "mount.flavors", FT_UINT32, BASE_DEC, + NULL, 0, "Flavors" }}, + { &hf_mount_flavor, { + "Flavor", "mount.flavor", FT_UINT32, BASE_DEC, + rpc_auth_flavor, 0, "Flavor" }}, }; static gint *ett[] = { &ett_mount, Index: packet-nfs.c =================================================================== RCS file: /cvsroot/ethereal/packet-nfs.c,v retrieving revision 1.5 diff -u -r1.5 packet-nfs.c --- packet-nfs.c 1999/11/16 11:42:41 1.5 +++ packet-nfs.c 1999/11/19 10:28:02 @@ -442,7 +442,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_setattr_reply }, + { 2, "SETATTR", dissect_nfs2_setattr_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 }, @@ -723,18 +723,18 @@ int dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name) { - guint fh_len; - guint fh_len_full; - guint fh_fill; + guint fh3_len; + guint fh3_len_full; + guint fh3_fill; proto_item* fitem; proto_tree* ftree = NULL; - fh_len = EXTRACT_UINT(pd, offset+0); - fh_len_full = rpc_roundup(fh_len); - fh_fill = fh_len_full - fh_len; + fh3_len = EXTRACT_UINT(pd, offset+0); + fh3_len_full = rpc_roundup(fh3_len); + fh3_fill = fh3_len_full - fh3_len; if (tree) { - fitem = proto_tree_add_text(tree, offset, 4+fh_len_full, + fitem = proto_tree_add_text(tree, offset, 4+fh3_len_full, "%s", name); if (fitem) ftree = proto_item_add_subtree(fitem, ett_nfs_fh3); @@ -742,14 +742,14 @@ if (ftree) { proto_tree_add_text(ftree,offset+0,4, - "length: %u", fh_len); - proto_tree_add_text(ftree,offset+4,fh_len, + "length: %u", fh3_len); + proto_tree_add_text(ftree,offset+4,fh3_len, "file handle (opaque data)"); - if (fh_fill) - proto_tree_add_text(ftree,offset+4+fh_len,fh_fill, + if (fh3_fill) + proto_tree_add_text(ftree,offset+4+fh3_len,fh3_fill, "fill bytes"); } - offset += 4 + fh_len_full; + offset += 4 + fh3_len_full; return offset; } @@ -802,7 +802,7 @@ } offset = dissect_ftype3 (pd,offset,fd,fattr3_tree,"type"); - offset = dissect_mode3 (pd,offset,fd,fattr3_tree,"mode"); + offset = dissect_mode3 (pd,offset,fdtr3_tree,"mode"); offset = dissect_uint32 (pd,offset,fd,fattr3_tree,"nlink"); offset = dissect_uid3 (pd,offset,fd,fattr3_tree,"uid"); offset = dissect_gid3 (pd,offset,fd,fattr3_tree,"gid"); Index: packet-portmap.c =================================================================== RCS file: /cvsroot/ethereal/packet-portmap.c,v retrieving revision 1.7 diff -u -r1.7 packet-portmap.c --- packet-portmap.c 1999/11/16 11:42:47 1.7 +++ packet-portmap.c 1999/11/19 10:28:04 @@ -37,6 +37,7 @@ #include "packet-rpc.h" #include "packet-portmap.h" + static int proto_portmap = -1; static int hf_portmap_proto = -1; static int hf_portmap_prog = -1; @@ -44,9 +45,23 @@ static int hf_portmap_version = -1; static int hf_portmap_port = -1; static int hf_portmap_answer = -1; +static int hf_portmap_rpcb = -1; +static int hf_portmap_rpcb_prog = -1; +static int hf_portmap_rpcb_version = -1; +static int hf_portmap_rpcb_netid = -1; +static int hf_portmap_rpcb_addr = -1; +static int hf_portmap_rpcb_owner = -1; +static int hf_portmap_uaddr = -1; +static int hf_portmap_value_follows = -1; + static gint ett_portmap = -1; +static gint ett_portmap_rpcb = -1; + +static struct true_false_string yesno = { "Yes", "No" }; + + /* Dissect a getport call */ int dissect_getport_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) @@ -59,14 +74,14 @@ { prog = pntohl(&pd[offset+0]); proto_tree_add_item_format(tree, hf_portmap_prog, - offset, 4, prog, "Program: %s (%d)", + offset, 4, prog, "Program: %s (%u)", rpc_prog_name(prog), prog); proto_tree_add_item(tree, hf_portmap_version, offset+4, 4, pntohl(&pd[offset+4])); proto = pntohl(&pd[offset+8]); proto_tree_add_item_format(tree, hf_portmap_proto, - offset+8, 4, proto, "Proto: %s (%d)", ipprotostr(proto), proto); + offset+8, 4, proto, "Proto: %s (%u)", ipprotostr(proto), proto); proto_tree_add_item(tree, hf_portmap_port, offset+12, 4, pntohl(&pd[offset+12])); @@ -188,6 +203,95 @@ /* end of Portmap version 2 */ +/* RFC 1833, Page 3 */ +int dissect_rpcb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hfindex) +{ + proto_item* rpcb_item = NULL; + proto_tree* rpcb_tree = NULL; + int old_offset = offset; + guint32 prog; + guint32 version; + + if (tree) { + rpcb_item = proto_tree_add_item(tree, hfindex, + offset+0, END_OF_FRAME, NULL); + if (rpcb_item) + rpcb_tree = proto_item_add_subtree(rpcb_item, ett_portmap_rpcb); + } + + if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset; + prog = EXTRACT_UINT(pd, offset + 0); + if (rpcb_tree) + proto_tree_add_item_format(rpcb_tree, hf_portmap_rpcb_prog, + offset+0, 4, prog, + "Program: %s (%u)", rpc_prog_name(prog), prog); + offset += 4; + + if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset; + version = EXTRACT_UINT(pd, offset + 0); + if (rpcb_tree) + proto_tree_add_item(rpcb_tree, hf_portmap_rpcb_version, + offset+0, 4, version); + offset += 4; + + offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_netid); + offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_addr); + offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_owner); + + /* now we know, that rpcb is shorter */ + if (rpcb_item) { + proto_item_set_len(rpcb_item, offset - old_offset); + } + + return offset; +} + + + +/* RFC 1833, Page 7 */ +int dissect_rpcb3_getaddr_call(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree) +{ + offset = dissect_rpcb(pd, offset, fd, tree, hf_portmap_rpcb); + + return offset; +} + + +/* RFC 1833, Page 7 */ +int dissect_rpcb3_getaddr_reply(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree) +{ + offset = dissect_rpc_string(pd, offset, fd, tree, hf_portmap_uaddr); + + return offset; +} + + +/* RFC 1833, Page 7 */ +int dissect_rpcb3_dump_reply(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree) +{ + guint32 value_follows; + + while (1) { + if (!BYTES_ARE_IN_FRAME(offset,4)) break; + value_follows = EXTRACT_UINT(pd, offset+0); + proto_tree_add_item(tree,hf_portmap_value_follows, + offset+0, 4, value_follows); + offset += 4; + if (value_follows == 1) { + offset = dissect_rpcb(pd, offset, fd, tree, hf_portmap_rpcb); + } + else { + break; + } + } + + return offset; +} + + /* Portmapper version 3, RFC 1833, Page 7 */ const vsff portmap3_proc[] = { { RPCBPROC_NULL, "NULL", @@ -197,9 +301,9 @@ { RPCBPROC_UNSET, "UNSET", NULL, NULL }, { RPCBPROC_GETADDR, "GETADDR", - NULL, NULL}, + dissect_rpcb3_getaddr_call, dissect_rpcb3_getaddr_reply}, { RPCBPROC_DUMP, "DUMP", - NULL, NULL }, + NULL, dissect_rpcb3_dump_reply }, { RPCBPROC_CALLIT, "CALLIT", NULL, NULL }, { RPCBPROC_GETTIME, "GETTIME", @@ -222,9 +326,9 @@ { RPCBPROC_UNSET, "UNSET", NULL, NULL }, { RPCBPROC_GETADDR, "GETADDR", - NULL, NULL}, + dissect_rpcb3_getaddr_call, dissect_rpcb3_getaddr_reply}, { RPCBPROC_DUMP, "DUMP", - NULL, NULL }, + NULL, dissect_rpcb3_dump_reply }, { RPCBPROC_BCAST, "BCAST", NULL, NULL }, { RPCBPROC_GETTIME, "GETTIME", @@ -267,9 +371,34 @@ { &hf_portmap_answer, { "Answer", "portmap.answer", FT_BOOLEAN, BASE_DEC, NULL, 0, "Answer" }}, + { &hf_portmap_rpcb, { + "RPCB", "portmap.rpcb", FT_NONE, 0, + NULL, 0, "RPCB" }}, + { &hf_portmap_rpcb_prog, { + "Program", "portmap.rpcb.prog", FT_UINT32, BASE_DEC, + NULL, 0, "Program" }}, + { &hf_portmap_rpcb_version, { + "Version", "portmap.rpcb.version", FT_UINT32, BASE_DEC, + NULL, 0, "Version" }}, + { &hf_portmap_rpcb_netid, { + "Network Id", "portmap.rpcb.netid", FT_STRING, BASE_DEC, + NULL, 0, "Network Id" }}, + { &hf_portmap_rpcb_addr, { + "Universal Address", "portmap.rpcb.addr", FT_STRING, BASE_DEC, + NULL, 0, "Universal Address" }}, + { &hf_portmap_rpcb_owner, { + "Owner of this Service", "portmap.rpcb.owner", FT_STRING, BASE_DEC, + NULL, 0, "Owner of this Service" }}, + { &hf_portmap_uaddr, { + "Universal Address", "portmap.uaddr", FT_STRING, BASE_DEC, + NULL, 0, "Universal Address" }}, + { &hf_portmap_value_follows, { + "Value Follows", "portmap.value_follows", FT_BOOLEAN, BASE_NONE, + &yesno, 0, "Value Follows" }}, }; static gint *ett[] = { &ett_portmap, + &ett_portmap_rpcb }; proto_portmap = proto_register_protocol("Portmap", "portmap"); Index: packet-rpc.c =================================================================== RCS file: /cvsroot/ethereal/packet-rpc.c,v retrieving revision 1.17 diff -u -r1.17 packet-rpc.c --- packet-rpc.c 1999/11/17 21:58:32 1.17 +++ packet-rpc.c 1999/11/19 10:28:09 @@ -42,6 +42,11 @@ #include "packet-rpc.h" +#define RPC_RM_FRAGLEN 0x7fffffffL + +static struct true_false_string yesno = { "Yes", "No" }; + + static const value_string rpc_msg_type[3] = { { RPC_CALL, "Call" }, { RPC_REPLY, "Reply" }, @@ -54,7 +59,7 @@ { 0, NULL } }; -static const value_string rpc_auth_flavor[5] = { +value_string rpc_auth_flavor[] = { { AUTH_NULL, "AUTH_NULL" }, { AUTH_UNIX, "AUTH_UNIX" }, { AUTH_SHORT, "AUTH_SHORT" }, @@ -89,6 +94,8 @@ /* the protocol number */ static int proto_rpc = -1; +static int hf_rpc_lastfrag = -1; +static int hf_rpc_fraglen = -1; static int hf_rpc_xid = -1; static int hf_rpc_msgtype = -1; static int hf_rpc_version = -1; @@ -378,33 +385,66 @@ } - -/* arbitrary limit */ -#define RPC_STRING_MAXBUF 2048 - int dissect_rpc_string(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hfindex) { - proto_item *string_item; + proto_item *string_item = NULL; proto_tree *string_tree = NULL; + int old_offset = offset; - guint32 string_length; - guint32 string_fill; + int truncated_length = 0; + guint32 string_length = 0; + guint32 string_length_packet; + guint32 string_length_copy = 0; guint32 string_length_full; - char string_buffer[RPC_STRING_MAXBUF]; + guint32 string_fill = 0; + char *string_buffer = NULL; + char *string_buffer_print = NULL; + + if (BYTES_ARE_IN_FRAME(offset,4)) { + string_length = EXTRACT_UINT(pd,offset+0); + string_length_full = rpc_roundup(string_length); + string_length_packet = pi.captured_len - (offset + 4); + if (string_length > string_length_packet) { + string_length_copy = string_length_packet; + string_fill = 0; + } + else { + string_length_copy = string_length; + string_fill = string_length_full - string_length; + } + string_buffer = (char*)g_malloc(string_length_copy + 1); + memcpy(string_buffer,pd+offset+4,string_length_copy); + string_buffer[string_length_copy] = '\0'; + + /* I use here strdup functions. This works only, if the + string does not contain 0 bytes. */ + + /* calculate a nice printable string */ + if (string_length) { + if (string_length != string_length_copy) { + string_buffer_print = (char*)g_malloc(string_length_copy + 1 + 12); + memcpy(string_buffer_print,string_buffer,string_length_copy); + memcpy(string_buffer_print+string_length_copy, + "<TRUNCATED>", 12); + } + else { + string_buffer_print = g_strdup(string_buffer); + } + } + else { + string_buffer_print = g_strdup("<EMPTY>"); + } + } + else { + truncated_length = 1; + string_buffer = g_strdup(""); + string_buffer_print = g_strdup("<TRUNCATED>"); + } - if (!BYTES_ARE_IN_FRAME(offset,4)) return offset; - string_length = EXTRACT_UINT(pd,offset+0); - 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; - memcpy(string_buffer,pd+offset+4,string_length); - string_buffer[string_length] = '\0'; if (tree) { - string_item = proto_tree_add_text(tree,offset+0, - 4+string_length_full, - "%s: %s", proto_registrar_get_name(hfindex), string_buffer); + string_item = proto_tree_add_text(tree,offset+0, END_OF_FRAME, + "%s: %s", proto_registrar_get_name(hfindex), string_buffer_print); proto_tree_add_item_hidden(tree, hfindex, offset+4, string_length, string_buffer); if (string_item) { @@ -412,16 +452,33 @@ } } if (string_tree) { - proto_tree_add_text(string_tree,offset+0,4, - "length: %u", string_length); - proto_tree_add_text(string_tree,offset+4,string_length, - "text: %s", string_buffer); - if (string_fill) - proto_tree_add_text(string_tree,offset+4+string_length,string_fill, + if (truncated_length) { + proto_tree_add_text(string_tree, + offset,pi.captured_len-offset, + "length: <TRUNCATED>"); + offset = pi.captured_len; + } + else { + proto_tree_add_text(string_tree,offset+0,4, + "length: %u", string_length); + offset += 4; + } + proto_tree_add_text(string_tree,offset,string_length_copy, + "text: %s", string_buffer_print); + offset += string_length_copy; + if (string_fill) { + proto_tree_add_text(string_tree,offset,string_fill, "fill bytes: opaque data"); + offset += string_fill; + } } - offset += 4 + string_length_full; + if (string_item) { + proto_item_set_len(string_item, offset - old_offset); + } + + if (string_buffer != NULL) g_free (string_buffer ); + if (string_buffer_print != NULL) g_free (string_buffer_print); return offset; } @@ -613,6 +670,9 @@ proto_tree *ptree = NULL; int offset_old = offset; + int use_rm = 0; + guint32 rpc_rm = 0; + rpc_call_info rpc_call_msg; rpc_proc_info_key key; rpc_proc_info_value *value = NULL; @@ -621,6 +681,17 @@ dissect_function_t *dissect_function = NULL; + /* TCP uses record marking */ + use_rm = (pi.ptype == PT_TCP); + + /* the first 4 bytes are special in "record marking mode" */ + if (use_rm) { + if (!BYTES_ARE_IN_FRAME(offset,4)) + return FALSE; + rpc_rm = EXTRACT_UINT(pd,offset); + offset += 4; + } + /* * Check to see whether this looks like an RPC call or reply. */ @@ -700,6 +771,13 @@ } } + if (use_rm && rpc_tree) { + proto_tree_add_item(rpc_tree,hf_rpc_lastfrag, + offset-4, 4, (rpc_rm >> 31) & 0x1); + proto_tree_add_item(rpc_tree,hf_rpc_fraglen, + offset-4, 4, rpc_rm & RPC_RM_FRAGLEN); + } + xid = EXTRACT_UINT(pd,offset+0); if (rpc_tree) { proto_tree_add_item_format(rpc_tree,hf_rpc_xid, @@ -1015,6 +1093,7 @@ return TRUE; } + /* Discard any state we've saved. */ static void rpc_init_protocol(void) @@ -1030,6 +1109,12 @@ proto_register_rpc(void) { static hf_register_info hf[] = { + { &hf_rpc_lastfrag, { + "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, BASE_NONE, + &yesno, 0, "Last Fragment" }}, + { &hf_rpc_fraglen, { + "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC, + NULL, 0, "Fragment Length" }}, { &hf_rpc_xid, { "XID", "rpc.xid", FT_UINT32, BASE_HEX, NULL, 0, "XID" }}, Index: packet-rpc.h =================================================================== RCS file: /cvsroot/ethereal/packet-rpc.h,v retrieving revision 1.7 diff -u -r1.7 packet-rpc.h --- packet-rpc.h 1999/11/16 11:42:52 1.7 +++ packet-rpc.h 1999/11/19 10:28:09 @@ -84,6 +84,8 @@ #define RPC_CALL_TABLE_LENGTH 1000 +extern value_string rpc_auth_flavor[]; + extern void rpc_call_insert(rpc_call_info *call); extern rpc_call_info* rpc_call_lookup(rpc_call_info *call); Index: packet-tcp.c =================================================================== RCS file: /cvsroot/ethereal/packet-tcp.c,v retrieving revision 1.44 diff -u -r1.44 packet-tcp.c --- packet-tcp.c 1999/11/16 11:42:59 1.44 +++ packet-tcp.c 1999/11/19 10:28:12 @@ -476,7 +476,7 @@ (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 + /* ONC RPC. We can't base this on anything in the TCP 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))
Attachment:
rpc.dump.gz
Description: Binary data
- Follow-Ups:
- Re: [ethereal-dev] some new RPC changes
- From: Gilbert Ramirez
- Re: [ethereal-dev] some new RPC changes
- Prev by Date: Re: [ethereal-dev] Antwort: Re: [ethereal-users] Reading AIX-iptrace on at0
- Next by Date: [ethereal-dev] Adding a "How you can help" button to Ethereal
- Previous by thread: [ethereal-dev] Any doco on NTcreateX?
- Next by thread: Re: [ethereal-dev] some new RPC changes
- Index(es):