aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ncp.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet-ncp.c')
-rw-r--r--packet-ncp.c142
1 files changed, 84 insertions, 58 deletions
diff --git a/packet-ncp.c b/packet-ncp.c
index d0c85c7f35..ef215e127f 100644
--- a/packet-ncp.c
+++ b/packet-ncp.c
@@ -3,7 +3,7 @@
* Gilbert Ramirez <gram@xiexie.org>
* Modified to allow NCP over TCP/IP decodes by James Coe <jammer@cin.net>
*
- * $Id: packet-ncp.c,v 1.33 2000/04/17 04:00:36 guy Exp $
+ * $Id: packet-ncp.c,v 1.34 2000/04/18 04:46:06 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -41,6 +41,7 @@
#include <glib.h>
#include "packet.h"
+#include "conversation.h"
#include "packet-ipx.h"
#include "packet-ncp.h"
@@ -56,15 +57,20 @@ static gint ett_ncp = -1;
static gint ett_ncp_request_fields = -1;
static gint ett_ncp_reply_fields = -1;
-#define TCP_PORT_NCP 524
+#define TCP_PORT_NCP 524
+#define UDP_PORT_NCP 524
struct svc_record;
static void
-dissect_ncp_request(const u_char *pd, int offset, frame_data *fd, proto_tree *ncp_tree, proto_tree *tree);
+dissect_ncp_request(const u_char *pd, int offset, frame_data *fd,
+ guint16 nw_connection, guint8 nw_sequence, guint16 nw_ncp_type,
+ proto_tree *ncp_tree, proto_tree *tree);
static void
-dissect_ncp_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *ncp_tree, proto_tree *tree);
+dissect_ncp_reply(const u_char *pd, int offset, frame_data *fd,
+ guint16 nw_connection, guint8 nw_sequence,
+ proto_tree *ncp_tree, proto_tree *tree);
static struct ncp2222_record *
ncp2222_find(guint8 func, guint8 subfunc);
@@ -425,42 +431,32 @@ static ncp2222_record ncp2222[] = {
* (NFS also requires it), so for now the NCP section will keep its own hash
* table keeping track of NCP packet types.
*
- * The key representing the unique NCP request is composed of 3 variables:
- *
- * ServerIPXNetwork.Connection.SequenceNumber
- * 4 bytes 2 bytes 1 byte
- * guint32 guint16 guint8 (all are host order)
- *
- * This assumes that all NCP connection is between a client and server.
- * Servers can be identified by having a 00:00:00:00:00:01 IPX Node address.
- * We have to let the IPX layer pass us the ServerIPXNetwork via a global
- * variable (nw_server_address). In the future, if we decode NCP over TCP/UDP,
- * then nw_server_address will represent the IP address of the server, which
- * conveniently, is also 4 bytes long.
+ * We construct a conversation specified by the client and server
+ * addresses and the connection number; the key representing the unique
+ * NCP request then is composed of the pointer to the conversation
+ * structure, cast to a "guint" (which may throw away the upper 32
+ * bits of the pointer on a P64 platform, but the low-order 32 bits
+ * are more likely to differ between conversations than the upper 32 bits),
+ * and the sequence number.
*
* The value stored in the hash table is the ncp_request_val pointer. This
* struct tells us the NCP type and gives the ncp2222_record pointer, if
* ncp_type == 0x2222.
*/
-guint32 nw_server_address = 0; /* set by IPX layer */
-guint16 nw_connection = 0; /* set by dissect_ncp */
-guint8 nw_sequence = 0; /* set by dissect_ncp */
-guint16 nw_ncp_type = 0; /* set by dissect_ncp */
struct ncp_request_key {
- guint32 nw_server_address;
- guint16 nw_connection;
- guint8 nw_sequence;
+ conversation_t *conversation;
+ guint8 nw_sequence;
};
struct ncp_request_val {
- guint32 ncp_type;
+ guint32 ncp_type;
struct ncp2222_record* ncp_record;
};
-GHashTable *ncp_request_hash = NULL;
-GMemChunk *ncp_request_keys = NULL;
-GMemChunk *ncp_request_records = NULL;
+static GHashTable *ncp_request_hash = NULL;
+static GMemChunk *ncp_request_keys = NULL;
+static GMemChunk *ncp_request_records = NULL;
/* Hash Functions */
gint ncp_equal (gconstpointer v, gconstpointer v2)
@@ -469,14 +465,13 @@ gint ncp_equal (gconstpointer v, gconstpointer v2)
struct ncp_request_key *val2 = (struct ncp_request_key*)v2;
#if defined(DEBUG_NCP_HASH)
- printf("Comparing %08X:%d:%d and %08X:%d:%d\n",
- val1->nw_server_address, val1->nw_connection, val1->nw_sequence,
- val2->nw_server_address, val2->nw_connection, val2->nw_sequence);
+ printf("Comparing %p:%d and %p:%d\n",
+ val1->conversation, val1->nw_sequence,
+ val2->conversation, val2->nw_sequence);
#endif
- if (val1->nw_server_address == val2->nw_server_address &&
- val1->nw_connection == val2->nw_connection &&
- val1->nw_sequence == val2->nw_sequence ) {
+ if (val1->conversation == val2->conversation &&
+ val1->nw_sequence == val2->nw_sequence ) {
return 1;
}
return 0;
@@ -486,13 +481,10 @@ guint ncp_hash (gconstpointer v)
{
struct ncp_request_key *ncp_key = (struct ncp_request_key*)v;
#if defined(DEBUG_NCP_HASH)
- printf("hash calculated as %d\n", ncp_key->nw_server_address +
- ((guint32) ncp_key->nw_connection << 16) +
- ncp_key->nw_sequence);
+ printf("hash calculated as %u\n",
+ GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence);
#endif
- return ncp_key->nw_server_address +
- ((guint32) ncp_key->nw_connection << 16) +
- ncp_key->nw_sequence;
+ return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence;
}
/* Initializes the hash table and the mem_chunk area each time a new
@@ -548,6 +540,9 @@ dissect_ncp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
struct ncp_ip_header ncpiph;
struct ncp_ip_rqhdr ncpiphrq;
struct ncp_common_header header;
+ guint16 nw_connection;
+ guint8 nw_sequence;
+ guint16 nw_ncp_type;
if ( pi.ptype == PT_TCP || pi.ptype == PT_UDP ) {
ncpiph.signature = pntohl(&pd[offset]);
@@ -612,20 +607,24 @@ dissect_ncp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
/* Note how I use ncp_tree *and* tree in my args for ncp request/reply */
if (ncp_hdr_length == 7)
- dissect_ncp_request(pd, offset, fd, ncp_tree, tree);
+ dissect_ncp_request(pd, offset, fd, nw_connection,
+ nw_sequence, nw_ncp_type, ncp_tree, tree);
else if (ncp_hdr_length == 8)
- dissect_ncp_reply(pd, offset, fd, ncp_tree, tree);
+ dissect_ncp_reply(pd, offset, fd, nw_connection,
+ nw_sequence, ncp_tree, tree);
else
dissect_data(pd, offset, fd, tree);
}
-void
+static void
dissect_ncp_request(const u_char *pd, int offset, frame_data *fd,
+ guint16 nw_connection, guint8 nw_sequence, guint16 nw_ncp_type,
proto_tree *ncp_tree, proto_tree *tree) {
struct ncp_request_header request;
struct ncp2222_record *ncp_request;
gchar *description = "";
+ conversation_t *conversation;
struct ncp_request_val *request_val;
struct ncp_request_key *request_key;
proto_tree *field_tree = NULL;
@@ -656,11 +655,25 @@ dissect_ncp_request(const u_char *pd, int offset, frame_data *fd,
if (!fd->flags.visited) {
/* This is the first time we've looked at this packet.
- Remember the request, so we can find it if we later
+ Keep track of the address and connection whence the request
+ came, and the address and connection to which the request
+ is being sent, so that we can match up calls with replies.
+ (We don't include the sequence number, as we may want
+ to have all packets over the same connection treated
+ as being part of a single conversation so that we can
+ let the user select that conversation to be displayed.) */
+ conversation = find_conversation(&pi.src, &pi.dst,
+ PT_NCP, nw_connection, nw_connection);
+ if (conversation == NULL) {
+ /* It's not part of any conversation - create a new one. */
+ conversation = conversation_new(&pi.src, &pi.dst,
+ PT_NCP, nw_connection, nw_connection, NULL);
+ }
+
+ /* Now remember the request, so we can find it if we later
a reply to it. */
request_key = g_mem_chunk_alloc(ncp_request_keys);
- request_key->nw_server_address = nw_server_address;
- request_key->nw_connection = nw_connection;
+ request_key->conversation = conversation;
request_key->nw_sequence = nw_sequence;
request_val = g_mem_chunk_alloc(ncp_request_records);
@@ -669,8 +682,8 @@ dissect_ncp_request(const u_char *pd, int offset, frame_data *fd,
g_hash_table_insert(ncp_request_hash, request_key, request_val);
#if defined(DEBUG_NCP_HASH)
- printf("Inserted server %08X connection %d sequence %d (val=%08X)\n",
- nw_server_address, nw_connection, nw_sequence, request_val);
+ printf("Inserted conversation %p sequence %d (val=%p)\n",
+ conversation, nw_sequence, request_val);
#endif
}
@@ -703,11 +716,13 @@ dissect_ncp_request(const u_char *pd, int offset, frame_data *fd,
}
}
-void
+static void
dissect_ncp_reply(const u_char *pd, int offset, frame_data *fd,
+ guint16 nw_connection, guint8 nw_sequence,
proto_tree *ncp_tree, proto_tree *tree) {
struct ncp_reply_header reply;
+ conversation_t *conversation;
struct ncp2222_record *ncp_request = NULL;
struct ncp_request_val *request_val;
struct ncp_request_key request_key;
@@ -716,18 +731,28 @@ dissect_ncp_reply(const u_char *pd, int offset, frame_data *fd,
memcpy(&reply, &pd[offset], sizeof(reply));
- /* find the record telling us the request made that caused this reply */
- request_key.nw_server_address = nw_server_address;
- request_key.nw_connection = nw_connection;
- request_key.nw_sequence = nw_sequence;
+ /* Find the conversation whence the request would have come. */
- request_val = (struct ncp_request_val*)
- g_hash_table_lookup(ncp_request_hash, &request_key);
+ conversation = find_conversation(&pi.src, &pi.dst,
+ PT_NCP, nw_connection, nw_connection);
+ if (conversation != NULL) {
+ /* find the record telling us the request made that caused
+ this reply */
+ request_key.conversation = conversation;
+ request_key.nw_sequence = nw_sequence;
- #if defined(DEBUG_NCP_HASH)
- printf("Looking for server %08X connection %d sequence %d (retval=%08X)\n",
- nw_server_address, nw_connection, nw_sequence, request_val);
- #endif
+ #if defined(DEBUG_NCP_HASH)
+ printf("Looking for conversation %p sequence %u (retval=%p)\n",
+ conversation, nw_sequence, request_val);
+ #endif
+
+ request_val = (struct ncp_request_val*)
+ g_hash_table_lookup(ncp_request_hash, &request_key);
+ } else {
+ /* We haven't seen an RPC call for that conversation,
+ so we can't check for a reply to that call. */
+ request_val = NULL;
+ }
if (request_val)
ncp_request = request_val->ncp_record;
@@ -1044,4 +1069,5 @@ void
proto_reg_handoff_ncp(void)
{
dissector_add("tcp.port", TCP_PORT_NCP, dissect_ncp);
+ dissector_add("udp.port", UDP_PORT_NCP, dissect_ncp);
}