aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ncp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-08-25 22:14:07 +0000
committerGuy Harris <guy@alum.mit.edu>2003-08-25 22:14:07 +0000
commitaabecd0a048ebac85ea6b793fd1e76da1ab1a898 (patch)
treee11358a9f8cab6aa7f908fa3ca2b984a8dbbdce0 /packet-ncp.c
parent4901c453340647933a1eb76c18159a8d83f47c32 (diff)
From Greg Morris:
1. Added support for defragmentation of NDS packets 2. The packet signature fixes seemed to never been applied. I have been using this code to dissect reply packets with packet signatures for quite some time and have never experienced any problems with it. Without these changes then reply packets containing signatures will not be decoded properly. It was recommended by Guy to not use public variables to track the signatures but it has been my experience that if signatures are enabled then it is enabled in the whole environment and would be valid for all NCP packets within the trace. I could change this but it would add additional code to build a memory table to track this. If for some reason it is determined to not add this part of the code then I will have to go back and add this table. svn path=/trunk/; revision=8258
Diffstat (limited to 'packet-ncp.c')
-rw-r--r--packet-ncp.c122
1 files changed, 93 insertions, 29 deletions
diff --git a/packet-ncp.c b/packet-ncp.c
index 3bad2c7af7..06b6048dce 100644
--- a/packet-ncp.c
+++ b/packet-ncp.c
@@ -5,7 +5,11 @@
* Modified to decode server op-lock
* & NDS packets by Greg Morris <gmorris@novell.com>
*
- * $Id: packet-ncp.c,v 1.72 2002/10/11 19:36:13 guy Exp $
+ * Portions Copyright (c) by Gilbert Ramirez 2000-2002
+ * Portions Copyright (c) by James Coe 2000-2002
+ * Portions Copyright (c) Novell, Inc. 2000-2003
+ *
+ * $Id: packet-ncp.c,v 1.73 2003/08/25 22:14:07 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -46,7 +50,9 @@
#include "packet-ipx.h"
#include "packet-tcp.h"
#include "packet-ncp-int.h"
+#include "reassemble.h"
+gboolean is_signed = FALSE;
int proto_ncp = -1;
static int hf_ncp_ip_ver = -1;
static int hf_ncp_ip_length = -1;
@@ -82,15 +88,21 @@ static int hf_ncp_slot = -1;
static int hf_ncp_control_code = -1;
static int hf_ncp_fragment_handle = -1;
static int hf_lip_echo = -1;
-/*static int hf_ping_version = -1;*/
gint ett_ncp = -1;
gint ett_nds = -1;
+gint ett_nds_segments = -1;
+gint ett_nds_segment = -1;
static gint ett_ncp_system_flags = -1;
+
+/* Tables for reassembly of fragments. */
+GHashTable *nds_fragment_table = NULL;
+GHashTable *nds_reassembled_table = NULL;
+dissector_handle_t nds_data_handle;
+
/* desegmentation of NCP over TCP */
static gboolean ncp_desegment = TRUE;
-/*static int ncp_nds_true = FALSE;*/
static dissector_handle_t data_handle;
@@ -189,7 +201,6 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_item *ti;
struct ncp_ip_header ncpiph;
struct ncp_ip_rqhdr ncpiphrq;
- gboolean is_signed = FALSE;
struct ncp_common_header header;
guint16 nw_connection;
guint16 flags = 0;
@@ -211,9 +222,15 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
+ hdr_offset = 0;
+
if (is_tcp) {
- ncpiph.signature = tvb_get_ntohl(tvb, 0);
- ncpiph.length = tvb_get_ntohl(tvb, 4);
+ if (tvb_get_ntohl(tvb, hdr_offset) != NCPIP_RQST && tvb_get_ntohl(tvb, hdr_offset) != NCPIP_RPLY)
+ {
+ hdr_offset += 1;
+ }
+ ncpiph.signature = tvb_get_ntohl(tvb, hdr_offset);
+ ncpiph.length = tvb_get_ntohl(tvb, hdr_offset+4);
hdr_offset += 8;
if ( ncpiph.signature == NCPIP_RQST ) {
ncpiphrq.version = tvb_get_ntohl(tvb, hdr_offset);
@@ -221,24 +238,54 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
ncpiphrq.rplybufsize = tvb_get_ntohl(tvb, hdr_offset);
hdr_offset += 4;
}
- if (ncpiph.length & 0x80000000) {
- /*
- * This appears to indicate that this packet
- * is signed; the signature is 8 bytes long.
- *
- * XXX - that bit does *not* appear to be set
- * in signed replies, and we can't dissect the
- * reply enough to find the matching request
- * without knowing whether the reply is
- * signed.
- *
- * XXX - what about NCP-over-IPX signed
- * messages?
- */
- is_signed = TRUE;
- hdr_offset += 8;
- ncpiph.length &= 0x7fffffff;
+ if (ncpiph.length & 0x80000000 || ncpiph.signature == NCPIP_RPLY)
+ {
+ if (!pinfo->fd->flags.visited)
+ {
+ /*
+ * This appears to indicate that this packet
+ * is signed; the signature is 8 bytes long.
+ *
+ * XXX - that bit does *not* appear to be set
+ * in signed replies, and we can't dissect the
+ * reply enough to find the matching request
+ * without knowing whether the reply is
+ * signed.
+ *
+ * XXX - what about NCP-over-IPX signed
+ * messages?
+ */
+ if (ncpiph.signature == NCPIP_RQST) {
+ is_signed = TRUE;
+ hdr_offset += 8;
+ ncpiph.length &= 0x7fffffff;
+ }
+ else
+ {
+ if (is_signed)
+ {
+ hdr_offset += 8;
+ ncpiph.length &= 0x7fffffff;
+ }
+ else
+ {
+ is_signed = FALSE;
+ }
+ }
+ }
+ else
+ {
+ if(is_signed)
+ {
+ hdr_offset += 8;
+ ncpiph.length &= 0x7fffffff;
+ }
+ }
}
+ else
+ {
+ is_signed = FALSE;
+ }
}
/* Record the offset where the NCP common header starts */
@@ -268,9 +315,14 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (ncpiph.signature == NCPIP_RQST) {
proto_tree_add_uint(ncp_tree, hf_ncp_ip_ver, tvb, 8, 4, ncpiphrq.version);
proto_tree_add_uint(ncp_tree, hf_ncp_ip_rplybufsize, tvb, 12, 4, ncpiphrq.rplybufsize);
+ if (is_signed)
+ proto_tree_add_item(ncp_tree, hf_ncp_ip_packetsig, tvb, 16, 8, FALSE);
}
- if (is_signed)
- proto_tree_add_item(ncp_tree, hf_ncp_ip_packetsig, tvb, 16, 8, FALSE);
+ else
+ {
+ if (is_signed)
+ proto_tree_add_item(ncp_tree, hf_ncp_ip_packetsig, tvb, 8, 8, FALSE);
+ }
}
proto_tree_add_uint(ncp_tree, hf_ncp_type, tvb, commhdr + 0, 2, header.type);
}
@@ -290,7 +342,7 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
break;
case NCP_LIP_ECHO: /* Lip Echo Packet */
- proto_tree_add_item(ncp_tree, hf_lip_echo, tvb, commhdr, 2, FALSE);
+ proto_tree_add_item(ncp_tree, hf_lip_echo, tvb, commhdr, 13, FALSE);
break;
case NCP_BURST_MODE_XFER: /* Packet Burst Packet */
@@ -416,6 +468,10 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
switch (header.type) {
+ case NCP_DEALLOCATE_SLOT: /* Deallocate Slot Request */
+ proto_tree_add_text(ncp_tree, tvb, commhdr, -1,
+ "Destroy Service Connection");
+ break;
case NCP_ALLOCATE_SLOT: /* Allocate Slot Request */
length_remaining = tvb_length_remaining(tvb, commhdr + 4);
if (length_remaining > 4) {
@@ -428,7 +484,6 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
case NCP_SERVICE_REQUEST: /* Server NCP Request */
- case NCP_DEALLOCATE_SLOT: /* Deallocate Slot Request */
case NCP_BROADCAST_SLOT: /* Server Broadcast Packet */
next_tvb = tvb_new_subset(tvb, hdr_offset, -1, -1);
if (tvb_get_guint8(tvb, commhdr+6) == 0x68) {
@@ -462,8 +517,7 @@ dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
case NCP_SERVICE_REPLY: /* Server NCP Reply */
case NCP_POSITIVE_ACK: /* Positive Acknowledgement */
next_tvb = tvb_new_subset(tvb, hdr_offset, -1, -1);
- dissect_ncp_reply(next_tvb, pinfo, nw_connection,
- header.sequence, header.type, ncp_tree);
+ nds_defrag(next_tvb, pinfo, nw_connection, header.sequence, header.type, ncp_tree);
break;
case NCP_WATCHDOG: /* Watchdog Packet */
@@ -558,6 +612,10 @@ get_ncp_pdu_len(tvbuff_t *tvb, int offset)
* packet length+"has signature" flag, so we just say the length is
* "what remains in the packet".
*/
+ /*if (tvb_get_guint8(tvb, offset)==0xff)
+ {
+ offset += 1;
+ }*/
signature = tvb_get_ntohl(tvb, offset);
if (signature != NCPIP_RQST && signature != NCPIP_RPLY)
return tvb_length_remaining(tvb, offset);
@@ -730,6 +788,8 @@ proto_register_ncp(void)
&ett_ncp,
&ett_ncp_system_flags,
&ett_nds,
+ &ett_nds_segments,
+ &ett_nds_segment,
};
module_t *ncp_module;
@@ -743,6 +803,10 @@ proto_register_ncp(void)
"Desegment all NCP-over-TCP messages spanning multiple segments",
"Whether the NCP dissector should desegment all messages spanning multiple TCP segments",
&ncp_desegment);
+ prefs_register_bool_preference(ncp_module, "defragment_nds",
+ "Defragment all NDS messages spanning multiple packets",
+ "Whether the NCP dissector should defragment all NDS messages spanning multiple packets",
+ &nds_defragment);
}
void