"Decode As" dialog, from David Hampton.

svn path=/trunk/; revision=2965
This commit is contained in:
Guy Harris 2001-02-01 07:34:33 +00:00
parent 562eae009f
commit 8b51643203
11 changed files with 1909 additions and 30 deletions

View File

@ -499,6 +499,10 @@ Alexandre P. Ferreira <alexandref@spliceip.com.br> {
WSP fixes
}
David Hampton <dhampton@mac.com> {
"Decode As" dialog
}
Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to
give his permission to use his version of snprintf.c.

View File

@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
* $Id: packet.c,v 1.18 2001/01/13 06:34:33 guy Exp $
* $Id: packet.c,v 1.19 2001/02/01 07:34:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -1009,6 +1009,7 @@ void blank_packetinfo(void)
pi.net_dst.type = AT_NONE;
pi.src.type = AT_NONE;
pi.dst.type = AT_NONE;
pi.ethertype = 0;
pi.ipproto = 0;
pi.ptype = PT_NONE;
pi.srcport = 0;
@ -1173,7 +1174,17 @@ typedef struct {
dissector_t new;
} dissector;
int proto_index;
} dtbl_entry_t;
} 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)
{
}
/* Finds a dissector table by field name. */
static dissector_table_t
@ -1196,9 +1207,11 @@ old_dissector_add(const char *name, guint32 pattern, old_dissector_t dissector,
g_assert( sub_dissectors);
dtbl_entry = g_malloc(sizeof (dtbl_entry_t));
dtbl_entry->is_old_dissector = TRUE;
dtbl_entry->dissector.old = dissector;
dtbl_entry->proto_index = proto;
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);
/* do the table insertion */
g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
@ -1216,9 +1229,11 @@ dissector_add(const char *name, guint32 pattern, dissector_t dissector,
g_assert( sub_dissectors);
dtbl_entry = g_malloc(sizeof (dtbl_entry_t));
dtbl_entry->is_old_dissector = FALSE;
dtbl_entry->dissector.new = dissector;
dtbl_entry->proto_index = proto;
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);
/* do the table insertion */
g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
@ -1288,6 +1303,78 @@ dissector_delete(const char *name, guint32 pattern, dissector_t dissector)
}
}
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
return FALSE.
@ -1309,8 +1396,8 @@ old_dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
/*
* Is this protocol enabled?
*/
if (dtbl_entry->proto_index != -1 &&
!proto_is_protocol_enabled(dtbl_entry->proto_index)) {
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
@ -1325,8 +1412,8 @@ old_dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
saved_proto = pi.current_proto;
saved_match_port = pi.match_port;
pi.match_port = port;
if (dtbl_entry->is_old_dissector)
(*dtbl_entry->dissector.old)(pd, offset, fd, tree);
if (dtbl_entry->current.is_old_dissector)
(*dtbl_entry->current.dissector.old)(pd, offset, fd, tree);
else {
/*
* Old dissector calling new dissector; use
@ -1337,12 +1424,12 @@ old_dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
* let the "offset" argument handle stepping
* through the packet?
*/
if (dtbl_entry->proto_index != -1) {
if (dtbl_entry->current.proto_index != -1) {
pi.current_proto =
proto_get_protocol_short_name(dtbl_entry->proto_index);
proto_get_protocol_short_name(dtbl_entry->current.proto_index);
}
tvb = tvb_create_from_top(offset);
(*dtbl_entry->dissector.new)(tvb, &pi, tree);
(*dtbl_entry->current.dissector.new)(tvb, &pi, tree);
}
pi.current_proto = saved_proto;
pi.match_port = saved_match_port;
@ -1367,8 +1454,8 @@ dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
/*
* Is this protocol enabled?
*/
if (dtbl_entry->proto_index != -1 &&
!proto_is_protocol_enabled(dtbl_entry->proto_index)) {
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
@ -1383,20 +1470,20 @@ dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
saved_proto = pinfo->current_proto;
saved_match_port = pinfo->match_port;
pinfo->match_port = port;
if (dtbl_entry->is_old_dissector) {
if (dtbl_entry->current.is_old_dissector) {
/*
* New dissector calling old dissector; use
* "tvb_compat()" to remap.
*/
tvb_compat(tvb, &pd, &offset);
(*dtbl_entry->dissector.old)(pd, offset, pinfo->fd,
(*dtbl_entry->current.dissector.old)(pd, offset, pinfo->fd,
tree);
} else {
if (dtbl_entry->proto_index != -1) {
if (dtbl_entry->current.proto_index != -1) {
pinfo->current_proto =
proto_get_protocol_short_name(dtbl_entry->proto_index);
proto_get_protocol_short_name(dtbl_entry->current.proto_index);
}
(*dtbl_entry->dissector.new)(tvb, pinfo, tree);
(*dtbl_entry->current.dissector.new)(tvb, pinfo, tree);
}
pinfo->current_proto = saved_proto;
pinfo->match_port = saved_match_port;
@ -1405,6 +1492,168 @@ dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
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)
{
@ -1569,14 +1818,14 @@ static GHashTable *conv_dissector_lists = NULL;
* Nuke this and go back to storing a pointer to the dissector when
* the last old-style dissector is gone.
*/
typedef struct {
struct conv_dtbl_entry {
gboolean is_old_dissector;
union {
old_dissector_t old;
dissector_t new;
} dissector;
int proto_index;
} conv_dtbl_entry_t;
};
/* Finds a conversation dissector table by table name. */
static conv_dissector_list_t *
@ -1600,6 +1849,7 @@ old_conv_dissector_add(const char *name, old_dissector_t dissector,
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);
@ -1618,6 +1868,7 @@ conv_dissector_add(const char *name, dissector_t dissector, int proto)
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);
@ -1640,6 +1891,64 @@ register_conv_dissector_list(const char *name, conv_dissector_list_t *sub_dissec
(gpointer) sub_dissectors);
}
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);
}
/*
* Register dissectors by name; used if one dissector always calls a
* particular dissector, or if it bases the decision of which dissector

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.20 2001/01/18 07:44:41 guy Exp $
* $Id: packet.h,v 1.21 2001/02/01 07:34:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -170,6 +170,7 @@ typedef struct _packet_info {
address net_dst; /* network-layer destination address */
address src; /* source address (net if present, DL otherwise )*/
address dst; /* destination address (net if present, DL otherwise )*/
guint32 ethertype; /* Ethernet Type Code, if this is an Ethernet packet */
guint32 ipproto; /* IP protocol, if this is an IP packet */
gboolean fragmented; /* TRUE if the protocol is only a fragment */
port_type ptype; /* type of the following two port numbers */
@ -206,6 +207,18 @@ typedef GHashTable* dissector_table_t;
typedef void (*old_dissector_t)(const u_char *, int, frame_data *, proto_tree *);
typedef void (*dissector_t)(tvbuff_t *, packet_info *, proto_tree *);
typedef void (*DATFunc) (gchar *table_name, gpointer key, gpointer value, gpointer user_data);
/* Opaque structure - provides type checking but no access to components */
typedef struct dtbl_entry dtbl_entry_t;
gboolean dissector_get_old_flag (dtbl_entry_t *entry);
gint dissector_get_proto (dtbl_entry_t * entry);
gint dissector_get_initial_proto (dtbl_entry_t * entry);
void dissector_table_foreach_changed (char *name, DATFunc func, gpointer user_data);
void dissector_table_foreach (char *name, DATFunc func, gpointer user_data);
void dissector_all_tables_foreach_changed (DATFunc func, gpointer user_data);
/* a protocol uses the function to register a sub-dissector table */
dissector_table_t register_dissector_table(const char *name);
@ -221,6 +234,11 @@ void dissector_add(const char *abbrev, guint32 pattern,
void old_dissector_delete(const char *name, guint32 pattern, old_dissector_t dissector);
void dissector_delete(const char *name, guint32 pattern, dissector_t dissector);
/* Reset a dissector in a sub-dissector table to its initial value. */
void dissector_change(const char *abbrev, guint32 pattern,
dissector_t dissector, gboolean old, int proto);
void dissector_reset(const char *name, guint32 pattern);
/* Look for a given port in a given dissector table and, if found, call
the dissector with the arguments supplied, and return TRUE, otherwise
return FALSE. */
@ -281,6 +299,14 @@ void old_conv_dissector_add(const char *name, old_dissector_t dissector,
void conv_dissector_add(const char *name, dissector_t dissector,
int proto);
/* Opaque structure - provides type checking but no access to components */
typedef struct conv_dtbl_entry conv_dtbl_entry_t;
gboolean conv_dissector_get_old_flag (conv_dtbl_entry_t *entry);
gint conv_dissector_get_proto (conv_dtbl_entry_t * entry);
void dissector_conv_foreach(char *name, DATFunc func, gpointer user_data);
void dissector_all_conv_foreach(DATFunc func, gpointer user_data);
/* Handle for dissectors you call directly.
This handle is opaque outside of "packet.c". */
struct dissector_handle;

View File

@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
* $Id: proto.c,v 1.5 2001/01/26 06:14:50 guy Exp $
* $Id: proto.c,v 1.6 2001/02/01 07:34:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -126,6 +126,7 @@ typedef struct {
GList *last_field; /* pointer to end of list of fields */
gboolean is_enabled; /* TRUE if protocol is enabled */
gboolean can_disable; /* TRUE if protocol can be disabled */
gpointer dissector;
} protocol_t;
/* List of all protocols */
@ -1519,6 +1520,7 @@ proto_register_protocol(char *name, char *short_name, char *filter_name)
protocol->fields = NULL;
protocol->is_enabled = TRUE; /* protocol is enabled by default */
protocol->can_disable = TRUE;
protocol->dissector = NULL;
protocols = g_list_insert_sorted(protocols, protocol,
proto_compare_name);
@ -1608,6 +1610,8 @@ proto_get_protocol_short_name(int proto_id)
{
protocol_t *protocol;
if (proto_id == -1)
return "(none)";
protocol = find_protocol_by_id(proto_id);
return protocol->short_name;
}
@ -1658,6 +1662,32 @@ proto_set_cant_disable(int proto_id)
protocol->can_disable = FALSE;
}
gpointer
proto_get_protocol_dissector(int proto_id)
{
protocol_t *protocol;
protocol = find_protocol_by_id(proto_id);
if (protocol == NULL)
return(NULL);
return protocol->dissector;
}
void
proto_set_protocol_dissector(int proto_id, gpointer dissector)
{
protocol_t *protocol;
protocol = find_protocol_by_id(proto_id);
if (protocol != NULL) {
if (protocol->dissector != NULL) {
/* Already set */
return;
}
protocol->dissector = dissector;
}
}
/* for use with static arrays only, since we don't allocate our own copies
of the header_field_info struct contained withing the hf_register_info struct */
void

View File

@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
* $Id: proto.h,v 1.4 2001/01/26 06:14:50 guy Exp $
* $Id: proto.h,v 1.5 2001/02/01 07:34:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -525,6 +525,9 @@ void proto_set_decoding(int proto_id, gboolean enabled);
/* Disable disabling of protocol */
void proto_set_cant_disable(int proto_id);
gpointer proto_get_protocol_dissector(int proto_id);
void proto_set_protocol_dissector(int proto_id, gpointer dissector);
/* Get length of registered field according to field type.
* 0 means undeterminable at registration time.
* -1 means unknown field */

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for the GTK interface routines for Ethereal
#
# $Id: Makefile.am,v 1.32 2001/01/02 01:32:21 guy Exp $
# $Id: Makefile.am,v 1.33 2001/02/01 07:34:33 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -39,6 +39,8 @@ libui_a_SOURCES = \
color_utils.h \
column_prefs.c \
column_prefs.h \
decode_as_dlg.c \
decode_as_dlg.h \
dfilter_expr_dlg.c \
dfilter_expr_dlg.h \
display_opts.c \

View File

@ -19,6 +19,7 @@ OBJECTS=capture_dlg.obj \
colors.obj \
color_utils.obj \
column_prefs.obj \
decode_as_dlg.obj \
dfilter_expr_dlg.obj \
display_opts.obj \
dlg_utils.obj \

1462
gtk/decode_as_dlg.c Normal file

File diff suppressed because it is too large Load Diff

33
gtk/decode_as_dlg.h Normal file
View File

@ -0,0 +1,33 @@
/* decode_as_dlg.c
*
* $Id: decode_as_dlg.h,v 1.1 2001/02/01 07:34:33 guy Exp $
*
* Routines to modify dissector tables on the fly.
*
* By David Hampton <dhampton@mac.com>
* Copyright 2001 David Hampton
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __DECODE_AS_DLG_H__
#define __DECODE_AS_DLG_H__
void decode_as_cb(GtkWidget *, gpointer);
void decode_show_cb(GtkWidget *, gpointer);
void decode_as_register_tcpudp(gint);
#endif

View File

@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
* $Id: menu.c,v 1.47 2001/01/28 09:13:10 guy Exp $
* $Id: menu.c,v 1.48 2001/02/01 07:34:33 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -55,6 +55,7 @@
#include "packet_win.h"
#include "print.h"
#include "follow_dlg.h"
#include "decode_as_dlg.h"
#include "help_dlg.h"
#include "proto_dlg.h"
#include "keys.h"
@ -140,11 +141,13 @@ static GtkItemFactoryEntry menu_items[] =
{"/Display/Collapse _All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
{"/Display/_Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL},
{"/Display/_Show Packet In New Window", NULL, GTK_MENU_FUNC(new_window_cb), 0, NULL},
{"/Display/User Specified Decodes...", NULL, GTK_MENU_FUNC(decode_show_cb), 0, NULL},
{"/_Tools", NULL, NULL, 0, "<Branch>" },
#ifdef HAVE_PLUGINS
{"/Tools/_Plugins...", NULL, GTK_MENU_FUNC(tools_plugins_cmd_cb), 0, NULL},
#endif
{"/Tools/_Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Tools/_Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL},
/* {"/Tools/Graph", NULL, NULL, 0, NULL}, future use */
{"/Tools/_Summary", NULL, GTK_MENU_FUNC(summary_open_cb), 0, NULL},
{"/_Help", NULL, NULL, 0, "<LastBranch>" },
@ -160,6 +163,7 @@ static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
static GtkItemFactoryEntry packet_list_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL},
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL},
{"/<separator>", NULL, NULL, 0, "<Separator>"},
{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
@ -171,6 +175,7 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
static GtkItemFactoryEntry tree_view_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL},
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL},
{"/<separator>", NULL, NULL, 0, "<Separator>"},
{"/Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL},
@ -184,6 +189,7 @@ static GtkItemFactoryEntry tree_view_menu_items[] =
static GtkItemFactoryEntry hexdump_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL},
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL}
};
@ -388,6 +394,7 @@ set_menus_for_selected_packet(gboolean have_selected_packet)
set_menu_sensitivity("/Display/Show Packet In New Window", have_selected_packet);
set_menu_sensitivity("/Tools/Follow TCP Stream",
have_selected_packet ? (pi.ipproto == 6) : FALSE);
set_menu_sensitivity("/Tools/Decode As...", have_selected_packet);
set_menu_sensitivity("/Resolve Name",
have_selected_packet && !g_resolving_actif);
}

View File

@ -1,7 +1,7 @@
/* ethertype.c
* Routines for calling the right protocol for the ethertype.
*
* $Id: packet-ethertype.c,v 1.11 2001/01/18 08:38:10 guy Exp $
* $Id: packet-ethertype.c,v 1.12 2001/02/01 07:34:29 guy Exp $
*
* Gilbert Ramirez <gram@xiexie.org>
*
@ -117,6 +117,8 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
/* Tvbuff for the payload after the Ethernet type. */
next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
pinfo->ethertype = etype;
/* Remember how much data there is in it. */
length_before = tvb_reported_length(next_tvb);