* Routines for NetWare Core Protocol
* Gilbert Ramirez <gram@alumni.rice.edu>
* Modified to allow NCP over TCP/IP decodes by James Coe <jammer@cin.net>
+ * Modified to decode server op-lock
+ * & NDS packets by Greg Morris <gmorris@novell.com>
*
- * $Id: packet-ncp.c,v 1.63 2002/05/25 01:05:56 guy Exp $
+ * $Id: packet-ncp.c,v 1.67 2002/08/23 21:54:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifdef HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static int hf_ncp_missing_fraglist_count = -1;
static int hf_ncp_missing_data_offset = -1;
static int hf_ncp_missing_data_count = -1;
+static int hf_ncp_oplock_flag = -1;
+static int hf_ncp_oplock_handle = -1;
static int hf_ncp_completion_code = -1;
static int hf_ncp_connection_status = -1;
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;
+
gint ett_ncp = -1;
static gint ett_ncp_system_flags = -1;
guint8 conn_low;
guint8 task;
guint8 conn_high; /* type=0x5555 doesn't have this */
-};
+};
static value_string ncp_type_vals[] = {
{ NCP_SERVICE_REPLY, "Service reply" },
{ NCP_WATCHDOG, "Watchdog" },
{ NCP_DEALLOCATE_SLOT, "Destroy service connection" },
+ { NCP_BROADCAST_SLOT, "Server Broadcast" },
{ NCP_BURST_MODE_XFER, "Burst mode transfer" },
{ NCP_POSITIVE_ACK, "Request being processed" },
+ { NCP_LIP_ECHO, "Large Internet Packet Echo" },
{ 0, NULL }
};
proto_tree *flags_tree = NULL;
guint16 data_len = 0;
guint16 missing_fraglist_count = 0;
+ guint16 ncp_nds_verb;
int hdr_offset = 0;
int commhdr;
int offset;
*/
switch (header.type) {
- case NCP_ALLOCATE_SLOT: /* Allocate Slot Request */
- case NCP_SERVICE_REQUEST: /* Server NCP Request */
- case NCP_SERVICE_REPLY: /* Server NCP Reply */
- case NCP_WATCHDOG: /* Watchdog Packet */
- case NCP_DEALLOCATE_SLOT: /* Deallocate Slot Request */
- case NCP_POSITIVE_ACK: /* Positive Acknowledgement */
- default:
+ case NCP_BROADCAST_SLOT: /* Server Broadcast */
proto_tree_add_uint(ncp_tree, hf_ncp_seq, tvb, commhdr + 2, 1, header.sequence);
proto_tree_add_uint(ncp_tree, hf_ncp_connection,tvb, commhdr + 3, 3, nw_connection);
proto_tree_add_item(ncp_tree, hf_ncp_task, tvb, commhdr + 4, 1, FALSE);
+ proto_tree_add_item(ncp_tree, hf_ncp_oplock_flag, tvb, commhdr + 9, 1, FALSE);
+ proto_tree_add_item(ncp_tree, hf_ncp_oplock_handle, tvb, commhdr + 10, 4, FALSE);
+ break;
+
+ case NCP_LIP_ECHO: /* Lip Echo Packet */
+ proto_tree_add_item(ncp_tree, hf_lip_echo, tvb, commhdr, 13, FALSE);
break;
case NCP_BURST_MODE_XFER: /* Packet Burst Packet */
proto_tree_add_item(ncp_tree, hf_ncp_missing_fraglist_count,
tvb, commhdr + 34, 2, FALSE);
break;
+
+ case NCP_SERVICE_REQUEST: /* Server NCP Request */
+ case NCP_SERVICE_REPLY: /* Server NCP Reply */
+ case NCP_ALLOCATE_SLOT: /* Allocate Slot Request */
+ case NCP_WATCHDOG: /* Watchdog Packet */
+ case NCP_DEALLOCATE_SLOT: /* Deallocate Slot Request */
+ case NCP_POSITIVE_ACK: /* Positive Acknowledgement */
+ default:
+ proto_tree_add_uint(ncp_tree, hf_ncp_seq, tvb, commhdr + 2, 1, header.sequence);
+ proto_tree_add_uint(ncp_tree, hf_ncp_connection,tvb, commhdr + 3, 3, nw_connection);
+ proto_tree_add_item(ncp_tree, hf_ncp_task, tvb, commhdr + 4, 1, FALSE);
+ break;
}
/*
case NCP_ALLOCATE_SLOT: /* Allocate Slot Request */
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);
- dissect_ncp_request(next_tvb, pinfo, nw_connection,
- header.sequence, header.type, ncp_tree);
+ if (tvb_get_guint8(tvb, commhdr+6) == 0x68) {
+ ncp_nds_verb = tvb_get_ntohl(tvb, commhdr+4);
+ if (tvb_get_guint8(tvb, commhdr+7) == 0x02) { /* NDS Packet to decode */
+ dissect_nds_request(next_tvb, pinfo, nw_connection,
+ header.sequence, header.type, ncp_tree);
+ } else {
+ dissect_ncp_request(next_tvb, pinfo, nw_connection,
+ header.sequence, header.type, ncp_tree);
+ }
+ } else {
+ dissect_ncp_request(next_tvb, pinfo, nw_connection,
+ header.sequence, header.type, ncp_tree);
+ }
break;
case NCP_SERVICE_REPLY: /* Server NCP Reply */
}
break;
+ case NCP_LIP_ECHO: /* LIP Echo Packet */
+ proto_tree_add_text(ncp_tree, tvb, commhdr, -1,
+ "Lip Echo Packet");
+ break;
+
default:
if (tree) {
proto_tree_add_text(ncp_tree, tvb, commhdr + 6, -1,
static guint
get_ncp_pdu_len(tvbuff_t *tvb, int offset)
{
+ guint32 signature;
+
+ /*
+ * Check the NCP-over-TCP header signature, to make sure it's there.
+ * If it's not there, we cannot trust the next 4 bytes to be a
+ * packet length+"has signature" flag, so we just say the length is
+ * "what remains in the packet".
+ */
+ signature = tvb_get_ntohl(tvb, offset);
+ if (signature != NCPIP_RQST && signature != NCPIP_RPLY)
+ return tvb_length_remaining(tvb, offset);
+
/*
* Get the length of the NCP-over-TCP packet. Strip off the "has
* signature" flag.
{ "Task Number", "ncp.task",
FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL }},
+ { &hf_ncp_oplock_flag,
+ { "Oplock Flag", "ncp.oplock_flag",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+ { &hf_ncp_oplock_handle,
+ { "File Handle", "ncp.oplock_handle",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
{ &hf_ncp_stream_type,
{ "Stream Type", "ncp.stream_type",
FT_UINT8, BASE_HEX, NULL, 0x0,
{ "Control Code", "ncp.control_code",
FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL }},
+ { &hf_ncp_fragment_handle,
+ { "Fragment Handle", "ncp.fragger_hndl",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+ { &hf_lip_echo,
+ { "Large Internet Packet Echo", "ncp.lip_echo",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
};
static gint *ett[] = {
&ett_ncp,