Merge the work in Novell_NCP_branch into the mainline code.

A little work still needs to be done on the new NCP dissector -- make
some of the COL_INFO texts more useful, handle a Unicode issue, and
modify some of the cases that use "request conditions".
But the NCP dissector as it stands is very usable now.

Note: I didn't merge in the PROTO_LENGTH_UNTIL_END macro... I wanted
to think about the various possible macros and review an email conversation
I had with Guy on the subject.

svn path=/trunk/; revision=5432
This commit is contained in:
Gilbert Ramirez 2002-05-09 23:50:34 +00:00
parent 9625720a39
commit 41cc7f0707
20 changed files with 11830 additions and 889 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.427 2002/05/03 16:23:25 nneul Exp $
# $Id: Makefile.am,v 1.428 2002/05/09 23:50:24 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -961,7 +961,7 @@ text2pcap.1: doc/text2pcap.pod
$(MAKE) ../text2pcap.1 )
packet-ncp2222.c : ncp2222.py
$(PYTHON) $(srcdir)/ncp2222.py > $@
$(PYTHON) $(srcdir)/ncp2222.py -o $@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.183 2002/05/03 15:50:11 nneul Exp $
# $Id: Makefile.nmake,v 1.184 2002/05/09 23:50:24 gram Exp $
include config.nmake
include <win32.mak>
@ -413,7 +413,7 @@ x11-declarations.h x11-register-info.h: x11-fields process-x11-fields.pl
packet-ncp2222.c : ncp2222.py
!IFDEF PYTHON
@echo Making packet-ncp2222.c
$(PYTHON) ncp2222.py > packet-ncp2222.c
$(PYTHON) ncp2222.py -o packet-ncp2222.c
!ELSE
@echo Faking packet-ncp2222.c...
@echo Python is required to build the NCP disector

View File

@ -1,5 +1,5 @@
/*
* $Id: dfilter.c,v 1.9 2002/04/29 07:55:32 guy Exp $
* $Id: dfilter.c,v 1.10 2002/05/09 23:50:30 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -284,26 +284,25 @@ FAILURE:
gboolean
dfilter_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
dfilter_apply(dfilter_t *df, proto_tree *tree)
{
return dfvm_apply(df, tvb, tree);
return dfvm_apply(df, tree);
}
gboolean
dfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt)
{
return dfvm_apply(df, edt->tvb, edt->tree);
return dfvm_apply(df, edt->tree);
}
void
dfilter_foreach_interesting_field(dfilter_t *df, GFunc func,
gpointer user_data)
dfilter_prime_proto_tree(dfilter_t *df, proto_tree *tree)
{
int i;
for (i = 0; i < df->num_interesting_fields; i++) {
func(GINT_TO_POINTER(df->interesting_fields[i]), user_data);
proto_tree_prime_hfid(tree, df->interesting_fields[i]);
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: dfilter.h,v 1.4 2002/01/21 07:37:37 guy Exp $
* $Id: dfilter.h,v 1.5 2002/05/09 23:50:30 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -74,12 +74,11 @@ dfilter_apply_edt(dfilter_t *df, epan_dissect_t* edt);
/* Apply compiled dfilter */
gboolean
dfilter_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree);
dfilter_apply(dfilter_t *df, proto_tree *tree);
/* Run a callback for each interesting field in the dfilter. */
/* Prime a proto_tree using the fields/protocols used in a dfilter. */
void
dfilter_foreach_interesting_field(dfilter_t *df, GFunc func,
gpointer user_data);
dfilter_prime_proto_tree(dfilter_t *df, proto_tree *tree);
/* Print bytecode of dfilter to stdout */
void

View File

@ -1,5 +1,5 @@
/*
* $Id: dfvm.c,v 1.6 2002/04/08 20:11:31 gram Exp $
* $Id: dfvm.c,v 1.7 2002/05/09 23:50:30 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -300,7 +300,7 @@ mk_range(dfilter_t *df, int from_reg, int to_reg, drange *drange)
gboolean
dfvm_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
dfvm_apply(dfilter_t *df, proto_tree *tree)
{
int i, id, length;
gboolean accum = TRUE;
@ -309,7 +309,6 @@ dfvm_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
dfvm_value_t *arg2;
dfvm_value_t *arg3;
g_assert(tvb);
g_assert(tree);

View File

@ -1,5 +1,5 @@
/*
* $Id: dfvm.h,v 1.5 2002/04/08 20:11:31 gram Exp $
* $Id: dfvm.h,v 1.6 2002/05/09 23:50:30 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -93,7 +93,7 @@ void
dfvm_dump(FILE *f, GPtrArray *insns);
gboolean
dfvm_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree);
dfvm_apply(dfilter_t *df, proto_tree *tree);
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: semcheck.c,v 1.10 2002/03/02 20:48:11 guy Exp $
* $Id: semcheck.c,v 1.11 2002/05/09 23:50:30 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -59,7 +59,8 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
case FT_ETHER:
case FT_BYTES:
return (b == FT_ETHER || b == FT_BYTES);
case FT_UINT_BYTES:
return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES);
case FT_BOOLEAN:
case FT_UINT8:
@ -140,6 +141,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
case FT_IPXNET:
case FT_ETHER:
case FT_BYTES:
case FT_UINT_BYTES:
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@ -212,6 +214,7 @@ is_bytes_type(enum ftenum type)
switch(type) {
case FT_ETHER:
case FT_BYTES:
case FT_UINT_BYTES:
case FT_IPv6:
return TRUE;

View File

@ -1,6 +1,6 @@
/* epan.h
*
* $Id: epan.c,v 1.17 2002/02/18 01:08:41 guy Exp $
* $Id: epan.c,v 1.18 2002/05/09 23:50:28 gram Exp $
*
* Ethereal Protocol Analyzer Library
*
@ -50,6 +50,7 @@ epan_init(const char *plugin_dir, void (register_all_protocols)(void),
proto_init(plugin_dir,register_all_protocols,register_all_handoffs);
packet_init();
dfilter_init();
final_registration_all_protocols();
}
void
@ -116,19 +117,10 @@ epan_dissect_free(epan_dissect_t* edt)
g_free(edt);
}
static void
prime_dfilter(gpointer data, gpointer user_data)
{
int hfid = GPOINTER_TO_INT(data);
proto_tree *tree = user_data;
proto_tree_prime_hfid(tree, hfid);
}
void
epan_dissect_prime_dfilter(epan_dissect_t *edt, dfilter_t* dfcode)
{
dfilter_foreach_interesting_field(dfcode, prime_dfilter, edt->tree);
dfilter_prime_proto_tree(dfcode, edt->tree);
}
void

View File

@ -1,5 +1,5 @@
/*
* $Id: ftype-bytes.c,v 1.10 2002/02/05 22:50:17 guy Exp $
* $Id: ftype-bytes.c,v 1.11 2002/05/09 23:50:32 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -551,19 +551,46 @@ ftype_register_bytes(void)
{
static ftype_t bytes_type = {
"FT_BYTES",
"sequence of bytes",
0,
bytes_fvalue_new,
bytes_fvalue_free,
val_from_string,
"FT_BYTES", /* name */
"sequence of bytes", /* pretty_name */
0, /* wire_size */
bytes_fvalue_new, /* new_value */
bytes_fvalue_free, /* free_value */
val_from_string, /* val_from_string */
bytes_fvalue_set,
NULL,
bytes_fvalue_set, /* set_value */
NULL, /* set_value_integer */
NULL, /* set_value_floating */
value_get, /* get_value */
NULL, /* get_value_integer */
NULL,
value_get,
NULL,
cmp_eq,
cmp_ne,
cmp_gt,
cmp_ge,
cmp_lt,
cmp_le,
len,
slice,
};
static ftype_t uint_bytes_type = {
"FT_UINT_BYTES", /* name */
"sequence of bytes", /* pretty_name */
0, /* wire_size */
bytes_fvalue_new, /* new_value */
bytes_fvalue_free, /* free_value */
val_from_string, /* val_from_string */
bytes_fvalue_set, /* set_value */
NULL, /* set_value_integer */
NULL, /* set_value_floating */
value_get, /* get_value */
NULL, /* get_value_integer */
NULL,
cmp_eq,
@ -686,6 +713,7 @@ ftype_register_bytes(void)
};
ftype_register(FT_BYTES, &bytes_type);
ftype_register(FT_UINT_BYTES, &bytes_type);
ftype_register(FT_ETHER, &ether_type);
ftype_register(FT_IPv6, &ipv6_type);
ftype_register(FT_UINT64, &u64_type);

View File

@ -1,7 +1,7 @@
/* ftypes.h
* Definitions for field types
*
* $Id: ftypes.h,v 1.9 2002/02/15 09:01:21 gram Exp $
* $Id: ftypes.h,v 1.10 2002/05/09 23:50:32 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -53,6 +53,7 @@ enum ftenum {
/*FT_UCS2_LE, */ /* Unicode, 2 byte, Little Endian */
FT_ETHER,
FT_BYTES,
FT_UINT_BYTES,
FT_IPv4,
FT_IPv6,
FT_IPXNET,

View File

@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
* $Id: packet.c,v 1.68 2002/04/28 00:13:05 guy Exp $
* $Id: packet.c,v 1.69 2002/05/09 23:50:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -237,6 +237,39 @@ free_data_sources(frame_data *fd)
fd->data_src = NULL;
}
/* Allow dissectors to register a "final_registration" routine
* that is run like the proto_register_XXX() routine, but the end
* end of the epan_init() function; that is, *after* all other
* subsystems, liked dfilters, have finished initializing. This is
* useful for dissector registration routines which need to compile
* display filters. dfilters can't initialize itself until all protocols
* have registereed themselvs. */
static GSList *final_registration_routines;
void
register_final_registration_routine(void (*func)(void))
{
final_registration_routines = g_slist_append(final_registration_routines,
func);
}
/* Call all the registered "final_registration" routines. */
static void
call_final_registration_routine(gpointer routine, gpointer dummy)
{
void (*func)(void) = routine;
(*func)();
}
void
final_registration_all_protocols(void)
{
g_slist_foreach(final_registration_routines,
&call_final_registration_routine, NULL);
}
/* Creates the top-most tvbuff and calls dissect_frame() */
void
dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header,

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.55 2002/04/28 00:13:05 guy Exp $
* $Id: packet.h,v 1.56 2002/05/09 23:50:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -248,6 +248,20 @@ extern void register_postseq_cleanup_routine(void (*func)(void));
/* Call all the registered "postseq_cleanup" routines. */
extern void postseq_cleanup_all_protocols(void);
/* Allow dissectors to register a "final_registration" routine
* that is run like the proto_register_XXX() routine, but the end
* end of the epan_init() function; that is, *after* all other
* subsystems, liked dfilters, have finished initializing. This is
* useful for dissector registration routines which need to compile
* display filters. dfilters can't initialize itself until all protocols
* have registereed themselvs. */
void
register_final_registration_routine(void (*func)(void));
/* Call all the registered "final_registration" routines. */
void
final_registration_all_protocols(void);
/*
* Add a new data source to the list of data sources for a frame, given
* the tvbuff for the data source and its name.

View File

@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
* $Id: proto.c,v 1.67 2002/04/29 07:55:31 guy Exp $
* $Id: proto.c,v 1.68 2002/05/09 23:50:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -633,6 +633,15 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
break;
case FT_UINT_BYTES:
n = get_uint_value(tvb, start, length, little_endian);
proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
/* Instead of calling proto_item_set_len(), since we don't yet
* have a proto_item, we set the field_info's length ourselves. */
new_fi->length = n + length;
break;
case FT_BOOLEAN:
proto_tree_set_boolean(new_fi,
get_uint_value(tvb, start, length, little_endian));
@ -690,19 +699,30 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
break;
case FT_STRINGZ:
/* In this case, length signifies maximum length. */
if (length == -1) {
/* This can throw an exception */
length = tvb_strsize(tvb, start);
/* This g_strdup'ed memory is freed in proto_tree_free_node() */
string = g_malloc(length);
/* This g_strdup'ed memory is freed in proto_tree_free_node() */
string = g_malloc(length);
CLEANUP_PUSH(g_free, string);
tvb_memcpy(tvb, string, start, length);
new_fi->length = length;
}
else {
/* In this case, length signifies maximum length. */
found_length = tvb_get_nstringz0(tvb, start, length, string);
/* This g_strdup'ed memory is freed in proto_tree_free_node() */
string = g_malloc(length);
CLEANUP_POP;
CLEANUP_PUSH(g_free, string);
found_length = tvb_get_nstringz0(tvb, start, length, string);
CLEANUP_POP;
new_fi->length = found_length + 1;
}
proto_tree_set_string(new_fi, string, TRUE);
new_fi->length = found_length + 1;
break;
@ -1749,7 +1769,8 @@ alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
g_assert(hfinfo->type == FT_PROTOCOL ||
hfinfo->type == FT_NONE ||
hfinfo->type == FT_BYTES ||
hfinfo->type == FT_STRING);
hfinfo->type == FT_STRING ||
hfinfo->type == FT_STRINGZ);
*length = tvb_ensure_length_remaining(tvb, start);
}
@ -1885,13 +1906,17 @@ proto_tree_create_root(void)
return (proto_tree*) g_node_new(pnode);
}
/* "prime" a proto_tree with a single hfid that a dfilter
* is interested in. */
void
proto_tree_prime_hfid(proto_tree *tree, int hfid)
proto_tree_prime_hfid(proto_tree *tree, gint hfid)
{
g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
GINT_TO_POINTER(hfid), g_ptr_array_new());
GINT_TO_POINTER(hfid), g_ptr_array_new());
}
proto_tree*
proto_item_add_subtree(proto_item *pi, gint idx) {
field_info *fi;
@ -2214,11 +2239,12 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
break;
case FT_BYTES:
case FT_UINT_BYTES:
bytes = fvalue_get(fi->value);
if (bytes) {
snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
bytes_to_str(bytes, fi->length));
bytes_to_str(bytes, fvalue_length(fi->value)));
}
else {
snprintf(label_str, ITEM_LABEL_LENGTH,
@ -3093,7 +3119,10 @@ proto_can_match_selected(field_info *finfo)
case FT_ABSOLUTE_TIME:
case FT_RELATIVE_TIME:
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_BYTES:
case FT_UINT_BYTES:
/*
* These all have values, so we can match.
*/
@ -3218,11 +3247,6 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd)
hfinfo->abbrev, value_str);
break;
#if 0
case FT_TEXT_ONLY:
; /* nothing */
break;
#endif
case FT_STRING:
value_str = fvalue_get(finfo->value);
@ -3233,12 +3257,15 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd)
break;
case FT_BYTES:
dfilter_len = finfo->length*3 - 1;
case FT_UINT_BYTES:
dfilter_len = fvalue_length(finfo->value)*3 - 1;
dfilter_len += abbrev_len + 7;
buf = g_malloc0(dfilter_len);
snprintf(buf, dfilter_len, "%s == %s",
hfinfo->abbrev,
bytes_to_str_punct(fvalue_get(finfo->value), finfo->length,':'));
/* XXX - bytes_to_str_punct() will truncate long strings with '...' */
bytes_to_str_punct(fvalue_get(finfo->value),
fvalue_length(finfo->value),':'));
break;
default:

11377
ncp2222.py

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* Structures and functions for NetWare Core Protocol.
* Gilbert Ramirez <gram@alumni.rice.edu>
*
* $Id: packet-ncp-int.h,v 1.6 2002/01/10 04:44:34 gram Exp $
* $Id: packet-ncp-int.h,v 1.7 2002/05/09 23:50:25 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -33,15 +33,35 @@ typedef struct _sub_ptvc_record sub_ptvc_record;
struct _ptvc_record {
int *hf_ptr;
gint length;
gboolean endianness;
const sub_ptvc_record *sub_ptvc_rec;
unsigned int endianness : 1; /* 0=BE, 1=LE */
unsigned int var_index : 2;
unsigned int repeat_index : 2;
unsigned int req_cond_index : 6;
unsigned int special_fmt : 2;
};
#define NCP_FMT_NONE 0
#define NCP_FMT_NW_DATE 1
#define NCP_FMT_NW_TIME 2
struct _sub_ptvc_record {
gint *ett;
const char *descr;
const ptvc_record *ptvc_rec;
};
typedef struct {
const char *dfilter_text;
dfilter_t *dfilter;
} conditional_record;
typedef struct {
int *hf_ptr;
const char *first_string;
const char *repeat_string;
} info_string_t;
typedef struct {
guint8 error_in_packet;
gint ncp_error_index;
@ -54,25 +74,21 @@ typedef struct {
gchar* name;
gint group;
const ptvc_record *request_ptvc;
void *requst_func;
const ptvc_record *reply_ptvc;
void *reply_func;
const error_equivalency *errors;
const int *req_cond_indexes;
unsigned int req_cond_size_type;
const info_string_t *req_info_str;
} ncp_record;
void dissect_ncp_request(tvbuff_t*, packet_info*, guint16,
guint8, guint16, proto_tree*, proto_tree*);
guint8, guint16, 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,
const ncp_record *ncp_rec);
const ncp_record* ncp_hash_lookup(conversation_t*, guint8 nw_sequence);
guint8, proto_tree*);
extern int proto_ncp;
extern gint ett_ncp;
#endif

View File

@ -3,7 +3,7 @@
* Gilbert Ramirez <gram@alumni.rice.edu>
* Modified to allow NCP over TCP/IP decodes by James Coe <jammer@cin.net>
*
* $Id: packet-ncp.c,v 1.55 2002/01/24 09:20:49 guy Exp $
* $Id: packet-ncp.c,v 1.56 2002/05/09 23:50:25 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -53,7 +53,7 @@ static int hf_ncp_seq = -1;
static int hf_ncp_connection = -1;
static int hf_ncp_task = -1;
static gint ett_ncp = -1;
gint ett_ncp = -1;
#define TCP_PORT_NCP 524
#define UDP_PORT_NCP 524
@ -65,8 +65,6 @@ static gint ett_ncp = -1;
gint ncp_equal (gconstpointer v, gconstpointer v2);
guint ncp_hash (gconstpointer v);
static guint ncp_packet_init_count = 200;
/* These are the header structures to handle NCP over IP */
#define NCPIP_RQST 0x446d6454 /* "DmdT" */
#define NCPIP_RPLY 0x744e6350 /* "tNcP" */
@ -127,113 +125,6 @@ static value_string ncp_type_vals[] = {
};
/* NCP packets come in request/reply pairs. The request packets tell the type
* of NCP request and give a sequence ID. The response, unfortunately, only
* identifies itself via the sequence ID; you have to know what type of NCP
* request the request packet contained in order to successfully parse the NCP
* response. A global method for doing this does not exist in ethereal yet
* (NFS also requires it), so for now the NCP section will keep its own hash
* table keeping track of NCP packet types.
*
* We construct a conversation specified by the client and server
* addresses and the connection number; the key representing the unique
* NCP request then is composed of the pointer to the conversation
* structure, cast to a "guint" (which may throw away the upper 32
* bits of the pointer on a P64 platform, but the low-order 32 bits
* are more likely to differ between conversations than the upper 32 bits),
* and the sequence number.
*
* The value stored in the hash table is the ncp_request_val pointer. This
* struct tells us the NCP type and gives the ncp2222_record pointer, if
* ncp_type == 0x2222.
*/
typedef struct {
conversation_t *conversation;
guint8 nw_sequence;
} ncp_request_key;
static GHashTable *ncp_request_hash = NULL;
static GMemChunk *ncp_request_keys = NULL;
/* Hash Functions */
gint ncp_equal (gconstpointer v, gconstpointer v2)
{
ncp_request_key *val1 = (ncp_request_key*)v;
ncp_request_key *val2 = (ncp_request_key*)v2;
if (val1->conversation == val2->conversation &&
val1->nw_sequence == val2->nw_sequence ) {
return 1;
}
return 0;
}
guint ncp_hash (gconstpointer v)
{
ncp_request_key *ncp_key = (ncp_request_key*)v;
return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence;
}
/* Initializes the hash table and the mem_chunk area each time a new
* file is loaded or re-loaded in ethereal */
static void
ncp_init_protocol(void)
{
if (ncp_request_hash)
g_hash_table_destroy(ncp_request_hash);
if (ncp_request_keys)
g_mem_chunk_destroy(ncp_request_keys);
ncp_request_hash = g_hash_table_new(ncp_hash, ncp_equal);
ncp_request_keys = g_mem_chunk_new("ncp_request_keys",
sizeof(ncp_request_key),
ncp_packet_init_count * sizeof(ncp_request_key), G_ALLOC_AND_FREE);
}
/* 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
ncp_postseq_cleanup(void)
{
if (ncp_request_hash) {
g_hash_table_destroy(ncp_request_hash);
ncp_request_hash = NULL;
}
if (ncp_request_keys) {
g_mem_chunk_destroy(ncp_request_keys);
ncp_request_keys = NULL;
}
}
void
ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
const ncp_record *ncp_rec)
{
ncp_request_key *request_key;
/* Now remember the request, so we can find it if we later
a reply to it. */
request_key = g_mem_chunk_alloc(ncp_request_keys);
request_key->conversation = conversation;
request_key->nw_sequence = nw_sequence;
g_hash_table_insert(ncp_request_hash, request_key, (void*)ncp_rec);
}
/* Returns the ncp_rec*, or NULL if not found. */
const ncp_record*
ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence)
{
ncp_request_key request_key;
request_key.conversation = conversation;
request_key.nw_sequence = nw_sequence;
return g_hash_table_lookup(ncp_request_hash, &request_key);
}
static void
dissect_ncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@ -296,12 +187,12 @@ dissect_ncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (header.type == 0x1111 || header.type == 0x2222) {
next_tvb = tvb_new_subset( tvb, hdr_offset, -1, -1 );
dissect_ncp_request(next_tvb, pinfo, nw_connection,
header.sequence, header.type, ncp_tree, tree);
header.sequence, header.type, ncp_tree);
}
else if (header.type == 0x3333) {
next_tvb = tvb_new_subset( tvb, hdr_offset, -1, -1 );
dissect_ncp_reply(next_tvb, pinfo, nw_connection,
header.sequence, ncp_tree, tree);
header.sequence, ncp_tree);
}
else if ( header.type == 0x5555 ||
header.type == 0x7777 ||
@ -367,20 +258,10 @@ proto_register_ncp(void)
static gint *ett[] = {
&ett_ncp,
};
module_t *ncp_module;
proto_ncp = proto_register_protocol("NetWare Core Protocol", "NCP", "ncp");
proto_register_field_array(proto_ncp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_init_routine(&ncp_init_protocol);
register_postseq_cleanup_routine(&ncp_postseq_cleanup);
/* Register a configuration option for initial size of NCP hash */
ncp_module = prefs_register_protocol(proto_ncp, NULL);
prefs_register_uint_preference(ncp_module, "initial_hash_size",
"Initial Hash Size",
"Number of entries initially allocated for NCP hash",
10, &ncp_packet_init_count);
}
void

View File

@ -7,7 +7,7 @@
*
* Gilbert Ramirez <gram@alumni.rice.edu>
*
* $Id: packet-ncp2222.inc,v 1.9 2002/04/04 03:51:39 gram Exp $
* $Id: packet-ncp2222.inc,v 1.10 2002/05/09 23:50:25 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -28,6 +28,158 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define NCP_PACKET_INIT_COUNT 200
#define PROTO_LENGTH_UNTIL_END -1
static void
process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
int *req_cond_results, gboolean really_decode,
const ncp_record *ncp_rec);
/* NCP packets come in request/reply pairs. The request packets tell the type
* of NCP request and give a sequence ID. The response, unfortunately, only
* identifies itself via the sequence ID; you have to know what type of NCP
* request the request packet contained in order to successfully parse the NCP
* response. A global method for doing this does not exist in ethereal yet
* (NFS also requires it), so for now the NCP section will keep its own hash
* table keeping track of NCP packet types.
*
* We construct a conversation specified by the client and server
* addresses and the connection number; the key representing the unique
* NCP request then is composed of the pointer to the conversation
* structure, cast to a "guint" (which may throw away the upper 32
* bits of the pointer on a P64 platform, but the low-order 32 bits
* are more likely to differ between conversations than the upper 32 bits),
* and the sequence number.
*
* The value stored in the hash table is the ncp_req_hash_value pointer. This
* struct tells us the NCP type and gives the ncp2222_record pointer, if
* ncp_type == 0x2222.
*/
typedef struct {
conversation_t *conversation;
guint8 nw_sequence;
} ncp_req_hash_key;
typedef struct {
const ncp_record *ncp_rec;
gboolean *req_cond_results;
} ncp_req_hash_value;
static GHashTable *ncp_req_hash = NULL;
static GMemChunk *ncp_req_hash_keys = NULL;
static GMemChunk *ncp_req_hash_values = NULL;
/* Hash Functions */
gint
ncp_equal(gconstpointer v, gconstpointer v2)
{
ncp_req_hash_key *val1 = (ncp_req_hash_key*)v;
ncp_req_hash_key *val2 = (ncp_req_hash_key*)v2;
if (val1->conversation == val2->conversation &&
val1->nw_sequence == val2->nw_sequence ) {
return 1;
}
return 0;
}
guint
ncp_hash(gconstpointer v)
{
ncp_req_hash_key *ncp_key = (ncp_req_hash_key*)v;
return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence;
}
/* Frees memory used by the ncp_req_hash_value's */
static void
ncp_req_hash_cleanup(gpointer key _U_, gpointer value, gpointer user_data _U_)
{
ncp_req_hash_value *request_value = (ncp_req_hash_value*) value;
if (request_value->req_cond_results) {
g_free(request_value->req_cond_results);
}
}
/* Initializes the hash table and the mem_chunk area each time a new
* file is loaded or re-loaded in ethereal */
static void
ncp_init_protocol(void)
{
if (ncp_req_hash) {
g_hash_table_foreach(ncp_req_hash, ncp_req_hash_cleanup, NULL);
g_hash_table_destroy(ncp_req_hash);
}
if (ncp_req_hash_keys)
g_mem_chunk_destroy(ncp_req_hash_keys);
if (ncp_req_hash_values)
g_mem_chunk_destroy(ncp_req_hash_values);
ncp_req_hash = g_hash_table_new(ncp_hash, ncp_equal);
ncp_req_hash_keys = g_mem_chunk_new("ncp_req_hash_keys",
sizeof(ncp_req_hash_key),
NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_key),
G_ALLOC_ONLY);
ncp_req_hash_values = g_mem_chunk_new("ncp_req_hash_values",
sizeof(ncp_req_hash_value),
NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_value),
G_ALLOC_ONLY);
}
/* 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
ncp_postseq_cleanup(void)
{
if (ncp_req_hash) {
/* Destroy the hash, but don't clean up request_condition data. */
g_hash_table_destroy(ncp_req_hash);
ncp_req_hash = NULL;
}
if (ncp_req_hash_keys) {
g_mem_chunk_destroy(ncp_req_hash_keys);
ncp_req_hash_keys = NULL;
}
/* Don't free the ncp_req_hash_values, as they're
* needed during random-access processing of the proto_tree.*/
}
ncp_req_hash_value*
ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
const ncp_record *ncp_rec)
{
ncp_req_hash_key *request_key;
ncp_req_hash_value *request_value;
/* Now remember the request, so we can find it if we later
a reply to it. */
request_key = g_mem_chunk_alloc(ncp_req_hash_keys);
request_key->conversation = conversation;
request_key->nw_sequence = nw_sequence;
request_value = g_mem_chunk_alloc(ncp_req_hash_values);
request_value->ncp_rec = ncp_rec;
request_value->req_cond_results = NULL;
g_hash_table_insert(ncp_req_hash, request_key, request_value);
return request_value;
}
/* Returns the ncp_rec*, or NULL if not found. */
ncp_req_hash_value*
ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence)
{
ncp_req_hash_key request_key;
request_key.conversation = conversation;
request_key.nw_sequence = nw_sequence;
return g_hash_table_lookup(ncp_req_hash, &request_key);
}
/* Does NCP func require a subfunction code? */
static gboolean
ncp_requires_subfunc(guint8 func)
@ -82,10 +234,110 @@ ncp_record_find(guint8 func, guint8 subfunc)
return NULL;
}
/* Given a proto_item*, assume it contains an integer value
* and return a guint from it. */
guint
get_item_value(proto_item *item)
{
return fvalue_get_integer(PITEM_FINFO(item)->value);
}
char*
get_item_name(proto_item *item)
{
return PITEM_FINFO(item)->hfinfo->name;
}
typedef proto_item* (*padd_func_t)(ptvcursor_t*, const ptvc_record*);
typedef struct {
guint year;
guint month;
guint day;
} nw_date_t;
typedef struct {
guint hour;
guint minute;
guint second;
} nw_time_t;
/* Given an integer, fill in a nw_date_t struct. */
static void
uint_to_nwdate(guint data, nw_date_t *nwdate)
{
nwdate->day = data & 0x001f;
nwdate->month = (data & 0x01e0) >> 5;
nwdate->year = ((data & 0xfe00) >> 9) + 1980;
}
/* Given an integer, fill in a nw_time_t struct. */
static void
uint_to_nwtime(guint data, nw_time_t *nwtime)
{
/* 2-second resolution */
nwtime->second = (data & 0x001f) * 2;
nwtime->minute = ((data & 0x07e0) >> 5) + 1;
nwtime->hour = ((data & 0xf800) >> 11) + 1;
}
static proto_item*
padd_normal(ptvcursor_t *ptvc, const ptvc_record *rec)
{
return ptvcursor_add(ptvc, *rec->hf_ptr,
rec->length, rec->endianness);
}
static proto_item*
padd_date(ptvcursor_t *ptvc, const ptvc_record *rec)
{
proto_item *item;
nw_date_t nw_date;
gint offset;
offset = ptvcursor_current_offset(ptvc);
item = ptvcursor_add(ptvc, *rec->hf_ptr,
rec->length, rec->endianness);
uint_to_nwdate(get_item_value(item), &nw_date);
proto_item_set_text(item, get_item_name(item));
proto_item_append_text(item, ": %04u/%02u/%02u",
nw_date.year, nw_date.month, nw_date.day);
return item;
}
static proto_item*
padd_time(ptvcursor_t *ptvc, const ptvc_record *rec)
{
proto_item *item;
nw_time_t nw_time;
gint offset;
offset = ptvcursor_current_offset(ptvc);
item = ptvcursor_add(ptvc, *rec->hf_ptr,
rec->length, rec->endianness);
uint_to_nwtime(get_item_value(item), &nw_time);
proto_item_set_text(item, get_item_name(item));
proto_item_append_text(item, ": %02u:%02u:%02u",
nw_time.hour, nw_time.minute, nw_time.second);
return item;
}
/* Add a value for a ptvc_record, and process the sub-ptvc_record
* that it points to. */
static void
process_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec)
process_bitfield_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
gboolean really_decode)
{
proto_item *item;
proto_tree *sub_tree;
@ -94,52 +346,222 @@ process_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec)
gint ett;
ptvcursor_t *sub_ptvc;
/* Save the current offset */
current_offset = ptvcursor_current_offset(ptvc);
if (really_decode) {
/* Save the current offset */
current_offset = ptvcursor_current_offset(ptvc);
/* Add the item */
item = ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
rec->endianness);
/* Add the item */
item = ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
rec->endianness);
ett = *rec->sub_ptvc_rec->ett;
ett = *rec->sub_ptvc_rec->ett;
/* Make a new protocol sub-tree */
sub_tree = proto_item_add_subtree(item, ett);
/* Make a new protocol sub-tree */
sub_tree = proto_item_add_subtree(item, ett);
/* Make a new ptvcursor */
sub_ptvc = ptvcursor_new(sub_tree, ptvcursor_tvbuff(ptvc),
current_offset);
/* Make a new ptvcursor */
sub_ptvc = ptvcursor_new(sub_tree, ptvcursor_tvbuff(ptvc),
current_offset);
/* Use it */
sub_rec = rec->sub_ptvc_rec->ptvc_rec;
while(sub_rec->hf_ptr != NULL) {
g_assert(!sub_rec->sub_ptvc_rec);
ptvcursor_add_no_advance(sub_ptvc, *sub_rec->hf_ptr,
sub_rec->length, sub_rec->endianness);
sub_rec++;
/* Use it */
sub_rec = rec->sub_ptvc_rec->ptvc_rec;
while(sub_rec->hf_ptr != NULL) {
g_assert(!sub_rec->sub_ptvc_rec);
ptvcursor_add_no_advance(sub_ptvc, *sub_rec->hf_ptr,
sub_rec->length, sub_rec->endianness);
sub_rec++;
}
/* Free it. */
ptvcursor_free(sub_ptvc);
}
else {
ptvcursor_advance(ptvc, rec->length);
}
/* Free it. */
ptvcursor_free(sub_ptvc);
}
/* Run through the table of ptvc_record's and add info to the tree */
/* Process a sub-ptvc_record that points to a "struct" ptvc_record. */
static void
process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec)
process_struct_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
int *req_cond_results, gboolean really_decode,
const ncp_record *ncp_rec)
{
while(rec->hf_ptr != NULL) {
if (rec->sub_ptvc_rec) {
process_sub_ptvc_record(ptvc, rec);
const ptvc_record *sub_rec;
gint ett;
proto_tree *old_tree=NULL, *new_tree;
proto_item *item=NULL;
gint offset=0;
/* Create a sub-proto_tree? */
if (rec->sub_ptvc_rec->descr) {
ett = *rec->sub_ptvc_rec->ett;
old_tree = ptvcursor_tree(ptvc);
offset = ptvcursor_current_offset(ptvc);
item = proto_tree_add_text(old_tree, ptvcursor_tvbuff(ptvc),
offset, PROTO_LENGTH_UNTIL_END,
rec->sub_ptvc_rec->descr);
new_tree = proto_item_add_subtree(item, ett);
ptvcursor_set_tree(ptvc, new_tree);
}
/* Get the ptvc_record for the struct and call our caller
* to process it. */
sub_rec = rec->sub_ptvc_rec->ptvc_rec;
process_ptvc_record(ptvc, sub_rec, req_cond_results, really_decode, ncp_rec);
/* Re-set the tree */
if (rec->sub_ptvc_rec->descr) {
proto_item_set_len(item, ptvcursor_current_offset(ptvc) - offset);
ptvcursor_set_tree(ptvc, old_tree);
}
}
/* Run through the table of ptvc_record's and add info to the tree. This
* is the work-horse of process_ptvc_record(). */
static void
_process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
int *req_cond_results, gboolean really_decode,
const ncp_record *ncp_rec)
{
proto_item *item;
guint i, repeat_count;
padd_func_t func = NULL;
if (rec->sub_ptvc_rec) {
/* Repeat this? */
if (rec->repeat_index == NO_REPEAT) {
if (rec->hf_ptr == PTVC_STRUCT) {
process_struct_sub_ptvc_record(ptvc, rec,
req_cond_results, really_decode,
ncp_rec);
}
else {
process_bitfield_sub_ptvc_record(ptvc, rec,
really_decode);
}
}
else {
ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
rec->endianness);
repeat_count = repeat_vars[rec->repeat_index];
for (i = 0; i < repeat_count; i++ ) {
if (rec->hf_ptr == PTVC_STRUCT) {
process_struct_sub_ptvc_record(ptvc, rec,
req_cond_results, really_decode,
ncp_rec);
}
else {
process_bitfield_sub_ptvc_record(ptvc, rec,
really_decode);
}
}
}
}
else {
/* If we can't repeat this field, we might use it
* to set a 'var'. */
if (rec->repeat_index == NO_REPEAT) {
if (really_decode) {
/* Handle any special formatting. */
switch(rec->special_fmt) {
case NCP_FMT_NONE:
func = padd_normal;
break;
case NCP_FMT_NW_DATE:
func = padd_date;
break;
case NCP_FMT_NW_TIME:
func = padd_time;
break;
default:
g_assert_not_reached();
}
item = func(ptvc, rec);
/* Set the value as a 'var' ? */
if (rec->var_index != NO_VAR) {
repeat_vars[rec->var_index] = get_item_value(item);
}
}
else {
/* If we don't decode the field, we
* better not use the value to set a var.
* Actually, we could, as long as we don't
* *use* that var; for now keep this assert in
* place. */
g_assert(rec->var_index == NO_VAR);
ptvcursor_advance(ptvc, rec->length);
}
}
else {
/* We do repeat this field. */
repeat_count = repeat_vars[rec->repeat_index];
if (really_decode) {
/* Handle any special formatting. */
switch(rec->special_fmt) {
case NCP_FMT_NONE:
func = padd_normal;
break;
case NCP_FMT_NW_DATE:
func = padd_date;
break;
case NCP_FMT_NW_TIME:
func = padd_time;
break;
default:
g_assert_not_reached();
}
for (i = 0; i < repeat_count; i++ ) {
func(ptvc, rec);
}
}
else {
for (i = 0; i < repeat_count; i++ ) {
ptvcursor_advance(ptvc, rec->length);
}
}
}
}
}
/* Run through the table of ptvc_record's and add info to the tree.
* Honor a request condition result. */
static void
process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
int *req_cond_results, gboolean really_decode,
const ncp_record *ncp_rec)
{
gboolean decode;
while(rec->hf_ptr != NULL) {
decode = really_decode;
/* If we're supposed to decode, check the request condition
* results to see if we should override this and *not* decode. */
if (decode && req_cond_results) {
if (rec->req_cond_index != NO_REQ_COND) {
if (req_cond_results[rec->req_cond_index] == FALSE) {
decode = FALSE;
}
}
}
if (decode || ncp_rec->req_cond_size_type == REQ_COND_SIZE_CONSTANT) {
_process_ptvc_record(ptvc, rec, req_cond_results, decode, ncp_rec);
}
rec++;
}
}
/* Clear the repeat_vars array. */
static void
clear_repeat_vars(void)
{
guint i;
for (i = 0 ; i < NUM_REPEAT_VARS; i++ ) {
repeat_vars[i] = 0;
}
}
/* Given an error_equivalency table and a completion code, return
* the string representing the error. */
static const char*
@ -157,21 +579,31 @@ ncp_error_string(const error_equivalency *errors, guint8 completion_code)
static const ncp_record ncp1111_request =
{ 0x01, 0x00, NO_SUBFUNC, "Create Connection Service", NCP_GROUP_CONNECTION,
NULL, NULL, NULL, NULL,
ncp_0x2_errors };
NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
/* Wrapper around proto_tree_free() */
void free_proto_tree(void *tree)
{
if (tree) {
proto_tree_free((proto_tree*) tree);
}
}
void
dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
guint16 nw_connection, guint8 sequence,
guint16 type, proto_tree *ncp_tree, proto_tree *tree)
guint16 type, proto_tree *ncp_tree)
{
guint8 func, subfunc = 0;
gboolean requires_subfunc;
gboolean has_length = TRUE;
ncp_req_hash_value *request_value = NULL;
const ncp_record *ncp_rec = NULL;
conversation_t *conversation;
ptvcursor_t *ptvc = NULL;
proto_tree *temp_tree = NULL;
gboolean run_req_cond = FALSE;
gboolean run_info_str = FALSE;
func = tvb_get_guint8(tvb, 6);
@ -206,12 +638,12 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
else {
if (requires_subfunc) {
col_add_fstr(pinfo->cinfo, COL_INFO,
"C Unknown Function 0x%02X/0x%02x (%d %d)",
"C Unknown Function %d %d (0x%02X/0x%02x)",
func, subfunc, func, subfunc);
}
else {
col_add_fstr(pinfo->cinfo, COL_INFO,
"C Unknown Function 0x%02x (%d)",
"C Unknown Function %d (0x%02x)",
func, func);
}
}
@ -234,10 +666,68 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
conversation = conversation_new(&pinfo->src, &pinfo->dst,
PT_NCP, nw_connection, nw_connection, 0);
}
ncp_hash_insert(conversation, sequence, ncp_rec);
request_value = ncp_hash_insert(conversation, sequence, ncp_rec);
/* If this is the first time we're examining the packet,
* check to see if this NCP type uses a "request condition".
* If so, we have to build a proto_tree because request conditions
* use display filters to work, and without a proto_tree,
* display filters can't possibly work. If we already have
* a proto_tree, then wonderful. If we don't, we need to build
* one. */
if (ncp_rec) {
if (ncp_rec->req_cond_indexes) {
run_req_cond = TRUE;
}
/* Only create info string if COL_INFO is available. */
if (ncp_rec->req_info_str && check_col(pinfo->cinfo, COL_INFO)) {
run_info_str = TRUE;
}
/* We also have to use a tree if we have to construct an info_str */
if ((run_info_str || run_req_cond) && !ncp_tree) {
proto_item *ti;
temp_tree = proto_tree_create_root();
proto_tree_set_visible(temp_tree, FALSE);
ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE);
ncp_tree = proto_item_add_subtree(ti, ett_ncp);
}
}
}
if (ncp_tree) {
/* If the dissection throws an exception, be sure to free
* the temporary proto_tree that was created. Because of the
* way the CLEANUP_PUSH macro works, we can't put it in an 'if'
* block; it has to be in the same scope as the terminating
* CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always
* call CLEANUP_POP and friends, but the value of temp_tree is
* NULL if no cleanup is needed, and non-null if cleanup is needed. */
CLEANUP_PUSH(free_proto_tree, temp_tree);
/* Before the dissection, if we're saving data for a request
* condition, we have to prime the proto tree using the
* dfilter information */
if (run_req_cond) {
const int *needed;
dfilter_t *dfilter;
needed = ncp_rec->req_cond_indexes;
while (*needed != -1) {
dfilter = req_conds[*needed].dfilter;
/* Prime the proto_tree with "interesting fields". */
dfilter_prime_proto_tree(dfilter, ncp_tree);
needed++;
}
}
/* Before the dissection, if we need a field for the info_str,
* prime the tree. */
if (run_info_str) {
proto_tree_prime_hfid(ncp_tree, *ncp_rec->req_info_str->hf_ptr);
}
conversation = find_conversation(&pinfo->src, &pinfo->dst,
PT_NCP, nw_connection, nw_connection, 0);
@ -248,8 +738,8 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
case 0x2222:
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");
func, "Function: %d (0x%02X), %s",
func, func, ncp_rec ? ncp_rec->name : "Unknown");
break;
default:
@ -260,14 +750,16 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
if (requires_subfunc) {
if (has_length) {
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);
2, FALSE);
proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 9, 1,
subfunc, "SubFunction: %d (0x%02x)",
subfunc, subfunc);
ptvc = ptvcursor_new(ncp_tree, tvb, 10);
}
else {
proto_tree_add_item(ncp_tree, hf_ncp_subfunc, tvb, 7,
1, FALSE);
proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 7, 1,
subfunc, "SubFunction: %d (0x%02x)",
subfunc, subfunc);
ptvc = ptvcursor_new(ncp_tree, tvb, 8);
}
}
@ -283,20 +775,79 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
}
if (ncp_rec && ncp_rec->request_ptvc) {
process_ptvc_record(ptvc, ncp_rec->request_ptvc);
clear_repeat_vars();
process_ptvc_record(ptvc, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec);
}
ptvcursor_free(ptvc);
/* Now that the dissection is done, do we need to run
* some display filters on the resulting tree in order
* to save results for "request conditions" ? */
if (run_req_cond) {
const int *needed;
gboolean *results;
dfilter_t *dfilter;
results = g_new0(gboolean, NUM_REQ_CONDS);
needed = ncp_rec->req_cond_indexes;
while (*needed != -1) {
/* ncp_tree is not a root proto_tree, but
* dfilters will still work on it. */
dfilter = req_conds[*needed].dfilter;
results[*needed] = dfilter_apply(dfilter, ncp_tree);
needed++;
}
/* Save the results so the reply packet dissection
* get to them. */
request_value->req_cond_results = results;
}
/* Construct the info string if necessary */
if (run_info_str) {
GPtrArray *parray;
int i, len;
field_info *finfo;
parray = proto_get_finfo_ptr_array(ncp_tree,
*ncp_rec->req_info_str->hf_ptr);
len = g_ptr_array_len(parray);
if (len > 0) {
col_set_str(pinfo->cinfo, COL_INFO, "C ");
finfo = g_ptr_array_index(parray, 0);
col_append_fstr(pinfo->cinfo, COL_INFO,
(gchar*) ncp_rec->req_info_str->first_string,
/* XXX - this only works for certain ftypes */
fvalue_get(finfo->value));
}
if (len > 1) {
for (i = 1; i < len; i++) {
finfo = g_ptr_array_index(parray, i);
col_append_fstr(pinfo->cinfo, COL_INFO,
(gchar*) ncp_rec->req_info_str->repeat_string,
/* XXX - this only works for certain ftypes */
fvalue_get(finfo->value));
}
}
}
/* Free the temporary proto_tree */
CLEANUP_CALL_AND_POP;
}
}
void
dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
guint16 nw_connection, guint8 sequence,
proto_tree *ncp_tree, proto_tree *tree) {
guint16 nw_connection, guint8 sequence, proto_tree *ncp_tree)
{
conversation_t *conversation;
ncp_req_hash_value *request_value = NULL;
const ncp_record *ncp_rec = NULL;
int *req_cond_results;
guint8 completion_code;
guint length;
ptvcursor_t *ptvc = NULL;
@ -309,13 +860,19 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
if (conversation != NULL) {
/* find the record telling us the request made that caused
this reply */
ncp_rec = ncp_hash_lookup(conversation, sequence);
p_add_proto_data(pinfo->fd, proto_ncp, (void*) ncp_rec);
request_value = ncp_hash_lookup(conversation, sequence);
if (request_value) {
ncp_rec = request_value->ncp_rec;
}
p_add_proto_data(pinfo->fd, proto_ncp, (void*) request_value);
}
/* else... we haven't seen an NCP Request for that conversation and sequence. */
}
else {
ncp_rec = p_get_proto_data(pinfo->fd, proto_ncp);
request_value = p_get_proto_data(pinfo->fd, proto_ncp);
if (request_value) {
ncp_rec = request_value->ncp_rec;
}
}
/* A completion code of 0 always means OK. Non-zero means failure,
@ -344,17 +901,19 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
* or ncp.subfunc will find both the requests and the replies.
*/
if (ncp_rec) {
proto_tree_add_uint(ncp_tree, hf_ncp_func, tvb,
6, 0, ncp_rec->func);
proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 0,
ncp_rec->func, "Function: %d (0x%02X), %s",
ncp_rec->func, ncp_rec->func, ncp_rec->name);
if (ncp_requires_subfunc(ncp_rec->func)) {
proto_tree_add_uint(ncp_tree, hf_ncp_subfunc,
tvb, 6, 0, ncp_rec->subfunc);
proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 6, 0,
ncp_rec->subfunc, "SubFunction: %d (0x%02x)",
ncp_rec->subfunc, 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);
completion_code, "Completion Code: %d (0x%02x), %s",
completion_code, completion_code, error_string);
proto_tree_add_item(ncp_tree, hf_ncp_connection_status, tvb, 7, 1, FALSE);
@ -371,8 +930,19 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
return;
}
/*printf("func=0x%x subfunc=0x%x\n", ncp_rec->func, ncp_rec->subfunc);*/
/* Any request condition results? */
if (request_value) {
req_cond_results = request_value->req_cond_results;
}
else {
req_cond_results = NULL;
}
clear_repeat_vars();
ptvc = ptvcursor_new(ncp_tree, tvb, 8);
process_ptvc_record(ptvc, ncp_rec->reply_ptvc);
process_ptvc_record(ptvc, ncp_rec->reply_ptvc, req_cond_results,
TRUE, ncp_rec);
ptvcursor_free(ptvc);
}
}

View File

@ -3,7 +3,7 @@
* Proto Tree TVBuff cursor
* Gilbert Ramirez <gram@alumni.rice.edu>
*
* $Id: ptvcursor.c,v 1.5 2002/01/10 04:44:34 gram Exp $
* $Id: ptvcursor.c,v 1.6 2002/05/09 23:50:25 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -75,6 +75,14 @@ ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
return item;
}
/* Advance the ptvcursor's offset within its tvbuff without
* adding anything to the proto_tree. */
void
ptvcursor_advance(ptvcursor_t* ptvc, gint length)
{
ptvc->offset += length;
}
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
void
ptvcursor_free(ptvcursor_t *ptvc)
@ -94,3 +102,15 @@ ptvcursor_current_offset(ptvcursor_t* ptvc)
{
return ptvc->offset;
}
proto_tree*
ptvcursor_tree(ptvcursor_t* ptvc)
{
return ptvc->tree;
}
void
ptvcursor_set_tree(ptvcursor_t* ptvc, proto_tree *tree)
{
ptvc->tree = tree;
}

View File

@ -3,7 +3,7 @@
* Proto Tree TVBuff cursor
* Gilbert Ramirez <gram@alumni.rice.edu>
*
* $Id: ptvcursor.h,v 1.5 2002/01/21 07:36:48 guy Exp $
* $Id: ptvcursor.h,v 1.6 2002/05/09 23:50:25 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -36,8 +36,6 @@
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*
@ -54,6 +52,11 @@ ptvcursor_add(ptvcursor_t*, int hf, gint length, gboolean endianness);
proto_item*
ptvcursor_add_no_advance(ptvcursor_t*, int hf, gint length, gboolean endianness);
/* Advance the ptvcursor's offset within its tvbuff without
* adding anything to the proto_tree. */
void
ptvcursor_advance(ptvcursor_t* ptvc, gint length);
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
void
ptvcursor_free(ptvcursor_t*);
@ -66,4 +69,12 @@ ptvcursor_tvbuff(ptvcursor_t*);
gint
ptvcursor_current_offset(ptvcursor_t*);
/* Returns the proto_tree* */
proto_tree*
ptvcursor_tree(ptvcursor_t* ptvc);
/* Sets a new proto_tree* for the ptvcursor_t */
void
ptvcursor_set_tree(ptvcursor_t* ptvc, proto_tree *tree);
#endif /* __PTVCURSOR_H__ */

View File

@ -1,5 +1,5 @@
# Generated automatically from Makefile.in by configure.
# Makefile.in generated automatically by automake 1.4a from Makefile.am
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
@ -11,6 +11,31 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Makefile.am
# Automake file for Wiretap
#
# $Id: Makefile,v 1.13 2002/05/09 23:50:34 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
# Copyright 1998 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.
SHELL = /bin/sh
srcdir = .
@ -45,10 +70,9 @@ AUTOMAKE = automake
AUTOHEADER = autoheader
INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_FLAG =
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
transform = s,x,x,
NORMAL_INSTALL = :
@ -57,17 +81,14 @@ POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
AMTAR = gtar
AMTARFLAGS = o
host_alias = i686-pc-linux-gnu
host_triplet = i686-pc-linux-gnu
CC = gcc
CPP = gcc -E
FLEX_PATH =
GLIB_CFLAGS = -I/usr/lib/glib/include
GLIB_CFLAGS = -I/usr/include/glib-1.2 -I/usr/lib/glib/include
GLIB_CONFIG = /usr/bin/glib-config
GLIB_LIBS = -L/usr/lib -lglib
GTK_CFLAGS =
GTK_CONFIG =
GTK_LIBS =
LEX = /usr/bin/flex
MAKEINFO = makeinfo
PACKAGE = libwtap.a
@ -75,71 +96,19 @@ RANLIB = ranlib
VERSION = 0.0.0
YACC = bison -y
# Makefile.am
# Automake file for Wiretap
#
# $Id: Makefile,v 1.12 1999/09/11 04:50:43 gerald Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
# Copyright 1998 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.
ACLOCAL_AMFLAGS = `../aclocal-flags`
noinst_LIBRARIES = libwiretap.a
#EXTRA_LIBRARIES = libwiretap.a
CLEANFILES = \
libwiretap.a \
*~
CLEANFILES = libwiretap.a *~
libwiretap_a_SOURCES = \
ascend-grammar.y \
ascend-scanner.l \
ascend.c \
ascend.h \
buffer.c \
buffer.h \
file.c \
iptrace.c \
iptrace.h \
lanalyzer.c \
lanalyzer.h \
libpcap.c \
libpcap.h \
netmon.c \
netmon.h \
netxray.c \
netxray.h \
ngsniffer.c \
ngsniffer.h \
radcom.c \
radcom.h \
snoop.c \
snoop.h \
wtap.c \
wtap.h
libwiretap_a_SOURCES = ascend-grammar.y ascend-scanner.l ascend.c ascend.h ascend-int.h atm.c atm.h buffer.c buffer.h csids.c csids.h dbs-etherwatch.c dbs-etherwatch.h etherpeek.c etherpeek.h file.c file_wrappers.c file_wrappers.h i4btrace.c i4btrace.h i4b_trace.h iptrace.c iptrace.h lanalyzer.c lanalyzer.h libpcap.c libpcap.h netmon.c netmon.h nettl.c nettl.h netxray.c netxray.h ngsniffer.c ngsniffer.h pppdump.c pppdump.h radcom.c radcom.h snoop.c snoop.h toshiba.c toshiba.h visual.c visual.h vms.c vms.h wtap.c wtap.h wtap-int.h
EXTRA_DIST = \
config.h.win32 \
Makefile.nmake
EXTRA_DIST = ascend-grammar.c ascend-grammar.h ascend-scanner.c config.h.win32 Makefile.nmake wtap.def
# Any POSIX-compatible YACC should honor the -p flag
@ -152,42 +121,44 @@ LIBRARIES = $(noinst_LIBRARIES)
DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.
CPPFLAGS =
LDFLAGS =
LIBS = -L/usr/lib -lglib
CPPFLAGS = -I/usr/local/include
LDFLAGS = -L/usr/local/lib
LIBS = -lz -L/usr/lib -lglib
libwiretap_a_LIBADD =
am_libwiretap_a_OBJECTS = ascend-grammar.o ascend-scanner.o ascend.o \
buffer.o file.o iptrace.o lanalyzer.o libpcap.o netmon.o netxray.o \
ngsniffer.o radcom.o snoop.o wtap.o
libwiretap_a_OBJECTS = $(am_libwiretap_a_OBJECTS)
libwiretap_a_OBJECTS = ascend-grammar.o ascend-scanner.o ascend.o atm.o \
buffer.o csids.o dbs-etherwatch.o etherpeek.o file.o file_wrappers.o \
i4btrace.o iptrace.o lanalyzer.o libpcap.o netmon.o nettl.o netxray.o \
ngsniffer.o pppdump.o radcom.o snoop.o toshiba.o visual.o vms.o wtap.o
AR = ar
LEX_OUTPUT_ROOT = lex.yy
LEXLIB = -lfl
CFLAGS = -Wall -g -O2 -I/usr/lib/glib/include
CFLAGS = -D_U_="__attribute__((unused))" -Wall -W -g -O2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/local/include
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libwiretap_a_SOURCES)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS acconfig.h acinclude.m4 aclocal.m4 \
ascend-grammar.c ascend-grammar.h ascend-scanner.c config.h.in \
configure configure.in
ascend-grammar.c ascend-scanner.c config.h.in configure configure.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
DEP_FILES = .deps/ascend-grammar.P .deps/ascend-scanner.P \
.deps/ascend.P .deps/buffer.P .deps/file.P .deps/iptrace.P \
.deps/lanalyzer.P .deps/libpcap.P .deps/netmon.P .deps/netxray.P \
.deps/ngsniffer.P .deps/radcom.P .deps/snoop.P .deps/wtap.P
.deps/ascend.P .deps/atm.P .deps/buffer.P .deps/csids.P \
.deps/dbs-etherwatch.P .deps/etherpeek.P .deps/file.P \
.deps/file_wrappers.P .deps/i4btrace.P .deps/iptrace.P \
.deps/lanalyzer.P .deps/libpcap.P .deps/netmon.P .deps/nettl.P \
.deps/netxray.P .deps/ngsniffer.P .deps/pppdump.P .deps/radcom.P \
.deps/snoop.P .deps/toshiba.P .deps/visual.P .deps/vms.P .deps/wtap.P
SOURCES = $(libwiretap_a_SOURCES)
OBJECTS = $(am_libwiretap_a_OBJECTS)
OBJECTS = $(libwiretap_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .c .l .o .y
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/$(altdir)configure.in $(ACLOCAL_M4)
.SUFFIXES: .S .c .l .o .s .y
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
@ -195,12 +166,12 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
config.status: $(srcdir)/configure.in $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/$(altdir)configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
config.h: stamp-h
@if test ! -f $@; then \
@ -208,22 +179,18 @@ config.h: stamp-h
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h stamp-hT
@echo timestamp > stamp-hT 2> /dev/null
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status
@mv stamp-hT stamp-h
$(srcdir)/config.h.in: $(srcdir)/./stamp-h.in
@echo timestamp > stamp-h 2> /dev/null
$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/./stamp-h.in; \
$(MAKE) $(srcdir)/./stamp-h.in; \
rm -f $(srcdir)/stamp-h.in; \
$(MAKE) $(srcdir)/stamp-h.in; \
else :; fi
$(srcdir)/./stamp-h.in: $(top_srcdir)/$(altdir)configure.in $(ACLOCAL_M4) acconfig.h
@rm -f $(srcdir)/./stamp-h.in $(srcdir)/./stamp-h.inT
@echo timestamp > $(srcdir)/./stamp-h.inT 2> /dev/null
cd $(top_srcdir) && $(AUTOHEADER)
@mv $(srcdir)/./stamp-h.inT $(srcdir)/./stamp-h.in
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
cd $(top_srcdir) && $(AUTOHEADER)
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
mostlyclean-hdr:
@ -243,6 +210,12 @@ distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
@ -252,20 +225,6 @@ distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
ascend-grammar.o:
ascend-scanner.o:
ascend.o:
buffer.o:
file.o:
iptrace.o:
lanalyzer.o:
libpcap.o:
netmon.o:
netxray.o:
ngsniffer.o:
radcom.o:
snoop.o:
wtap.o:
libwiretap.a: $(libwiretap_a_OBJECTS) $(libwiretap_a_DEPENDENCIES)
-rm -f libwiretap.a
@ -318,7 +277,7 @@ top_distdir = $(distdir)
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
@ -338,11 +297,11 @@ distcheck: dist
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
$(AMTAR) ch$(AMTARFLAGS)f - $(distdir) | GZIP=$(GZIP_ENV) gzip -c > $(distdir).tar.gz
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
$(AMTAR) ch$(AMTARFLAGS)f - $(distdir) | GZIP=$(GZIP_ENV) gzip -c > $(distdir).tar.gz
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
@ -379,22 +338,22 @@ maintainer-clean-depend:
%.o: %.c
@echo '$(COMPILE) -c $<'; \
$(COMPILE) -Wp,-MD,.deps/$(*D)/$(*F).pp -c $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-cp .deps/$(*F).pp .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
>> .deps/$(*F).P; \
rm .deps/$(*F).pp
%.lo: %.c
@echo '$(LTCOMPILE) -c $<'; \
$(LTCOMPILE) -Wp,-MD,.deps/$(*D)/$(*F).pp -c $<
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
< .deps/$(*F).pp > .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
>> .deps/$(*F).P; \
rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
@ -420,7 +379,7 @@ uninstall: uninstall-am
all-am: Makefile $(LIBRARIES) config.h
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
@ -434,7 +393,7 @@ distclean-generic:
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
-test -z "ascend-scanner.cascend-grammar.hascend-grammar.c" || rm -f ascend-scanner.c ascend-grammar.h ascend-grammar.c
-test -z "ascend-scannerlascend-grammarhascend-grammarc" || rm -f ascend-scannerl ascend-grammarh ascend-grammarc
mostlyclean-am: mostlyclean-hdr mostlyclean-noinstLIBRARIES \
mostlyclean-compile mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
@ -473,13 +432,13 @@ clean-tags maintainer-clean-tags distdir mostlyclean-depend \
distclean-depend clean-depend maintainer-clean-depend info-am info \
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all install-strip \
installdirs mostlyclean-generic distclean-generic clean-generic \
install uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
ascend-scanner.c : ascend-scanner.l
$(LEX) -Pascend -t $(srcdir)/ascend-scanner.l > ascend-scanner.c
$(LEX) -Pascend -oascend-scanner.c $(srcdir)/ascend-scanner.l
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.