aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ipx.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet-ipx.c')
-rw-r--r--packet-ipx.c136
1 files changed, 74 insertions, 62 deletions
diff --git a/packet-ipx.c b/packet-ipx.c
index 657df6fd6f..2d295ae858 100644
--- a/packet-ipx.c
+++ b/packet-ipx.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 2000-2002 by Gilbert Ramirez.
* Portions Copyright (c) Novell, Inc. 2002-2003
*
- * $Id: packet-ipx.c,v 1.123 2003/04/08 00:39:27 guy Exp $
+ * $Id: packet-ipx.c,v 1.124 2003/04/08 02:00:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -354,14 +354,6 @@ typedef struct {
guint32 spx_src;
} spx_hash_key;
-typedef struct {
- guint16 spx_seq;
- guint16 spx_ack;
- guint16 spx_all;
- guint32 num;
- gboolean retransmission;
-} spx_hash_value;
-
static GHashTable *spx_hash = NULL;
static GMemChunk *spx_hash_keys = NULL;
static GMemChunk *spx_hash_values = NULL;
@@ -406,8 +398,8 @@ spx_init_protocol(void)
SPX_PACKET_INIT_COUNT * sizeof(spx_hash_key),
G_ALLOC_ONLY);
spx_hash_values = g_mem_chunk_new("spx_hash_values",
- sizeof(spx_hash_value),
- SPX_PACKET_INIT_COUNT * sizeof(spx_hash_value),
+ sizeof(spx_info),
+ SPX_PACKET_INIT_COUNT * sizeof(spx_info),
G_ALLOC_ONLY);
}
@@ -430,11 +422,11 @@ spx_postseq_cleanup(void)
* needed during random-access processing of the proto_tree.*/
}
-spx_hash_value*
+spx_info*
spx_hash_insert(conversation_t *conversation, guint32 spx_src)
{
spx_hash_key *key;
- spx_hash_value *value;
+ spx_info *value;
/* Now remember the packet, so we can find it if we later. */
key = g_mem_chunk_alloc(spx_hash_keys);
@@ -446,7 +438,6 @@ spx_hash_insert(conversation_t *conversation, guint32 spx_src)
value->spx_ack = 0;
value->spx_all = 0;
value->num = 0;
- value->retransmission = FALSE;
g_hash_table_insert(spx_hash, key, value);
@@ -454,7 +445,7 @@ spx_hash_insert(conversation_t *conversation, guint32 spx_src)
}
/* Returns the spx_rec*, or NULL if not found. */
-spx_hash_value*
+spx_info*
spx_hash_lookup(conversation_t *conversation, guint32 spx_src)
{
spx_hash_key key;
@@ -520,7 +511,7 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
const char *spx_msg_string;
guint16 low_socket, high_socket;
guint32 src;
- spx_hash_value *pkt_value = NULL;
+ spx_info *pkt_value = NULL;
conversation_t *conversation = NULL;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
@@ -555,56 +546,70 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(spx_tree, hf_spx_ack_nr, tvb, 8, 2, FALSE);
proto_tree_add_item(spx_tree, hf_spx_all_nr, tvb, 10, 2, FALSE);
}
- src = tvb_get_ntohs(tvb, 0)+tvb_get_ntohs(tvb, 2)+tvb_get_ntohs(tvb, 4)+tvb_get_ntohs(tvb, 6)+tvb_get_ntohs(tvb, 8);
- /* SPX is Connection Oriented and Delivery Guaranteed
- * We need to flag retransmissions by the SPX protocol
+
+ /*
+ * SPX is Connection Oriented and Delivery Guaranteed.
+ * We need to flag retransmissions by the SPX protocol, so that
+ * subdissectors know whether a packet was retransmitted.
+ *
+ * We start out by creating a conversation for this IPX session.
+ * XXX - should we be using "pinfo->srcport" twice, or
+ * "pinfo->srcport" and "pinfo->destport"? For that matter, should
+ * we just be using PT_IPX, and get rid of PT_NCP?
*/
- if (!pinfo->fd->flags.visited) {
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ PT_NCP, pinfo->srcport, pinfo->srcport, 0);
+ if (conversation == NULL) {
+ /*
+ * It's not part of any conversation - create a new one.
+ */
+ conversation = conversation_new(&pinfo->src, &pinfo->dst,
PT_NCP, pinfo->srcport, pinfo->srcport, 0);
-
- if (conversation == NULL) {
- /*
- * It's not part of any conversation - create a new
- * one.
- */
- conversation = conversation_new(&pinfo->src,
- &pinfo->dst, PT_NCP, pinfo->srcport,
- pinfo->srcport, 0);
- pkt_value = spx_hash_insert(conversation, src);
- pkt_value->spx_seq = tvb_get_ntohs(tvb, 6);
- pkt_value->spx_ack = tvb_get_ntohs(tvb, 8);
- pkt_value->spx_all = tvb_get_ntohs(tvb, 10);
- pkt_value->num = pinfo->fd->num;
- pkt_value->retransmission = FALSE;
- } else {
- pkt_value = spx_hash_lookup(conversation, src);
- if (pkt_value &&
- tvb_reported_length_remaining(tvb, SPX_HEADER_LEN) > 0) {
- if (check_col(pinfo->cinfo, COL_INFO)) {
- col_add_fstr(pinfo->cinfo, COL_INFO,
- "[Retransmission] Original Packet %u",
- pkt_value->num);
- }
- pkt_value->spx_seq = tvb_get_ntohs(tvb, 6);
- pkt_value->spx_ack = tvb_get_ntohs(tvb, 8);
- pkt_value->spx_all = tvb_get_ntohs(tvb, 10);
- pkt_value->retransmission = TRUE;
- } else {
- pkt_value = spx_hash_insert(conversation, src);
- pkt_value->spx_seq = tvb_get_ntohs(tvb, 6);
- pkt_value->spx_ack = tvb_get_ntohs(tvb, 8);
- pkt_value->spx_all = tvb_get_ntohs(tvb, 10);
- pkt_value->num = pinfo->fd->num;
- pkt_value->retransmission = FALSE;
- }
- }
+ }
+
+ /*
+ * Now we'll hash the SPX header and use the result of that,
+ * plus the conversation, as a hash key to identify this packet,
+ * and, if it's not already in the SPX packet hash table, enter
+ * it into that hash table so we can detect retransmissions.
+ *
+ * On the first pass, if we don't find it in the hash table, it's
+ * not a retransmission, otherwise it is. If we don't find it,
+ * we enter it into the hash table, with the frame number.
+ *
+ * On subsequent passes, we should find it in the frame table
+ * whether it's a retransmission or not; it's a retransmission
+ * iff the frame number doesn't match the frame number in the
+ * hash table.
+ */
+ src = tvb_get_ntohs(tvb, 0)+tvb_get_ntohs(tvb, 2)+tvb_get_ntohs(tvb, 4)+tvb_get_ntohs(tvb, 6)+tvb_get_ntohs(tvb, 8);
+ pkt_value = spx_hash_lookup(conversation, src);
+ if (pkt_value == NULL) {
/*
- * Store the spx info so that subidissectors know what this
- * is.
- * Note: num will equal retransmitted source packet number.
+ * Not found in the hash table.
+ * Enter it into the hash table.
*/
- pinfo->private_data = pkt_value;
+ pkt_value = spx_hash_insert(conversation, src);
+ pkt_value->spx_seq = tvb_get_ntohs(tvb, 6);
+ pkt_value->spx_ack = tvb_get_ntohs(tvb, 8);
+ pkt_value->spx_all = tvb_get_ntohs(tvb, 10);
+ pkt_value->num = pinfo->fd->num;
+ }
+
+ /*
+ * It's a retransmission iff the frame number in the hash table
+ * entry (which is the frame number of the original transmission)
+ * isn't the frame number of this frame.
+ *
+ * XXX - put something into the protocol tree as well?
+ * If so, give the frame number, as an FT_FRAMENUM.
+ */
+ if (pkt_value->num != pinfo->fd->num) {
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "[Retransmission] Original Packet %u",
+ pkt_value->num);
+ }
}
if (tvb_reported_length_remaining(tvb, SPX_HEADER_LEN) > 0) {
@@ -631,6 +636,13 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
high_socket = pinfo->destport;
}
+ /*
+ * Pass the SPX info to subdissectors, so that they know
+ * what this is.
+ * Note: num will equal retransmitted source packet number.
+ */
+ pinfo->private_data = pkt_value;
+
next_tvb = tvb_new_subset(tvb, SPX_HEADER_LEN, -1, -1);
if (dissector_try_port(spx_socket_dissector_table, low_socket,
next_tvb, pinfo, tree))