diff options
author | Gerald Combs <gerald@wireshark.org> | 2018-11-13 10:40:55 -0800 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-11-14 04:59:25 +0000 |
commit | 50433f4b4dde42ce50b0e2d899671c2b2cef526d (patch) | |
tree | 70e3b2c9fd7e67171d127bcd2296deb13be26829 /dumpcap.c | |
parent | 0795c988b072ef45e1a389d51b49ec4ee235c216 (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.c | 96 |
1 files changed, 46 insertions, 50 deletions
@@ -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); |