[pve-devel] [PATCH v2 firewall 1/2] add connection tracking via libnetfilter_conntrack

Wolfgang Bumiller w.bumiller at proxmox.com
Mon Dec 3 14:07:26 CET 2018


On Wed, Nov 28, 2018 at 12:05:54PM +0100, David Limbeck wrote:
> adds connection tracking (NEW, DESTROY) to the pvefw-logger so beginning
> and end of sessions can be tracked
> 
> Signed-off-by: David Limbeck <d.limbeck at proxmox.com>
> ---
>  src/pvefw-logger.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/src/pvefw-logger.c b/src/pvefw-logger.c
> index 2bd869c..c8693c8 100644
> --- a/src/pvefw-logger.c
> +++ b/src/pvefw-logger.c
> @@ -40,6 +40,7 @@
>  #include <linux/netlink.h>
>  #include <libnfnetlink/libnfnetlink.h>
>  #include <libnetfilter_log/libnetfilter_log.h>
> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
>  #include <netinet/ip.h>
>  #include <netinet/ip_icmp.h>
>  #include <netinet/ip6.h>
> @@ -53,6 +54,7 @@
>  
>  static struct nflog_handle *logh = NULL;
>  static struct nlif_handle *nlifh = NULL;
> +static struct nfct_handle *nfcth = NULL;
>  GMainLoop *main_loop;
>  
>  gboolean foreground = FALSE;
> @@ -917,6 +919,36 @@ signal_read_cb(GIOChannel *source,
>      return TRUE;
>  }
>  
> +static int
> +nfct_cb(const struct nlmsghdr *nlh,
> +        enum nf_conntrack_msg_type type,
> +        struct nf_conntrack *ct,
> +        void *data)
> +{
> +    char buf[LE_MAX];
> +    nfct_snprintf(buf, LE_MAX, ct, type, NFCT_O_DEFAULT, NFCT_OF_SHOW_LAYER3|NFCT_OF_TIMESTAMP);
> +
> +    struct log_entry *le = g_new0(struct log_entry, 1);
> +    LEPRINTF("%s\n", &buf[0]);

I'd prefer to allocate log_entry first and then let nfct_snprintf()
write directly to le->buf, use its return value (clamped to a maximum
of sizeof(le->buf), as it will return the space it _would_ need if it
had enough available, much like the regular sprintf() function family),
and write that to le->len.
(Also make sure le->buf[le->len-1] = 0; given that the nfct_snprintf()
documentation doesn't say anything about whether it'll ensure
null-termination when the buffer was too small, writing out the 0
byte may be necessary when nfct_snprintf() returns a length >= LE_MAX.)

> +
> +    queue_log_entry(le);
> +
> +    return NFCT_CB_STOP;
> +}
> +
> +static gboolean
> +nfct_read_cb(GIOChannel *source,
> +             GIOCondition condition,
> +             gpointer data)
> +{
> +    int res;
> +    if ((res = nfct_catch(nfcth)) < 0) {
> +        log_status_message(3, "error catching nfct");
> +        return FALSE;
> +    }
> +    return TRUE;
> +}
> +
>  int
>  main(int argc, char *argv[])
>  {
> @@ -1017,6 +1049,11 @@ main(int argc, char *argv[])
>          exit(-1);
>      }
>  
> +    if ((nfcth = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_NEW|NF_NETLINK_CONNTRACK_DESTROY)) == NULL) {
> +	fprintf(stderr, "unable to open netfilter conntrack\n");
> +	exit(-1);

^ Rest of the code doesn't use tabs here.

> +    }
> +
>      sigset_t mask;
>      sigemptyset(&mask);
>      sigaddset(&mask, SIGINT);
> @@ -1076,6 +1113,11 @@ main(int argc, char *argv[])
>  
>      g_io_add_watch(nflog_ch, G_IO_IN, nflog_read_cb, NULL);
>  
> +    nfct_callback_register2(nfcth, NFCT_T_NEW|NFCT_T_DESTROY, &nfct_cb, NULL);
> +    int nfctfd = nfct_fd(nfcth);
> +    GIOChannel *nfct_ch = g_io_channel_unix_new(nfctfd);
> +    g_io_add_watch(nfct_ch, G_IO_IN, nfct_read_cb, NULL);
> +
>      GIOChannel *sig_ch = g_io_channel_unix_new(sigfd);
>      if (!g_io_add_watch(sig_ch, G_IO_IN, signal_read_cb, NULL)) {
>          exit(-1);
> @@ -1093,6 +1135,9 @@ main(int argc, char *argv[])
>  
>      close(outfd);
>  
> +    nfct_callback_unregister2(nfcth);
> +    nfct_close(nfcth);
> +
>      nflog_close(logh);
>  
>      if (wrote_pidfile)
> -- 
> 2.11.0




More information about the pve-devel mailing list