wireshark/epan/packet.c

1044 lines
26 KiB
C
Raw Normal View History

/* packet.c
* Routines for packet disassembly
*
* $Id: packet.c,v 1.33 2001/04/01 23:11:43 hagbard 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef NEED_SNPRINTF_H
# include "snprintf.h"
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef NEED_INET_V6DEFS_H
# include "inet_v6defs.h"
#endif
#include "packet.h"
#include "timestamp.h"
#include "atalk-utils.h"
#include "ipv6-utils.h"
#include "sna-utils.h"
#include "osi-utils.h"
#include "to_str.h"
#include "resolv.h"
#include "tvbuff.h"
#include "plugins.h"
static gint proto_malformed = -1;
static dissector_handle_t frame_handle = NULL;
void
packet_init(void)
{
frame_handle = find_dissector("frame");
proto_malformed = proto_get_id_by_filter_name("malformed");
}
void
packet_cleanup(void)
{
/* nothing */
}
/* Allow protocols to register "init" routines, which are called before
we make a pass through a capture file and dissect all its packets
(e.g., when we read in a new capture file, or run a "filter packets"
or "colorize packets" pass over the current capture file). */
static GSList *init_routines;
void
register_init_routine(void (*func)(void))
{
init_routines = g_slist_append(init_routines, func);
}
/* Call all the registered "init" routines. */
static void
call_init_routine(gpointer routine, gpointer dummy)
{
void (*func)(void) = routine;
(*func)();
}
void
init_all_protocols(void)
{
g_slist_foreach(init_routines, &call_init_routine, NULL);
}
/* Creates the top-most tvbuff and calls dissect_frame() */
void
dissect_packet(tvbuff_t **p_tvb, union wtap_pseudo_header *pseudo_header,
const u_char *pd, frame_data *fd, proto_tree *tree)
{
blank_packetinfo();
/* Set the initial payload to the packet length, and the initial
captured payload to the capture length (other protocols may
reduce them if their headers say they're less). */
pi.len = fd->pkt_len;
pi.captured_len = fd->cap_len;
pi.fd = fd;
pi.pseudo_header = pseudo_header;
col_set_writable(fd, TRUE);
TRY {
*p_tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len, "Frame");
/* Add this tvbuffer into the data_src list */
fd->data_src = g_slist_append( fd->data_src, *p_tvb);
pi.compat_top_tvb = *p_tvb;
}
CATCH(BoundsError) {
g_assert_not_reached();
}
CATCH(ReportedBoundsError) {
if(proto_malformed != -1){
proto_tree_add_protocol_format(tree, proto_malformed, *p_tvb, 0, 0,
"[Malformed Frame: Packet Length]" );
}
else {
g_assert_not_reached();
}
}
ENDTRY;
if(frame_handle != NULL)
call_dissector(frame_handle, *p_tvb, &pi, tree);
fd->flags.visited = 1;
}
/*********************** code added for sub-dissector lookup *********************/
static GHashTable *dissector_tables = NULL;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/*
* XXX - for now, we support having both "old" dissectors, with packet
* data pointer, packet offset, frame_data pointer, and protocol tree
* pointer arguments, and "new" dissectors, with tvbuff pointer,
* packet_info pointer, and protocol tree pointer arguments.
*
* Nuke this and go back to storing a pointer to the dissector when
* the last old-style dissector is gone.
*/
typedef struct {
gboolean is_old_dissector;
union {
old_dissector_t old;
dissector_t new;
} dissector;
int proto_index;
} dissector_entry_t;
struct dtbl_entry {
dissector_entry_t initial;
dissector_entry_t current;
};
static void
dissect_null(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* Finds a dissector table by field name. */
static dissector_table_t
find_dissector_table(const char *name)
{
g_assert(dissector_tables);
return g_hash_table_lookup( dissector_tables, name );
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* add an entry, lookup the dissector table for the specified field name, */
/* if a valid table found, add the subdissector */
void
old_dissector_add(const char *name, guint32 pattern, old_dissector_t dissector,
int proto)
{
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dissector_table_t sub_dissectors = find_dissector_table( name);
dtbl_entry_t *dtbl_entry;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* sanity check */
g_assert( sub_dissectors);
dtbl_entry = g_malloc(sizeof (dtbl_entry_t));
dtbl_entry->current.is_old_dissector = TRUE;
dtbl_entry->current.dissector.old = dissector;
dtbl_entry->current.proto_index = proto;
dtbl_entry->initial = dtbl_entry->current;
proto_set_protocol_dissector(proto, dissector);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* do the table insertion */
g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
(gpointer)dtbl_entry);
}
void
dissector_add(const char *name, guint32 pattern, dissector_t dissector,
int proto)
{
dissector_table_t sub_dissectors = find_dissector_table( name);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert( sub_dissectors);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry = g_malloc(sizeof (dtbl_entry_t));
dtbl_entry->current.is_old_dissector = FALSE;
dtbl_entry->current.dissector.new = dissector;
dtbl_entry->current.proto_index = proto;
dtbl_entry->initial = dtbl_entry->current;
proto_set_protocol_dissector(proto, dissector);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* do the table insertion */
g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
(gpointer)dtbl_entry);
}
/* 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 implemented. */
/* If temporary dissectors are deleted, then the original dissector must */
/* be available. */
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
void
old_dissector_delete(const char *name, guint32 pattern, old_dissector_t dissector)
{
dissector_table_t sub_dissectors = find_dissector_table( name);
dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert( sub_dissectors);
/*
* Find the entry.
*/
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(pattern));
if (dtbl_entry != NULL) {
/*
* Found - remove it.
*/
g_hash_table_remove(sub_dissectors, GUINT_TO_POINTER(pattern));
/*
* Now free up the entry.
*/
g_free(dtbl_entry);
}
}
void
dissector_delete(const char *name, guint32 pattern, dissector_t dissector)
{
dissector_table_t sub_dissectors = find_dissector_table( name);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert( sub_dissectors);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/*
* Find the entry.
*/
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(pattern));
if (dtbl_entry != NULL) {
/*
* Found - remove it.
*/
g_hash_table_remove(sub_dissectors, GUINT_TO_POINTER(pattern));
/*
* Now free up the entry.
*/
g_free(dtbl_entry);
}
}
void
dissector_change(const char *name, guint32 pattern, dissector_t dissector,
gboolean old, int proto)
{
dissector_table_t sub_dissectors = find_dissector_table( name);
dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert( sub_dissectors);
/*
* See if the entry already exists. If so, reuse it.
*/
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(pattern));
if (dtbl_entry != NULL) {
dtbl_entry->current.is_old_dissector = old;
dtbl_entry->current.dissector.new = dissector ? dissector : dissect_null;
dtbl_entry->current.proto_index = proto;
return;
}
/*
* Don't create an entry if there is no dissector - I.E. the
* user said not to decode something that wasn't being decoded
* in the first place.
*/
if (dissector == NULL)
return;
dtbl_entry = g_malloc(sizeof (dtbl_entry_t));
dtbl_entry->initial.is_old_dissector = FALSE;
dtbl_entry->initial.dissector.old = NULL;
dtbl_entry->initial.proto_index = -1;
dtbl_entry->current.is_old_dissector = old;
dtbl_entry->current.dissector.new = dissector;
dtbl_entry->current.proto_index = proto;
/* do the table insertion */
g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
(gpointer)dtbl_entry);
}
void
dissector_reset(const char *name, guint32 pattern)
{
dissector_table_t sub_dissectors = find_dissector_table( name);
dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert( sub_dissectors);
/*
* Find the entry.
*/
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(pattern));
if (dtbl_entry == NULL)
return;
/*
* Found - is there an initial value?
*/
if (dtbl_entry->initial.dissector.new != NULL) {
dtbl_entry->current = dtbl_entry->initial;
} else {
g_hash_table_remove(sub_dissectors, GUINT_TO_POINTER(pattern));
g_free(dtbl_entry);
}
}
/* Look for a given port in a given dissector table and, if found, call
the dissector with the arguments supplied, and return TRUE, otherwise
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
return FALSE.
If the arguments supplied don't match the arguments to the dissector,
do the appropriate translation. */
gboolean
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
old_dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry_t *dtbl_entry;
tvbuff_t *tvb;
const char *saved_proto;
guint32 saved_match_port;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(port));
if (dtbl_entry != NULL) {
/*
* Is this protocol enabled?
*/
if (dtbl_entry->current.proto_index != -1 &&
!proto_is_protocol_enabled(dtbl_entry->current.proto_index)) {
/*
* No - pretend this dissector didn't exist,
* so that other dissectors might have a chance
* to dissect this packet.
*/
return FALSE;
}
/*
* Yes, it's enabled.
*/
saved_proto = pi.current_proto;
saved_match_port = pi.match_port;
pi.match_port = port;
if (dtbl_entry->current.is_old_dissector)
(*dtbl_entry->current.dissector.old)(pd, offset, fd, tree);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
else {
/*
* Old dissector calling new dissector; use
* "tvb_create_from_top()" to remap.
*
* XXX - what about the "pd" argument? Do
* any dissectors not just pass that along and
* let the "offset" argument handle stepping
* through the packet?
*/
if (dtbl_entry->current.proto_index != -1) {
pi.current_proto =
proto_get_protocol_short_name(dtbl_entry->current.proto_index);
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
tvb = tvb_create_from_top(offset);
(*dtbl_entry->current.dissector.new)(tvb, &pi, tree);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
}
pi.current_proto = saved_proto;
pi.match_port = saved_match_port;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
return TRUE;
} else
return FALSE;
}
gboolean
dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
dtbl_entry_t *dtbl_entry;
const guint8 *pd;
int offset;
const char *saved_proto;
guint32 saved_match_port;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry = g_hash_table_lookup(sub_dissectors,
GUINT_TO_POINTER(port));
if (dtbl_entry != NULL) {
/*
* Is this protocol enabled?
*/
if (dtbl_entry->current.proto_index != -1 &&
!proto_is_protocol_enabled(dtbl_entry->current.proto_index)) {
/*
* No - pretend this dissector didn't exist,
* so that other dissectors might have a chance
* to dissect this packet.
*/
return FALSE;
}
/*
* Yes, it's enabled.
*/
saved_proto = pinfo->current_proto;
saved_match_port = pinfo->match_port;
pinfo->match_port = port;
if (dtbl_entry->current.is_old_dissector) {
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/*
* New dissector calling old dissector; use
* "tvb_compat()" to remap.
*/
tvb_compat(tvb, &pd, &offset);
(*dtbl_entry->current.dissector.old)(pd, offset, pinfo->fd,
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
tree);
} else {
if (dtbl_entry->current.proto_index != -1) {
pinfo->current_proto =
proto_get_protocol_short_name(dtbl_entry->current.proto_index);
}
(*dtbl_entry->current.dissector.new)(tvb, pinfo, tree);
}
pinfo->current_proto = saved_proto;
pinfo->match_port = saved_match_port;
return TRUE;
} else
return FALSE;
}
gboolean
dissector_get_old_flag (dtbl_entry_t *dtbl_entry)
{
g_assert(dtbl_entry);
return(dtbl_entry->current.is_old_dissector);
}
gint
dissector_get_proto (dtbl_entry_t *dtbl_entry)
{
g_assert(dtbl_entry);
return(dtbl_entry->current.proto_index);
}
gint
dissector_get_initial_proto (dtbl_entry_t *dtbl_entry)
{
g_assert(dtbl_entry);
return(dtbl_entry->initial.proto_index);
}
/**************************************************/
/* */
/* Routines to walk dissector tables */
/* */
/**************************************************/
typedef struct dissector_foreach_info {
gpointer caller_data;
DATFunc caller_func;
GHFunc next_func;
gchar *table_name;
} dissector_foreach_info_t;
/*
* Walk all dissector tables calling a user supplied function on each
* entry. These three routines handle traversing the hash of hashes
* that is the dissector tables.
*/
static void
dissector_all_tables_foreach_func2 (gpointer key, gpointer value, gpointer user_data)
{
dissector_foreach_info_t *info;
dtbl_entry_t *dtbl_entry;
g_assert(value);
g_assert(user_data);
dtbl_entry = value;
if (dtbl_entry->current.proto_index == -1) {
return;
}
info = user_data;
info->caller_func(info->table_name, key, value, info->caller_data);
}
static void
dissector_all_tables_foreach_func1 (gpointer key, gpointer value, gpointer user_data)
{
GHashTable *hash_table;
dissector_foreach_info_t *info;
g_assert(value);
g_assert(user_data);
hash_table = value;
info = user_data;
info->table_name = (gchar*) key;
g_hash_table_foreach(hash_table, info->next_func, info);
}
void
dissector_all_tables_foreach (DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
info.caller_data = user_data;
info.caller_func = func;
info.next_func = dissector_all_tables_foreach_func2;
g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func1, &info);
}
/*
* Walk one dissector table calling a user supplied function on each
* entry.
*/
void
dissector_table_foreach (char *name,
DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
GHashTable *hash_table;
hash_table = find_dissector_table(name);
g_assert(hash_table);
info.table_name = name;
info.caller_func = func;
info.caller_data = user_data;
g_hash_table_foreach(hash_table, dissector_all_tables_foreach_func2, &info);
}
/*
* Walk all dissector tables calling a user supplied function only on
* any entry that has been changed from its original state. These two
* routines (plus one above) handle traversing the hash of hashes that
* is the dissector tables.
*/
static void
dissector_all_tables_foreach_changed_func2 (gpointer key, gpointer value, gpointer user_data)
{
dtbl_entry_t *dtbl_entry;
dissector_foreach_info_t *info;
g_assert(value);
g_assert(user_data);
dtbl_entry = value;
if (dtbl_entry->initial.proto_index == dtbl_entry->current.proto_index) {
return;
}
info = user_data;
info->caller_func(info->table_name, key, value, info->caller_data);
}
void
dissector_all_tables_foreach_changed (DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
info.caller_data = user_data;
info.caller_func = func;
info.next_func = dissector_all_tables_foreach_changed_func2;
g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func1, &info);
}
/*
* Walk one dissector table calling a user supplied function only on
* any entry that has been changed from its original state.
*/
void
dissector_table_foreach_changed (char *name,
DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
GHashTable *hash_table;
hash_table = find_dissector_table(name);
g_assert(hash_table);
info.table_name = name;
info.caller_func = func;
info.caller_data = user_data;
g_hash_table_foreach(hash_table, dissector_all_tables_foreach_changed_func2, &info);
}
dissector_table_t
register_dissector_table(const char *name)
{
dissector_table_t sub_dissectors;
/* Create our hash-of-hashes if it doesn't already exist */
if (!dissector_tables) {
dissector_tables = g_hash_table_new( g_str_hash, g_str_equal );
g_assert(dissector_tables);
}
/* Make sure the registration is unique */
g_assert(!g_hash_table_lookup( dissector_tables, name ));
/* 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;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/*
* XXX - for now, we support having both "old" dissectors, with packet
* data pointer, packet offset, frame_data pointer, and protocol tree
* pointer arguments, and "new" dissectors, with tvbuff pointer,
* packet_info pointer, and protocol tree pointer arguments.
*
* Nuke this and go back to storing a pointer to the dissector when
* the last old-style dissector is gone.
*/
typedef struct {
gboolean is_old_dissector;
union {
old_heur_dissector_t old;
heur_dissector_t new;
} dissector;
int proto_index;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
} heur_dtbl_entry_t;
/* 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);
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
void
old_heur_dissector_add(const char *name, old_heur_dissector_t dissector,
int proto)
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
{
heur_dissector_list_t *sub_dissectors = find_heur_dissector_list(name);
heur_dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert(sub_dissectors != NULL);
dtbl_entry = g_malloc(sizeof (heur_dtbl_entry_t));
dtbl_entry->is_old_dissector = TRUE;
dtbl_entry->dissector.old = dissector;
dtbl_entry->proto_index = proto;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* do the table insertion */
*sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dtbl_entry);
}
void
heur_dissector_add(const char *name, heur_dissector_t dissector, int proto)
{
heur_dissector_list_t *sub_dissectors = find_heur_dissector_list(name);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
heur_dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert(sub_dissectors != NULL);
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry = g_malloc(sizeof (heur_dtbl_entry_t));
dtbl_entry->is_old_dissector = FALSE;
dtbl_entry->dissector.new = dissector;
dtbl_entry->proto_index = proto;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
/* do the table insertion */
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
*sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dtbl_entry);
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
gboolean
dissector_try_heuristic(heur_dissector_list_t sub_dissectors,
tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
gboolean status;
const char *saved_proto;
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
GSList *entry;
heur_dtbl_entry_t *dtbl_entry;
const guint8 *pd = NULL;
int offset;
status = FALSE;
saved_proto = pinfo->current_proto;
for (entry = sub_dissectors; entry != NULL; entry = g_slist_next(entry)) {
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
dtbl_entry = (heur_dtbl_entry_t *)entry->data;
if (dtbl_entry->proto_index != -1 &&
!proto_is_protocol_enabled(dtbl_entry->proto_index)) {
/*
* No - don't try this dissector.
*/
continue;
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
if (dtbl_entry->is_old_dissector) {
/*
* New dissector calling old dissector; use
* "tvb_compat()" to remap.
*/
if (pd == NULL)
tvb_compat(tvb, &pd, &offset);
if ((*dtbl_entry->dissector.old)(pd, offset, pinfo->fd,
tree)) {
status = TRUE;
break;
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
} else {
if (dtbl_entry->proto_index != -1) {
pinfo->current_proto =
proto_get_protocol_short_name(dtbl_entry->proto_index);
}
if ((*dtbl_entry->dissector.new)(tvb, pinfo, tree)) {
status = TRUE;
break;
}
Allow either old-style (pre-tvbuff) or new-style (tvbuffified) dissectors to be registered as dissectors for particular ports, registered as heuristic dissectors, and registered as dissectors for conversations, and have routines to be used both by old-style and new-style dissectors to call registered dissectors. Have the code that calls those dissectors translate the arguments as necessary. (For conversation dissectors, replace "find_conversation_dissector()", which just returns a pointer to the dissector, with "old_try_conversation_dissector()" and "try_conversation_dissector()", which actually call the dissector, so that there's a single place at which we can do that translation. Also make "dissector_lookup()" static and, instead of calling it and, if it returns a non-null pointer, calling that dissector, just use "old_dissector_try_port()" or "dissector_try_port()", for the same reason.) This allows some dissectors that took old-style arguments and immediately translated them to new-style arguments to just take new-style arguments; make them do so. It also allows some new-style dissectors not to have to translate arguments before calling routines to look up and call dissectors; make them not do so. Get rid of checks for too-short frames in new-style dissectors - the tvbuff code does those checks for you. Give the routines to register old-style dissectors, and to call dissectors from old-style dissectors, names beginning with "old_", with the routines for new-style dissectors not having the "old_". Update the dissectors that use those routines appropriately. Rename "dissect_data()" to "old_dissect_data()", and "dissect_data_tvb()" to "dissect_data()". svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
}
}
pinfo->current_proto = saved_proto;
return status;
}
void
register_heur_dissector_list(const char *name, heur_dissector_list_t *sub_dissectors)
{
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
/* Create our hash-of-lists 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);
}
static GHashTable *conv_dissector_lists = NULL;
/*
* XXX - for now, we support having both "old" dissectors, with packet
* data pointer, packet offset, frame_data pointer, and protocol tree
* pointer arguments, and "new" dissectors, with tvbuff pointer,
* packet_info pointer, and protocol tree pointer arguments.
*
* Nuke this and go back to storing a pointer to the dissector when
* the last old-style dissector is gone.
*/
struct conv_dtbl_entry {
gboolean is_old_dissector;
union {
old_dissector_t old;
dissector_t new;
} dissector;
int proto_index;
};
/* Finds a conversation dissector table by table name. */
static conv_dissector_list_t *
find_conv_dissector_list(const char *name)
{
g_assert(conv_dissector_lists != NULL);
return g_hash_table_lookup(conv_dissector_lists, name);
}
void
old_conv_dissector_add(const char *name, old_dissector_t dissector,
int proto)
{
conv_dissector_list_t *sub_dissectors = find_conv_dissector_list(name);
conv_dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert(sub_dissectors != NULL);
dtbl_entry = g_malloc(sizeof (conv_dtbl_entry_t));
dtbl_entry->is_old_dissector = TRUE;
dtbl_entry->dissector.old = dissector;
dtbl_entry->proto_index = proto;
proto_set_protocol_dissector(proto, dissector);
/* do the table insertion */
*sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dtbl_entry);
}
void
conv_dissector_add(const char *name, dissector_t dissector, int proto)
{
conv_dissector_list_t *sub_dissectors = find_conv_dissector_list(name);
conv_dtbl_entry_t *dtbl_entry;
/* sanity check */
g_assert(sub_dissectors != NULL);
dtbl_entry = g_malloc(sizeof (conv_dtbl_entry_t));
dtbl_entry->is_old_dissector = FALSE;
dtbl_entry->dissector.new = dissector;
dtbl_entry->proto_index = proto;
proto_set_protocol_dissector(proto, dissector);
/* do the table insertion */
*sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dtbl_entry);
}
void
register_conv_dissector_list(const char *name, conv_dissector_list_t *sub_dissectors)
{
/* Create our hash-of-lists if it doesn't already exist */
if (conv_dissector_lists == NULL) {
conv_dissector_lists = g_hash_table_new(g_str_hash, g_str_equal);
g_assert(conv_dissector_lists != NULL);
}
/* Make sure the registration is unique */
g_assert(g_hash_table_lookup(conv_dissector_lists, name) == NULL);
*sub_dissectors = NULL; /* initially empty */
g_hash_table_insert(conv_dissector_lists, (gpointer)name,
(gpointer) sub_dissectors);
}
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
gboolean
conv_dissector_get_old_flag (conv_dtbl_entry_t *dtbl_entry)
{
g_assert(dtbl_entry);
return(dtbl_entry->is_old_dissector);
}
gint
conv_dissector_get_proto (conv_dtbl_entry_t *dtbl_entry)
{
g_assert(dtbl_entry);
return(dtbl_entry->proto_index);
}
void
dissector_conv_foreach (char *name,
DATFunc func,
gpointer user_data)
{
conv_dissector_list_t *sub_dissectors = find_conv_dissector_list(name);
GSList *tmp;
/* sanity check */
g_assert(sub_dissectors != NULL);
for (tmp = *sub_dissectors; tmp; tmp = g_slist_next(tmp)) {
func(name, 0, tmp->data, user_data);
}
}
static void
dissector_all_conv_foreach_func1 (gpointer key, gpointer value, gpointer user_data)
{
conv_dissector_list_t *sub_dissectors;
GSList *tmp;
dissector_foreach_info_t *info;
g_assert(value);
g_assert(user_data);
sub_dissectors = value;
for (tmp = *sub_dissectors; tmp; tmp = g_slist_next(tmp)) {
info = user_data;
info->caller_func(key, 0, tmp->data, info->caller_data);
}
}
void
dissector_all_conv_foreach (DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
info.caller_data = user_data;
info.caller_func = func;
g_hash_table_foreach(conv_dissector_lists, dissector_all_conv_foreach_func1, &info);
}
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
/*
* Register dissectors by name; used if one dissector always calls a
* particular dissector, or if it bases the decision of which dissector
* to call on something other than a numerical value or on "try a bunch
* of dissectors until one likes the packet".
*/
/*
* List of registered dissectors.
*/
static GHashTable *registered_dissectors = NULL;
/*
* An entry in the list of registered dissectors.
*/
struct dissector_handle {
const char *name; /* dissector name */
dissector_t dissector;
int proto_index;
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
};
/* Find a registered dissector by name. */
dissector_handle_t
find_dissector(const char *name)
{
g_assert(registered_dissectors != NULL);
return g_hash_table_lookup(registered_dissectors, name);
}
/* Register a dissector by name. */
void
register_dissector(const char *name, dissector_t dissector, int proto)
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
{
struct dissector_handle *handle;
/* Create our hash table if it doesn't already exist */
if (registered_dissectors == NULL) {
registered_dissectors = g_hash_table_new(g_str_hash, g_str_equal);
g_assert(registered_dissectors != NULL);
}
/* Make sure the registration is unique */
g_assert(g_hash_table_lookup(registered_dissectors, name) == NULL);
handle = g_malloc(sizeof (struct dissector_handle));
handle->name = name;
handle->dissector = dissector;
handle->proto_index = proto;
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
g_hash_table_insert(registered_dissectors, (gpointer)name,
(gpointer) handle);
}
/* Call a dissector through a handle. */
void
call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree)
{
const char *saved_proto;
if (handle->proto_index != -1 &&
!proto_is_protocol_enabled(handle->proto_index)) {
/*
* No - just dissect this packet as data.
*/
dissect_data(tvb, 0, pinfo, tree);
return;
}
saved_proto = pinfo->current_proto;
if (handle->proto_index != -1) {
pinfo->current_proto =
proto_get_protocol_short_name(handle->proto_index);
}
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
(*handle->dissector)(tvb, pinfo, tree);
pinfo->current_proto = saved_proto;
Add a mechanism by which a dissector can be registered by name, another dissector can get a "handle" for that dissector by name and then call that dissector through the handle. This allows dissectors that can't be called through a port table or a heuristic table to be called from other dissectors without directly referring to the dissector function - dynamically-loaded modules, under Windows, cannot directly call functions in the main program, and non-plugin dissectors are in the main program and thus cannot be called from plugin dissectors unless either 1) a pointer to the dissector is put in the Big Transfer Vector or 2) some other mechanism for getting a pointer to the dissector is provided. This mechanism could also support registering old-style dissectors and calling them from new-style dissectors without the new-style dissector having to do the argument translation itself (I didn't add support for registering old-style dissectors because I'd prefer to have people tvbuffify their code if they have to register a dissector...). It could also, in the future, perhaps support disabling of protocols; setting "pinfo->current_proto"; inside "call_dissector()" - and inside "{old_}dissector_try_port()" and "{old_"dissector_try_heuristic()" - allowing a pile of stuff that currently has to be done in every dissector be done by common code. (I have some ideas about how to do this, by having "proto_register_protocol()" take an abbreviation - of the sort that would be put in, for example, "pinfo->current_proto" - as an argument; having the calls to register dissectors take an index returned by "proto_register_protocol()" as an argument. The abbreviation could be used elsewhere as well, e.g. in the "Decoding" tab of the "Edit->Protocols" dialog box, and in a GUI for constructing protocol filters. Watch this space.) Make "dissect_sdp()" the first client of this mechanism; it's now static to "packet-sdp.c", and all dissectors that call it - including the MGCP plugin - now call it through a dissector handle fetched by "find_dissector()". (Next step - see if Ethereal can now compile on Windows as a result of this.) svn path=/trunk/; revision=2647
2000-11-15 07:07:52 +00:00
}