forked from osmocom/wireshark
Fix 'Decode As' when used with IPv6-in-IPv6 packets
Add the ability to identify an instance of the dissector table to be modified by 'Decode As' thanks to pinfo->curr_layer_num For now only IPv6 makes use of it but it could be extended to any other protocol Also get rid of ipv6.nxt protocol: it is not required for 'Decode As' functionality and was colliding with ipv6.nxt field Change-Id: I3c7403c77328ad7170e13af028d178f962a2b508 Reviewed-on: https://code.wireshark.org/review/10552 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: João Valverde <j@v6e.pt> Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
This commit is contained in:
parent
608029b331
commit
1d7bcb28f9
|
@ -107,7 +107,6 @@ typedef struct {
|
|||
static int ipv6_tap = -1;
|
||||
|
||||
static int proto_ipv6 = -1;
|
||||
static int proto_ipv6_nxt = -1;
|
||||
static int proto_ipv6_hopopts = -1;
|
||||
static int proto_ipv6_routing = -1;
|
||||
static int proto_ipv6_shim6 = -1;
|
||||
|
@ -340,23 +339,23 @@ static expert_field ei_ipv6_invalid_header = EI_INIT;
|
|||
static void ipv6_prompt(packet_info *pinfo, gchar* result)
|
||||
{
|
||||
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IP protocol %u as",
|
||||
GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_VALUE)));
|
||||
GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_VALUE)));
|
||||
}
|
||||
|
||||
static gpointer ipv6_value(packet_info *pinfo)
|
||||
{
|
||||
return p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_VALUE);
|
||||
return p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_VALUE);
|
||||
}
|
||||
|
||||
static void ipv6_next_header_prompt(packet_info *pinfo, gchar* result)
|
||||
{
|
||||
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IP Next Header %u as",
|
||||
GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_NXT_HDR)));
|
||||
GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_NXT_HDR)));
|
||||
}
|
||||
|
||||
static gpointer ipv6_next_header_value(packet_info *pinfo)
|
||||
{
|
||||
return p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_NXT_HDR);
|
||||
return p_get_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_NXT_HDR);
|
||||
}
|
||||
|
||||
static const char* ipv6_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
|
||||
|
@ -2036,12 +2035,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
offset + IP6H_CTL_PLEN, 2, ENC_BIG_ENDIAN);
|
||||
|
||||
proto_tree_add_item(ipv6_tree, hf_ipv6_nxt, tvb, offset + IP6H_CTL_NXT, 1, ENC_NA);
|
||||
}
|
||||
|
||||
/* Needed for Decode As */
|
||||
wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_ipv6_nxt));
|
||||
|
||||
if (tree) {
|
||||
proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
|
||||
offset + IP6H_CTL_HLIM, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
|
@ -2237,7 +2231,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* start of the new header (could be a extension header) */
|
||||
nxt = tvb_get_guint8(tvb, offset + 6);
|
||||
/* Save next header value for Decode As dialog */
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_NXT_HDR, GUINT_TO_POINTER((guint)nxt));
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_NXT_HDR, GUINT_TO_POINTER((guint)nxt));
|
||||
offset += (int)sizeof(struct ip6_hdr);
|
||||
offlg = 0;
|
||||
ident = 0;
|
||||
|
@ -2351,7 +2345,7 @@ again:
|
|||
proto_item_set_len (ipv6_item, offset);
|
||||
|
||||
/* collect packet info */
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_ipv6, IPV6_PROTO_VALUE, GUINT_TO_POINTER((guint)nxt));
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_ipv6, (pinfo->curr_layer_num<<8) | IPV6_PROTO_VALUE, GUINT_TO_POINTER((guint)nxt));
|
||||
tap_queue_packet(ipv6_tap, pinfo, ipv6);
|
||||
|
||||
if (offlg & IP6F_OFF_MASK || (ipv6_reassemble && offlg & IP6F_MORE_FRAG)) {
|
||||
|
@ -3185,7 +3179,7 @@ proto_register_ipv6(void)
|
|||
|
||||
static build_valid_func ipv6_next_header_da_build_value[1] = {ipv6_next_header_value};
|
||||
static decode_as_value_t ipv6_next_header_da_values = {ipv6_next_header_prompt, 1, ipv6_next_header_da_build_value};
|
||||
static decode_as_t ipv6_next_header_da = {"ipv6.nxt", "IPv6 Next Header", "ipv6.nxt", 1, 0, &ipv6_next_header_da_values, NULL, NULL,
|
||||
static decode_as_t ipv6_next_header_da = {"ipv6", "IPv6 Next Header", "ipv6.nxt", 1, 0, &ipv6_next_header_da_values, NULL, NULL,
|
||||
decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
|
||||
|
||||
module_t *ipv6_module;
|
||||
|
@ -3197,7 +3191,6 @@ proto_register_ipv6(void)
|
|||
expert_ipv6 = expert_register_protocol(proto_ipv6);
|
||||
expert_register_field_array(expert_ipv6, ei, array_length(ei));
|
||||
|
||||
proto_ipv6_nxt = proto_register_protocol("IPv6 Next Header", "IPv6 Next Header", "ipv6.nxt");
|
||||
proto_ipv6_hopopts = proto_register_protocol("IPv6 Hop-by-Hop Options", "IPv6 Hop-by-Hop", "ipv6.hopopts");
|
||||
proto_ipv6_routing = proto_register_protocol("IPv6 Routing", "IPv6 Routing", "ipv6.routing_hdr");
|
||||
proto_ipv6_shim6 = proto_register_protocol("IPv6 SHIM6", "SHIM6", "ipv6.shim6");
|
||||
|
|
|
@ -79,10 +79,11 @@
|
|||
#define E_LIST_S_MAX E_LIST_S_TABLE
|
||||
#define E_LIST_S_COLUMNS (E_LIST_S_MAX + 1)
|
||||
|
||||
#define E_PAGE_LIST "notebook_page_list"
|
||||
#define E_PAGE_TABLE "notebook_page_table_name"
|
||||
#define E_PAGE_TITLE "notebook_page_title"
|
||||
#define E_PAGE_VALUE "notebook_page_value"
|
||||
#define E_PAGE_LIST "notebook_page_list"
|
||||
#define E_PAGE_TABLE "notebook_page_table_name"
|
||||
#define E_PAGE_TITLE "notebook_page_title"
|
||||
#define E_PAGE_VALUE "notebook_page_value"
|
||||
#define E_PAGE_CURR_LAYER_NUM "notebook_page_curr_layer_num"
|
||||
|
||||
#define E_PAGE_ACTION "notebook_page_action"
|
||||
|
||||
|
@ -671,12 +672,15 @@ decode_simple (GtkWidget *notebook_pg)
|
|||
/* Apply values to dissector table (stored in entry) */
|
||||
for (value_loop = 0; value_loop < entry->values[requested_index].num_values; value_loop++)
|
||||
{
|
||||
guint8 saved_curr_layer_num = cfile.edt->pi.curr_layer_num;
|
||||
cfile.edt->pi.curr_layer_num = (guint8)GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(notebook_pg), E_PAGE_CURR_LAYER_NUM));
|
||||
value_ptr = entry->values[requested_index].build_values[value_loop](&cfile.edt->pi);
|
||||
if (abbrev != NULL && strcmp(abbrev, "(default)") == 0) {
|
||||
add_reset_list = entry->reset_value(table_name, value_ptr);
|
||||
} else {
|
||||
add_reset_list = entry->change_value(table_name, value_ptr, &handle, abbrev);
|
||||
}
|
||||
cfile.edt->pi.curr_layer_num = saved_curr_layer_num;
|
||||
|
||||
if (add_reset_list) {
|
||||
selector_type = g_new(guint,1);
|
||||
|
@ -1214,6 +1218,7 @@ decode_add_simple_page (decode_as_t *entry)
|
|||
if (entry->num_items == 1)
|
||||
{
|
||||
g_object_set_data(G_OBJECT(page), E_PAGE_VALUE, entry->values[0].build_values[0](&cfile.edt->pi));
|
||||
g_object_set_data(G_OBJECT(page), E_PAGE_CURR_LAYER_NUM, GUINT_TO_POINTER(cfile.edt->pi.curr_layer_num));
|
||||
|
||||
/* Always enabled */
|
||||
entry->values->label_func(&cfile.edt->pi, prompt);
|
||||
|
@ -1303,6 +1308,9 @@ decode_add_notebook (GtkWidget *format_hb)
|
|||
const char* proto_name;
|
||||
GList *list_entry;
|
||||
decode_as_t *entry;
|
||||
guint8 saved_curr_layer_num = cfile.edt->pi.curr_layer_num;
|
||||
|
||||
cfile.edt->pi.curr_layer_num = 1;
|
||||
|
||||
/* Start a nootbook for flipping between sets of changes */
|
||||
notebook = gtk_notebook_new();
|
||||
|
@ -1332,8 +1340,11 @@ decode_add_notebook (GtkWidget *format_hb)
|
|||
}
|
||||
|
||||
protos = wmem_list_frame_next(protos);
|
||||
cfile.edt->pi.curr_layer_num++;
|
||||
}
|
||||
|
||||
cfile.edt->pi.curr_layer_num = saved_curr_layer_num;
|
||||
|
||||
/* Select the last added page (selects first by default) */
|
||||
/* Notebook must be visible for set_page to work. */
|
||||
gtk_widget_show_all(notebook);
|
||||
|
|
|
@ -62,6 +62,13 @@ typedef struct _dissector_info_t {
|
|||
|
||||
Q_DECLARE_METATYPE(dissector_info_t *)
|
||||
|
||||
typedef struct _table_item_t {
|
||||
const gchar* proto_name;
|
||||
guint8 curr_layer_num;
|
||||
} table_item_t;
|
||||
|
||||
Q_DECLARE_METATYPE(table_item_t)
|
||||
|
||||
DecodeAsDialog::DecodeAsDialog(QWidget *parent, capture_file *cf, bool create_new) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DecodeAsDialog),
|
||||
|
@ -220,6 +227,7 @@ void DecodeAsDialog::on_decodeAsTreeWidget_itemActivated(QTreeWidgetItem *item,
|
|||
if (cap_file_ && cap_file_->edt) {
|
||||
bool copying = !current_text.isEmpty();
|
||||
wmem_list_frame_t * protos = wmem_list_head(cap_file_->edt->pi.layers);
|
||||
guint8 curr_layer_num = 1;
|
||||
while (protos != NULL) {
|
||||
int proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
|
||||
const gchar * proto_name = proto_get_protocol_filter_name(proto_id);
|
||||
|
@ -227,7 +235,10 @@ void DecodeAsDialog::on_decodeAsTreeWidget_itemActivated(QTreeWidgetItem *item,
|
|||
decode_as_t *entry = (decode_as_t *) cur->data;
|
||||
if (g_strcmp0(proto_name, entry->name) == 0) {
|
||||
QString table_ui_name = get_dissector_table_ui_name(entry->table_name);
|
||||
table_names_combo_box_->insertItem(0, table_ui_name, entry->table_name);
|
||||
table_item_t table_item;
|
||||
table_item.proto_name = proto_name;
|
||||
table_item.curr_layer_num = curr_layer_num;
|
||||
table_names_combo_box_->insertItem(0, table_ui_name, QVariant::fromValue<table_item_t>(table_item));
|
||||
da_set.remove(table_ui_name);
|
||||
if (!copying) {
|
||||
current_text = table_ui_name;
|
||||
|
@ -235,6 +246,7 @@ void DecodeAsDialog::on_decodeAsTreeWidget_itemActivated(QTreeWidgetItem *item,
|
|||
}
|
||||
}
|
||||
protos = wmem_list_frame_next(protos);
|
||||
curr_layer_num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,11 +436,21 @@ void DecodeAsDialog::tableNamesCurrentIndexChanged(const QString &text)
|
|||
|
||||
selector_combo_box_->clear();
|
||||
|
||||
QVariant variant = table_names_combo_box_->itemData(table_names_combo_box_->currentIndex());
|
||||
gint8 curr_layer_num_saved = cap_file_->edt->pi.curr_layer_num;
|
||||
const gchar *proto_name = NULL;
|
||||
if (variant.canConvert<table_item_t>()) {
|
||||
table_item_t table_item = variant.value<table_item_t>();
|
||||
cap_file_->edt->pi.curr_layer_num = table_item.curr_layer_num;
|
||||
proto_name = table_item.proto_name;
|
||||
}
|
||||
|
||||
QSet<dissector_info_t *> dissector_info_set;
|
||||
GList *cur;
|
||||
for (cur = decode_as_list; cur; cur = cur->next) {
|
||||
decode_as_t *entry = (decode_as_t *) cur->data;
|
||||
if (g_strcmp0(ui_name_to_name_[text], entry->table_name) == 0) {
|
||||
if ((g_strcmp0(proto_name, entry->name) == 0) &&
|
||||
(g_strcmp0(ui_name_to_name_[text], entry->table_name) == 0)) {
|
||||
if (cap_file_ && cap_file_->edt) {
|
||||
for (uint ni = 0; ni < entry->num_items; ni++) {
|
||||
if (entry->values[ni].num_values == 1) { // Skip over multi-value ("both") entries
|
||||
|
@ -441,6 +463,7 @@ void DecodeAsDialog::tableNamesCurrentIndexChanged(const QString &text)
|
|||
entry->populate_list(entry->table_name, decodeAddProtocol, &dissector_info_set);
|
||||
}
|
||||
}
|
||||
cap_file_->edt->pi.curr_layer_num = curr_layer_num_saved;
|
||||
if (selector_combo_box_->count() > 0) {
|
||||
selector_combo_box_->setCurrentIndex(0);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue