summaryrefslogtreecommitdiff
path: root/c-sources/pcap-monitor.c
diff options
context:
space:
mode:
authorWill Thompson <will@willthompson.co.uk>2020-05-16 15:53:22 +0100
committerWill Thompson <will@willthompson.co.uk>2020-06-05 09:24:02 +0100
commit2b7de5136fbf9185f222de092afa99dc8e0ce1d7 (patch)
tree341bbba97f21b76a3d5461503168d0bbb6f289fc /c-sources/pcap-monitor.c
parent3ac734ab948998e1386ac6f6738c68eeac9f03fd (diff)
Factor out BustlePcapReader
Diffstat (limited to 'c-sources/pcap-monitor.c')
-rw-r--r--c-sources/pcap-monitor.c75
1 files changed, 29 insertions, 46 deletions
diff --git a/c-sources/pcap-monitor.c b/c-sources/pcap-monitor.c
index 18b15e4..cb1d272 100644
--- a/c-sources/pcap-monitor.c
+++ b/c-sources/pcap-monitor.c
@@ -37,6 +37,8 @@
#include <glib/gstdio.h>
#include <gio/gunixinputstream.h>
+#include "pcap-reader.h"
+
/* Prefix of name claimed by the connection that collects name owners. */
const char *BUSTLE_MONITOR_NAME_PREFIX = "org.freedesktop.Bustle.Monitor.";
@@ -100,7 +102,7 @@ typedef struct _BustlePcapMonitor {
/* If >= 0, master side of controlling terminal for dbus_monitor */
int pt_master;
GSource *dbus_monitor_source;
- pcap_t *pcap_in;
+ BustlePcapReader *reader;
/* output */
gchar *filename;
@@ -230,7 +232,7 @@ bustle_pcap_monitor_dispose (GObject *object)
g_clear_object (&self->cancellable);
g_clear_pointer (&self->dbus_monitor_source, g_source_destroy);
- g_clear_pointer (&self->pcap_in, pcap_close);
+ g_clear_object (&self->reader);
g_clear_object (&self->dbus_monitor);
close_dump (self);
@@ -654,7 +656,6 @@ start_pcap (
GInputStream *stdout_pipe = NULL;
gint stdout_fd = -1;
FILE *dbus_monitor_filep = NULL;
- char errbuf[PCAP_ERRBUF_SIZE] = {0};
stdout_pipe = g_subprocess_get_stdout_pipe (self->dbus_monitor);
g_return_val_if_fail (stdout_pipe != NULL, FALSE);
@@ -676,24 +677,17 @@ start_pcap (
* fread(). It's safe to do this on the main thread, since we know the pipe
* is readable. On short read, pcap_fopen_offline() fails immediately.
*/
- self->pcap_in = pcap_fopen_offline (dbus_monitor_filep, errbuf);
- if (self->pcap_in == NULL)
+ self->reader = bustle_pcap_reader_fopen (g_steal_pointer (&dbus_monitor_filep), error);
+ if (self->reader == NULL)
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Couldn't read messages from dbus-monitor: %s",
- errbuf);
-
- /* Cause dbus-monitor to exit next time it tries to write a message */
- g_clear_pointer (&dbus_monitor_filep, fclose);
+ g_prefix_error (error, "Couldn't read messages from dbus-monitor: ");
- /* And try to terminate it immediately. */
+ /* Try to terminate dbus-monitor immediately. The reader closes the FILE * on error. */
send_sigint (self);
return FALSE;
}
- /* pcap_close() will call fclose() on the FILE * passed to
- * pcap_fopen_offline() */
dump_names_async (self);
self->state = STATE_RUNNING;
return TRUE;
@@ -706,41 +700,30 @@ read_one (
{
struct pcap_pkthdr *hdr;
const guchar *blob;
- int ret;
g_autoptr(GDBusMessage) message = NULL;
- ret = pcap_next_ex (self->pcap_in, &hdr, &blob);
- switch (ret)
+ if (!bustle_pcap_reader_read_one (self->reader, &hdr, &blob, &message, error))
+ {
+ return FALSE;
+ }
+ else if (message == NULL)
{
- case 1:
- message = g_dbus_message_new_from_blob ((guchar *) blob, hdr->caplen, G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING, error);
- if (message == NULL)
- {
- g_prefix_error (error, "Error while parsing message from dbus-monitor: ");
- return FALSE;
- }
-
- g_signal_emit (self, signals[SIG_MESSAGE_LOGGED], 0,
- hdr->ts.tv_sec, hdr->ts.tv_usec, blob, hdr->caplen, message);
-
- /* cast necessary because pcap_dump has a type matching the callback
- * argument to pcap_loop()
- * TODO don't block
- */
- pcap_dump ((u_char *) self->dumper, hdr, blob);
- return TRUE;
-
- case -2:
- /* EOF; shouldn't happen since we waited for the FD to be readable */
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
- "EOF when reading from dbus-monitor");
- return FALSE;
+ /* EOF; shouldn't happen since we waited for the FD to be readable */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
+ "EOF when reading from dbus-monitor");
+ return FALSE;
+ }
+ else
+ {
+ g_signal_emit (self, signals[SIG_MESSAGE_LOGGED], 0,
+ hdr->ts.tv_sec, hdr->ts.tv_usec, blob, hdr->caplen, message);
- default:
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error %i reading dbus-monitor stream: %s",
- ret, pcap_geterr (self->pcap_in));
- return FALSE;
+ /* cast necessary because pcap_dump has a type matching the callback
+ * argument to pcap_loop()
+ * TODO don't block
+ */
+ pcap_dump ((u_char *) self->dumper, hdr, blob);
+ return TRUE;
}
}
@@ -834,7 +817,7 @@ cancellable_cancelled_cb (GCancellable *cancellable,
/* Closes the stream; should cause dbus-monitor to quit in due course when it
* tries to write to the other end of the pipe.
*/
- g_clear_pointer (&self->pcap_in, pcap_close);
+ bustle_pcap_reader_close (self->reader);
/* And try to terminate it immediately. */
send_sigint (self);