aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packet-ipx.c171
-rw-r--r--packet-ipx.h12
-rw-r--r--packet-ndps.c6
3 files changed, 115 insertions, 74 deletions
diff --git a/packet-ipx.c b/packet-ipx.c
index 2d295ae858..6eeb25f7ee 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.124 2003/04/08 02:00:53 guy Exp $
+ * $Id: packet-ipx.c,v 1.125 2003/04/09 20:45:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -354,9 +354,17 @@ typedef struct {
guint32 spx_src;
} spx_hash_key;
+typedef struct {
+ guint16 spx_seq;
+ guint16 spx_ack;
+ guint16 spx_all;
+ guint32 num;
+} spx_hash_value;
+
static GHashTable *spx_hash = NULL;
static GMemChunk *spx_hash_keys = NULL;
static GMemChunk *spx_hash_values = NULL;
+static GMemChunk *spx_infos = NULL;
/* Hash Functions */
gint
@@ -391,6 +399,8 @@ spx_init_protocol(void)
g_mem_chunk_destroy(spx_hash_keys);
if (spx_hash_values)
g_mem_chunk_destroy(spx_hash_values);
+ if (spx_infos)
+ g_mem_chunk_destroy(spx_infos);
spx_hash = g_hash_table_new(spx_hash_func, spx_equal);
spx_hash_keys = g_mem_chunk_new("spx_hash_keys",
@@ -398,14 +408,19 @@ 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_info),
- SPX_PACKET_INIT_COUNT * sizeof(spx_info),
+ sizeof(spx_hash_value),
+ SPX_PACKET_INIT_COUNT * sizeof(spx_hash_value),
+ G_ALLOC_ONLY);
+ spx_infos = g_mem_chunk_new("spx_infos",
+ sizeof(spx_infos),
+ SPX_PACKET_INIT_COUNT * sizeof(spx_infos),
G_ALLOC_ONLY);
}
-/* After the sequential run, we don't need the spx hash and keys
- * anymore; the lookups have already been done and the vital info
- * saved in the reply-packets' private_data in the frame_data struct. */
+/* After the sequential run, we don't need the spx hash table, or
+ * the keys and values, anymore; the lookups have already been done
+ * and the relevant info saved as SPX private data with the frame
+ * if the frame was a retransmission. */
static void
spx_postseq_cleanup(void)
{
@@ -418,15 +433,19 @@ spx_postseq_cleanup(void)
g_mem_chunk_destroy(spx_hash_keys);
spx_hash_keys = NULL;
}
- /* Don't free the spx_hash_values, as they're
+ if (spx_hash_values) {
+ g_mem_chunk_destroy(spx_hash_values);
+ spx_hash_values = NULL;
+ }
+ /* Don't free the spx_infos, as they're
* needed during random-access processing of the proto_tree.*/
}
-spx_info*
+spx_hash_value*
spx_hash_insert(conversation_t *conversation, guint32 spx_src)
{
spx_hash_key *key;
- spx_info *value;
+ spx_hash_value *value;
/* Now remember the packet, so we can find it if we later. */
key = g_mem_chunk_alloc(spx_hash_keys);
@@ -438,14 +457,14 @@ spx_hash_insert(conversation_t *conversation, guint32 spx_src)
value->spx_ack = 0;
value->spx_all = 0;
value->num = 0;
-
+
g_hash_table_insert(spx_hash, key, value);
return value;
}
-/* Returns the spx_rec*, or NULL if not found. */
-spx_info*
+/* Returns the spx_hash_value*, or NULL if not found. */
+spx_hash_value*
spx_hash_lookup(conversation_t *conversation, guint32 spx_src)
{
spx_hash_key key;
@@ -511,8 +530,9 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
const char *spx_msg_string;
guint16 low_socket, high_socket;
guint32 src;
- spx_info *pkt_value = NULL;
- conversation_t *conversation = NULL;
+ conversation_t *conversation;
+ spx_hash_value *pkt_value;
+ spx_info *spx_info;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SPX");
@@ -549,66 +569,93 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/*
* 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.
+ * On the first pass, 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 direction of the
+ * IPX session; we use "pinfo->srcport" twice, so that we have
+ * separate conversations for the two directions.
*
- * 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?
+ * XXX - that might not work correctly if there's more than one
+ * SPX session using that source port; can that happen? If so,
+ * we should probably use the direction, as well as the conversation,
+ * as part of the hash key; if we do that, we can probably just
+ * use PT_IPX as the port type, and possibly get rid of PT_NCP.
*/
- 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,
+ if (!pinfo->fd->flags.visited) {
+ 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);
+ }
- /*
- * 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) {
/*
- * Not found in the hash table.
- * Enter it into the hash table.
+ * Now we'll hash the SPX header and use the result of that,
+ * plus the conversation, as a hash key to identify this
+ * packet.
+ *
+ * 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.
+ * If we do, we attach to this frame a structure giving
+ * the frame number of the original transmission, so that
+ * we, and subdissectors, know it's a retransmission.
+ */
+ 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) {
+ /*
+ * Not found in the hash table.
+ * Enter it into the hash table.
+ */
+ 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;
+
+ /*
+ * This is not a retransmission, so we shouldn't
+ * have any retransmission indicator.
+ */
+ spx_info = NULL;
+ } else {
+ /*
+ * Found in the hash table. Mark this frame as
+ * a retransmission.
+ */
+ spx_info = g_mem_chunk_alloc(spx_infos);
+ spx_info->num = pkt_value->num;
+ p_add_proto_data(pinfo->fd, proto_spx, spx_info);
+ }
+ } else {
+ /*
+ * Do we have per-packet SPX data for this frame?
+ * If so, it's a retransmission, and the per-packet
+ * data indicates which frame had the original
+ * transmission.
*/
- 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;
+ spx_info = p_get_proto_data(pinfo->fd, proto_spx);
}
/*
- * 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.
+ * It's a retransmission if we have a retransmission indicator.
*
* 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 (spx_info != NULL) {
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO,
"[Retransmission] Original Packet %u",
- pkt_value->num);
+ spx_info->num);
}
}
@@ -637,11 +684,11 @@ dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
/*
- * Pass the SPX info to subdissectors, so that they know
- * what this is.
- * Note: num will equal retransmitted source packet number.
+ * Pass the retransmission info, if any, to subdissectors,
+ * so they know whether it's a retransmission or not and,
+ * if it is, what frame had the original packet.
*/
- pinfo->private_data = pkt_value;
+ pinfo->private_data = spx_info;
next_tvb = tvb_new_subset(tvb, SPX_HEADER_LEN, -1, -1);
if (dissector_try_port(spx_socket_dissector_table, low_socket,
diff --git a/packet-ipx.h b/packet-ipx.h
index cabccc3296..ce01d46e8b 100644
--- a/packet-ipx.h
+++ b/packet-ipx.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) by Gilbert Ramirez 2000-2002
* Portions Copyright (c) Novell, Inc. 2002-2003
*
- * $Id: packet-ipx.h,v 1.25 2003/04/08 02:00:53 guy Exp $
+ * $Id: packet-ipx.h,v 1.26 2003/04/09 20:45:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -152,16 +152,10 @@ extern const value_string server_vals[];
void capture_ipx(packet_counts *);
/*
- * Structure passed to subdissectors of the SPX dissector.
- * It contains fields from the SPX header, plus the frame number.
- * It's kept in a hash table, so if an SPX packet is retransmitted,
- * there's only one copy, and "num" is the frame number of the first
- * transmission.
+ * Structure attached to retransmitted SPX frames; it contains the
+ * frame number of the original transmission.
*/
typedef struct _spx_info{
- guint16 spx_seq;
- guint16 spx_ack;
- guint16 spx_all;
guint32 num;
} spx_info;
diff --git a/packet-ndps.c b/packet-ndps.c
index 33865d6694..183006beb8 100644
--- a/packet-ndps.c
+++ b/packet-ndps.c
@@ -3,7 +3,7 @@
* Greg Morris <gmorris@novell.com>
* Copyright (c) Novell, Inc. 2002-2003
*
- * $Id: packet-ndps.c,v 1.17 2003/04/09 08:51:18 guy Exp $
+ * $Id: packet-ndps.c,v 1.18 2003/04/09 20:45:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -3330,8 +3330,8 @@ ndps_defrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
spx_info *spx_data;
spx_data = pinfo->private_data;
- if (!ndps_defragment || spx_data->num != pinfo->fd->num) {
- if (spx_data->num != pinfo->fd->num) {
+ if (!ndps_defragment || spx_data != NULL) {
+ if (spx_data != NULL) {
if (check_col(pinfo->cinfo, COL_INFO))
{
col_add_fstr(pinfo->cinfo, COL_INFO, "[Retransmission] Original Packet %d", spx_data->num);