Add the re-write of the NetWare Core Protocol dissector. It's mostly

a framework for the dissector; of the more than 400 NCP packet types, only
a handful are defined. But this dissector framework is much better than
the previous one.

svn path=/trunk/; revision=2173
This commit is contained in:
Gilbert Ramirez 2000-07-28 20:03:59 +00:00
parent 551a4d58fd
commit 8ceb7d40f9
13 changed files with 2069 additions and 833 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.216 2000/07/28 16:30:15 gram Exp $
# $Id: Makefile.am,v 1.217 2000/07/28 20:03:39 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -96,6 +96,7 @@ DISSECTOR_SOURCES = \
packet-nbipx.c \
packet-nbns.c \
packet-ncp.c \
packet-ncp2222.c \
packet-netbios.c \
packet-nfs.c \
packet-nlm.c \
@ -200,6 +201,7 @@ noinst_HEADERS = \
packet-llc.h \
packet-mount.h \
packet-nbipx.h \
packet-ncp-int.h \
packet-netbios.h \
packet-nfs.h \
packet-nlm.h \
@ -270,6 +272,7 @@ ETHEREAL_COMMON_SOURCES = \
ipv4.c \
ipv4.h \
llcsaps.h \
ncp2222.h \
nlpid.h \
oui.h \
packet.c \
@ -286,6 +289,8 @@ ETHEREAL_COMMON_SOURCES = \
proto.h \
ps.c \
ps.h \
ptvcursor.c \
ptvcursor.h \
register.c \
register.h \
resolv.c \
@ -506,6 +511,7 @@ EXTRA_DIST = \
Makefile.nmake \
make-reg-dotc \
manuf \
ncp2222.py \
print.ps \
README.aix \
README.bsd \
@ -564,6 +570,9 @@ editcap.1: doc/editcap.pod
dfilter-scanner.c : dfilter-scanner.l
$(LEX) -Pdfilter_ -odfilter-scanner.c $(srcdir)/dfilter-scanner.l
packet-ncp2222.c : ncp2222.py
$(PYTHON) $(srcdir)/ncp2222.py > $@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: nmake -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.47 2000/07/27 11:00:48 girlich Exp $
# $Id: Makefile.nmake,v 1.48 2000/07/28 20:03:40 gram Exp $
include config.nmake
@ -81,6 +81,7 @@ DISSECTOR_SOURCES = \
packet-nbipx.c \
packet-nbns.c \
packet-ncp.c \
packet-ncp2222.c \
packet-netbios.c \
packet-nfs.c \
packet-nlm.c \
@ -241,6 +242,9 @@ config.h : config.h.win32
ps.c : rdps.exe print.ps
rdps print.ps ps.c
packet-ncp2222.c : ncp2222.py
$(PYTHON) ncp2222.py > packet-ncp2222.c
dfilter-scanner.obj : dfilter-scanner.c dfilter-grammar.h
dfilter-scanner.c : dfilter-scanner.l

18
README
View File

@ -1,4 +1,4 @@
$Id: README,v 1.38 2000/06/08 03:09:26 gram Exp $
$Id: README,v 1.39 2000/07/28 20:03:40 gram Exp $
General Information
------- -----------
@ -29,7 +29,7 @@ Installation
Ethereal is known to compile and run on the following systems:
- Linux (2.0.x, 2.1.x, 2.2.x, 2.3.x)
- Linux (2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x)
- Solaris (2.5.1, 2.6, 7)
- FreeBSD (2.2.5, 2.2.6, 3.1, 3.2, 3.3)
- Sequent PTX v4.4.5 (Nick Williams <njw@sequent.com>)
@ -49,6 +49,10 @@ you need "flex" - it cannot be built with vanilla "lex" -
and either "bison" or the Berkeley "yacc". Your flex
version must be 2.5.1 or greater. Check this with 'flex -V'.
If you decide to modify the NetWare Core Protocol dissector, you
will need python, as the data for packet types is stored in a python
script, ncp2222.py.
You must therefore install Perl, GNU "make", "flex", and either "bison" or
Berkeley "yacc" on systems that lack them.
@ -158,6 +162,15 @@ The "Follow TCP Stream" feature only supports TCP over IPv4. Support for TCP
over IPv6 is planned.
NetWare Core Protocol
---------------------
There are over 400 different NCP packet types. The NCP dissector does
not understand all of these; support is being added little by little. If
you have some NCP packets that are not dissected by Ethereal, send
a trace file to ethereal-dev@zing.org and if possible, we will add support
for those packets types.
SNMP
----
Ethereal can do some basic decoding of SNMP packets; it can also use an
@ -214,3 +227,4 @@ Use at your own risk.
Gerald Combs <gerald@zing.org>
Gilbert Ramirez <gram@xiexie.org>
Guy Harris <guy@alum.mit.edu>

View File

@ -11,6 +11,8 @@ LOCAL_CFLAGS=-Zi
LOCAL_LDFLAGS=/DEBUG
PATH=t:\w32-ix86\cygnus\cygwin-b20\H-i586-cygwin32\bin;$(PATH)
PERL=perl
PYTHON=python
LEX=flex
YACC=bison
YACC_OPTS=-S t:\w32-ix86\cygnus\cygwin-b20\share\bison.simple

View File

@ -1,4 +1,4 @@
# $Id: configure.in,v 1.98 2000/07/28 16:30:17 gram Exp $
# $Id: configure.in,v 1.99 2000/07/28 20:03:41 gram Exp $
dnl
dnl Process this file with autoconf 2.13 or later to produce a
dnl configure script; 2.12 doesn't generate a "configure" script that
@ -26,11 +26,13 @@ AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_YACC
AM_PROG_LEX
AC_PATH_PROG(PERL_PATH, perl)
AC_PATH_PROG(PERL, perl)
AC_PATH_PROG(LEX, flex)
AC_PATH_PROG(PYTHON, python)
AC_SUBST(PERL_PATH)
AC_SUBST(FLEX_PATH)
AC_SUBST(PERL)
AC_SUBST(LEX)
AC_SUBST(PYTHON)
# Check for packaging utilities

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal documentation
#
# $Id: Makefile.am,v 1.7 2000/07/28 16:30:28 gram Exp $
# $Id: Makefile.am,v 1.8 2000/07/28 20:03:59 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -22,8 +22,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
PERL=@PERL_PATH@
../ethereal.1: ethereal.pod
pod2man ethereal.pod \
--center="The Ethereal Network Analyzer" \

261
ncp2222.h Normal file
View File

@ -0,0 +1,261 @@
/* ncp2222.h
* Routines for NetWare Core Protocol
* Gilbert Ramirez <gram@xiexie.org>
*
* $Id: ncp2222.h,v 1.1 2000/07/28 20:03:41 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
* 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.
*/
/* Does NCP func require a subfunction code? */
static gboolean
ncp_requires_subfunc(guint8 func)
{
const guint8 *ncp_func_requirement = ncp_func_requires_subfunc;
while (*ncp_func_requirement != 0) {
if (*ncp_func_requirement == func) {
return TRUE;
}
ncp_func_requirement++;
}
return FALSE;
}
/* Return a ncp_record* based on func and possibly subfunc */
static const ncp_record *
ncp_record_find(guint8 func, guint8 subfunc)
{
const ncp_record *ncp_rec = ncp_packets;
while(ncp_rec->func != 0 || ncp_rec->subfunc != 0 ||
ncp_rec->name != NULL ) {
if (ncp_rec->func == func &&
ncp_rec->subfunc == (subfunc & ncp_rec->submask)) {
return ncp_rec;
}
ncp_rec++;
}
return NULL;
}
/* Run through the table of ptv_record's and add info to the tree */
static void
process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec)
{
while(rec->hf_ptr != NULL) {
ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
rec->endianness);
rec++;
}
}
/* Given an error_equivalency table and a completion code, return
* the string representing the error. */
static const char*
ncp_error_string(const error_equivalency *errors, guint8 completion_code)
{
while (errors->ncp_error_index != -1) {
if (errors->error_in_packet == completion_code) {
return ncp_errors[errors->ncp_error_index];
}
errors++;
}
return "Unknown";
}
void
dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
guint16 nw_connection, guint8 sequence,
guint16 type, proto_tree *ncp_tree, proto_tree *tree)
{
guint8 func, subfunc = 0;
gboolean requires_subfunc;
const ncp_record *ncp_rec;
conversation_t *conversation;
ptvcursor_t *ptvc = NULL;
func = tvb_get_guint8(tvb, 6);
requires_subfunc = ncp_requires_subfunc(func);
if (requires_subfunc) {
subfunc = tvb_get_guint8(tvb, 9);
}
ncp_rec = ncp_record_find(func, subfunc);
if (check_col(pinfo->fd, COL_INFO)) {
if (ncp_rec) {
col_add_fstr(pinfo->fd, COL_INFO, "C %s", ncp_rec->name);
}
else {
if (requires_subfunc) {
col_add_fstr(pinfo->fd, COL_INFO,
"C Unknown Function 0x%02X/0x%02x",
func, subfunc);
}
else {
col_add_fstr(pinfo->fd, COL_INFO,
"C Unknown Function 0x%02x",
func);
}
}
}
if (!pinfo->fd->flags.visited) {
/* This is the first time we've looked at this packet.
Keep track of the address and connection whence the request
came, and the address and connection to which the request
is being sent, so that we can match up calls with replies.
(We don't include the sequence number, as we may want
to have all packets over the same connection treated
as being part of a single conversation so that we can
let the user select that conversation to be displayed.) */
conversation = find_conversation(&pi.src, &pi.dst,
PT_NCP, nw_connection, nw_connection);
if (conversation == NULL) {
/* It's not part of any conversation - create a new one. */
conversation = conversation_new(&pi.src, &pi.dst,
PT_NCP, nw_connection, nw_connection, NULL);
}
ncp_hash_insert(conversation, sequence, 0x2222, ncp_rec);
}
if (ncp_tree) {
proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 1,
func, "Function Code: 0x%02X (%s)",
func, ncp_rec ? ncp_rec->name : "Unknown");
if (requires_subfunc) {
proto_tree_add_item(ncp_tree, hf_ncp_length, tvb, 7,
2, FALSE);
proto_tree_add_item(ncp_tree, hf_ncp_subfunc, tvb, 9,
1, FALSE);
ptvc = ptvcursor_new(ncp_tree, tvb, 10);
}
else {
ptvc = ptvcursor_new(ncp_tree, tvb, 7);
}
/* The group is not part of the packet, but it's useful
* information to display anyway. */
if (ncp_rec) {
proto_tree_add_text(ncp_tree, tvb, 6, 1, "Group: %s",
ncp_groups[ncp_rec->group]);
}
if (ncp_rec && ncp_rec->request_ptvc) {
process_ptvc_record(ptvc, ncp_rec->request_ptvc);
}
ptvcursor_free(ptvc);
}
}
void
dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
guint16 nw_connection, guint8 sequence,
proto_tree *ncp_tree, proto_tree *tree) {
conversation_t *conversation;
const ncp_record *ncp_rec = NULL;
guint16 ncp_type;
gboolean found_request = FALSE;
guint8 completion_code;
guint length;
ptvcursor_t *ptvc = NULL;
const char *error_string;
/* Find the conversation whence the request would have come. */
conversation = find_conversation(&pi.src, &pi.dst,
PT_NCP, nw_connection, nw_connection);
if (conversation != NULL) {
/* find the record telling us the request made that caused
this reply */
found_request = ncp_hash_lookup(conversation, sequence,
&ncp_type, &ncp_rec);
}
/* else... we haven't seen an NCP Request for that conversation and sequence. */
/* A completion code of 0 always means OK. Non-zero means failure,
* but each non-zero value has a different meaning. And the same value
* can have different meanings, depending on the ncp.func (and ncp.subfunc)
* value. */
completion_code = tvb_get_guint8(tvb, 6);
if (ncp_rec && ncp_rec->errors) {
error_string = ncp_error_string(ncp_rec->errors, completion_code);
}
else if (completion_code == 0) {
error_string = "OK";
}
else {
error_string = "Not OK";
}
if (check_col(pinfo->fd, COL_INFO)) {
col_add_fstr(pinfo->fd, COL_INFO, "R %s", error_string);
}
if (ncp_tree) {
/* Put the func (and maybe subfunc) from the request packet
* in the proto tree, but hidden. That way filters on ncp.func
* or ncp.subfunc will find both the requests and the replies.
*/
if (ncp_rec) {
proto_tree_add_uint_hidden(ncp_tree, hf_ncp_func, tvb,
6, 1, ncp_rec->func);
if (ncp_requires_subfunc(ncp_rec->func)) {
proto_tree_add_uint_hidden(ncp_tree, hf_ncp_subfunc,
tvb, 6, 1, ncp_rec->subfunc);
}
}
proto_tree_add_uint_format(ncp_tree, hf_ncp_completion_code, tvb, 6, 1,
completion_code, "Completion Code: 0x%02x (%s)",
completion_code, error_string);
proto_tree_add_item(ncp_tree, hf_ncp_connection_status, tvb, 7, 1, FALSE);
length = tvb_length(tvb);
if (!ncp_rec && length > 8) {
proto_tree_add_text(ncp_tree, tvb, 8, length - 8,
"No request record found. Parsing is impossible.");
}
else if (ncp_rec && ncp_rec->reply_ptvc) {
/* If a non-zero completion code was found, it is
* legal to not have any fields, even if the packet
* type is defined as having fields. */
if (completion_code != 0 && tvb_length(tvb) == 8) {
return;
}
if (ncp_requires_subfunc(ncp_rec->func)) {
ptvc = ptvcursor_new(ncp_tree, tvb, 9);
}
else {
ptvc = ptvcursor_new(ncp_tree, tvb, 8);
}
process_ptvc_record(ptvc, ncp_rec->reply_ptvc);
ptvcursor_free(ptvc);
}
}
}

1406
ncp2222.py Executable file

File diff suppressed because it is too large Load Diff

67
packet-ncp-int.h Normal file
View File

@ -0,0 +1,67 @@
/* packet-ncp-int.h
* Structures and functions for NetWare Core Protocol.
* Gilbert Ramirez <gram@xiexie.org>
*
* $Id: packet-ncp-int.h,v 1.1 2000/07/28 20:03:42 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
*
* 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.
*/
typedef struct {
int *hf_ptr;
gint length;
gboolean endianness;
} ptvc_record;
typedef struct {
guint8 error_in_packet;
gint ncp_error_index;
} error_equivalency;
typedef struct {
guint8 func;
guint8 subfunc;
guint8 submask;
gchar* name;
gint group;
const ptvc_record *request_ptvc;
void *requst_func;
const ptvc_record *reply_ptvc;
void *reply_func;
const error_equivalency *errors;
} ncp_record;
void dissect_ncp_request(tvbuff_t*, packet_info*, guint16,
guint8, guint16, proto_tree*, proto_tree*);
void dissect_ncp_reply(tvbuff_t *, packet_info*, guint16,
guint8, proto_tree*, proto_tree*);
void ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
guint16 ncp_type, const ncp_record *ncp_rec);
/* Returns TRUE or FALSE. If TRUE, the record was found and
* ncp_type and ncp_rec are set. */
gboolean ncp_hash_lookup(conversation_t*, guint8 nw_sequence,
guint16 *ncp_type, const ncp_record **ncp_rec);
extern int proto_ncp;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
* $Id: proto.c,v 1.71 2000/07/27 06:41:58 gram Exp $
* $Id: proto.c,v 1.72 2000/07/28 20:03:43 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -2359,6 +2359,9 @@ proto_registrar_dump(void)
case FT_RELATIVE_TIME:
enum_name = "FT_RELATIVE_TIME";
break;
case FT_NSTRING_UINT8:
enum_name = "FT_NSTRING_UINT8";
break;
case FT_STRING:
enum_name = "FT_STRING";
break;
@ -2381,8 +2384,7 @@ proto_registrar_dump(void)
enum_name = "FT_TEXT_ONLY";
break;
default:
enum_name = "UNKNOWN";
break;
g_assert_not_reached();
}
printf("F\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
enum_name,parent_hfinfo->abbrev);

78
ptvcursor.c Normal file
View File

@ -0,0 +1,78 @@
/* ptvcursor.c
*
* Proto Tree TVBuff cursor
* Gilbert Ramirez <gram@xiexie.org>
*
* $Id: ptvcursor.c,v 1.1 2000/07/28 20:03:43 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
* 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.
*/
#ifndef __PTVCURSOR_H__
#include "ptvcursor.h"
#endif
struct ptvcursor {
proto_tree *tree;
tvbuff_t *tvb;
gint offset;
};
/* Allocates an initializes a ptvcursor_t with 3 variables:
* proto_tree, tvbuff, and offset. */
ptvcursor_t*
ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
{
ptvcursor_t *ptvc;
ptvc = g_new(ptvcursor_t, 1);
ptvc->tree = tree;
ptvc->tvb = tvb;
ptvc->offset = offset;
return ptvc;
}
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* */
proto_item*
ptvcursor_add(ptvcursor_t *ptvc, int hf, gint length, gboolean endianness)
{
proto_item *item;
item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
length, endianness);
if (length == PTVC_VARIABLE_LENGTH) {
ptvc->offset += proto_item_get_len(item);
}
else {
ptvc->offset += length;
}
return item;
}
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
void
ptvcursor_free(ptvcursor_t *ptvc)
{
g_free(ptvc);
}

58
ptvcursor.h Normal file
View File

@ -0,0 +1,58 @@
/* ptvcursor.h
*
* Proto Tree TVBuff cursor
* Gilbert Ramirez <gram@xiexie.org>
*
* $Id: ptvcursor.h,v 1.1 2000/07/28 20:03:43 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
* 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
#include <glib.h>
#ifndef __PACKET_H__
#include "packet.h"
#endif
#ifndef __PTVCURSOR_H__
#define __PTVCURSOR_H__
typedef struct ptvcursor ptvcursor_t;
#define PTVC_VARIABLE_LENGTH -1
/* Allocates an initializes a ptvcursor_t with 3 variables:
* proto_tree, tvbuff, and offset. */
ptvcursor_t*
ptvcursor_new(proto_tree*, tvbuff_t*, gint);
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* */
proto_item*
ptvcursor_add(ptvcursor_t*, int hf, gint length, gboolean endianness);
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
void
ptvcursor_free(ptvcursor_t*);
#endif /* __PTVCURSOR_H__ */