summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-11-05 17:48:48 +0000
committerEvan Huus <eapache@gmail.com>2013-11-05 17:48:48 +0000
commit389423aaaac460f5b0fcbaf37b4f3d5cd7941c5b (patch)
tree7ad4c2fcd1bb606b9c88d33e6489650aafe4f661
parentd04079eedc5e7ea91b3ca940ce43d7fa4dd47856 (diff)
downloadwireshark-389423aaaac460f5b0fcbaf37b4f3d5cd7941c5b.tar.gz
Replace pinfo->layer_names as a string with pinfo->layers as a wmem_list of
protocol IDs. This is substantially more efficient, which means we can build it all the time rather than only if tree (in my benchmarks the extra time taken is not large enough to be statistically significant even over tens of thousands of packets). This fixes what was probably a bug in btobex that relied on layer_names for non-tree dissection. It also enables a much simpler fix for https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9303 svn path=/trunk/; revision=53089
-rw-r--r--epan/dissectors/packet-btobex.c6
-rw-r--r--epan/dissectors/packet-btrfcomm.c2
-rw-r--r--epan/dissectors/packet-btrfcomm.h2
-rw-r--r--epan/dissectors/packet-frame.c36
-rw-r--r--epan/dissectors/packet-icmp.c2
-rw-r--r--epan/dissectors/packet-icmp.h2
-rw-r--r--epan/dissectors/packet-ip.c2
-rw-r--r--epan/dissectors/packet-ip.h2
-rw-r--r--epan/dissectors/packet-tcp.c21
-rw-r--r--epan/packet.c35
-rw-r--r--epan/packet_info.h7
11 files changed, 68 insertions, 49 deletions
diff --git a/epan/dissectors/packet-btobex.c b/epan/dissectors/packet-btobex.c
index db55218199..b55f49be40 100644
--- a/epan/dissectors/packet-btobex.c
+++ b/epan/dissectors/packet-btobex.c
@@ -1275,10 +1275,14 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
guint32 k_channel;
obex_last_opcode_data_t *obex_last_opcode_data;
guint32 k_direction;
+ gint parent_proto;
save_fragmented = pinfo->fragmented;
- if (!pinfo->fd->flags.visited && pinfo->layer_names && !g_strrstr(pinfo->layer_names->str, "btrfcomm")) {
+ parent_proto = (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
+ wmem_list_frame_prev(wmem_list_tail(pinfo->layers))));
+
+ if (!pinfo->fd->flags.visited && parent_proto == proto_btrfcomm) {
wmem_tree_insert32(obex_over_l2cap, pinfo->fd->num, (void *) TRUE);
} else {
is_obex_over_l2cap = wmem_tree_lookup32(obex_over_l2cap, pinfo->fd->num) ? TRUE : FALSE;
diff --git a/epan/dissectors/packet-btrfcomm.c b/epan/dissectors/packet-btrfcomm.c
index bdd90d5e57..1ab4dfb517 100644
--- a/epan/dissectors/packet-btrfcomm.c
+++ b/epan/dissectors/packet-btrfcomm.c
@@ -98,7 +98,7 @@ static int hf_address = -1;
static int hf_control = -1;
/* Initialize the protocol and registered fields */
-static int proto_btrfcomm = -1;
+int proto_btrfcomm = -1;
static int proto_btdun = -1;
static int proto_btspp = -1;
static int proto_btgnss = -1;
diff --git a/epan/dissectors/packet-btrfcomm.h b/epan/dissectors/packet-btrfcomm.h
index 986c0d1eb2..78c2b83dae 100644
--- a/epan/dissectors/packet-btrfcomm.h
+++ b/epan/dissectors/packet-btrfcomm.h
@@ -24,6 +24,8 @@
#ifndef __PACKET_BTRFCOMM_H__
#define __PACKET_BTRFCOMM_H__
+extern int proto_btrfcomm;
+
typedef struct _btrfcomm_data_t {
guint32 interface_id;
guint32 adapter_id;
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index ad27194933..826c9eb09c 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -415,11 +415,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, "");
PROTO_ITEM_SET_GENERATED(ti);
proto_tree_set_visible(fh_tree, old_visible);
-
- pinfo->layer_names = g_string_new("");
}
- else
- pinfo->layer_names = NULL;
if(pinfo->fd->pfd != 0){
proto_item *ppd_item;
@@ -523,10 +519,21 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
ENDTRY;
- if (tree && pinfo->layer_names) {
- proto_item_append_string(ti, pinfo->layer_names->str);
- g_string_free(pinfo->layer_names, TRUE);
- pinfo->layer_names = NULL;
+ if(proto_field_is_referenced(tree, hf_frame_protocols)) {
+ wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
+ wmem_list_frame_t *frame;
+ /* skip the first entry, it's always the "frame" protocol */
+ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
+ if (frame) {
+ wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
+ frame = wmem_list_frame_next(frame);
+ }
+ while (frame) {
+ wmem_strbuf_append_c(val, ':');
+ wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
+ frame = wmem_list_frame_next(frame);
+ }
+ proto_item_append_string(ti, wmem_strbuf_get_str(val));
}
/* Call postdissectors if we have any (while trying to avoid another
@@ -846,3 +853,16 @@ proto_reg_handoff_frame(void)
data_handle = find_dissector("data");
docsis_handle = find_dissector("docsis");
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */
diff --git a/epan/dissectors/packet-icmp.c b/epan/dissectors/packet-icmp.c
index d9cd166cbd..c7a05002c5 100644
--- a/epan/dissectors/packet-icmp.c
+++ b/epan/dissectors/packet-icmp.c
@@ -73,7 +73,7 @@ static icmp_transaction_t *transaction_end(packet_info * pinfo,
if the packet in the payload has more than 128 bytes */
static gboolean favor_icmp_mpls_ext = FALSE;
-static int proto_icmp = -1;
+int proto_icmp = -1;
static int hf_icmp_type = -1;
static int hf_icmp_code = -1;
static int hf_icmp_checksum = -1;
diff --git a/epan/dissectors/packet-icmp.h b/epan/dissectors/packet-icmp.h
index 93c1efb2e8..5e7917bec2 100644
--- a/epan/dissectors/packet-icmp.h
+++ b/epan/dissectors/packet-icmp.h
@@ -25,6 +25,8 @@
#ifndef __PACKET_ICMP_H__
#define __PACKET_ICMP_H__
+extern int proto_icmp;
+
/* ICMP echo request/reply transaction statistics ... used by ICMP tap(s) */
typedef struct _icmp_transaction_t {
guint32 rqst_frame;
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 589ba2ba6b..abe4156611 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -88,7 +88,7 @@ static gboolean ip_use_geoip = TRUE;
/* Interpret the reserved flag as security flag (RFC 3514) */
static gboolean ip_security_flag = FALSE;
-static int proto_ip = -1;
+int proto_ip = -1;
static int hf_ip_version = -1;
static int hf_ip_hdr_len = -1;
static int hf_ip_dsfield = -1;
diff --git a/epan/dissectors/packet-ip.h b/epan/dissectors/packet-ip.h
index 249b387040..de2e8ea540 100644
--- a/epan/dissectors/packet-ip.h
+++ b/epan/dissectors/packet-ip.h
@@ -28,6 +28,8 @@
#include "ws_symbol_export.h"
+extern int proto_ip;
+
typedef struct _ws_ip
{
guint8 ip_v_hl; /* combines ip_v and ip_hl */
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 0b0e09b709..3464005607 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -43,6 +43,8 @@
#include <epan/tap.h>
#include "packet-tcp.h"
+#include "packet-ip.h"
+#include "packet-icmp.h"
static int tcp_tap = -1;
@@ -4079,16 +4081,15 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* carry enough TCP payload for this dissector to put the sequence
* numbers in via the regular code path.
*/
- if (pinfo->layer_names != NULL && pinfo->layer_names->str != NULL) {
- /* use strstr because g_strrstr is only present in glib2.0 and
- * g_str_has_suffix in glib2.2
- *
- * TODO: Both g_strrstr and g_str_has_suffix could be used now, so
- * should we use one of them? And if g_str_has_suffix, then
- * the needle probably needs to be "icmp:ip:tcp", doesn't it?
- */
- if (strstr(pinfo->layer_names->str, "icmp:ip") != NULL)
- proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
+ {
+ wmem_list_frame_t *frame;
+ frame = wmem_list_frame_prev(wmem_list_tail(pinfo->layers));
+ if (proto_ip == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
+ frame = wmem_list_frame_prev(frame);
+ if (proto_icmp == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
+ proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
+ }
+ }
}
}
diff --git a/epan/packet.c b/epan/packet.c
index e84bd1f24c..09e38ad2b2 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -427,8 +427,10 @@ dissect_packet(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
edt->pi.annex_a_used = MTP2_ANNEX_A_USED_UNKNOWN;
edt->pi.dcerpc_procedure_name="";
edt->pi.link_dir = LINK_DIR_UNKNOWN;
+ edt->pi.layers = wmem_list_new(edt->pi.pool);
edt->tvb = tvb;
+
frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
/* pkt comment use first user, later from phdr */
@@ -551,7 +553,7 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
const char *saved_proto;
guint16 saved_can_desegment;
int ret;
- gint saved_layer_names_len = 0;
+ guint saved_layers_len = 0;
if (handle->protocol != NULL &&
!proto_is_protocol_enabled(handle->protocol)) {
@@ -563,9 +565,7 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
saved_proto = pinfo->current_proto;
saved_can_desegment = pinfo->can_desegment;
-
- if (pinfo->layer_names != NULL)
- saved_layer_names_len = (gint) pinfo->layer_names->len;
+ saved_layers_len = wmem_list_count(pinfo->layers);
/*
* can_desegment is set to 2 by anyone which offers the
@@ -591,12 +591,7 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
*/
if (add_proto_name) {
pinfo->curr_layer_num++;
- if (pinfo->layer_names) {
- if (pinfo->layer_names->len > 0)
- g_string_append(pinfo->layer_names, ":");
- g_string_append(pinfo->layer_names,
- proto_get_protocol_filter_name(proto_get_id(handle->protocol)));
- }
+ wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_get_id(handle->protocol)));
}
}
@@ -614,8 +609,8 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
* remove its protocol's name from the list
* of protocols.
*/
- if ((pinfo->layer_names != NULL)&&(add_proto_name)) {
- g_string_truncate(pinfo->layer_names, saved_layer_names_len);
+ while (wmem_list_count(pinfo->layers) > saved_layers_len) {
+ wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
}
}
pinfo->current_proto = saved_proto;
@@ -1814,7 +1809,7 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
GSList *entry;
heur_dtbl_entry_t *hdtbl_entry;
guint16 saved_can_desegment;
- gint saved_layer_names_len = 0;
+ guint saved_layers_len = 0;
/* can_desegment is set to 2 by anyone which offers this api/service.
then everytime a subdissector is called it is decremented by one.
@@ -1832,8 +1827,7 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
status = FALSE;
saved_proto = pinfo->current_proto;
- if (pinfo->layer_names != NULL)
- saved_layer_names_len = (gint) pinfo->layer_names->len;
+ saved_layers_len = wmem_list_count(pinfo->layers);
for (entry = sub_dissectors; entry != NULL; entry = g_slist_next(entry)) {
/* XXX - why set this now and above? */
@@ -1856,12 +1850,7 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
* Add the protocol name to the layers; we'll remove it
* if the dissector fails.
*/
- if (pinfo->layer_names) {
- if (pinfo->layer_names->len > 0)
- g_string_append(pinfo->layer_names, ":");
- g_string_append(pinfo->layer_names,
- proto_get_protocol_filter_name(proto_get_id(hdtbl_entry->protocol)));
- }
+ wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_get_id(hdtbl_entry->protocol)));
}
EP_CHECK_CANARY(("before calling heuristic dissector for protocol: %s",
proto_get_protocol_filter_name(proto_get_id(hdtbl_entry->protocol))));
@@ -1879,8 +1868,8 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
* remove its protocol's name from the list
* of protocols.
*/
- if (pinfo->layer_names != NULL) {
- g_string_truncate(pinfo->layer_names, saved_layer_names_len);
+ while (wmem_list_count(pinfo->layers) > saved_layers_len) {
+ wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
}
}
}
diff --git a/epan/packet_info.h b/epan/packet_info.h
index 508361401c..ce56ad4aff 100644
--- a/epan/packet_info.h
+++ b/epan/packet_info.h
@@ -185,11 +185,10 @@ typedef struct _packet_info {
void *private_data; /**< pointer to data passed from one dissector to another */
GHashTable *private_table; /**< a hash table passed from one dissector to another */
+ wmem_list_t *layers; /**< layers of each protocol */
guint8 curr_layer_num; /**< The current "depth" or layer number in the current frame */
- /* TODO: Use emem_strbuf_t instead */
- GString *layer_names; /**< layers of each protocol */
guint16 link_number;
- guint8 annex_a_used; /**< used in packet-mtp2.c
+ guint8 annex_a_used; /**< used in packet-mtp2.c
* defined in wtap.h
* MTP2_ANNEX_A_NOT_USED 0
* MTP2_ANNEX_A_USED 1
@@ -210,7 +209,7 @@ typedef struct _packet_info {
GSList *frame_end_routines;
- struct _wmem_allocator_t *pool; /**< Memory pool scoped to the pinfo struct */
+ wmem_allocator_t *pool; /**< Memory pool scoped to the pinfo struct */
struct epan_session *epan;
nstime_t rel_ts; /**< Relative timestamp (yes, it can be negative) */
const gchar *pkt_comment; /**< NULL if not available */