aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tap.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-05-16 11:37:28 -0700
committerGuy Harris <guy@alum.mit.edu>2015-05-16 18:38:26 +0000
commitcfc5a2e05f58d815b9e9c580daccb56b9c4714c0 (patch)
treea998181289f83f1668c738e5c5459670e076a187 /epan/tap.c
parent63295df6554a724cfa342cfbc299ee45807cd5ab (diff)
Have per-queued-packet flags, including "is a packet in error".
The contents of the packet_info structure change during the dissection process, so you can't rely on its contents when running tap listeners. Bug: 11184 Change-Id: I52fc45774add56ee2bcb5faef2af7c731b4304fd Reviewed-on: https://code.wireshark.org/review/8486 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/tap.c')
-rw-r--r--epan/tap.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/epan/tap.c b/epan/tap.c
index 0abcbdee71..605c4990ee 100644
--- a/epan/tap.c
+++ b/epan/tap.c
@@ -51,13 +51,39 @@ static tap_dissector_t *tap_dissector_list=NULL;
* in order to be as fast as possible as we need to build and tear down the
* queued list at least once for each packet we see and thus we must be able
* to build and tear it down as fast as possible.
+ *
+ * XXX - some fields in packet_info get overwritten in the dissection
+ * process, such as the addresses and the "this is an error packet" flag.
+ * A packet may be queued at multiple protocol layers, but the packet_info
+ * structure will, when the tap listeners are run, contain the values as
+ * set by the topmost protocol layers.
+ *
+ * This means that the tap listener code can't rely on pinfo->flags.in_error_pkt
+ * to determine whether the packet should be handed to the listener, as, for
+ * a protocol with error report packets that include a copy of the
+ * packet in error (ICMP, ICMPv6, CLNP), that flag changes during the
+ * processing of the packet depending on whether we're currently dissecting
+ * the packet in error or not.
+ *
+ *
+ * It also means that a tap listener can't depend on the source and destination
+ * addresses being the correct ones for the packet being processed if, for
+ * example, you have some tunneling that causes multiple layers of the same
+ * protocol.
+ *
+ * For now, we handle the error packet flag by setting a bit in the flags
+ * field of the tap_packet_t structure. We may ultimately want stacks of
+ * addresses for this and other reasons.
*/
typedef struct _tap_packet_t {
int tap_id;
+ guint32 flags;
packet_info *pinfo;
const void *tap_specific_data;
} tap_packet_t;
+#define TAP_PACKET_IS_ERROR_PACKET 0x00000001 /* packet being queued is an error packet */
+
#define TAP_PACKET_QUEUE_LEN 5000
static tap_packet_t tap_packet_array[TAP_PACKET_QUEUE_LEN];
static guint tap_packet_index;
@@ -245,6 +271,9 @@ tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data)
tpt=&tap_packet_array[tap_packet_index];
tpt->tap_id=tap_id;
+ tpt->flags = 0;
+ if (pinfo->flags.in_error_pkt)
+ tpt->flags |= TAP_PACKET_IS_ERROR_PACKET;
tpt->pinfo=pinfo;
tpt->tap_specific_data=tap_specific_data;
tap_packet_index++;
@@ -322,8 +351,8 @@ tap_push_tapped_queue(epan_dissect_t *edt)
for(i=0;i<tap_packet_index;i++){
for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
tp=&tap_packet_array[i];
- /* Don't tap the packet if its an "error" unless the listener tells us to */
- if ((!tp->pinfo->flags.in_error_pkt) || (tl->flags & TL_REQUIRES_ERROR_PACKETS))
+ /* Don't tap the packet if it's an "error" unless the listener tells us to */
+ if ((!tp->flags & TAP_PACKET_IS_ERROR_PACKET) || (tl->flags & TL_REQUIRES_ERROR_PACKETS))
{
if(tp->tap_id==tl->tap_id){
gboolean passed=TRUE;