1998-09-23 05:25:12 +00:00
|
|
|
/* packet-ncp.c
|
|
|
|
* Routines for NetWare Core Protocol
|
2001-11-13 23:55:44 +00:00
|
|
|
* Gilbert Ramirez <gram@alumni.rice.edu>
|
1999-12-07 06:13:19 +00:00
|
|
|
* Modified to allow NCP over TCP/IP decodes by James Coe <jammer@cin.net>
|
1998-09-23 05:25:12 +00:00
|
|
|
*
|
2002-05-11 18:58:02 +00:00
|
|
|
* $Id: packet-ncp.c,v 1.57 2002/05/11 18:58:02 guy Exp $
|
1998-09-23 05:25:12 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
2001-12-03 04:00:26 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
2000-07-28 20:03:59 +00:00
|
|
|
* Copyright 2000 Gerald Combs
|
1998-09-23 05:25:12 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
#include <glib.h>
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/conversation.h>
|
2000-07-28 20:03:59 +00:00
|
|
|
#include "prefs.h"
|
1998-10-15 21:12:17 +00:00
|
|
|
#include "packet-ipx.h"
|
2000-07-28 20:03:59 +00:00
|
|
|
#include "packet-ncp-int.h"
|
1998-09-23 05:25:12 +00:00
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
int proto_ncp = -1;
|
1999-12-07 06:13:19 +00:00
|
|
|
static int hf_ncp_ip_ver = -1;
|
2000-07-28 20:03:59 +00:00
|
|
|
static int hf_ncp_ip_length = -1;
|
|
|
|
static int hf_ncp_ip_rplybufsize = -1;
|
1999-12-07 06:13:19 +00:00
|
|
|
static int hf_ncp_ip_sig = -1;
|
1999-10-17 14:09:35 +00:00
|
|
|
static int hf_ncp_type = -1;
|
|
|
|
static int hf_ncp_seq = -1;
|
|
|
|
static int hf_ncp_connection = -1;
|
|
|
|
static int hf_ncp_task = -1;
|
1999-07-29 05:47:07 +00:00
|
|
|
|
2002-05-09 23:50:34 +00:00
|
|
|
gint ett_ncp = -1;
|
1999-11-16 11:44:20 +00:00
|
|
|
|
2000-04-18 04:46:07 +00:00
|
|
|
#define TCP_PORT_NCP 524
|
|
|
|
#define UDP_PORT_NCP 524
|
2000-04-08 07:07:42 +00:00
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
#define NCP_RQST_HDR_LENGTH 7
|
|
|
|
#define NCP_RPLY_HDR_LENGTH 8
|
1999-03-20 04:38:57 +00:00
|
|
|
|
|
|
|
/* Hash functions */
|
1999-07-07 22:52:57 +00:00
|
|
|
gint ncp_equal (gconstpointer v, gconstpointer v2);
|
|
|
|
guint ncp_hash (gconstpointer v);
|
1999-03-20 04:38:57 +00:00
|
|
|
|
1999-12-07 06:13:19 +00:00
|
|
|
/* These are the header structures to handle NCP over IP */
|
2000-01-01 21:05:02 +00:00
|
|
|
#define NCPIP_RQST 0x446d6454 /* "DmdT" */
|
|
|
|
#define NCPIP_RPLY 0x744e6350 /* "tNcP" */
|
1999-12-07 06:13:19 +00:00
|
|
|
|
|
|
|
struct ncp_ip_header {
|
|
|
|
guint32 signature;
|
|
|
|
guint32 length;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* This header only appears on NCP over IP request packets */
|
|
|
|
struct ncp_ip_rqhdr {
|
|
|
|
guint32 version;
|
|
|
|
guint32 rplybufsize;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ncp_ip_signature[] = {
|
|
|
|
{ NCPIP_RQST, "Demand Transport (Request)" },
|
|
|
|
{ NCPIP_RPLY, "Transport is NCP (Reply)" },
|
2001-01-03 16:41:08 +00:00
|
|
|
{ 0, NULL },
|
1999-12-07 06:13:19 +00:00
|
|
|
};
|
|
|
|
|
1998-09-23 05:25:12 +00:00
|
|
|
/* The information in this module comes from:
|
|
|
|
NetWare LAN Analysis, Second Edition
|
|
|
|
Laura A. Chappell and Dan E. Hakes
|
|
|
|
(c) 1994 Novell, Inc.
|
|
|
|
Novell Press, San Jose.
|
|
|
|
ISBN: 0-7821-1362-1
|
|
|
|
|
|
|
|
And from the ncpfs source code by Volker Lendecke
|
1999-03-20 04:38:57 +00:00
|
|
|
|
|
|
|
And:
|
|
|
|
Programmer's Guide to the NetWare Core Protocol
|
|
|
|
Steve Conner & Diane Conner
|
|
|
|
(c) 1996 by Steve Conner & Diane Conner
|
|
|
|
Published by Annabooks, San Diego, California
|
|
|
|
ISBN: 0-929392-31-0
|
|
|
|
|
1998-09-23 05:25:12 +00:00
|
|
|
*/
|
|
|
|
|
1999-05-13 16:42:43 +00:00
|
|
|
/* Every NCP packet has this common header */
|
1999-03-20 04:38:57 +00:00
|
|
|
struct ncp_common_header {
|
|
|
|
guint16 type;
|
|
|
|
guint8 sequence;
|
|
|
|
guint8 conn_low;
|
|
|
|
guint8 task;
|
2000-07-28 20:03:59 +00:00
|
|
|
guint8 conn_high; /* type=0x5555 doesn't have this */
|
1999-03-20 04:38:57 +00:00
|
|
|
};
|
1998-09-23 05:25:12 +00:00
|
|
|
|
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
static value_string ncp_type_vals[] = {
|
1999-03-20 04:38:57 +00:00
|
|
|
{ 0x1111, "Create a service connection" },
|
1998-10-22 04:50:21 +00:00
|
|
|
{ 0x2222, "Service request" },
|
|
|
|
{ 0x3333, "Service reply" },
|
|
|
|
{ 0x5555, "Destroy service connection" },
|
|
|
|
{ 0x7777, "Burst mode transfer" },
|
|
|
|
{ 0x9999, "Request being processed" },
|
|
|
|
{ 0x0000, NULL }
|
|
|
|
};
|
1998-09-23 05:25:12 +00:00
|
|
|
|
1999-05-14 21:30:13 +00:00
|
|
|
|
Allow either old-style (pre-tvbuff) or new-style (tvbuffified)
dissectors to be registered as dissectors for particular ports,
registered as heuristic dissectors, and registered as dissectors for
conversations, and have routines to be used both by old-style and
new-style dissectors to call registered dissectors.
Have the code that calls those dissectors translate the arguments as
necessary. (For conversation dissectors, replace
"find_conversation_dissector()", which just returns a pointer to the
dissector, with "old_try_conversation_dissector()" and
"try_conversation_dissector()", which actually call the dissector, so
that there's a single place at which we can do that translation. Also
make "dissector_lookup()" static and, instead of calling it and, if it
returns a non-null pointer, calling that dissector, just use
"old_dissector_try_port()" or "dissector_try_port()", for the same
reason.)
This allows some dissectors that took old-style arguments and
immediately translated them to new-style arguments to just take
new-style arguments; make them do so. It also allows some new-style
dissectors not to have to translate arguments before calling routines to
look up and call dissectors; make them not do so.
Get rid of checks for too-short frames in new-style dissectors - the
tvbuff code does those checks for you.
Give the routines to register old-style dissectors, and to call
dissectors from old-style dissectors, names beginning with "old_", with
the routines for new-style dissectors not having the "old_". Update the
dissectors that use those routines appropriately.
Rename "dissect_data()" to "old_dissect_data()", and
"dissect_data_tvb()" to "dissect_data()".
svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
|
|
|
static void
|
2000-07-28 20:03:59 +00:00
|
|
|
dissect_ncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
|
|
{
|
|
|
|
proto_tree *ncp_tree = NULL;
|
|
|
|
proto_item *ti;
|
1999-12-07 06:13:19 +00:00
|
|
|
struct ncp_ip_header ncpiph;
|
|
|
|
struct ncp_ip_rqhdr ncpiphrq;
|
1998-10-15 21:12:17 +00:00
|
|
|
struct ncp_common_header header;
|
2000-07-28 20:03:59 +00:00
|
|
|
guint16 nw_connection;
|
|
|
|
int hdr_offset = 0;
|
|
|
|
int commhdr;
|
2001-07-12 01:48:05 +00:00
|
|
|
tvbuff_t *next_tvb;
|
2000-07-28 20:03:59 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "NCP");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
1999-03-20 04:38:57 +00:00
|
|
|
|
2001-01-22 03:33:45 +00:00
|
|
|
if ( pinfo->ptype == PT_TCP || pinfo->ptype == PT_UDP ) {
|
2000-07-28 20:03:59 +00:00
|
|
|
ncpiph.signature = tvb_get_ntohl(tvb, 0);
|
|
|
|
ncpiph.length = tvb_get_ntohl(tvb, 4);
|
|
|
|
hdr_offset += 8;
|
1999-12-07 06:13:19 +00:00
|
|
|
if ( ncpiph.signature == NCPIP_RQST ) {
|
2000-07-28 20:03:59 +00:00
|
|
|
ncpiphrq.version = tvb_get_ntohl(tvb, hdr_offset);
|
|
|
|
hdr_offset += 4;
|
|
|
|
ncpiphrq.rplybufsize = tvb_get_ntohl(tvb, hdr_offset);
|
|
|
|
hdr_offset += 4;
|
1999-12-07 06:13:19 +00:00
|
|
|
};
|
|
|
|
};
|
1999-12-15 04:20:46 +00:00
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
/* Record the offset where the NCP common header starts */
|
|
|
|
commhdr = hdr_offset;
|
1998-09-23 05:25:12 +00:00
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
header.type = tvb_get_ntohs(tvb, commhdr);
|
|
|
|
header.sequence = tvb_get_guint8(tvb, commhdr+2);
|
|
|
|
header.conn_low = tvb_get_guint8(tvb, commhdr+3);
|
|
|
|
header.conn_high = tvb_get_guint8(tvb, commhdr+5);
|
1999-05-13 16:42:43 +00:00
|
|
|
|
1999-03-20 04:38:57 +00:00
|
|
|
nw_connection = (header.conn_high << 16) + header.conn_low;
|
1998-10-15 21:12:17 +00:00
|
|
|
|
1998-09-23 05:25:12 +00:00
|
|
|
if (tree) {
|
2002-01-24 09:20:54 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_ncp, tvb, 0, -1, FALSE);
|
1999-11-16 11:44:20 +00:00
|
|
|
ncp_tree = proto_item_add_subtree(ti, ett_ncp);
|
1998-09-23 05:25:12 +00:00
|
|
|
|
2001-01-22 03:33:45 +00:00
|
|
|
if ( pinfo->ptype == PT_TCP || pinfo->ptype == PT_UDP ) {
|
2000-07-28 20:03:59 +00:00
|
|
|
proto_tree_add_uint(ncp_tree, hf_ncp_ip_sig, tvb, 0, 4, ncpiph.signature);
|
|
|
|
proto_tree_add_uint(ncp_tree, hf_ncp_ip_length, tvb, 4, 4, ncpiph.length);
|
1999-12-07 06:13:19 +00:00
|
|
|
if ( ncpiph.signature == NCPIP_RQST ) {
|
2000-07-28 20:03:59 +00:00
|
|
|
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);
|
1999-12-07 06:13:19 +00:00
|
|
|
};
|
|
|
|
};
|
2000-07-28 20:03:59 +00:00
|
|
|
proto_tree_add_uint(ncp_tree, hf_ncp_type, tvb, commhdr + 0, 2, header.type);
|
|
|
|
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);
|
1999-03-20 04:38:57 +00:00
|
|
|
}
|
1998-09-23 05:25:12 +00:00
|
|
|
|
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
if (header.type == 0x1111 || header.type == 0x2222) {
|
2001-07-12 01:48:05 +00:00
|
|
|
next_tvb = tvb_new_subset( tvb, hdr_offset, -1, -1 );
|
|
|
|
dissect_ncp_request(next_tvb, pinfo, nw_connection,
|
2002-05-09 23:50:34 +00:00
|
|
|
header.sequence, header.type, ncp_tree);
|
1999-12-13 20:20:09 +00:00
|
|
|
}
|
2000-07-28 20:03:59 +00:00
|
|
|
else if (header.type == 0x3333) {
|
2001-07-12 01:48:05 +00:00
|
|
|
next_tvb = tvb_new_subset( tvb, hdr_offset, -1, -1 );
|
|
|
|
dissect_ncp_reply(next_tvb, pinfo, nw_connection,
|
2002-05-09 23:50:34 +00:00
|
|
|
header.sequence, ncp_tree);
|
1999-05-13 16:42:43 +00:00
|
|
|
}
|
2000-07-28 20:03:59 +00:00
|
|
|
else if ( header.type == 0x5555 ||
|
|
|
|
header.type == 0x7777 ||
|
|
|
|
header.type == 0x9999 ) {
|
1999-03-20 04:38:57 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Type 0x%04x", header.type);
|
2000-04-18 04:46:07 +00:00
|
|
|
}
|
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_text(ncp_tree, tvb, commhdr + 0, 2, "Type 0x%04x not supported yet", header.type);
|
1998-09-23 05:25:12 +00:00
|
|
|
}
|
1999-05-13 16:42:43 +00:00
|
|
|
|
2000-07-28 20:03:59 +00:00
|
|
|
return;
|
1999-05-14 21:30:13 +00:00
|
|
|
}
|
2000-07-28 20:03:59 +00:00
|
|
|
else {
|
|
|
|
/* The value_string for hf_ncp_type already indicates that this type is unknown.
|
|
|
|
* Just return and do no more parsing. */
|
|
|
|
return;
|
|
|
|
}
|
1999-05-13 16:42:43 +00:00
|
|
|
}
|
1999-05-14 21:30:13 +00:00
|
|
|
|
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_ncp(void)
|
|
|
|
{
|
|
|
|
|
1999-10-17 14:09:35 +00:00
|
|
|
static hf_register_info hf[] = {
|
1999-12-07 06:13:19 +00:00
|
|
|
{ &hf_ncp_ip_sig,
|
|
|
|
{ "NCP over IP signature", "ncp.ip.signature",
|
|
|
|
FT_UINT32, BASE_HEX, VALS(ncp_ip_signature), 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
2000-07-28 20:03:59 +00:00
|
|
|
{ &hf_ncp_ip_length,
|
|
|
|
{ "NCP over IP length", "ncp.ip.length",
|
|
|
|
FT_UINT32, BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-12-07 06:13:19 +00:00
|
|
|
{ &hf_ncp_ip_ver,
|
2000-07-28 20:03:59 +00:00
|
|
|
{ "NCP over IP Version", "ncp.ip.version",
|
1999-12-07 06:13:19 +00:00
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
2000-07-28 20:03:59 +00:00
|
|
|
{ &hf_ncp_ip_rplybufsize,
|
|
|
|
{ "NCP over IP Reply Buffer Size", "ncp.ip.replybufsize",
|
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-17 14:09:35 +00:00
|
|
|
{ &hf_ncp_type,
|
|
|
|
{ "Type", "ncp.type",
|
2000-07-28 20:03:59 +00:00
|
|
|
FT_UINT16, BASE_HEX, VALS(ncp_type_vals), 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"NCP message type", HFILL }},
|
1999-10-17 14:09:35 +00:00
|
|
|
{ &hf_ncp_seq,
|
|
|
|
{ "Sequence Number", "ncp.seq",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-17 14:09:35 +00:00
|
|
|
{ &hf_ncp_connection,
|
|
|
|
{ "Connection Number", "ncp.connection",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-17 14:09:35 +00:00
|
|
|
{ &hf_ncp_task,
|
|
|
|
{ "Task Number", "ncp.task",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }}
|
1999-10-17 14:09:35 +00:00
|
|
|
};
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_ncp,
|
|
|
|
};
|
2002-05-11 18:58:02 +00:00
|
|
|
module_t *ncp_module;
|
1999-10-17 14:09:35 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_ncp = proto_register_protocol("NetWare Core Protocol", "NCP", "ncp");
|
1999-10-17 14:09:35 +00:00
|
|
|
proto_register_field_array(proto_ncp, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2002-05-11 18:58:02 +00:00
|
|
|
|
|
|
|
/* Register an obsolete configuration option for what used to be the
|
|
|
|
initial size of the NCP hash. */
|
|
|
|
ncp_module = prefs_register_protocol_obsolete(proto_ncp);
|
|
|
|
prefs_register_obsolete_preference(ncp_module, "initial_hash_size");
|
1999-07-29 05:47:07 +00:00
|
|
|
}
|
2000-04-08 07:07:42 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_ncp(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t ncp_handle;
|
|
|
|
|
|
|
|
ncp_handle = create_dissector_handle(dissect_ncp, proto_ncp);
|
|
|
|
dissector_add("tcp.port", TCP_PORT_NCP, ncp_handle);
|
|
|
|
dissector_add("udp.port", UDP_PORT_NCP, ncp_handle);
|
|
|
|
dissector_add("ipx.packet_type", IPX_PACKET_TYPE_NCP, ncp_handle);
|
|
|
|
dissector_add("ipx.socket", IPX_SOCKET_NCP, ncp_handle);
|
2000-04-08 07:07:42 +00:00
|
|
|
}
|