Skip to content

Commit

Permalink
Merge pull request #74 from raybellis/rpb-gzip
Browse files Browse the repository at this point in the history
auto gzip for pcaps
  • Loading branch information
jelu committed May 11, 2017
2 parents 4d603b5 + 419a8ab commit a4be541
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 5 deletions.
3 changes: 3 additions & 0 deletions configure.ac
Expand Up @@ -65,6 +65,7 @@ AC_CHECK_LIB([tinycbor], [cbor_parser_init])
AM_CONDITIONAL([HAVE_CBOR], [test "x$ac_cv_lib_tinycbor_cbor_parser_init" = "xyes"])
AC_CHECK_LIB([ldns], [ldns_wire2pkt])
AM_CONDITIONAL([HAVE_LDNS], [test "x$ac_cv_lib_ldns_ldns_wire2pkt" = "xyes"])
AC_CHECK_LIB([z], [gzopen])

# Check for OS specific libraries
case "$host_os" in
Expand All @@ -89,10 +90,12 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h])
AC_CHECK_HEADERS([ldns/ldns.h arpa/nameser_compat.h cbor.h cbor/cbor.h])
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([zlib.h])

# Checks for library functions.
AC_CHECK_FUNCS([snprintf])
AC_CHECK_FUNCS([setreuid setresuid setregid setresgid setegid seteuid])
AC_CHECK_FUNCS([funopen fopencookie gzopen])
AC_CHECK_FUNC([ns_initparse],
[AC_DEFINE([HAVE_NS_INITPARSE], [1], [Define to 1 if you have the `ns_initparse' function.])],
[AC_CHECK_FUNC(__ns_initparse,
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Expand Up @@ -3,7 +3,7 @@ Section: net
Priority: optional
Maintainer: Jerry Lundström <lundstrom.jerry@gmail.com>
Build-Depends: debhelper (>= 8.0.0), build-essential, automake, autoconf,
libpcap-dev, netbase, libldns-dev, libtool
libpcap-dev, netbase, libldns-dev, libtool, zlib1g-dev
Standards-Version: 3.9.4
Homepage: https://www.dns-oarc.net/tools/dnscap
Vcs-Git: https://github.com/DNS-OARC/dnscap.git
Expand Down
1 change: 1 addition & 0 deletions rpm/spec
Expand Up @@ -12,6 +12,7 @@ Source0: %{name}_%{version}.orig.tar.gz
BuildRequires: libpcap-devel
BuildRequires: ldns-devel
BuildRequires: openssl-devel
BuildRequires: zlib-devel
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
Expand Down
27 changes: 25 additions & 2 deletions src/config.h.in
Expand Up @@ -18,9 +18,21 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H

/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H

/* Define to 1 if you have the `fopencookie' function. */
#undef HAVE_FOPENCOOKIE

/* Define to 1 if you have the `funopen' function. */
#undef HAVE_FUNOPEN

/* Define to 1 if you have the `gzopen' function. */
#undef HAVE_GZOPEN

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

Expand Down Expand Up @@ -60,6 +72,12 @@
/* Define to 1 if you have the `tinycbor' library (-ltinycbor). */
#undef HAVE_LIBTINYCBOR

/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ

/* Define to 1 if you have the <machine/endian.h> header file. */
#undef HAVE_MACHINE_ENDIAN_H

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

Expand Down Expand Up @@ -154,6 +172,9 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Define to 1 if you have the <sys/endian.h> header file. */
#undef HAVE_SYS_ENDIAN_H

/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H

Expand All @@ -175,11 +196,13 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H

/* Define to 1 if you have the `__assertion_failed' function. */
#undef HAVE___ASSERTION_FAILED

/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR

/* Name of package */
Expand Down
5 changes: 4 additions & 1 deletion src/dnscap.1.in
Expand Up @@ -228,7 +228,10 @@ and
options affect the total duration of the capture, and not merely the size and
time limits of each individual dump file.
.It Fl W Ar suffix
The provided suffix is added to the dump file name, e. g.: ".pcap"
The provided suffix is added to the dump file name, e. g.: ".pcap". If the
suffix ends with ".gz" then files will be automatically gzip compressed. If
gzip compression is requested but not supported (i.e. because of lack of
system support) an error will be generated.
.It Fl k Ar cmd
After each dump file specified by
.Fl w
Expand Down
84 changes: 83 additions & 1 deletion src/dnscap.c
Expand Up @@ -139,6 +139,10 @@
#include <pwd.h>
#include <grp.h>

#if HAVE_ZLIB_H
#include <zlib.h>
#endif

#include "dnscap_common.h"
#include "dnscap.h"
#define ISC_CHECK_NONE 1
Expand Down Expand Up @@ -322,6 +326,7 @@ static void network_pkt(const char *, my_bpftimeval, unsigned,
static output_t output;
static int dumper_open(my_bpftimeval);
static int dumper_close(my_bpftimeval);
static pcap_dumper_t *dnscap_pcap_dump_open(pcap_t *, const char *);
static void sigclose(int);
static void sigbreak(int);
#if HAVE_PTHREAD
Expand Down Expand Up @@ -379,6 +384,7 @@ static int immediate_mode = FALSE;
static int background = FALSE;
static char errbuf[PCAP_ERRBUF_SIZE];
static int v6bug = FALSE;
static int wantgzip = FALSE;
static int wantfrags = FALSE;
static int wanticmp = FALSE;
static int wanttcp = FALSE;
Expand Down Expand Up @@ -837,6 +843,21 @@ help_2(void) {
);
}

static void
check_gzip() {
char *dot = strrchr(dump_suffix, '.');
if (dot) {
wantgzip = (strcmp(dot, ".gz") == 0) ? TRUE : FALSE;
}

#if ! ( HAVE_GZOPEN && (HAVE_FUNOPEN || HAVE_FOPENCOOKIE ))
if (wantgzip) {
fprintf(stderr, "error: gzip compression requested but not supported\n");
exit(1);
}
#endif
}

static void
parse_args(int argc, char *argv[]) {
mypcap_ptr mypcap;
Expand Down Expand Up @@ -1040,6 +1061,7 @@ parse_args(int argc, char *argv[]) {
if (dump_suffix)
free(dump_suffix);
dump_suffix = strdup(optarg);
check_gzip();
break;
case 'k':
if (dump_type != to_file)
Expand Down Expand Up @@ -2660,7 +2682,7 @@ dumper_open(my_bpftimeval ts) {
}
if (NULL != t) {
if (options.dump_format == pcap) {
dumper = pcap_dump_open(pcap_dead, t);
dumper = dnscap_pcap_dump_open(pcap_dead, t);
if (dumper == NULL) {
logerr("pcap dump open: %s",
pcap_geterr(pcap_dead));
Expand Down Expand Up @@ -2957,3 +2979,63 @@ daemonize(void)
#endif
logerr("Backgrounded as pid %u", getpid());
}

#if HAVE_ZLIB_H
#if HAVE_FUNOPEN
static int
gzip_cookie_write(void *cookie, const char *buf, int size) {
return gzwrite((gzFile)cookie, (voidpc)buf, (unsigned) size);
}
#elif HAVE_FOPENCOOKIE
static ssize_t
gzip_cookie_write(void *cookie, const char *buf, size_t size) {
return gzwrite((gzFile)cookie, (voidpc)buf, (unsigned) size);
}
#endif

static int
gzip_cookie_close(void *cookie)
{
return gzclose((gzFile)cookie);
}
#endif /* HAVE_ZLIB_H */

static pcap_dumper_t *
dnscap_pcap_dump_open(pcap_t *pcap, const char *path)
{
#if HAVE_ZLIB_H
#if HAVE_GZOPEN
if (wantgzip) {
FILE *fp = NULL;
gzFile z = gzopen(path, "w");
if (z == NULL) {
perror("gzopen");
return NULL;
}

#if HAVE_FUNOPEN
fp = funopen(z, NULL, gzip_cookie_write, NULL, gzip_cookie_close);
if (fp == NULL) {
perror("funopen");
return NULL;
}
#elif HAVE_FOPENCOOKIE
{
static cookie_io_functions_t cookiefuncs = {
NULL, gzip_cookie_write, NULL, gzip_cookie_close
};

fp = fopencookie(z, "w", cookiefuncs);
if (fp == NULL) {
perror("fopencookie");
return NULL;
}
}
#endif
return pcap_dump_fopen(pcap, fp);
}
#endif /* HAVE_GZOPEN */
#endif /* HAVE_ZLIB_H */

return pcap_dump_open(pcap, path);
}

1 comment on commit a4be541

@raybellis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realised later that the cookie_io_functions_t doesn't even need to be static because it's passed to fopencookie by value, not by pointer.

Please sign in to comment.