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 >
2004-02-18 06:01:47 +00:00
* Modified to decode server op - lock , packet signature ,
2002-08-23 17:47:31 +00:00
* & NDS packets by Greg Morris < gmorris @ novell . com >
1998-09-23 05:25:12 +00:00
*
2003-08-25 22:14:07 +00:00
* Portions Copyright ( c ) by Gilbert Ramirez 2000 - 2002
* Portions Copyright ( c ) by James Coe 2000 - 2002
* Portions Copyright ( c ) Novell , Inc . 2000 - 2003
*
2004-07-18 00:24:25 +00:00
* $ Id $
1998-09-23 05:25:12 +00:00
*
2006-05-21 04:49:01 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2000-07-28 20:03:59 +00:00
* Copyright 2000 Gerald Combs
2002-08-28 21:04:11 +00:00
*
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 .
2002-08-28 21:04:11 +00:00
*
1998-09-23 05:25:12 +00:00
* 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 .
2002-08-28 21:04:11 +00:00
*
1998-09-23 05:25:12 +00:00
* 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 .
*/
2002-08-28 21:04:11 +00:00
# ifdef HAVE_CONFIG_H
1998-09-23 05:25:12 +00:00
# include "config.h"
# endif
2002-08-23 17:47:31 +00:00
# ifdef HAVE_SYS_TYPES_H
# include <sys / types.h>
# endif
# ifdef HAVE_NETINET_IN_H
# include <netinet / in.h>
# endif
2002-05-15 06:50:33 +00:00
# include <string.h>
1999-03-23 03:14:46 +00:00
# include <glib.h>
2002-01-21 07:37:49 +00:00
# include <epan/packet.h>
2005-08-13 01:29:31 +00:00
# include <epan/emem.h>
2004-09-27 22:55:15 +00:00
# include <epan/prefs.h>
1998-10-15 21:12:17 +00:00
# include "packet-ipx.h"
2002-05-25 01:05:56 +00:00
# include "packet-tcp.h"
2000-07-28 20:03:59 +00:00
# include "packet-ncp-int.h"
2005-02-09 23:38:00 +00:00
# include <epan/reassemble.h>
2004-02-18 06:01:47 +00:00
# include <epan/conversation.h>
2005-10-19 14:28:26 +00:00
# include <epan/tap.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 ;
2002-05-24 03:03:49 +00:00
static int hf_ncp_ip_packetsig = - 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 ;
2002-05-15 06:50:33 +00:00
static int hf_ncp_stream_type = - 1 ;
static int hf_ncp_system_flags = - 1 ;
static int hf_ncp_system_flags_abt = - 1 ;
static int hf_ncp_system_flags_eob = - 1 ;
static int hf_ncp_system_flags_sys = - 1 ;
2004-06-15 09:30:54 +00:00
static int hf_ncp_system_flags_bsy = - 1 ;
static int hf_ncp_system_flags_lst = - 1 ;
2002-05-15 06:50:33 +00:00
static int hf_ncp_src_connection = - 1 ;
static int hf_ncp_dst_connection = - 1 ;
static int hf_ncp_packet_seqno = - 1 ;
static int hf_ncp_delay_time = - 1 ;
static int hf_ncp_burst_seqno = - 1 ;
static int hf_ncp_ack_seqno = - 1 ;
static int hf_ncp_burst_len = - 1 ;
2004-09-18 09:19:33 +00:00
static int hf_ncp_burst_offset = - 1 ;
2002-05-15 06:50:33 +00:00
static int hf_ncp_data_offset = - 1 ;
static int hf_ncp_data_bytes = - 1 ;
static int hf_ncp_missing_fraglist_count = - 1 ;
static int hf_ncp_missing_data_offset = - 1 ;
static int hf_ncp_missing_data_count = - 1 ;
2002-08-23 17:47:31 +00:00
static int hf_ncp_oplock_flag = - 1 ;
static int hf_ncp_oplock_handle = - 1 ;
2002-05-15 21:17:21 +00:00
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 ;
2002-08-23 17:47:31 +00:00
static int hf_ncp_fragment_handle = - 1 ;
static int hf_lip_echo = - 1 ;
2004-06-15 09:30:54 +00:00
static int hf_ncp_burst_command = - 1 ;
static int hf_ncp_burst_file_handle = - 1 ;
static int hf_ncp_burst_reserved = - 1 ;
1999-07-29 05:47:07 +00:00
2002-05-09 23:50:34 +00:00
gint ett_ncp = - 1 ;
2002-09-22 15:46:42 +00:00
gint ett_nds = - 1 ;
2003-08-25 22:14:07 +00:00
gint ett_nds_segments = - 1 ;
gint ett_nds_segment = - 1 ;
2002-05-15 06:50:33 +00:00
static gint ett_ncp_system_flags = - 1 ;
1999-11-16 11:44:20 +00:00
2005-10-19 14:28:26 +00:00
static struct novell_tap ncp_tap ;
struct ncp_common_header header ;
struct ncp_common_header * ncp_hdr ;
2003-08-25 22:14:07 +00:00
/* Tables for reassembly of fragments. */
GHashTable * nds_fragment_table = NULL ;
GHashTable * nds_reassembled_table = NULL ;
dissector_handle_t nds_data_handle ;
2002-05-25 01:05:56 +00:00
/* desegmentation of NCP over TCP */
static gboolean ncp_desegment = TRUE ;
2002-05-15 21:17:21 +00:00
static dissector_handle_t data_handle ;
2005-10-19 14:28:26 +00:00
static proto_item * expert_item = NULL ;
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
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
} ;
2004-06-15 09:30:54 +00:00
static const value_string burst_command [ ] = {
2005-10-24 02:05:19 +00:00
{ 0x01000000 , " Burst Read " } ,
{ 0x02000000 , " Burst Write " } ,
{ 0 , NULL } ,
2004-06-15 09:30:54 +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
2002-09-22 15:46:42 +00:00
And :
http : developer . novell . com
NCP documentation
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 [ ] = {
2002-05-15 21:17:21 +00:00
{ NCP_ALLOCATE_SLOT , " Create a service connection " } ,
{ NCP_SERVICE_REQUEST , " Service request " } ,
{ NCP_SERVICE_REPLY , " Service reply " } ,
{ NCP_WATCHDOG , " Watchdog " } ,
{ NCP_DEALLOCATE_SLOT , " Destroy service connection " } ,
2003-10-23 07:52:56 +00:00
{ NCP_BROADCAST_SLOT , " Server Broadcast " } ,
2002-05-15 21:17:21 +00:00
{ NCP_BURST_MODE_XFER , " Burst mode transfer " } ,
{ NCP_POSITIVE_ACK , " Request being processed " } ,
2003-10-23 07:52:56 +00:00
{ NCP_LIP_ECHO , " Large Internet Packet Echo " } ,
2002-05-15 21:17:21 +00:00
{ 0 , NULL }
1998-10-22 04:50:21 +00:00
} ;
1998-09-23 05:25:12 +00:00
2006-03-15 18:56:35 +00:00
static value_string ncp_oplock_vals [ ] = {
{ 0x21 , " Message Waiting " } ,
{ 0x24 , " Clear Op-lock " } ,
{ 0 , NULL }
} ;
/* Conversation Struct so we can detect NCP server sessions */
2004-02-18 06:01:47 +00:00
typedef struct {
conversation_t * conversation ;
2006-03-15 18:56:35 +00:00
guint32 nwconnection ;
guint8 nwtask ;
2004-02-18 06:01:47 +00:00
} mncp_rhash_key ;
2006-03-15 18:56:35 +00:00
/* Store the packet number for the start of the NCP session.
* Note sessions are defined as
* NCP Connection + NCP Task = = Unique NCP server session
* It is normal for multiple sessions per connection to exist
* These are normally different applications running on multi - tasking
* Operating Systems .
*/
2004-02-18 06:01:47 +00:00
typedef struct {
2006-03-15 18:56:35 +00:00
guint32 session_start_packet_num ;
2004-02-18 06:01:47 +00:00
} mncp_rhash_value ;
static GHashTable * mncp_rhash = NULL ;
/* Hash Functions */
2005-07-30 16:34:38 +00:00
static gint
2004-02-18 06:01:47 +00:00
mncp_equal ( gconstpointer v , gconstpointer v2 )
{
const mncp_rhash_key * val1 = ( const mncp_rhash_key * ) v ;
const mncp_rhash_key * val2 = ( const mncp_rhash_key * ) v2 ;
2006-03-15 18:56:35 +00:00
if ( val1 - > conversation = = val2 - > conversation & & val1 - > nwconnection = = val2 - > nwconnection & & val1 - > nwtask = = val2 - > nwtask ) {
2004-02-18 06:01:47 +00:00
return 1 ;
}
return 0 ;
}
2005-07-30 16:34:38 +00:00
static guint
2004-02-18 06:01:47 +00:00
mncp_hash ( gconstpointer v )
{
const mncp_rhash_key * mncp_key = ( const mncp_rhash_key * ) v ;
2006-03-15 18:56:35 +00:00
return GPOINTER_TO_UINT ( mncp_key - > conversation ) + mncp_key - > nwconnection + mncp_key - > nwtask ;
2004-02-18 06:01:47 +00:00
}
/* Initializes the hash table and the mem_chunk area each time a new
2006-05-21 04:49:01 +00:00
* file is loaded or re - loaded in wireshark */
2004-02-18 06:01:47 +00:00
static void
mncp_init_protocol ( void )
{
if ( mncp_rhash )
g_hash_table_destroy ( mncp_rhash ) ;
mncp_rhash = g_hash_table_new ( mncp_hash , mncp_equal ) ;
}
/* After the sequential run, we don't need the ncp_request 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 . */
static void
mncp_postseq_cleanup ( void )
{
}
2005-07-30 16:34:38 +00:00
static mncp_rhash_value *
2006-03-15 18:56:35 +00:00
mncp_hash_insert ( conversation_t * conversation , guint32 nwconnection , guint8 nwtask , packet_info * pinfo )
2004-02-18 06:01:47 +00:00
{
mncp_rhash_key * key ;
mncp_rhash_value * value ;
/* Now remember the request, so we can find it if we later
2006-03-15 18:56:35 +00:00
a reply to it . Track by conversation , connection , and task number .
in NetWare these values determine each unique session */
2005-08-13 01:29:31 +00:00
key = se_alloc ( sizeof ( mncp_rhash_key ) ) ;
2004-02-18 06:01:47 +00:00
key - > conversation = conversation ;
2006-03-15 18:56:35 +00:00
key - > nwconnection = nwconnection ;
key - > nwtask = nwtask ;
2004-02-18 06:01:47 +00:00
2005-08-13 01:29:31 +00:00
value = se_alloc ( sizeof ( mncp_rhash_value ) ) ;
2004-02-18 06:01:47 +00:00
g_hash_table_insert ( mncp_rhash , key , value ) ;
2006-03-15 18:56:35 +00:00
if ( ncp_echo_conn & & nwconnection ! = 65535 ) {
expert_add_info_format ( pinfo , NULL , PI_RESPONSE_CODE , PI_CHAT , " Detected New Server Session. Connection %d, Task %d " , nwconnection , nwtask ) ;
value - > session_start_packet_num = pinfo - > fd - > num ;
}
2004-02-18 06:01:47 +00:00
return value ;
}
/* Returns the ncp_rec*, or NULL if not found. */
2005-07-30 16:34:38 +00:00
static mncp_rhash_value *
2006-03-15 18:56:35 +00:00
mncp_hash_lookup ( conversation_t * conversation , guint32 nwconnection , guint8 nwtask )
2004-02-18 06:01:47 +00:00
{
mncp_rhash_key key ;
key . conversation = conversation ;
2006-03-15 18:56:35 +00:00
key . nwconnection = nwconnection ;
key . nwtask = nwtask ;
2004-02-18 06:01:47 +00:00
return g_hash_table_lookup ( mncp_rhash , & key ) ;
}
1999-05-14 21:30:13 +00:00
2002-05-15 06:50:33 +00:00
/*
* Burst packet system flags .
*/
# define ABT 0x04 /* Abort request */
2004-06-15 09:30:54 +00:00
# define BSY 0x08 /* Server Busy */
2002-05-15 06:50:33 +00:00
# define EOB 0x10 /* End of burst */
2004-06-15 09:30:54 +00:00
# define LST 0x40 /* Include Fragment List */
2002-05-15 06:50:33 +00:00
# define SYS 0x80 /* System packet */
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
2002-05-25 01:05:56 +00:00
dissect_ncp_common ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
gboolean is_tcp )
2000-07-28 20:03:59 +00:00
{
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 ;
2005-10-19 14:28:26 +00:00
guint16 ncp_burst_seqno , ncp_ack_seqno ;
2002-05-15 21:17:21 +00:00
guint16 flags = 0 ;
2002-05-15 06:50:33 +00:00
proto_tree * flags_tree = NULL ;
2000-07-28 20:03:59 +00:00
int hdr_offset = 0 ;
2006-03-15 18:56:35 +00:00
int commhdr = 0 ;
2004-09-18 09:19:33 +00:00
int offset = 0 ;
2002-05-15 21:17:21 +00:00
gint length_remaining ;
2001-07-12 01:48:05 +00:00
tvbuff_t * next_tvb ;
2004-06-15 09:30:54 +00:00
guint32 testvar = 0 , ncp_burst_command , burst_len , burst_off , burst_file ;
2002-10-10 03:03:30 +00:00
guint8 subfunction ;
2006-03-15 18:56:35 +00:00
guint32 nw_connection = 0 , data_offset ;
2004-09-18 09:19:33 +00:00
guint16 data_len = 0 ;
guint16 missing_fraglist_count = 0 ;
2004-07-28 08:23:52 +00:00
mncp_rhash_value * request_value = NULL ;
conversation_t * conversation ;
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
2003-10-23 07:52:56 +00:00
hdr_offset = 0 ;
2005-10-24 02:05:19 +00:00
ncp_hdr = & header ;
2006-03-15 18:56:35 +00:00
commhdr = hdr_offset ;
ti = proto_tree_add_item ( tree , proto_ncp , tvb , 0 , - 1 , FALSE ) ;
ncp_tree = proto_item_add_subtree ( ti , ett_ncp ) ;
if ( is_tcp ) {
if ( tvb_get_ntohl ( tvb , hdr_offset ) ! = NCPIP_RQST & & tvb_get_ntohl ( tvb , hdr_offset ) ! = NCPIP_RPLY )
commhdr + = 1 ;
/* Get NCPIP Header data */
ncpiph . signature = tvb_get_ntohl ( tvb , commhdr ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_ip_sig , tvb , commhdr , 4 , ncpiph . signature ) ;
ncpiph . length = ( 0x7fffffff & tvb_get_ntohl ( tvb , commhdr + 4 ) ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_ip_length , tvb , commhdr + 4 , 4 , ncpiph . length ) ;
commhdr + = 8 ;
if ( ncpiph . signature = = NCPIP_RQST ) {
ncpiphrq . version = tvb_get_ntohl ( tvb , commhdr ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_ip_ver , tvb , commhdr , 4 , ncpiphrq . version ) ;
commhdr + = 4 ;
ncpiphrq . rplybufsize = tvb_get_ntohl ( tvb , commhdr ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_ip_rplybufsize , tvb , commhdr , 4 , ncpiphrq . rplybufsize ) ;
commhdr + = 4 ;
}
/* Check to see if this is a valid offset, otherwise increment for packet signature */
if ( match_strval ( tvb_get_ntohs ( tvb , commhdr ) , ncp_type_vals ) = = NULL ) {
proto_tree_add_item ( ncp_tree , hf_ncp_ip_packetsig , tvb , commhdr , 8 , FALSE ) ;
commhdr + = 8 ;
}
}
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 . task = tvb_get_guint8 ( tvb , commhdr + 4 ) ;
header . conn_high = tvb_get_guint8 ( tvb , commhdr + 5 ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_type , tvb , commhdr , 2 , header . type ) ;
nw_connection = ( header . conn_high * 256 ) + header . conn_low ;
/* Ok, we need to track the conversation so that we can
* determine if a new server session is occuring for this
* connection .
*/
conversation = find_conversation ( pinfo - > fd - > num , & pinfo - > src , & pinfo - > dst ,
PT_NCP , ( guint32 ) pinfo - > srcport , ( guint32 ) pinfo - > destport ,
0 ) ;
if ( ( ncpiph . length & 0x80000000 ) | | ncpiph . signature = = NCPIP_RPLY ) {
/* First time through we will record the initial connection and task
* values
*/
if ( ! pinfo - > fd - > flags . visited ) {
if ( conversation ! = NULL ) {
/* find the record telling us the
* request made that caused this
* reply
*/
request_value = mncp_hash_lookup ( conversation , nw_connection , header . task ) ;
/* if for some reason we have no
* conversation in our hash , create
* one */
if ( request_value = = NULL ) {
request_value = mncp_hash_insert ( conversation , nw_connection , header . task , pinfo ) ;
}
} else {
/* It's not part of any conversation
* - create a new one .
*/
conversation = conversation_new ( pinfo - > fd - > num , & pinfo - > src ,
& pinfo - > dst , PT_NCP , ( guint32 ) pinfo - > srcport , ( guint32 ) pinfo - > destport , 0 ) ;
request_value = mncp_hash_insert ( conversation , nw_connection , header . task , pinfo ) ;
}
/* If this is a request packet then we
* might have a new task
*/
if ( ncpiph . signature = = NCPIP_RPLY ) {
/* Now on reply packets we have to
* use the state of the original
* request packet , so look up the
* request value and check the task number
*/
request_value = mncp_hash_lookup ( conversation , nw_connection , header . task ) ;
}
} else {
/* Get request value data */
request_value = mncp_hash_lookup ( conversation , nw_connection , header . task ) ;
if ( request_value ) {
if ( ( request_value - > session_start_packet_num = = pinfo - > fd - > num ) & & ncp_echo_conn )
{
expert_add_info_format ( pinfo , NULL , PI_RESPONSE_CODE , PI_CHAT , " Detected New Server Session. Connection %d, Task %d " , nw_connection , header . task ) ;
}
}
}
} else {
if ( ! pinfo - > fd - > flags . visited ) {
if ( conversation ! = NULL ) {
/* find the record telling us the
* request made that caused this
* reply
*/
request_value = mncp_hash_lookup ( conversation , nw_connection , header . task ) ;
/* if for some reason we have no
* conversation in our hash , create
* one */
if ( request_value = = NULL ) {
request_value = mncp_hash_insert ( conversation , nw_connection , header . task , pinfo ) ;
}
} else {
/* It's not part of any conversation
* - create a new one .
*/
conversation = conversation_new ( pinfo - > fd - > num , & pinfo - > src ,
& pinfo - > dst , PT_NCP , ( guint32 ) pinfo - > srcport , ( guint32 ) pinfo - > destport , 0 ) ;
request_value = mncp_hash_insert ( conversation , nw_connection , header . task , pinfo ) ;
}
/* find the record telling us the request
* made that caused this reply
*/
} else {
request_value = mncp_hash_lookup ( conversation , nw_connection , header . task ) ;
if ( request_value ) {
if ( ( request_value - > session_start_packet_num = = pinfo - > fd - > num ) & & ncp_echo_conn )
{
expert_add_info_format ( pinfo , NULL , PI_RESPONSE_CODE , PI_CHAT , " Detected New Server Session. Connection %d, Task %d " , nw_connection , header . task ) ;
}
}
}
2002-05-24 03:03:49 +00:00
}
1999-12-15 04:20:46 +00:00
2005-10-24 02:05:19 +00:00
tap_queue_packet ( ncp_tap . hdr , pinfo , ncp_hdr ) ;
2005-10-19 14:28:26 +00:00
2002-05-15 06:50:33 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) ) {
2002-09-22 15:46:42 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO ,
2002-05-15 06:50:33 +00:00
" %s " ,
val_to_str ( header . type , ncp_type_vals , " Unknown type (0x%04x) " ) ) ;
}
2005-10-24 02:05:19 +00:00
/*
2002-05-15 21:17:21 +00:00
* Process the packet - type - specific header .
*/
2002-05-15 06:50:33 +00:00
switch ( header . type ) {
2002-10-10 03:03:30 +00:00
case NCP_BROADCAST_SLOT : /* Server Broadcast */
proto_tree_add_uint ( ncp_tree , hf_ncp_seq , tvb , commhdr + 2 , 1 , header . sequence ) ;
2002-05-15 06:50:33 +00:00
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 ) ;
2006-03-15 18:56:35 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_oplock_flag , tvb , commhdr + 9 , 1 , tvb_get_guint8 ( tvb , commhdr + 9 ) ) ;
2002-08-23 17:47:31 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_oplock_handle , tvb , commhdr + 10 , 4 , FALSE ) ;
2006-03-15 18:56:35 +00:00
if ( ( tvb_get_guint8 ( tvb , commhdr + 9 ) = = 0x24 ) & & ncp_echo_file )
{
expert_add_info_format ( pinfo , NULL , PI_RESPONSE_CODE , PI_CHAT , " Server requesting station to clear oplock on handle - %08x " , tvb_get_ntohl ( tvb , commhdr + 10 ) ) ;
}
2002-10-10 03:03:30 +00:00
break ;
2002-05-15 06:50:33 +00:00
2002-10-10 03:03:30 +00:00
case NCP_LIP_ECHO : /* Lip Echo Packet */
2003-08-25 22:14:07 +00:00
proto_tree_add_item ( ncp_tree , hf_lip_echo , tvb , commhdr , 13 , FALSE ) ;
2002-10-10 03:03:30 +00:00
break ;
2002-08-23 17:47:31 +00:00
2002-10-10 03:03:30 +00:00
case NCP_BURST_MODE_XFER : /* Packet Burst Packet */
2002-05-15 06:50:33 +00:00
/*
* XXX - we should keep track of whether there ' s a burst
* outstanding on a connection and , if not , treat the
* beginning of the data as a burst header .
*
* The burst header contains :
*
* 4 bytes of little - endian function number :
* 1 = read , 2 = write ;
*
* 4 bytes of file handle ;
*
* 8 reserved bytes ;
*
* 4 bytes of big - endian file offset ;
*
* 4 bytes of big - endian byte count .
*
* The data follows for a burst write operation .
*
* The first packet of a burst read reply contains :
*
* 4 bytes of little - endian result code :
* 0 : No error
* 1 : Initial error
* 2 : I / O error
* 3 : No data read ;
*
* 4 bytes of returned byte count ( big - endian ? ) .
*
* The data follows .
*
* Each burst of a write request is responded to with a
* burst packet with a 2 - byte little - endian result code :
*
* 0 : Write successful
* 4 : Write error
*/
flags = tvb_get_guint8 ( tvb , commhdr + 2 ) ;
2005-11-05 01:23:06 +00:00
ti = proto_tree_add_uint ( ncp_tree , hf_ncp_system_flags ,
tvb , commhdr + 2 , 1 , flags ) ;
2002-05-15 06:50:33 +00:00
flags_tree = proto_item_add_subtree ( ti , ett_ncp_system_flags ) ;
2005-11-05 01:23:06 +00:00
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( flags_tree , hf_ncp_system_flags_abt ,
tvb , commhdr + 2 , 1 , FALSE ) ;
2005-11-05 01:23:06 +00:00
if ( flags & ABT ) {
proto_item_append_text ( ti , " ABT " ) ;
}
flags & = ( ~ ( ABT ) ) ;
2004-06-15 09:30:54 +00:00
proto_tree_add_item ( flags_tree , hf_ncp_system_flags_bsy ,
tvb , commhdr + 2 , 1 , FALSE ) ;
2005-11-05 01:23:06 +00:00
if ( flags & BSY ) {
proto_item_append_text ( ti , " BSY " ) ;
}
flags & = ( ~ ( BSY ) ) ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( flags_tree , hf_ncp_system_flags_eob ,
tvb , commhdr + 2 , 1 , FALSE ) ;
2005-11-05 01:23:06 +00:00
if ( flags & EOB ) {
proto_item_append_text ( ti , " EOB " ) ;
}
flags & = ( ~ ( EOB ) ) ;
2004-06-15 09:30:54 +00:00
proto_tree_add_item ( flags_tree , hf_ncp_system_flags_lst ,
tvb , commhdr + 2 , 1 , FALSE ) ;
2005-11-05 01:23:06 +00:00
if ( flags & LST ) {
proto_item_append_text ( ti , " LST " ) ;
}
flags & = ( ~ ( LST ) ) ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( flags_tree , hf_ncp_system_flags_sys ,
tvb , commhdr + 2 , 1 , FALSE ) ;
2005-11-05 01:23:06 +00:00
if ( flags & SYS ) {
proto_item_append_text ( ti , " SYS " ) ;
}
flags & = ( ~ ( SYS ) ) ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_stream_type ,
tvb , commhdr + 3 , 1 , FALSE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_src_connection ,
tvb , commhdr + 4 , 4 , FALSE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_dst_connection ,
tvb , commhdr + 8 , 4 , FALSE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_packet_seqno ,
tvb , commhdr + 12 , 4 , FALSE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_delay_time ,
tvb , commhdr + 16 , 4 , FALSE ) ;
2004-07-28 08:23:52 +00:00
ncp_burst_seqno = tvb_get_ntohs ( tvb , commhdr + 20 ) ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_burst_seqno ,
tvb , commhdr + 20 , 2 , FALSE ) ;
2004-07-28 08:23:52 +00:00
ncp_ack_seqno = tvb_get_ntohs ( tvb , commhdr + 22 ) ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_ack_seqno ,
tvb , commhdr + 22 , 2 , FALSE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_burst_len ,
tvb , commhdr + 24 , 4 , FALSE ) ;
2004-09-18 09:19:33 +00:00
data_offset = tvb_get_ntohl ( tvb , commhdr + 28 ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_data_offset ,
tvb , commhdr + 28 , 4 , data_offset ) ;
2002-05-15 06:50:33 +00:00
data_len = tvb_get_ntohs ( tvb , commhdr + 32 ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_data_bytes ,
tvb , commhdr + 32 , 2 , data_len ) ;
missing_fraglist_count = tvb_get_ntohs ( tvb , commhdr + 34 ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_missing_fraglist_count ,
tvb , commhdr + 34 , 2 , FALSE ) ;
2004-09-18 09:19:33 +00:00
offset = commhdr + 36 ;
if ( ! ( flags & SYS ) & & ncp_burst_seqno = = ncp_ack_seqno & &
data_offset = = 0 ) {
/*
* This is either a Burst Read or Burst Write
* command . The data length includes the burst
* mode header , plus any data in the command
* ( there shouldn ' t be any in a read , but there
* might be some in a write ) .
*/
if ( data_len < 4 )
return ;
ncp_burst_command = tvb_get_ntohl ( tvb , offset ) ;
2004-07-28 08:23:52 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_burst_command ,
2004-09-18 09:19:33 +00:00
tvb , offset , 4 , FALSE ) ;
offset + = 4 ;
data_len - = 4 ;
if ( data_len < 4 )
return ;
burst_file = tvb_get_ntohl ( tvb , offset ) ;
2004-07-28 08:23:52 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_burst_file_handle ,
2004-09-18 09:19:33 +00:00
tvb , offset , 4 , FALSE ) ;
offset + = 4 ;
data_len - = 4 ;
if ( data_len < 8 )
return ;
2004-07-28 08:23:52 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_burst_reserved ,
2004-09-18 09:19:33 +00:00
tvb , offset , 8 , FALSE ) ;
offset + = 8 ;
data_len - = 8 ;
if ( data_len < 4 )
return ;
burst_off = tvb_get_ntohl ( tvb , offset ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_burst_offset ,
tvb , offset , 4 , burst_off ) ;
offset + = 4 ;
data_len - = 4 ;
if ( data_len < 4 )
return ;
burst_len = tvb_get_ntohl ( tvb , offset ) ;
proto_tree_add_uint ( ncp_tree , hf_ncp_burst_len ,
tvb , offset , 4 , burst_len ) ;
offset + = 4 ;
data_len - = 4 ;
2004-07-28 08:23:52 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) ) {
2004-09-18 09:19:33 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO ,
" %s %d bytes starting at offset %d in file 0x%08x " ,
val_to_str ( ncp_burst_command ,
burst_command , " Unknown (0x%08x) " ) ,
burst_len , burst_off , burst_file ) ;
2004-07-28 08:23:52 +00:00
}
2004-09-18 09:19:33 +00:00
break ;
2004-07-28 08:23:52 +00:00
} else {
if ( tvb_get_guint8 ( tvb , commhdr + 2 ) & 0x10 ) {
if ( check_col ( pinfo - > cinfo , COL_INFO ) ) {
col_set_str ( pinfo - > cinfo , COL_INFO ,
" End of Burst " ) ;
}
}
}
2002-05-15 21:17:21 +00:00
break ;
2002-08-23 17:47:31 +00:00
case NCP_ALLOCATE_SLOT : /* Allocate Slot Request */
2002-10-10 03:03:30 +00:00
length_remaining = tvb_length_remaining ( tvb , commhdr + 4 ) ;
if ( length_remaining > 4 ) {
testvar = tvb_get_ntohl ( tvb , commhdr + 4 ) ;
if ( testvar = = 0x4c495020 ) {
proto_tree_add_item ( ncp_tree , hf_lip_echo , tvb , commhdr + 4 , 13 , FALSE ) ;
break ;
}
}
/* otherwise fall through */
2002-09-25 00:37:01 +00:00
case NCP_POSITIVE_ACK : /* Positive Acknowledgement */
2002-10-10 03:03:30 +00:00
case NCP_SERVICE_REQUEST : /* Server NCP Request */
case NCP_SERVICE_REPLY : /* Server NCP Reply */
case NCP_WATCHDOG : /* Watchdog Packet */
2002-08-23 17:47:31 +00:00
case NCP_DEALLOCATE_SLOT : /* Deallocate Slot Request */
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 ;
2002-05-15 21:17:21 +00:00
}
/*
* Process the packet body .
*/
switch ( header . type ) {
2002-10-10 03:03:30 +00:00
case NCP_ALLOCATE_SLOT : /* Allocate Slot Request */
length_remaining = tvb_length_remaining ( tvb , commhdr + 4 ) ;
if ( length_remaining > 4 ) {
testvar = tvb_get_ntohl ( tvb , commhdr + 4 ) ;
if ( testvar = = 0x4c495020 ) {
proto_tree_add_text ( ncp_tree , tvb , commhdr , - 1 ,
" Lip Echo Packet " ) ;
/*break;*/
}
}
2006-03-15 18:56:35 +00:00
next_tvb = tvb_new_subset ( tvb , commhdr , - 1 , - 1 ) ;
2005-10-24 02:05:19 +00:00
dissect_ncp_request ( next_tvb , pinfo , nw_connection ,
header . sequence , header . type , ncp_tree ) ;
break ;
case NCP_DEALLOCATE_SLOT : /* Deallocate Slot Request */
2006-03-15 18:56:35 +00:00
next_tvb = tvb_new_subset ( tvb , commhdr , - 1 , - 1 ) ;
2005-10-24 02:05:19 +00:00
dissect_ncp_request ( next_tvb , pinfo , nw_connection ,
header . sequence , header . type , ncp_tree ) ;
break ;
2002-10-10 03:03:30 +00:00
case NCP_SERVICE_REQUEST : /* Server NCP Request */
case NCP_BROADCAST_SLOT : /* Server Broadcast Packet */
2006-03-15 18:56:35 +00:00
next_tvb = tvb_new_subset ( tvb , commhdr , - 1 , - 1 ) ;
2002-10-10 03:03:30 +00:00
if ( tvb_get_guint8 ( tvb , commhdr + 6 ) = = 0x68 ) {
subfunction = tvb_get_guint8 ( tvb , commhdr + 7 ) ;
switch ( subfunction ) {
case 0x02 : /* NDS Frag Packet to decode */
dissect_nds_request ( next_tvb , pinfo ,
nw_connection , header . sequence ,
header . type , ncp_tree ) ;
break ;
case 0x01 : /* NDS Ping */
dissect_ping_req ( next_tvb , pinfo ,
nw_connection , header . sequence ,
header . type , ncp_tree ) ;
break ;
default :
dissect_ncp_request ( next_tvb , pinfo ,
nw_connection , header . sequence ,
header . type , ncp_tree ) ;
break ;
}
} else {
dissect_ncp_request ( next_tvb , pinfo , nw_connection ,
header . sequence , header . type , ncp_tree ) ;
}
2002-05-15 21:17:21 +00:00
break ;
2002-10-10 03:03:30 +00:00
case NCP_SERVICE_REPLY : /* Server NCP Reply */
2006-03-15 18:56:35 +00:00
next_tvb = tvb_new_subset ( tvb , commhdr , - 1 , - 1 ) ;
2003-12-22 02:04:18 +00:00
nds_defrag ( next_tvb , pinfo , nw_connection , header . sequence ,
2005-10-19 14:28:26 +00:00
header . type , ncp_tree , & ncp_tap ) ;
2003-12-22 02:04:18 +00:00
break ;
2002-05-16 09:59:52 +00:00
case NCP_POSITIVE_ACK : /* Positive Acknowledgement */
2003-12-22 02:04:18 +00:00
/*
* XXX - this used to call " nds_defrag() " , which would
* clear out " frags " . Was that the right thing to
* do ?
*/
2006-03-15 18:56:35 +00:00
next_tvb = tvb_new_subset ( tvb , commhdr , - 1 , - 1 ) ;
2003-12-22 02:04:18 +00:00
dissect_ncp_reply ( next_tvb , pinfo , nw_connection ,
2005-10-19 14:28:26 +00:00
header . sequence , header . type , ncp_tree , & ncp_tap ) ;
2002-05-15 21:17:21 +00:00
break ;
case NCP_WATCHDOG : /* Watchdog Packet */
2002-05-16 09:59:52 +00:00
/*
* XXX - should the completion code be interpreted as
* it is in " packet-ncp2222.inc " ? If so , this
* packet should be handled by " dissect_ncp_reply() " .
*/
2002-05-15 21:17:21 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_completion_code ,
tvb , commhdr + 6 , 1 , TRUE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_connection_status ,
tvb , commhdr + 7 , 1 , TRUE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_slot ,
tvb , commhdr + 8 , 1 , TRUE ) ;
proto_tree_add_item ( ncp_tree , hf_ncp_control_code ,
tvb , commhdr + 9 , 1 , TRUE ) ;
/*
* Display the rest of the packet as data .
*/
if ( tvb_offset_exists ( tvb , commhdr + 10 ) ) {
call_dissector ( data_handle ,
tvb_new_subset ( tvb , commhdr + 10 , - 1 , - 1 ) ,
pinfo , ncp_tree ) ;
}
break ;
case NCP_BURST_MODE_XFER : /* Packet Burst Packet */
2002-05-15 06:50:33 +00:00
if ( flags & SYS ) {
/*
* System packet ; show missing fragments if there
* are any .
*/
while ( missing_fraglist_count ! = 0 ) {
proto_tree_add_item ( ncp_tree , hf_ncp_missing_data_offset ,
tvb , offset , 4 , FALSE ) ;
2004-09-18 09:19:33 +00:00
offset + = 4 ;
2002-05-15 06:50:33 +00:00
proto_tree_add_item ( ncp_tree , hf_ncp_missing_data_count ,
tvb , offset , 2 , FALSE ) ;
2004-09-18 09:19:33 +00:00
offset + = 2 ;
2002-05-15 06:50:33 +00:00
missing_fraglist_count - - ;
}
} else {
2002-05-15 21:17:21 +00:00
/*
* XXX - do this by using - 1 and - 1 as the length
* arguments to " tvb_new_subset() " and then calling
* " tvb_set_reported_length() " ? That ' ll throw an
* exception if " data_len " goes past the reported
* length of the packet , but that ' s arguably a
* feature in this case .
*/
2004-09-18 09:19:33 +00:00
length_remaining = tvb_length_remaining ( tvb , offset ) ;
2002-05-15 21:17:21 +00:00
if ( length_remaining > data_len )
length_remaining = data_len ;
2002-05-15 06:50:33 +00:00
if ( data_len ! = 0 ) {
2002-05-15 21:17:21 +00:00
call_dissector ( data_handle ,
2004-09-18 09:19:33 +00:00
tvb_new_subset ( tvb , offset ,
2002-05-15 21:17:21 +00:00
length_remaining , data_len ) ,
pinfo , ncp_tree ) ;
2002-05-15 06:50:33 +00:00
}
}
break ;
2002-10-10 03:03:30 +00:00
case NCP_LIP_ECHO : /* LIP Echo Packet */
proto_tree_add_text ( ncp_tree , tvb , commhdr , - 1 ,
" Lip Echo Packet " ) ;
break ;
2002-05-15 06:50:33 +00:00
default :
2002-05-15 21:17:21 +00:00
if ( tree ) {
2005-10-19 14:28:26 +00:00
expert_item = proto_tree_add_text ( ncp_tree , tvb , commhdr + 6 , - 1 ,
2002-05-15 21:17:21 +00:00
" %s packets not supported yet " ,
val_to_str ( header . type , ncp_type_vals ,
" Unknown type (0x%04x) " ) ) ;
2005-11-24 05:55:18 +00:00
if ( ncp_echo_err ) {
expert_add_info_format ( pinfo , expert_item , PI_UNDECODED , PI_NOTE , " %s packets not supported yet " , val_to_str ( header . type , ncp_type_vals ,
" Unknown type (0x%04x) " ) ) ;
}
2002-05-15 21:17:21 +00:00
}
2002-05-15 06:50:33 +00:00
break ;
2000-07-28 20:03:59 +00:00
}
1999-05-13 16:42:43 +00:00
}
1999-05-14 21:30:13 +00:00
2002-05-25 01:05:56 +00:00
static void
dissect_ncp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
dissect_ncp_common ( tvb , pinfo , tree , FALSE ) ;
}
static guint
get_ncp_pdu_len ( tvbuff_t * tvb , int offset )
{
2002-05-25 12:44:06 +00:00
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 ) ;
2002-08-28 21:04:11 +00:00
2002-05-25 01:05:56 +00:00
/*
* Get the length of the NCP - over - TCP packet . Strip off the " has
* signature " flag.
*/
2002-09-22 15:46:42 +00:00
2002-05-25 01:05:56 +00:00
return tvb_get_ntohl ( tvb , offset + 4 ) & 0x7fffffff ;
}
static void
dissect_ncp_tcp_pdu ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
dissect_ncp_common ( tvb , pinfo , tree , TRUE ) ;
}
1999-05-14 21:30:13 +00:00
2002-05-25 01:05:56 +00:00
static void
dissect_ncp_tcp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
tcp_dissect_pdus ( tvb , pinfo , tree , ncp_desegment , 8 , get_ncp_pdu_len ,
dissect_ncp_tcp_pdu ) ;
}
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 ,
2002-05-24 03:03:49 +00:00
{ " NCP over IP signature " , " ncp.ip.signature " ,
1999-12-07 06:13:19 +00:00
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 " ,
2002-05-24 03:03:49 +00:00
FT_UINT32 , BASE_DEC , 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 } } ,
2002-05-24 03:03:49 +00:00
{ & hf_ncp_ip_packetsig ,
{ " NCP over IP Packet Signature " , " ncp.ip.packetsig " ,
FT_BYTES , BASE_NONE , NULL , 0x0 ,
" " , 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 ,
2002-05-15 06:50:33 +00:00
" " , HFILL } } ,
2002-08-23 17:47:31 +00:00
{ & hf_ncp_oplock_flag ,
2006-03-15 18:56:35 +00:00
{ " Broadcast Message Flag " , " ncp.msg_flag " ,
FT_UINT8 , BASE_HEX , VALS ( ncp_oplock_vals ) , 0x0 ,
2002-08-23 17:47:31 +00:00
" " , HFILL } } ,
{ & hf_ncp_oplock_handle ,
{ " File Handle " , " ncp.oplock_handle " ,
FT_UINT16 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
2002-05-15 06:50:33 +00:00
{ & hf_ncp_stream_type ,
{ " Stream Type " , " ncp.stream_type " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" Type of burst " , HFILL } } ,
{ & hf_ncp_system_flags ,
{ " System Flags " , " ncp.system_flags " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_ncp_system_flags_abt ,
{ " ABT " , " ncp.system_flags.abt " ,
FT_BOOLEAN , 8 , NULL , ABT ,
" Is this an abort request? " , HFILL } } ,
{ & hf_ncp_system_flags_eob ,
{ " EOB " , " ncp.system_flags.eob " ,
FT_BOOLEAN , 8 , NULL , EOB ,
" Is this the last packet of the burst? " , HFILL } } ,
{ & hf_ncp_system_flags_sys ,
{ " SYS " , " ncp.system_flags.sys " ,
FT_BOOLEAN , 8 , NULL , SYS ,
" Is this a system packet? " , HFILL } } ,
2004-06-15 09:30:54 +00:00
{ & hf_ncp_system_flags_bsy ,
{ " BSY " , " ncp.system_flags.bsy " ,
FT_BOOLEAN , 8 , NULL , BSY ,
" Is the server busy? " , HFILL } } ,
{ & hf_ncp_system_flags_lst ,
{ " LST " , " ncp.system_flags.lst " ,
FT_BOOLEAN , 8 , NULL , LST ,
" Return Fragment List? " , HFILL } } ,
2002-05-15 06:50:33 +00:00
{ & hf_ncp_src_connection ,
{ " Source Connection ID " , " ncp.src_connection " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" The workstation's connection identification number " , HFILL } } ,
{ & hf_ncp_dst_connection ,
{ " Destination Connection ID " , " ncp.dst_connection " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" The server's connection identification number " , HFILL } } ,
{ & hf_ncp_packet_seqno ,
{ " Packet Sequence Number " , " ncp.packet_seqno " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Sequence number of this packet in a burst " , HFILL } } ,
{ & hf_ncp_delay_time ,
{ " Delay Time " , " ncp.delay_time " , /* in 100 us increments */
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Delay time between consecutive packet sends (100 us increments) " , HFILL } } ,
{ & hf_ncp_burst_seqno ,
{ " Burst Sequence Number " , " ncp.burst_seqno " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Sequence number of this packet in the burst " , HFILL } } ,
{ & hf_ncp_ack_seqno ,
{ " ACK Sequence Number " , " ncp.ack_seqno " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Next expected burst sequence number " , HFILL } } ,
{ & hf_ncp_burst_len ,
{ " Burst Length " , " ncp.burst_len " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Total length of data in this burst " , HFILL } } ,
2004-09-18 09:19:33 +00:00
{ & hf_ncp_burst_offset ,
{ " Burst Offset " , " ncp.burst_offset " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Offset of data in the burst " , HFILL } } ,
2002-05-15 06:50:33 +00:00
{ & hf_ncp_data_offset ,
{ " Data Offset " , " ncp.data_offset " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
2004-09-18 09:19:33 +00:00
" Offset of this packet " , HFILL } } ,
2002-05-15 06:50:33 +00:00
{ & hf_ncp_data_bytes ,
{ " Data Bytes " , " ncp.data_bytes " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Number of data bytes in this packet " , HFILL } } ,
{ & hf_ncp_missing_fraglist_count ,
{ " Missing Fragment List Count " , " ncp.missing_fraglist_count " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Number of missing fragments reported " , HFILL } } ,
{ & hf_ncp_missing_data_offset ,
{ " Missing Data Offset " , " ncp.missing_data_offset " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Offset of beginning of missing data " , HFILL } } ,
{ & hf_ncp_missing_data_count ,
{ " Missing Data Count " , " ncp.missing_data_count " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Number of bytes of missing data " , HFILL } } ,
2002-05-15 21:17:21 +00:00
{ & hf_ncp_completion_code ,
{ " Completion Code " , " ncp.completion_code " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_ncp_connection_status ,
{ " Connection Status " , " ncp.connection_status " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_ncp_slot ,
{ " Slot " , " ncp.slot " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_ncp_control_code ,
{ " Control Code " , " ncp.control_code " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
2002-08-23 17:47:31 +00:00
{ & 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 } } ,
2004-06-15 09:30:54 +00:00
{ & hf_ncp_burst_command ,
{ " Burst Command " , " ncp.burst_command " ,
FT_UINT32 , BASE_HEX , VALS ( burst_command ) , 0x0 ,
" Packet Burst Command " , HFILL } } ,
{ & hf_ncp_burst_file_handle ,
{ " Burst File Handle " , " ncp.file_handle " ,
FT_UINT32 , BASE_HEX , NULL , 0x0 ,
" Packet Burst File Handle " , HFILL } } ,
{ & hf_ncp_burst_reserved ,
{ " Reserved " , " ncp.burst_reserved " ,
FT_BYTES , BASE_HEX , NULL , 0x0 , " " , HFILL } } ,
2002-09-22 15:46:42 +00:00
1999-10-17 14:09:35 +00:00
} ;
1999-11-16 11:44:20 +00:00
static gint * ett [ ] = {
& ett_ncp ,
2002-05-15 06:50:33 +00:00
& ett_ncp_system_flags ,
2002-09-22 15:46:42 +00:00
& ett_nds ,
2003-08-25 22:14:07 +00:00
& ett_nds_segments ,
& ett_nds_segment ,
1999-11-16 11:44:20 +00:00
} ;
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
2002-05-25 01:05:56 +00:00
ncp_module = prefs_register_protocol ( proto_ncp , NULL ) ;
2002-05-11 18:58:02 +00:00
prefs_register_obsolete_preference ( ncp_module , " initial_hash_size " ) ;
2002-05-25 01:05:56 +00:00
prefs_register_bool_preference ( ncp_module , " desegment " ,
2004-08-21 09:02:52 +00:00
" Reassemble NCP-over-TCP messages spanning multiple TCP segments " ,
" Whether the NCP dissector should reassemble messages spanning multiple TCP segments. "
" To use this option, you must also enable \" Allow subdissectors to reassemble TCP streams \" in the TCP protocol settings. " ,
2002-05-25 01:05:56 +00:00
& ncp_desegment ) ;
2003-08-25 22:14:07 +00:00
prefs_register_bool_preference ( ncp_module , " defragment_nds " ,
2005-11-24 05:55:18 +00:00
" Reassemble fragmented NDS messages spanning multiple reply packets " ,
" Whether the NCP dissector should defragment NDS messages spanning multiple reply packets. " ,
& nds_defragment ) ;
prefs_register_bool_preference ( ncp_module , " eid_2_expert " ,
" Expert: EID to Name lookups? " ,
" Whether the NCP dissector should echo the NDS Entry ID to name resolves to the expert table. " ,
& nds_echo_eid ) ;
prefs_register_bool_preference ( ncp_module , " connection_2_expert " ,
" Expert: NCP Connections? " ,
" Whether the NCP dissector should echo NCP connection information to the expert table. " ,
& ncp_echo_conn ) ;
prefs_register_bool_preference ( ncp_module , " error_2_expert " ,
" Expert: NCP Errors? " ,
" Whether the NCP dissector should echo protocol errors to the expert table. " ,
& ncp_echo_err ) ;
prefs_register_bool_preference ( ncp_module , " server_2_expert " ,
" Expert: Server Information? " ,
" Whether the NCP dissector should echo server information to the expert table. " ,
& ncp_echo_server ) ;
2006-03-15 18:56:35 +00:00
prefs_register_bool_preference ( ncp_module , " file_2_expert " ,
" Expert: File Information? " ,
" Whether the NCP dissector should echo file information to the expert table. " ,
& ncp_echo_file ) ;
2004-02-18 06:01:47 +00:00
register_init_routine ( & mncp_init_protocol ) ;
2005-10-19 14:28:26 +00:00
ncp_tap . stat = register_tap ( " ncp_srt " ) ;
ncp_tap . hdr = register_tap ( " ncp_hdr " ) ;
2004-02-18 06:01:47 +00:00
register_postseq_cleanup_routine ( & mncp_postseq_cleanup ) ;
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 ;
2002-05-25 01:05:56 +00:00
dissector_handle_t ncp_tcp_handle ;
2001-12-03 04:00:26 +00:00
ncp_handle = create_dissector_handle ( dissect_ncp , proto_ncp ) ;
2002-05-25 01:05:56 +00:00
ncp_tcp_handle = create_dissector_handle ( dissect_ncp_tcp , proto_ncp ) ;
dissector_add ( " tcp.port " , TCP_PORT_NCP , ncp_tcp_handle ) ;
2001-12-03 04:00:26 +00:00
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 ) ;
2002-05-15 21:17:21 +00:00
data_handle = find_dissector ( " data " ) ;
2000-04-08 07:07:42 +00:00
}