aboutsummaryrefslogtreecommitdiffstats
path: root/dumpcap.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2018-11-13 10:40:55 -0800
committerAnders Broman <a.broman58@gmail.com>2018-11-14 04:59:25 +0000
commit50433f4b4dde42ce50b0e2d899671c2b2cef526d (patch)
tree70e3b2c9fd7e67171d127bcd2296deb13be26829 /dumpcap.c
parent0795c988b072ef45e1a389d51b49ec4ee235c216 (diff)
Dumpcap: Move packet dequeueing code to a common routine.
Dequeue and write packets in capture_loop_dequeue_packet. This ensures that we properly handle pcapng packets both inside our capture loop and after it's finished. Change-Id: Iacc980c90481b1378761eac83d8044aaddabfdc2 Reviewed-on: https://code.wireshark.org/review/30609 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'dumpcap.c')
-rw-r--r--dumpcap.c96
1 files changed, 46 insertions, 50 deletions
diff --git a/dumpcap.c b/dumpcap.c
index 23fe8b03f0..51af62153c 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -3598,6 +3598,48 @@ pcap_read_handler(void* arg)
return (NULL);
}
+/* Try to pop an item off the packet queue and if it exists, write it */
+static gboolean
+capture_loop_dequeue_packet(void) {
+ pcap_queue_element *queue_element;
+
+ g_async_queue_lock(pcap_queue);
+ queue_element = (pcap_queue_element *)g_async_queue_timeout_pop_unlocked(pcap_queue, WRITER_THREAD_TIMEOUT);
+ if (queue_element) {
+ if (queue_element->pcap_src->from_pcapng) {
+ pcap_queue_bytes -= queue_element->u.bh.block_total_length;
+ } else {
+ pcap_queue_bytes -= queue_element->u.phdr.caplen;
+ }
+ pcap_queue_packets -= 1;
+ }
+ g_async_queue_unlock(pcap_queue);
+ if (queue_element) {
+ if (queue_element->pcap_src->from_pcapng) {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
+ "Dequeued a block of type 0x%08x of length %d captured on interface %d.",
+ queue_element->u.bh.block_type, queue_element->u.bh.block_total_length,
+ queue_element->pcap_src->interface_id);
+
+ capture_loop_write_pcapng_cb(queue_element->pcap_src,
+ &queue_element->u.bh,
+ queue_element->pd);
+ } else {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
+ "Dequeued a packet of length %d captured on interface %d.",
+ queue_element->u.phdr.caplen, queue_element->pcap_src->interface_id);
+
+ capture_loop_write_packet_cb((u_char *) queue_element->pcap_src,
+ &queue_element->u.phdr,
+ queue_element->pd);
+ }
+ g_free(queue_element->pd);
+ g_free(queue_element);
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* Do the low-level work of a capture.
Returns TRUE if it succeeds, FALSE otherwise. */
static gboolean
@@ -3755,40 +3797,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
while (global_ld.go) {
/* dispatch incoming packets */
if (use_threads) {
- pcap_queue_element *queue_element;
-
- g_async_queue_lock(pcap_queue);
- queue_element = (pcap_queue_element *)g_async_queue_timeout_pop_unlocked(pcap_queue, WRITER_THREAD_TIMEOUT);
- if (queue_element) {
- if (queue_element->pcap_src->from_pcapng) {
- pcap_queue_bytes -= queue_element->u.bh.block_total_length;
- pcap_queue_packets -= 1;
- } else {
- pcap_queue_bytes -= queue_element->u.phdr.caplen;
- pcap_queue_packets -= 1;
- }
- }
- g_async_queue_unlock(pcap_queue);
- if (queue_element) {
- if (queue_element->pcap_src->from_pcapng) {
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
- "Dequeued a block of length %d captured on interface %d.",
- queue_element->u.bh.block_total_length, queue_element->pcap_src->interface_id);
-
- capture_loop_write_pcapng_cb(queue_element->pcap_src,
- &queue_element->u.bh,
- queue_element->pd);
- } else {
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
- "Dequeued a packet of length %d captured on interface %d.",
- queue_element->u.phdr.caplen, queue_element->pcap_src->interface_id);
+ gboolean dequeued = capture_loop_dequeue_packet();
- capture_loop_write_packet_cb((u_char *) queue_element->pcap_src,
- &queue_element->u.phdr,
- queue_element->pd);
- }
- g_free(queue_element->pd);
- g_free(queue_element);
+ if (dequeued) {
inpkts = 1;
} else {
inpkts = 0;
@@ -3883,7 +3894,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture loop stopping ...");
if (use_threads) {
- pcap_queue_element *queue_element;
for (i = 0; i < global_ld.pcaps->len; i++) {
pcap_src = g_array_index(global_ld.pcaps, capture_src *, i);
@@ -3894,24 +3904,10 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
pcap_src->interface_id);
}
while (1) {
- g_async_queue_lock(pcap_queue);
- queue_element = (pcap_queue_element *)g_async_queue_try_pop_unlocked(pcap_queue);
- if (queue_element) {
- pcap_queue_bytes -= queue_element->u.phdr.caplen;
- pcap_queue_packets -= 1;
- }
- g_async_queue_unlock(pcap_queue);
- if (queue_element == NULL) {
+ gboolean dequeued = capture_loop_dequeue_packet();
+ if (!dequeued) {
break;
}
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
- "Dequeued a packet of length %d captured on interface %d.",
- queue_element->u.phdr.caplen, queue_element->pcap_src->interface_id);
- capture_loop_write_packet_cb((u_char *)queue_element->pcap_src,
- &queue_element->u.phdr,
- queue_element->pd);
- g_free(queue_element->pd);
- g_free(queue_element);
global_ld.inpkts_to_sync_pipe += 1;
if (capture_opts->output_to_pipe) {
fflush(global_ld.pdh);