diff options
author | Will Thompson <will@willthompson.co.uk> | 2020-05-16 15:53:22 +0100 |
---|---|---|
committer | Will Thompson <will@willthompson.co.uk> | 2020-06-05 09:24:02 +0100 |
commit | 2b7de5136fbf9185f222de092afa99dc8e0ce1d7 (patch) | |
tree | 341bbba97f21b76a3d5461503168d0bbb6f289fc /c-sources/pcap-monitor.c | |
parent | 3ac734ab948998e1386ac6f6738c68eeac9f03fd (diff) |
Factor out BustlePcapReader
Diffstat (limited to 'c-sources/pcap-monitor.c')
-rw-r--r-- | c-sources/pcap-monitor.c | 75 |
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); |