From 6bbfd97bde03e01dbf64173b9fd4e85747fabf8e Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 5 May 2000 09:32:36 +0000 Subject: [PATCH] Add routines to: register lists of "heuristic" dissectors, which are handed a frame that may or may contain a payload for the protocol they dissect, and that return FALSE if it's not or dissect the packet and return TRUE if it is; add a dissector to such a list; go through such a list, calling each dissector until either a dissector returns TRUE, in which case the routine returns TRUE, or it runs out of entries in the list, in which case the routine returns FALSE. Have lists of heuristic dissectors for TCP and for COTP when used with the Inactive Subset of CLNP, and add the GIOP and Yahoo Messenger dissectors to the first list and the Sinec H1 dissector to the second list. Make the dissector name argument to "dissector_add()" and "dissector_delete()" a "const char *" rarther than just a "char *". Add "heur_dissector_add()", the routine to add a heuristic dissector to a list of heuristic dissectors, to the set of routines we can export to plugins through a table on platforms where dynamically-loaded code can't call stuff in the main program, and initialize the element in the table in question for "dissector_add()" (which we'd forgotten to do). svn path=/trunk/; revision=1909 --- Makefile.am | 4 +-- packet-clnp.c | 15 +++++--- packet-eth.c | 5 ++- packet-giop.c | 37 ++++++++++++------- packet-giop.h | 26 -------------- packet-h1.c | 11 ++++-- packet-h1.h | 27 -------------- packet-tcp.c | 24 ++++--------- packet-yhoo.c | 33 ++++++++++++++--- packet-yhoo.h | 4 +-- packet.c | 81 +++++++++++++++++++++++++++++++++--------- packet.h | 32 ++++++++++++++--- plugins.c | 6 +++- plugins/plugin_api.c | 3 +- plugins/plugin_api.h | 4 ++- plugins/plugin_table.h | 8 +++-- 16 files changed, 193 insertions(+), 127 deletions(-) delete mode 100644 packet-giop.h delete mode 100644 packet-h1.h diff --git a/Makefile.am b/Makefile.am index 7c900ed170..792127214d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.192 2000/04/21 01:45:57 guy Exp $ +# $Id: Makefile.am,v 1.193 2000/05/05 09:32:00 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs @@ -74,10 +74,8 @@ DISSECTOR_SOURCES = \ packet-fddi.h \ packet-ftp.c \ packet-giop.c \ - packet-giop.h \ packet-gre.c \ packet-h1.c \ - packet-h1.h \ packet-hsrp.c \ packet-http.c \ packet-http.h \ diff --git a/packet-clnp.c b/packet-clnp.c index 66ba406951..febb4556e8 100644 --- a/packet-clnp.c +++ b/packet-clnp.c @@ -1,7 +1,7 @@ /* packet-clnp.c * Routines for ISO/OSI network and transport protocol packet disassembly * - * $Id: packet-clnp.c,v 1.5 2000/04/28 19:35:39 guy Exp $ + * $Id: packet-clnp.c,v 1.6 2000/05/05 09:32:01 guy Exp $ * Laurent Deniel * Ralf Schneider * @@ -44,7 +44,6 @@ #include "packet-clnp.h" #include "packet-isis.h" #include "packet-esis.h" -#include "packet-h1.h" #include "nlpid.h" /* protocols and fields */ @@ -66,8 +65,6 @@ static int hf_clnp_dest = -1; static int hf_clnp_src_length = -1; static int hf_clnp_src = -1; - - /* * ISO 8473 OSI CLNP definition (see RFC994) * @@ -230,6 +227,10 @@ struct clnp_segment { static u_char li, tpdu, cdt; /* common fields */ static u_short dst_ref; +/* List of dissectors to call for COTP packets put atop the Inactive + Subset of CLNP. */ +static heur_dissector_list_t cotp_is_heur_subdissector_list; + /* function definitions */ static int osi_decode_DR(const u_char *pd, int offset, @@ -428,7 +429,8 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, offset += li + 1; if (uses_inactive_subset){ - if (dissect_h1(pd, offset, fd, tree)) { + if (dissector_try_heuristic(cotp_is_heur_subdissector_list, pd, offset, + fd, tree)) { return TRUE; } /* Fill in other Dissectors using inactive subset here */ @@ -1771,6 +1773,9 @@ void proto_register_cotp(void) proto_cotp = proto_register_protocol(PROTO_STRING_COTP, "cotp"); /* proto_register_field_array(proto_cotp, hf, array_length(hf));*/ proto_register_subtree_array(ett, array_length(ett)); + +/* subdissector code */ + register_heur_dissector_list("cotp_is", &cotp_is_heur_subdissector_list); } void diff --git a/packet-eth.c b/packet-eth.c index ed570090b0..fec20d78e3 100644 --- a/packet-eth.c +++ b/packet-eth.c @@ -1,7 +1,7 @@ /* packet-eth.c * Routines for ethernet packet disassembly * - * $Id: packet-eth.c,v 1.31 2000/03/20 21:21:33 gram Exp $ + * $Id: packet-eth.c,v 1.32 2000/05/05 09:32:02 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -139,6 +139,7 @@ capture_eth(const u_char *pd, int offset, packet_counts *ld) void dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { + int orig_captured_len; guint16 etype, length; proto_tree *fh_tree = NULL; proto_item *ti; @@ -149,6 +150,8 @@ dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) return; } + orig_captured_len = pi.captured_len; + SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &pd[offset+6]); SET_ADDRESS(&pi.src, AT_ETHER, 6, &pd[offset+6]); SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset+0]); diff --git a/packet-giop.c b/packet-giop.c index 8157864143..74328c1e87 100644 --- a/packet-giop.c +++ b/packet-giop.c @@ -3,7 +3,7 @@ * * Laurent Deniel * - * $Id: packet-giop.c,v 1.11 2000/03/12 04:47:38 gram Exp $ + * $Id: packet-giop.c,v 1.12 2000/05/05 09:32:03 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -189,7 +189,8 @@ static u_char *print_object_key(int length, u_char *from) /* main entry point */ -void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +static gboolean +dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { MessageHeader header; @@ -216,8 +217,9 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree #define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE) if (!BYTES_ARE_IN_FRAME(offset, GIOP_HEADER_SIZE)) { - dissect_data(pd, offset, fd, tree); - return; + /* Not enough data, or not enough captured data; perhaps it was + a GIOP message, but we can't tell. */ + return FALSE; } /* avoid alignment problem */ @@ -227,14 +229,18 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree /* check magic number and version */ if (memcmp(header.magic, GIOP_MAGIC, sizeof(header.magic)) != 0) { - dissect_data(pd, offset, fd, tree); - return; + /* Not a GIOP message. */ + return FALSE; } if (header.GIOP_version.major != GIOP_MAJOR || ((minor_version = header.GIOP_version.minor) > GIOP_MINOR)) { + /* Bad version number; should we note that and dissect the rest + as data, or should we return FALSE on the theory that it + might have been some other packet that happened to begin with + "GIOP"? */ dissect_data(pd, offset, fd, tree); - return; + return TRUE; } switch(minor_version) { @@ -315,7 +321,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree if (!BYTES_ARE_IN_FRAME(offset, message_size)) { dissect_data(pd, offset, fd, tree); - return; + return TRUE; } /* skip service_context in Request/Reply messages */ @@ -440,7 +446,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree if (sequence_length > message_size) { dissect_data(pd, offset, fd, tree); - return; + return TRUE; } if (tree) { @@ -509,7 +515,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree if (sequence_length > message_size) { dissect_data(pd, offset, fd, tree); - return; + return TRUE; } if (tree) { @@ -548,7 +554,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree if (sequence_length > message_size) { dissect_data(pd, offset, fd, tree); - return; + return TRUE; } if (tree) { @@ -568,7 +574,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree if (sequence_length > message_size) { dissect_data(pd, offset, fd, tree); - return; + return TRUE; } if (tree && sequence_length) { @@ -704,6 +710,7 @@ void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree dissect_data(pd, offset, fd, tree); } + return TRUE; } /* dissect_giop */ void @@ -725,3 +732,9 @@ proto_register_giop(void) proto_register_field_array(proto_giop, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } + +void +proto_reg_handoff_giop(void) +{ + heur_dissector_add("tcp", dissect_giop); +} diff --git a/packet-giop.h b/packet-giop.h deleted file mode 100644 index a2bd8e0734..0000000000 --- a/packet-giop.h +++ /dev/null @@ -1,26 +0,0 @@ -/* packet-giop.h - * - * $Id: packet-giop.h,v 1.1 2000/02/15 21:02:10 gram Exp $ - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * 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. - */ - - -void dissect_giop(const u_char *, int, frame_data *, proto_tree *); diff --git a/packet-h1.c b/packet-h1.c index 5c636caaa8..894b98935b 100644 --- a/packet-h1.c +++ b/packet-h1.c @@ -2,7 +2,7 @@ * Routines for Sinec H1 packet disassembly * Gerrit Gehnen * - * $Id: packet-h1.c,v 1.5 2000/04/28 19:35:40 guy Exp $ + * $Id: packet-h1.c,v 1.6 2000/05/05 09:32:05 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -37,7 +37,6 @@ #include #include "packet.h" #include "globals.h" -#include "packet-h1.h" static int proto_h1 = -1; static int hf_h1_header = -1; @@ -101,7 +100,7 @@ static gint ett_response = -1; static gint ett_empty = -1; -gboolean +static gboolean dissect_h1 (const u_char * pd, int offset, frame_data * fd, proto_tree * tree) { proto_tree *h1_tree = NULL; @@ -307,3 +306,9 @@ proto_register_h1 (void) proto_register_field_array (proto_h1, hf, array_length (hf)); proto_register_subtree_array (ett, array_length (ett)); } + +void +proto_reg_handoff_h1(void) +{ + heur_dissector_add("cotp_is", dissect_h1); +} diff --git a/packet-h1.h b/packet-h1.h deleted file mode 100644 index b9ba335e05..0000000000 --- a/packet-h1.h +++ /dev/null @@ -1,27 +0,0 @@ -/* packet-h1.h - * Declarations of outines for Sinec H1 packet disassembly - * Gerrit Gehnen - * - * $Id: packet-h1.h,v 1.2 2000/04/28 19:35:41 guy Exp $ - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * 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. - */ - -gboolean dissect_h1(const u_char *, int, frame_data *, proto_tree *); diff --git a/packet-tcp.c b/packet-tcp.c index 67b4b6dbe0..29c0f7d7d5 100644 --- a/packet-tcp.c +++ b/packet-tcp.c @@ -1,7 +1,7 @@ /* packet-tcp.c * Routines for TCP packet disassembly * - * $Id: packet-tcp.c,v 1.72 2000/04/20 07:05:57 guy Exp $ + * $Id: packet-tcp.c,v 1.73 2000/05/05 09:32:05 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -54,9 +54,7 @@ #include "packet-tcp.h" #include "packet-ip.h" -#include "packet-giop.h" #include "packet-rpc.h" -#include "packet-yhoo.h" extern FILE* data_out_file; @@ -89,11 +87,11 @@ static gint ett_tcp_options = -1; static gint ett_tcp_option_sack = -1; static dissector_table_t subdissector_table; +static heur_dissector_list_t heur_subdissector_list; /* TCP Ports */ #define TCP_PORT_SMTP 25 -#define TCP_PORT_YHOO 5050 /* TCP structs and definitions */ @@ -403,22 +401,11 @@ decode_tcp_ports( const u_char *pd, int offset, frame_data *fd, proto_tree *tree dissector_try_port(subdissector_table, dst_port, pd, offset, fd, tree)) return; - /* check existence of high level protocols */ - -#define PORT_IS(port) ( src_port == port || dst_port == port) - - if (memcmp(&pd[offset], "GIOP", 4) == 0) { - dissect_giop(pd, offset, fd, tree); + /* do lookup with the heuristic subdissector table */ + if (dissector_try_heuristic(heur_subdissector_list, pd, offset, fd, tree)) return; - } - - if ( PORT_IS(TCP_PORT_YHOO) && - (memcmp(&pd[offset], "YPNS", 4) == 0 || - memcmp(&pd[offset], "YHOO", 4) == 0 )) { - dissect_yhoo(pd, offset, fd, tree); - return; - } + /* Oh, well, we don't know this; dissect it as data. */ dissect_data(pd, offset, fd, tree); } @@ -637,6 +624,7 @@ proto_register_tcp(void) /* subdissector code */ subdissector_table = register_dissector_table("tcp.port"); + register_heur_dissector_list("tcp", &heur_subdissector_list); } void diff --git a/packet-yhoo.c b/packet-yhoo.c index 4dcc965c51..5f6361b694 100644 --- a/packet-yhoo.c +++ b/packet-yhoo.c @@ -2,7 +2,7 @@ * Routines for yahoo messenger packet dissection * Copyright 1999, Nathan Neulinger * - * $Id: packet-yhoo.c,v 1.5 2000/01/07 22:05:42 guy Exp $ + * $Id: packet-yhoo.c,v 1.6 2000/05/05 09:32:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -58,6 +58,8 @@ static int hf_yhoo_content = -1; static gint ett_yhoo = -1; +#define TCP_PORT_YHOO 5050 + static const value_string yhoo_service_vals[] = { {YAHOO_SERVICE_LOGON, "Pager Logon"}, {YAHOO_SERVICE_LOGOFF, "Pager Logoff"}, @@ -102,15 +104,30 @@ static const value_string yhoo_msgtype_vals[] = { {0, NULL} }; -void +static gboolean dissect_yhoo(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { proto_tree *yhoo_tree, *ti; struct yahoo_rawpacket *pkt; + if (pi.srcport != TCP_PORT_YHOO && pi.destport != TCP_PORT_YHOO) { + /* Not the Yahoo port - not a Yahoo Messenger packet. */ + return FALSE; + } + /* get at least a full packet structure */ - if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct yahoo_rawpacket)) ) - return; + if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct yahoo_rawpacket)) ) { + /* Not enough data captured; maybe it is a Yahoo + Messenger packet, but it contains too little data to + tell. */ + return FALSE; + } + + if (memcmp(&pd[offset], "YPNS", 4) != 0 && + memcmp(&pd[offset], "YHOO", 4) != 0) { + /* Not a Yahoo Messenger packet. */ + return FALSE; + } pkt = (struct yahoo_rawpacket *) &pd[offset]; @@ -150,6 +167,8 @@ dissect_yhoo(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) proto_tree_add_item(yhoo_tree, hf_yhoo_content, offset+104, END_OF_FRAME, pkt->content); } + + return TRUE; } void @@ -197,3 +216,9 @@ proto_register_yhoo(void) proto_register_subtree_array(ett, array_length(ett)); } + +void +proto_reg_handoff_yhoo(void) +{ + heur_dissector_add("tcp", dissect_yhoo); +} diff --git a/packet-yhoo.h b/packet-yhoo.h index 848642a1f0..364fbb1115 100644 --- a/packet-yhoo.h +++ b/packet-yhoo.h @@ -1,7 +1,7 @@ /* packet-yhoo.h * Definitions for packet disassembly structures and routines * - * $Id: packet-yhoo.h,v 1.5 2000/02/15 21:03:32 gram Exp $ + * $Id: packet-yhoo.h,v 1.6 2000/05/05 09:32:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -29,8 +29,6 @@ #ifndef YAHOO_LIB_H #define YAHOO_LIB_H -void dissect_yhoo(const u_char *, int, frame_data *, proto_tree *); - /* Service constants */ #define YAHOO_SERVICE_LOGON 1 #define YAHOO_SERVICE_LOGOFF 2 diff --git a/packet.c b/packet.c index 5ea544d4d8..8a6f8a0d73 100644 --- a/packet.c +++ b/packet.c @@ -1,7 +1,7 @@ /* packet.c * Routines for packet disassembly * - * $Id: packet.c,v 1.78 2000/04/19 03:28:07 gram Exp $ + * $Id: packet.c,v 1.79 2000/05/05 09:32:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -1303,21 +1303,19 @@ find_dissector_table(const char *name) return g_hash_table_lookup( dissector_tables, name ); } +/* lookup a dissector based upon pattern. */ dissector_t dissector_lookup( dissector_table_t table, guint32 pattern) { - /* lookup a dissector based upon pattern. */ return g_hash_table_lookup( table, GUINT_TO_POINTER( pattern)); } -void -dissector_add( char *name, guint32 pattern, dissector_t dissector) -{ - /* add an entry, lookup the dissector table for the specified field name, */ /* if a valid table found, add the subdissector */ - +void +dissector_add(const char *name, guint32 pattern, dissector_t dissector) +{ dissector_table_t sub_dissectors = find_dissector_table( name); /* sanity check */ @@ -1328,19 +1326,16 @@ dissector_add( char *name, guint32 pattern, dissector_t dissector) (gpointer)dissector); } - -void -dissector_delete( char *name, guint32 pattern, dissector_t dissector) -{ - /* delete the entry for this dissector at this pattern */ /* NOTE: this doesn't use the dissector call variable. It is included to */ /* be consistant with the dissector_add and more importantly to be used */ -/* if the technique of adding a temporary dissector is implimented. */ -/* If temporary dissectors are deleted, then the original dissector must */ +/* if the technique of adding a temporary dissector is implemented. */ +/* If temporary dissectors are deleted, then the original dissector must */ /* be available. */ - +void +dissector_delete(const char *name, guint32 pattern, dissector_t dissector) +{ dissector_table_t sub_dissectors = find_dissector_table( name); /* sanity check */ @@ -1382,9 +1377,63 @@ register_dissector_table(const char *name) /* Make sure the registration is unique */ g_assert(!g_hash_table_lookup( dissector_tables, name )); - /* Create and register the dissector array for this field; returns */ + /* Create and register the dissector table for this name; returns */ /* a pointer to the dissector table. */ sub_dissectors = g_hash_table_new( g_direct_hash, g_direct_equal ); g_hash_table_insert( dissector_tables, (gpointer)name, (gpointer) sub_dissectors ); return sub_dissectors; } + +static GHashTable *heur_dissector_lists = NULL; + +/* Finds a heuristic dissector table by field name. */ +static heur_dissector_list_t * +find_heur_dissector_list(const char *name) +{ + g_assert(heur_dissector_lists != NULL); + return g_hash_table_lookup(heur_dissector_lists, name); +} + +void +heur_dissector_add(const char *name, heur_dissector_t dissector) +{ + heur_dissector_list_t *sub_dissectors = find_heur_dissector_list(name); + + /* sanity check */ + g_assert(sub_dissectors != NULL); + + /* do the table insertion */ + *sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dissector); +} + +gboolean +dissector_try_heuristic(heur_dissector_list_t sub_dissectors, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + heur_dissector_t subdissector; + GSList *entry; + + for (entry = sub_dissectors; entry != NULL; entry = g_slist_next(entry)) { + subdissector = (heur_dissector_t)entry->data; + if ((subdissector)(pd, offset, fd, tree)) + return TRUE; + } + return FALSE; +} + +void +register_heur_dissector_list(const char *name, heur_dissector_list_t *sub_dissectors) +{ + /* Create our hash-of-hashes if it doesn't already exist */ + if (heur_dissector_lists == NULL) { + heur_dissector_lists = g_hash_table_new(g_str_hash, g_str_equal); + g_assert(heur_dissector_lists != NULL); + } + + /* Make sure the registration is unique */ + g_assert(g_hash_table_lookup(heur_dissector_lists, name) == NULL); + + *sub_dissectors = NULL; /* initially empty */ + g_hash_table_insert(heur_dissector_lists, (gpointer)name, + (gpointer) sub_dissectors); +} diff --git a/packet.h b/packet.h index a83c7feb8f..3a8636223c 100644 --- a/packet.h +++ b/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.182 2000/04/18 04:46:07 guy Exp $ + * $Id: packet.h,v 1.183 2000/05/05 09:32:09 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -214,12 +214,13 @@ typedef struct true_false_string { char *false_string; } true_false_string; +/* Hash table for matching port numbers and dissectors */ typedef GHashTable* dissector_table_t; /* types for sub-dissector lookup */ typedef void (*dissector_t)(const u_char *, int, frame_data *, proto_tree *); -/* a protocol uses the function to register its sub-dissector table */ +/* a protocol uses the function to register a sub-dissector table */ dissector_table_t register_dissector_table(const char *name); /* dissector lookup routine. called by protocol dissector to find a sub-dissector */ @@ -227,11 +228,11 @@ dissector_t dissector_lookup( dissector_table_t table, guint32 pattern); /* Add a sub-dissector to a dissector table. Called by the protocol routine */ /* that wants to register a sub-dissector. */ -void dissector_add( char *abbrev, guint32 pattern, dissector_t dissector); +void dissector_add(const char *abbrev, guint32 pattern, dissector_t dissector); /* Add a sub-dissector to a dissector table. Called by the protocol routine */ /* that wants to de-register a sub-dissector. */ -void dissector_delete( char *abbrev, guint32 pattern, dissector_t dissector); +void dissector_delete(const char *name, guint32 pattern, dissector_t dissector); /* Look for a given port in a given dissector table and, if found, call the dissector with the arguments supplied, and return TRUE, otherwise @@ -239,6 +240,29 @@ void dissector_delete( char *abbrev, guint32 pattern, dissector_t dissector); gboolean dissector_try_port(dissector_table_t sub_dissectors, guint32 port, const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +/* List of "heuristic" dissectors (which get handed a packet, look at it, + and either recognize it as being for their protocol, dissect it, and + return TRUE, or don't recognize it and return FALSE) to be called + by another dissector. */ +typedef GSList *heur_dissector_list_t; + +/* Type of a heuristic dissector */ +typedef gboolean (*heur_dissector_t)(const u_char *, int, frame_data *, + proto_tree *); + +/* A protocol uses this function to register a heuristic dissector list */ +void register_heur_dissector_list(const char *name, heur_dissector_list_t *list); + +/* Add a sub-dissector to a heuristic dissector list. Called by the + protocol routine that wants to register a sub-dissector. */ +void heur_dissector_add(const char *name, heur_dissector_t dissector); + +/* Try all the dissectors in a given heuristic dissector list until + we find one that recognizes the protocol, in which case we return + TRUE, or we run out of dissectors, in which case we return FALSE. */ +gboolean dissector_try_heuristic(heur_dissector_list_t sub_dissectors, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree); + /* Many of the structs and definitions below and in packet-*.c files * were taken from include files in the Linux distribution. */ diff --git a/plugins.c b/plugins.c index 7535cad892..d809a384a0 100644 --- a/plugins.c +++ b/plugins.c @@ -1,7 +1,7 @@ /* plugins.c * plugin routines * - * $Id: plugins.c,v 1.14 2000/04/12 21:02:51 gram Exp $ + * $Id: plugins.c,v 1.15 2000/05/05 09:32:10 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -469,6 +469,10 @@ init_plugins() patable.p_proto_register_field_array = proto_register_field_array; patable.p_proto_register_subtree_array = proto_register_subtree_array; + patable.p_dissector_add = dissector_add; + + patable.p_heur_dissector_add = heur_dissector_add; + patable.p_proto_item_add_subtree = proto_item_add_subtree; patable.p_proto_tree_add_item = proto_tree_add_item; patable.p_proto_tree_add_item_hidden = proto_tree_add_item_hidden; diff --git a/plugins/plugin_api.c b/plugins/plugin_api.c index c5831e8ab8..7de21def62 100644 --- a/plugins/plugin_api.c +++ b/plugins/plugin_api.c @@ -1,7 +1,7 @@ /* plugin_api.c * Routines for Ethereal plugins. * - * $Id: plugin_api.c,v 1.6 2000/04/04 21:46:29 guy Exp $ + * $Id: plugin_api.c,v 1.7 2000/05/05 09:32:34 guy Exp $ * * Ethereal - Network traffic analyzer * Copyright 2000 by Gilbert Ramirez @@ -48,6 +48,7 @@ plugin_address_table_init(plugin_address_table_t *pat) p_proto_register_field_array = pat->p_proto_register_field_array; p_proto_register_subtree_array = pat->p_proto_register_subtree_array; p_dissector_add = pat->p_dissector_add; + p_heur_dissector_add = pat->p_heur_dissector_add; p_proto_item_add_subtree = pat->p_proto_item_add_subtree; p_proto_tree_add_item = pat->p_proto_tree_add_item; p_proto_tree_add_item_hidden = pat->p_proto_tree_add_item_hidden; diff --git a/plugins/plugin_api.h b/plugins/plugin_api.h index 50ca1749b9..c009d5bc1d 100644 --- a/plugins/plugin_api.h +++ b/plugins/plugin_api.h @@ -1,7 +1,7 @@ /* plugin_api.h * Routines for Ethereal plugins. * - * $Id: plugin_api.h,v 1.4 2000/04/04 21:46:29 guy Exp $ + * $Id: plugin_api.h,v 1.5 2000/05/05 09:32:35 guy Exp $ * * Ethereal - Network traffic analyzer * Copyright 2000 by Gilbert Ramirez @@ -50,6 +50,8 @@ #define dissector_add (*p_dissector_add) +#define heur_dissector_add (*p_heur_dissector_add) + #define proto_item_add_subtree (*p_proto_item_add_subtree) #define proto_tree_add_item (*p_proto_tree_add_item) #define proto_tree_add_item_hidden (*p_proto_tree_add_item_hidden) diff --git a/plugins/plugin_table.h b/plugins/plugin_table.h index ac8d3d5cf9..d00a5a948e 100644 --- a/plugins/plugin_table.h +++ b/plugins/plugin_table.h @@ -1,7 +1,7 @@ /* plugin_table.h * Table of exported addresses for Ethereal plugins. * - * $Id: plugin_table.h,v 1.2 2000/04/04 21:46:29 guy Exp $ + * $Id: plugin_table.h,v 1.3 2000/05/05 09:32:36 guy Exp $ * * Ethereal - Network traffic analyzer * Copyright 2000 by Gilbert Ramirez @@ -43,7 +43,9 @@ typedef int (*addr_proto_register_protocol)(char*, char*); typedef void (*addr_proto_register_field_array)(int, hf_register_info*, int); typedef void (*addr_proto_register_subtree_array)(int**, int); -typedef void (*addr_dissector_add)(char *, guint32, dissector_t); +typedef void (*addr_dissector_add)(const char *, guint32, dissector_t); + +typedef void (*addr_heur_dissector_add)(const char *, heur_dissector_t); typedef proto_tree* (*addr_proto_item_add_subtree)(proto_item*, gint); typedef proto_item* (*addr_proto_tree_add_item)(proto_tree*, int, gint, gint, ...); @@ -79,6 +81,8 @@ typedef struct { addr_dissector_add p_dissector_add; + addr_heur_dissector_add p_heur_dissector_add; + addr_proto_item_add_subtree p_proto_item_add_subtree; addr_proto_tree_add_item p_proto_tree_add_item; addr_proto_tree_add_item_hidden p_proto_tree_add_item_hidden;