diff options
54 files changed, 922 insertions, 1070 deletions
@@ -1,14 +1,17 @@ +*~ +.\#* +\#*\# # global *.la *.lo *.o .deps/ +.dirstamp .libs/ Makefile Makefile.in # this dir -/Rules.make /ulogd.conf # build system diff --git a/Make_global.am b/Make_global.am new file mode 100644 index 0000000..4ce896d --- /dev/null +++ b/Make_global.am @@ -0,0 +1,2 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CFLAGS = -Wall -Wextra -Wno-unused-parameter diff --git a/Makefile.am b/Makefile.am index 5600f8c..bf390a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,10 @@ +SUBDIRS = include libipulog src input filter output -ACLOCAL_AMFLAGS = -I m4 - -man_MANS = ulogd.8 +ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = $(man_MANS) ulogd.conf.in doc +dist_man_MANS = ulogd.8 -AM_CPPFLAGS = -I$(top_srcdir)/include -SUBDIRS = include libipulog src input filter output +EXTRA_DIST = ulogd.conf.in doc noinst_DATA = ulogd.conf @@ -18,4 +16,3 @@ ulogd.conf: Makefile $(srcdir)/ulogd.conf.in dist-hook: rm -f ulogd.conf - diff --git a/Rules.make.in b/Rules.make.in deleted file mode 100644 index 21b05d9..0000000 --- a/Rules.make.in +++ /dev/null @@ -1,43 +0,0 @@ -# - -PREFIX=@prefix@ -exec_prefix=@exec_prefix@ -ETCDIR=@sysconfdir@ -BINDIR=@sbindir@ - -ULOGD_CONFIGFILE=@sysconfdir@/ulogd.conf - -ULOGD_LIB_PATH=@libdir@/ulogd - -# Path of libipulog (from iptables) -LIBIPULOG=@top_srcdir@/libipulog -INCIPULOG=-I@top_srcdir@/libipulog/include -INCCONFFILE=-I@top_srcdir@/conffile - -CC=@CC@ -LD=@LD@ -INSTALL=@INSTALL@ - -CFLAGS=@CFLAGS@ @CPPFLAGS@ -Wall -CFLAGS+=-DULOGD_CONFIGFILE=\"$(ULOGD_CONFIGFILE)\" -# doesn't work for subdirs -#CFLAGS+=$(INCIPULOG) $(INCCONFFILE) -CFLAGS+=-I/lib/modules/`uname -r`/build/include -#CFLAGS+=@DEFS@ -#CFLAGS+=-g -DDEBUG -DDEBUG_MYSQL -DDEBUG_PGSQL - -LIBS=@LIBS@ - - -# Names of the plugins to be compiled -ULOGD_SL:=BASE OPRINT PWSNIFF LOGEMU LOCAL SYSLOG - -# mysql output support -#ULOGD_SL+=MYSQL -MYSQL_CFLAGS=-I@MYSQLINCLUDES@ @EXTRA_MYSQL_DEF@ -MYSQL_LDFLAGS=@DATABASE_LIB_DIR@ @MYSQL_LIB@ - -# postgreSQL output support -#ULOGD_SL+=PGSQL -PGSQL_CFLAGS=-I@PGSQLINCLUDES@ @EXTRA_PGSQL_DEF@ -PGSQL_LDFLAGS=@DATABASE_LIB_DIR@ @PGSQL_LIB@ diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index 8388c45..0000000 --- a/acinclude.m4 +++ /dev/null @@ -1,351 +0,0 @@ -dnl @synopsis CT_CHECK_POSTGRES_DB -dnl -dnl This macro tries to find the headers and libraries for the -dnl PostgreSQL database to build client applications. -dnl -dnl If includes are found, the variable PQINCPATH will be set. If -dnl libraries are found, the variable PQLIBPATH will be set. if no check -dnl was successful, the script exits with a error message. -dnl -dnl @category InstalledPackages -dnl @author Christian Toepp <c.toepp@gmail.com> -dnl @version 2005-12-30 -dnl @license AllPermissive - -AC_DEFUN([CT_CHECK_POSTGRES_DB], [ - -AC_ARG_WITH(pgsql, - [ --with-pgsql=PREFIX Prefix of your PostgreSQL installation], - [pg_prefix=$withval], [pg_prefix=]) -AC_ARG_WITH(pgsql-inc, - [ --with-pgsql-inc=PATH Path to the include directory of PostgreSQL], - [pg_inc=$withval], [pg_inc=]) -AC_ARG_WITH(pgsql-lib, - [ --with-pgsql-lib=PATH Path to the libraries of PostgreSQL], - [pg_lib=$withval], [pg_lib=]) - - -AC_SUBST(PQINCPATH) -AC_SUBST(PQLIBPATH) -AC_SUBST(PQLIBS) -PQLIBS=-lpq - -if test "$pg_prefix" != "no"; then - -AC_MSG_CHECKING([for PostgreSQL pg_config program]) -for d in $pg_prefix/bin /usr/bin /usr/local/bin /usr/local/pgsql/bin /opt/pgsql/bin /opt/packages/pgsql/bin -do - if test -x $d/pg_config -a "$cross_compiling" = "no"; - then - AC_MSG_RESULT(found pg_config in $d) - PQINCPATH=`$d/pg_config --includedir` - PQLIBPATH=`$d/pg_config --libdir` - break - fi -done - -if test "$PQINCPATH" = ""; then - if test "$pg_prefix" != ""; then - AC_MSG_CHECKING([for PostgreSQL includes in $pg_prefix/include]) - if test -f "$pg_prefix/include/libpq-fe.h" ; then - PQINCPATH="-I$pg_prefix/include" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpq-fe.h not found) - fi - AC_MSG_CHECKING([for PostgreSQL libraries in $pg_prefix/lib]) - if test -f "$pg_prefix/lib/libpq.so" ; then - PQLIBPATH="-L$pg_prefix/lib" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpq.so not found) - fi - else - if test "$pg_inc" != ""; then - AC_MSG_CHECKING([for PostgreSQL includes in $pg_inc]) - if test -f "$pg_inc/libpq-fe.h" ; then - PQINCPATH="-I$pg_inc" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpq-fe.h not found) - fi - fi - if test "$pg_lib" != ""; then - AC_MSG_CHECKING([for PostgreSQL libraries in $pg_lib]) - if test -f "$pg_lib/libpq.so" ; then - PQLIBPATH="-L$pg_lib" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpq.so not found) - fi - fi - fi -fi - -if test "$PQINCPATH" = "" ; then - AC_CHECK_HEADER([libpq-fe.h], [], AC_MSG_WARN(libpq-fe.h not found)) -fi -if test "$PQLIBPATH" = "" ; then - AC_CHECK_LIB(pq, PQconnectdb, [], AC_MSG_WARN(libpq.so not found)) -fi - -fi - -]) - -dnl @synopsis CT_CHECK_MYSQL_DB -dnl -dnl This macro tries to find the headers and librariess for the -dnl MySQL database to build client applications. -dnl -dnl If includes are found, the variable MYSQL_INC will be set. If -dnl libraries are found, the variable MYSQL_LIB will be set. if no check -dnl was successful, the script exits with a error message. -dnl -dnl @category InstalledPackages -dnl @author Harald Welte <laforge@gnumonks.org> -dnl @version 2006-01-07 -dnl @license AllPermissive - -AC_DEFUN([CT_CHECK_MYSQL_DB], [ - -AC_ARG_WITH(mysql, - [ --with-mysql=PREFIX Prefix of your MySQL installation], - [my_prefix=$withval], [my_prefix=]) -AC_ARG_WITH(mysql-inc, - [ --with-mysql-inc=PATH Path to the include directory of MySQL], - [my_inc=$withval], [my_inc=]) -AC_ARG_WITH(mysql-lib, - [ --with-mysql-lib=PATH Path to the libraries of MySQL], - [my_lib=$withval], [my_lib=]) - - -AC_SUBST(MYSQL_INC) -AC_SUBST(MYSQL_LIB) - -if test "$my_prefix" != "no"; then - -AC_MSG_CHECKING([for MySQL mysql_config program]) -for d in $my_prefix/bin /usr/bin /usr/local/bin /usr/local/mysql/bin /opt/mysql/bin /opt/packages/mysql/bin -do - if test -x $d/mysql_config -a "$cross_compiling" = "no"; - then - AC_MSG_RESULT(found mysql_config in $d) - MYSQL_INC=`$d/mysql_config --include` - MYSQL_LIB=`$d/mysql_config --libs` - break - fi -done - -if test "$MYSQL_INC" = ""; then - if test "$my_prefix" != ""; then - AC_MSG_CHECKING([for MySQL includes in $my_prefix/include]) - if test -f "$my_prefix/include/mysql.h" ; then - MYSQL_INC="-I$my_prefix/include" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(mysql.h not found) - fi - AC_MSG_CHECKING([for MySQL libraries in $my_prefix/lib]) - if test -f "$my_prefix/lib/libmysql.so" ; then - MYSQL_LIB="-L$my_prefix/lib -lmysqlclient" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libmysqlclient.so not found) - fi - else - if test "$my_inc" != ""; then - AC_MSG_CHECKING([for MySQL includes in $my_inc]) - if test -f "$my_inc/mysql.h" ; then - MYSQL_INC="-I$my_inc" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(mysql.h not found) - fi - fi - if test "$my_lib" != ""; then - AC_MSG_CHECKING([for MySQL libraries in $my_lib]) - if test -f "$my_lib/libmysqlclient.so" ; then - MYSQL_LIB="-L$my_lib -lmysqlclient" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libmysqlclient.so not found) - fi - fi - fi -fi - -if test "$MYSQL_INC" = "" ; then - AC_CHECK_HEADER([mysql.h], [], AC_MSG_WARN(mysql.h not found)) -fi -if test "$MYSQL_LIB" = "" ; then - AC_CHECK_LIB(mysqlclient, mysql_close, [], AC_MSG_WARN(libmysqlclient.so not found)) -fi - -fi - -]) - -dnl @synopsis CT_CHECK_PCAP -dnl -dnl This macro tries to find the headers and libraries for libpcap. -dnl -dnl If includes are found, the variable PCAP_INC will be set. If -dnl libraries are found, the variable PCAP_LIB will be set. if no check -dnl was successful, the script exits with a error message. -dnl -dnl @category InstalledPackages -dnl @author Harald Welte <laforge@gnumonks.org> -dnl @version 2006-01-07 -dnl @license AllPermissive - -AC_DEFUN([CT_CHECK_PCAP], [ - -AC_ARG_WITH(pcap, - [ --with-pcap=PREFIX Prefix of your libpcap installation], - [pcap_prefix=$withval], [pcap_prefix=]) -AC_ARG_WITH(pcap-inc, - [ --with-pcap-inc=PATH Path to the include directory of pcap], - [pcap_inc=$withval], [pcap_inc=/usr/include]) -AC_ARG_WITH(pcap-lib, - [ --with-pcap-lib=PATH Path to the libraries of pcap], - [pcap_lib=$withval], [pcap_lib=/usr/lib]) - - -AC_SUBST(PCAP_INC) -AC_SUBST(PCAP_LIB) -AC_SUBST(HAVE_PCAP_LIB) - -if test "$pcap_prefix" != "no"; then - -if test "$pcap_prefix" != ""; then - AC_MSG_CHECKING([for libpcap includes in $pcap_prefix/include]) - if test -f "$pcap_prefix/include/pcap.h" ; then - PCAP_INC="-I$pcap_prefix/include" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(pcap.h not found) - fi - AC_MSG_CHECKING([for libpcap in $pcap_prefix/lib]) - if test -f "$pcap_prefix/lib/libpcap.so" ; then - PCAP_LIB="-L$pcap_prefix/lib -lpcap"; - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpcap.so not found) - fi -else - if test "$pcap_inc" != ""; then - AC_MSG_CHECKING([for libpcap includes in $pcap_inc]) - if test -f "$pcap_inc/pcap.h" ; then - PCAP_INC="-I$pcap_inc" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(pcap.h not found) - fi - fi - if test "$pcap_lib" != ""; then - AC_MSG_CHECKING([for libpcap in $pcap_lib]) - if test -f "$pcap_lib/libpcap.so" ; then - PCAP_LIB="-L$pcap_lib -lpcap"; - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libpcap.so not found) - fi - fi -fi - -if test "$PCAP_INC" = "" ; then - AC_CHECK_HEADER([pcap.h], [], AC_MSG_WARN(pcap.h not found)) -fi -if test "$PCAP_LIB" = "" ; then - AC_CHECK_LIB(pcap, pcap_close, [HAVE_PCAP_LIB="yes"], AC_MSG_WARN(libpcap.so not found)) -fi - -fi - -]) - -dnl @synopsis CT_CHECK_DBI -dnl -dnl This macro tries to find the headers and libraries for libdbi. -dnl -dnl If includes are found, the variable DBI_INC will be set. If -dnl libraries are found, the variable DBI_LIB will be set. if no check -dnl was successful, the script exits with a error message. -dnl -dnl @category InstalledPackages -dnl @author Pierre Chifflier <chifflier@inl.fr> -dnl @version 2008-10-30 -dnl @license AllPermissive - -AC_DEFUN([CT_CHECK_DBI], [ - -AC_ARG_WITH(dbi, - [ --with-dbi=PREFIX Prefix of your libdbi installation], - [dbi=$withval], [dbi_prefix=]) -AC_ARG_WITH(dbi-inc, - [ --with-dbi-inc=PATH Path to the include directory of dbi], - [dbi_inc=$withval], [dbi_inc=/usr/include]) -AC_ARG_WITH(dbi-lib, - [ --with-dbi-lib=PATH Path to the libraries of dbi], - [dbi_lib=$withval], [dbi_lib=/usr/lib]) - - -AC_SUBST(DBI_INC) -AC_SUBST(DBI_LIB) - -if test "$dbi_prefix" != "no"; then - -if test "$dbi_prefix" != ""; then - AC_MSG_CHECKING([for libdbi includes in $dbi_prefix/include]) - if test -f "$dbi_prefix/include/dbi.h" ; then - DBI_INC="-I$dbi_prefix/include" - AC_MSG_RESULT([yes]) - elif test -f "$dbi_prefix/include/dbi/dbi.h" ; then - DBI_INC="-I$dbi_prefix/include/dbi" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(dbi.h not found) - fi - AC_MSG_CHECKING([for libdbi in $dbi_prefix/lib]) - if test -f "$dbi_prefix/lib/libdbi.so" ; then - DBI_LIB="-L$dbi_prefix/lib -ldbi"; - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libdbi.so not found) - fi -else - if test "$dbi_inc" != ""; then - AC_MSG_CHECKING([for libdbi includes in $dbi_inc]) - if test -f "$dbi_inc/dbi.h" ; then - DBI_INC="-I$dbi_inc" - AC_MSG_RESULT([yes]) - elif test -f "$dbi_inc/dbi/dbi.h" ; then - DBI_INC="-I$dbi_inc/dbi" - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(dbi.h not found) - fi - fi - if test "$dbi_lib" != ""; then - AC_MSG_CHECKING([for libdbi in $dbi_lib]) - if test -f "$dbi_lib/libdbi.so" ; then - DBI_LIB="-L$dbi_lib -ldbi"; - AC_MSG_RESULT([yes]) - else - AC_MSG_WARN(libdbi.so not found) - fi - fi -fi - -if test "$DBI_INC" = "" ; then - AC_CHECK_HEADER([dbi.h], [], AC_MSG_WARN(dbi.h not found)) -fi -if test "$DBI_LIB" = "" ; then - AC_CHECK_LIB(dbi, dbi_close, [], AC_MSG_WARN(libdbi.so not found)) -fi - -fi - -]) - diff --git a/configure.ac b/configure.ac index 48b4995..3c9249e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,9 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([ulogd], [2.0.7]) +AC_INIT([ulogd], [2.0.8]) AC_PREREQ([2.50]) AC_CONFIG_AUX_DIR([build-aux]) -AM_INIT_AUTOMAKE([-Wall foreign tar-pax no-dist-gzip dist-bzip2 1.10b subdir-objects]) -AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([-Wall foreign tar-pax no-dist-gzip dist-xz 1.10b subdir-objects]) +AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) @@ -14,8 +14,7 @@ dnl Checks for programs. AC_PROG_MAKE_SET AC_PROG_CC AC_PROG_INSTALL -AC_DISABLE_STATIC -AC_PROG_LIBTOOL +LT_INIT([disable-static]) dnl Checks for libraries. AC_SEARCH_LIBS([dlopen], [dl], [libdl_LIBS="$LIBS"; LIBS=""]) @@ -23,8 +22,7 @@ AC_SUBST([libdl_LIBS]) dnl Checks for header files. AC_HEADER_DIRENT -AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h unistd.h) +AC_CHECK_HEADERS([fcntl.h unistd.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -34,153 +32,246 @@ AC_SYS_LARGEFILE dnl Checks for library functions. AC_FUNC_VPRINTF -AC_CHECK_FUNCS(socket strerror) +AC_CHECK_FUNCS([socket strerror]) AC_SEARCH_LIBS([pthread_create], [pthread], [libpthread_LIBS="$LIBS"; LIBS=""]) AC_SUBST([libpthread_LIBS]) -AC_ARG_ENABLE(ulog, - AS_HELP_STRING([--enable-ulog], [Enable ulog module [default=yes]]),[enable_ulog=$enableval],[enable_ulog=yes]) +AC_ARG_ENABLE([ulog], + [AS_HELP_STRING([--enable-ulog], [Enable ulog module [default=yes]])], + [enable_ulog=$enableval], + [enable_ulog=yes]) +AS_IF([test "x$enable_ulog" != "xyes"], [enable_ulog=no]) AM_CONDITIONAL([BUILD_ULOG], [test "x$enable_ulog" = "xyes"]) -if [! test "x$enable_ulog" = "xyes"]; then - enable_ulog="no" -fi dnl Check for the right nfnetlink version PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= 1.0.1]) -AC_ARG_ENABLE(nflog, - AS_HELP_STRING([--enable-nflog], [Enable nflog module [default=yes]]),[enable_nflog=$enableval],[enable_nflog=yes]) -AS_IF([test "x$enable_nflog" = "xyes"], [ - PKG_CHECK_MODULES([LIBNETFILTER_LOG], [libnetfilter_log >= 1.0.0]) - AC_DEFINE([BUILD_NFLOG], [1], [Building nflog module]) -]) + +AC_ARG_ENABLE([nflog], + [AS_HELP_STRING([--enable-nflog], [Enable nflog module [default=yes]])], + [enable_nflog=$enableval], + [enable_nflog=yes]) +AS_IF([test "x$enable_nflog" = "xyes"], + [PKG_CHECK_MODULES([LIBNETFILTER_LOG], [libnetfilter_log >= 1.0.2]) + AC_DEFINE([BUILD_NFLOG], [1], [Building nflog module])], + [enable_nflog=no]) AM_CONDITIONAL([BUILD_NFLOG], [test "x$enable_nflog" = "xyes"]) -if [! test "x$enable_nflog" = "xyes"]; then - enable_nflog="no" -fi -AC_ARG_ENABLE(nfct, - AS_HELP_STRING([--enable-nfct], [Enable nfct module [default=yes]]),[enable_nfct=$enableval],[enable_nfct=yes]) -AS_IF([test "x$enable_nfct" = "xyes"], [ - PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 1.0.2]) - AC_DEFINE([BUILD_NFCT], [1], [Building nfct module]) -]) +AC_ARG_ENABLE([nfct], + [AS_HELP_STRING([--enable-nfct], [Enable nfct module [default=yes]])], + [enable_nfct=$enableval], + [enable_nfct=yes]) +AS_IF([test "x$enable_nfct" = "xyes"], + [PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 1.0.2]) + AC_DEFINE([BUILD_NFCT], [1], [Building nfct module])], + [enable_nfct=no]) AM_CONDITIONAL([BUILD_NFCT], [test "x$enable_nfct" = "xyes"]) -if [! test "x$enable_nfct" = "xyes"]; then - enable_nfct="no" -fi -AC_ARG_ENABLE(nfacct, - AS_HELP_STRING([--enable-nfacct], [Enable nfacct module [default=yes]]),[enable_nfacct=$enableval],[enable_nfacct=yes]) -AS_IF([test "x$enable_nfacct" = "xyes"], [ - PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3]) - PKG_CHECK_MODULES([LIBNETFILTER_ACCT], [libnetfilter_acct >= 1.0.1]) - AC_DEFINE([BUILD_NFACCT], [1], [Building nfacct module]) -]) +AC_ARG_ENABLE([nfacct], + [AS_HELP_STRING([--enable-nfacct], [Enable nfacct module [default=yes]])], + [enable_nfacct=$enableval], + [enable_nfacct=yes]) +AS_IF([test "x$enable_nfacct" = "xyes"], + [PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3]) + PKG_CHECK_MODULES([LIBNETFILTER_ACCT], [libnetfilter_acct >= 1.0.1]) + AC_DEFINE([BUILD_NFACCT], [1], [Building nfacct module])], + [enable_nfacct=no]) AM_CONDITIONAL([BUILD_NFACCT], [test "x$enable_nfacct" = "xyes"]) -if [! test "x$enable_nfacct" = "xyes"]; then - enable_nfacct="no" -fi -AC_ARG_WITH([pgsql], AS_HELP_STRING([--without-pgsql], [Build without postgresql output plugin [default=test]])) -AS_IF([test "x$with_pgsql" != "xno"], [ - CT_CHECK_POSTGRES_DB() -]) -AM_CONDITIONAL(HAVE_PGSQL, test "x$PQLIBPATH" != "x") -if test "x$PQLIBPATH" != "x"; then - enable_pgsql="yes" -else - enable_pgsql="no" -fi +AC_ARG_ENABLE([pgsql], + [AS_HELP_STRING([--enable-pgsql], [Enable PostgreSQL output plugin [default=test]])]) +AS_IF([test "x$enable_pgsql" != "xno"], [ + + PKG_CHECK_EXISTS([libpq], [PKG_CHECK_MODULES([libpq], [libpq])], [ + + AC_ARG_WITH([pg_config], + [AS_HELP_STRING([--with-pg-config=PATH], [Path to the pg_config script])], + [pg_config="$withval"], [pg_config=pg_config]) + + AC_MSG_CHECKING([for pg_config]) + + AS_IF([command -v "$pg_config" >/dev/null], [ + + libpq_CFLAGS="-I`$pg_config --includedir`" + libpq_LIBS="`$pg_config --libdir` -lpq" + + AC_SUBST([libpq_CFLAGS]) + AC_SUBST([libpq_LIBS]) + + AC_MSG_RESULT([$pg_config]) + + ], [ + AC_MSG_RESULT([no]) + ]) + + AS_IF([test "x$libpq_LIBS" = "x"], [ + AS_IF([test "x$enable_pgsql" = "xyes"], [ + AC_MSG_ERROR([libpq not found]) + ]) + ]) + + ]) -AC_ARG_WITH([mysql], AS_HELP_STRING([--without-mysql], [Build without mysql output plugin [default=test]])) -AS_IF([test "x$with_mysql" != "xno"], [ - CT_CHECK_MYSQL_DB() ]) -AM_CONDITIONAL(HAVE_MYSQL, test "x$MYSQL_LIB" != "x") -if test "x$MYSQL_LIB" != "x"; then - enable_mysql="yes" -else - enable_mysql="no" -fi +AS_IF([test "x$libpq_LIBS" != "x"], [enable_pgsql=yes], [enable_pgsql=no]) +AM_CONDITIONAL([HAVE_PGSQL], [test "x$libpq_LIBS" != "x"]) + +AC_ARG_ENABLE([mysql], + [AS_HELP_STRING([--enable-mysql], [Enable MySQL output plugin [default=test]])]) +AS_IF([test "x$enable_mysql" != "xno"], [ + + PKG_CHECK_EXISTS([mysqlclient], + [PKG_CHECK_MODULES([libmysqlclient], [mysqlclient])], + [ + + AC_ARG_WITH([mysql-config], + [AS_HELP_STRING([--with-mysql-config=PATH], [Path to the mysql_config script])], + [mysql_config="$withval"], [mysql_config=mysql_config]) + + AC_MSG_CHECKING([for mysql_config]) + + AS_IF([command -v "$mysql_config" >/dev/null], [ + + MYSQL_CLIENT_CFLAGS=`$mysql_config --cflags` + MYSQL_CLIENT_LIBS=`$mysql_config --libs` + AC_SUBST([MYSQL_CLIENT_CFLAGS]) + AC_SUBST([MYSQL_CLIENT_LIBS]) + + AC_MSG_RESULT([$mysql_config]) + + dnl Some distro's don't put mysql_config in the same package as the + dnl headers and .so sym-links. Therefore, it is possible that the former + dnl may be available, but the latter may not. Hence, we check explicitly + dnl for mysql.h. + + ulogd_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$MYSQL_CLIENT_CFLAGS" + AC_CHECK_HEADER([mysql.h], [ + + libmysqlclient_CFLAGS="$MYSQL_CLIENT_CFLAGS" + libmysqlclient_LIBS="$MYSQL_CLIENT_LIBS" + + AC_SUBST([libmysqlclient_CFLAGS]) + AC_SUBST([libmysqlclient_LIBS]) + + ]) + CPPFLAGS="$ulogd_save_CPPFLAGS" + + ], [ + AC_MSG_RESULT([no]) + ]) + + AS_IF([test "x$libmysqlclient_LIBS" = "x"], [ + AS_IF([test "x$enable_mysql" = "xyes"], [ + AC_MSG_ERROR([libmysqlclient not found]) + ]) + ]) + + ]) -AC_ARG_WITH([sqlite], AS_HELP_STRING([--without-sqlite], [Build without SQLITE3 output plugin [default=test]])) -AS_IF([test "x$with_sqlite" != "xno"], [ - PKG_CHECK_MODULES([libsqlite3], [sqlite3], [], [:]) ]) -AM_CONDITIONAL([HAVE_SQLITE3], [test -n "$libsqlite3_LIBS"]) -if test "x$libsqlite3_LIBS" != "x"; then - enable_sqlite3="yes" -else - enable_sqlite3="no" -fi +AS_IF([test "x$libmysqlclient_LIBS" != "x"], [enable_mysql=yes], [enable_mysql=no]) +AM_CONDITIONAL([HAVE_MYSQL], [test "x$libmysqlclient_LIBS" != "x"]) -AC_ARG_WITH([dbi], AS_HELP_STRING([--without-dbi], [Build without DBI output plugin [default=test]])) -AS_IF([test "x$with_dbi" != "xno"], [ - CT_CHECK_DBI() +AC_ARG_ENABLE([sqlite3], + [AS_HELP_STRING([--enable-sqlite3], [Enable SQLITE3 output plugin [default=test]])]) +AS_IF([test "x$enable_sqlite3" != "xno"], [ + PKG_CHECK_MODULES([libsqlite3], [sqlite3], [], [ + AS_IF([test "x$enable_sqlite3" = "xyes"], [ + AC_MSG_ERROR([$libsqlite3_PKG_ERRORS]) + ]) + ]) ]) -AM_CONDITIONAL(HAVE_DBI, test "x$DBI_LIB" != "x") -if test "x$DBI_LIB" != "x"; then - enable_dbi="yes" -else - enable_dbi="no" -fi +AS_IF([test "x$libsqlite3_LIBS" != "x"], [enable_sqlite3=yes], [enable_sqlite3=no]) +AM_CONDITIONAL([HAVE_SQLITE3], [test "x$libsqlite3_LIBS" != "x"]) -AC_ARG_WITH([pcap], AS_HELP_STRING([--without-pcap], [Build without PCAP output plugin [default=test]])) -AS_IF([test "x$with_pcap" != "xno"], [ - AC_SEARCH_LIBS([pcap_close], [pcap], [libpcap_LIBS="-lpcap"; LIBS=""]) - AC_SUBST([libpcap_LIBS]) +AC_ARG_ENABLE([dbi], + [AS_HELP_STRING([--enable-dbi], [Enable DBI output plugin [default=test]])]) +AS_IF([test "x$enable_dbi" != "xno"], [ + PKG_CHECK_MODULES([libdbi], [dbi], [], [ + AS_IF([test "x$enable_dbi" = "xyes"], [ + AC_MSG_ERROR([$libdbi_PKG_ERRORS]) + ]) + ]) ]) -AM_CONDITIONAL([HAVE_PCAP], [test -n "$libpcap_LIBS"]) -if test "x$libpcap_LIBS" != "x"; then - enable_pcap="yes" -else - enable_pcap="no" -fi +AS_IF([test "x$libdbi_LIBS" != "x"], [enable_dbi=yes], [enable_dbi=no]) +AM_CONDITIONAL([HAVE_DBI], [test "x$libdbi_LIBS" != "x"]) + +AC_ARG_ENABLE([pcap], + [AS_HELP_STRING([--enable-pcap], [Enable PCAP output plugin [default=test]])]) +AS_IF([test "x$enable_pcap" != "xno"], [ + + PKG_CHECK_EXISTS([libpcap], [PKG_CHECK_MODULES([libpcap], [libpcap])], [ + + AC_ARG_WITH([pcap-config], + [AS_HELP_STRING([--with-pcap-config=PATH], [Path to the pcap-config script])], + [pcap_config="$withval"], [pcap_config=pcap-config]) + + AC_MSG_CHECKING([for pcap-config]) + + AS_IF([command -v "$pcap_config" >/dev/null], [ + + libpcap_CFLAGS="`$pcap_config --cflags`" + libpcap_LIBS="`$pcap_config --libs`" + + AC_SUBST([libpcap_CFLAGS]) + AC_SUBST([libpcap_LIBS]) + + AC_MSG_RESULT([$pcap_config]) + + ], [ + AC_MSG_RESULT([no]) + ]) + + AS_IF([test "x$libpcap_LIBS" = "x"], [ + AS_IF([test "x$enable_pcap" = "xyes"], [ + AC_MSG_ERROR([libpcap not found]) + ]) + ]) + + ]) -AC_ARG_WITH([jansson], AS_HELP_STRING([--without-jansson], [Build without JSON output plugin [default=test]])) -AS_IF([test "x$with_jansson" != "xno"], [ - PKG_CHECK_MODULES([libjansson], [jansson], [], [:]) ]) -AM_CONDITIONAL([HAVE_JANSSON], [test -n "$libjansson_LIBS"]) -if test "x$libjansson_LIBS" != "x"; then - enable_jansson="yes" -else - enable_jansson="no" -fi +AS_IF([test "x$libpcap_LIBS" != "x"], [enable_pcap=yes], [enable_pcap=no]) +AM_CONDITIONAL([HAVE_PCAP], [test "x$libpcap_LIBS" != "x"]) + +AC_ARG_ENABLE([json], + [AS_HELP_STRING([--enable-json], [Enable JSON output plugin [default=test]])]) +AS_IF([test "x$enable_json" != "xno"], + [PKG_CHECK_MODULES([libjansson], [jansson], [], [:])]) +AS_IF([test "x$libjansson_LIBS" != "x"], [enable_json=yes], [enable_json=no]) +AM_CONDITIONAL([HAVE_JANSSON], [test "x$libjansson_LIBS" != "x"]) AC_ARG_WITH([ulogd2libdir], - AS_HELP_STRING([--with-ulogd2libdir=PATH], - [Default directory to load ulogd2 plugin from [[LIBDIR/ulogd]]]), - [ulogd2libdir="$withval"], - [ulogd2libdir="${libdir}/ulogd"]) + [AS_HELP_STRING([--with-ulogd2libdir=PATH], [Default directory to load ulogd2 plugin from [[LIBDIR/ulogd]]])], + [ulogd2libdir="$withval"], + [ulogd2libdir="${libdir}/ulogd"]) AC_SUBST([ulogd2libdir]) -regular_CFLAGS="-Wall -Wextra -Wno-unused-parameter -DULOGD2_LIBDIR=\\\"\${ulogd2libdir}\\\""; -AC_SUBST([regular_CFLAGS]) - -dnl AC_SUBST(DATABASE_DIR) -dnl AC_SUBST(DATABASE_LIB) -dnl AC_SUBST(DATABASE_LIB_DIR) -dnl AC_SUBST(DB_DEF) -dnl AC_SUBST(EXTRA_MYSQL_DEF) -dnl AC_SUBST(EXTRA_PGSQL_DEF) - -dnl AC_SUBST(DATABASE_DRIVERS) - -dnl AM_CONDITIONAL(HAVE_MYSQL, test x$mysqldir != x) -dnl AM_CONDITIONAL(HAVE_PGSQL, test x$pgsqldir != x) - -AC_CONFIG_FILES(include/Makefile include/ulogd/Makefile include/libipulog/Makefile \ - include/linux/Makefile include/linux/netfilter/Makefile \ - include/linux/netfilter_ipv4/Makefile libipulog/Makefile \ - input/Makefile input/packet/Makefile input/flow/Makefile \ - input/sum/Makefile \ - filter/Makefile filter/raw2packet/Makefile filter/packet2flow/Makefile \ - output/Makefile output/pcap/Makefile output/mysql/Makefile output/pgsql/Makefile output/sqlite3/Makefile \ - output/dbi/Makefile output/ipfix/Makefile \ - src/Makefile Makefile Rules.make) +AC_CONFIG_FILES([Makefile + filter/Makefile + filter/raw2packet/Makefile + include/Makefile + include/libipulog/Makefile + include/linux/Makefile + include/linux/netfilter/Makefile + include/linux/netfilter_ipv4/Makefile + include/ulogd/Makefile + input/Makefile + input/flow/Makefile + input/packet/Makefile + input/sum/Makefile + libipulog/Makefile + output/Makefile + output/dbi/Makefile + output/ipfix/Makefile + output/mysql/Makefile + output/pcap/Makefile + output/pgsql/Makefile + output/sqlite3/Makefile + src/Makefile]) + AC_OUTPUT define([EXPAND_VARIABLE], @@ -213,6 +304,6 @@ Ulogd configuration: MySQL plugin: ${enable_mysql} SQLITE3 plugin: ${enable_sqlite3} DBI plugin: ${enable_dbi} - JSON plugin: ${enable_jansson} + JSON plugin: ${enable_json} " echo "You can now run 'make' and 'make install'" diff --git a/doc/mysql-ulogd2-flat.sql b/doc/mysql-ulogd2-flat.sql index d71608c..6d663f6 100644 --- a/doc/mysql-ulogd2-flat.sql +++ b/doc/mysql-ulogd2-flat.sql @@ -51,7 +51,7 @@ CREATE TABLE `ulog2` ( `raw_label` tinyint(3) unsigned default NULL, `mac_saddr_str` varchar(32) default NULL, `mac_daddr_str` varchar(32) default NULL, - `oob_protocol` smallint(5) default NULL, + `oob_protocol` smallint(5) unsigned default NULL, `raw_type` int(10) unsigned default NULL, `mac_str` varchar(255) default NULL, `tcp_sport` int(5) unsigned default NULL, diff --git a/doc/mysql-ulogd2.sql b/doc/mysql-ulogd2.sql index c44f9a9..782f368 100644 --- a/doc/mysql-ulogd2.sql +++ b/doc/mysql-ulogd2.sql @@ -84,7 +84,7 @@ CREATE TABLE `mac` ( `_mac_id` bigint unsigned NOT NULL auto_increment, `mac_saddr` varchar(32) default NULL, `mac_daddr` varchar(32) default NULL, - `mac_protocol` smallint(5) default NULL, + `mac_protocol` smallint(5) unsigned default NULL, UNIQUE KEY `key_id` (`_mac_id`) ) ENGINE=INNODB; @@ -681,7 +681,7 @@ delimiter $$ CREATE FUNCTION INSERT_OR_SELECT_MAC( `_saddr` varchar(32), `_daddr` varchar(32), - `_protocol` smallint(5) + `_protocol` smallint(5) unsigned ) RETURNS bigint unsigned NOT DETERMINISTIC READS SQL DATA @@ -764,7 +764,7 @@ CREATE FUNCTION INSERT_PACKET_FULL( raw_header varchar(256), mac_saddr varchar(32), mac_daddr varchar(32), - mac_protocol smallint(5), + mac_protocol smallint(5) unsigned, _label tinyint(4) unsigned, sctp_sport smallint(5) unsigned, sctp_dport smallint(5) unsigned, diff --git a/doc/pgsql-ulogd2-flat.sql b/doc/pgsql-ulogd2-flat.sql index 6cd2150..94c9037 100644 --- a/doc/pgsql-ulogd2-flat.sql +++ b/doc/pgsql-ulogd2-flat.sql @@ -43,7 +43,7 @@ CREATE TABLE ulog2 ( ip_protocol smallint default NULL, ip_tos smallint default NULL, ip_ttl smallint default NULL, - ip_totlen smallint default NULL, + ip_totlen integer default NULL, ip_ihl smallint default NULL, ip_csum integer default NULL, ip_id integer default NULL, diff --git a/doc/pgsql-ulogd2.sql b/doc/pgsql-ulogd2.sql index 0e01ba4..edc81e7 100644 --- a/doc/pgsql-ulogd2.sql +++ b/doc/pgsql-ulogd2.sql @@ -55,7 +55,7 @@ CREATE TABLE ulog2 ( ip_protocol smallint default NULL, ip_tos smallint default NULL, ip_ttl smallint default NULL, - ip_totlen smallint default NULL, + ip_totlen integer default NULL, ip_ihl smallint default NULL, ip_csum integer default NULL, ip_id integer default NULL, diff --git a/filter/Makefile.am b/filter/Makefile.am index 875850b..f1d2c81 100644 --- a/filter/Makefile.am +++ b/filter/Makefile.am @@ -1,7 +1,8 @@ -SUBDIRS = raw2packet packet2flow +SUBDIRS = raw2packet -AM_CPPFLAGS = -I$(top_srcdir)/include ${LIBNFNETLINK_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am + +AM_CPPFLAGS += ${LIBNFNETLINK_CFLAGS} pkglib_LTLIBRARIES = ulogd_filter_IFINDEX.la ulogd_filter_PWSNIFF.la \ ulogd_filter_PRINTPKT.la ulogd_filter_PRINTFLOW.la \ diff --git a/filter/packet2flow/Makefile.am b/filter/packet2flow/Makefile.am deleted file mode 100644 index e69de29..0000000 --- a/filter/packet2flow/Makefile.am +++ /dev/null diff --git a/filter/raw2packet/Makefile.am b/filter/raw2packet/Makefile.am index 7498f9a..90768ef 100644 --- a/filter/raw2packet/Makefile.am +++ b/filter/raw2packet/Makefile.am @@ -1,6 +1,4 @@ - -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am pkglib_LTLIBRARIES = ulogd_raw2packet_BASE.la diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c index fd2665a..09e9313 100644 --- a/filter/raw2packet/ulogd_raw2packet_BASE.c +++ b/filter/raw2packet/ulogd_raw2packet_BASE.c @@ -645,7 +645,7 @@ static int _interp_icmp(struct ulogd_pluginstance *pi, struct icmphdr *icmph, break; case ICMP_REDIRECT: case ICMP_PARAMETERPROB: - okey_set_u32(&ret[KEY_ICMP_GATEWAY], ntohl(icmph->un.gateway)); + okey_set_u32(&ret[KEY_ICMP_GATEWAY], icmph->un.gateway); break; case ICMP_DEST_UNREACH: if (icmph->code == ICMP_FRAG_NEEDED) { @@ -896,18 +896,23 @@ static int _interp_arp(struct ulogd_pluginstance *pi, uint32_t len) struct ulogd_key *ret = pi->output.keys; const struct ether_arp *arph = ikey_get_ptr(&pi->input.keys[INKEY_RAW_PCKT]); + uint32_t arp_spa, arp_tpa; if (len < sizeof(struct ether_arp)) return ULOGD_IRET_OK; - okey_set_u16(&ret[KEY_ARP_HTYPE], ntohs(arph->arp_hrd)); - okey_set_u16(&ret[KEY_ARP_PTYPE], ntohs(arph->arp_pro)); + okey_set_u16(&ret[KEY_ARP_HTYPE], ntohs(arph->arp_hrd)); + okey_set_u16(&ret[KEY_ARP_PTYPE], ntohs(arph->arp_pro)); okey_set_u16(&ret[KEY_ARP_OPCODE], ntohs(arph->arp_op)); okey_set_ptr(&ret[KEY_ARP_SHA], (void *)&arph->arp_sha); - okey_set_ptr(&ret[KEY_ARP_SPA], (void *)&arph->arp_spa), okey_set_ptr(&ret[KEY_ARP_THA], (void *)&arph->arp_tha); - okey_set_ptr(&ret[KEY_ARP_TPA], (void *)&arph->arp_tpa); + + memcpy(&arp_spa, arph->arp_spa, sizeof(arp_spa)); + memcpy(&arp_tpa, arph->arp_tpa, sizeof(arp_tpa)); + + okey_set_u32(&ret[KEY_ARP_SPA], arp_spa); + okey_set_u32(&ret[KEY_ARP_TPA], arp_tpa); return ULOGD_IRET_OK; } diff --git a/filter/ulogd_filter_HWHDR.c b/filter/ulogd_filter_HWHDR.c index 10c95c4..a5ee60d 100644 --- a/filter/ulogd_filter_HWHDR.c +++ b/filter/ulogd_filter_HWHDR.c @@ -109,7 +109,7 @@ static struct ulogd_key mac2str_keys[] = { }, }; -static char hwmac_str[MAX_KEY - START_KEY][HWADDR_LENGTH]; +static char hwmac_str[MAX_KEY - START_KEY + 1][HWADDR_LENGTH]; static int parse_mac2str(struct ulogd_key *ret, unsigned char *mac, int okey, int len) @@ -126,7 +126,7 @@ static int parse_mac2str(struct ulogd_key *ret, unsigned char *mac, buf_cur = hwmac_str[okey - START_KEY]; for (i = 0; i < len; i++) buf_cur += sprintf(buf_cur, "%02x%c", mac[i], - i == len - 1 ? 0 : ':'); + i == len - 1 ? 0 : ':'); okey_set_ptr(&ret[okey], hwmac_str[okey - START_KEY]); @@ -171,7 +171,7 @@ static int interp_mac2str(struct ulogd_pluginstance *pi) { struct ulogd_key *ret = pi->output.keys; struct ulogd_key *inp = pi->input.keys; - uint16_t type = 0; + uint16_t type; if (pp_is_valid(inp, KEY_OOB_PROTOCOL)) okey_set_u16(&ret[KEY_MAC_PROTOCOL], @@ -191,35 +191,31 @@ static int interp_mac2str(struct ulogd_pluginstance *pi) okey_set_u16(&ret[KEY_MAC_TYPE], ARPHRD_VOID); } - if (pp_is_valid(inp, KEY_RAW_MAC)) { - if (! pp_is_valid(inp, KEY_RAW_MACLEN)) - return ULOGD_IRET_ERR; - if (pp_is_valid(inp, KEY_RAW_TYPE)) { - /* NFLOG with Linux >= 2.6.27 case */ - type = ikey_get_u16(&inp[KEY_RAW_TYPE]); - } else { - /* ULOG case, treat ethernet encapsulation */ - if (ikey_get_u16(&inp[KEY_RAW_MACLEN]) == ETH_HLEN) - type = ARPHRD_ETHER; - else - type = ARPHRD_VOID; - } - okey_set_u16(&ret[KEY_MAC_TYPE], type); - } + if (!pp_is_valid(inp, KEY_RAW_MAC)) + return ULOGD_IRET_OK; - switch (type) { - case ARPHRD_ETHER: - parse_ethernet(ret, inp); - default: - if (!pp_is_valid(inp, KEY_RAW_MAC)) - return ULOGD_IRET_OK; - /* convert raw header to string */ - return parse_mac2str(ret, - ikey_get_ptr(&inp[KEY_RAW_MAC]), - KEY_MAC_ADDR, - ikey_get_u16(&inp[KEY_RAW_MACLEN])); - } - return ULOGD_IRET_OK; + if (!pp_is_valid(inp, KEY_RAW_MACLEN)) + return ULOGD_IRET_ERR; + + if (pp_is_valid(inp, KEY_RAW_TYPE)) + /* NFLOG with Linux >= 2.6.27 case */ + type = ikey_get_u16(&inp[KEY_RAW_TYPE]); + else if (ikey_get_u16(&inp[KEY_RAW_MACLEN]) == ETH_HLEN) + /* ULOG case, treat ethernet encapsulation */ + type = ARPHRD_ETHER; + else + type = ARPHRD_VOID; + + okey_set_u16(&ret[KEY_MAC_TYPE], type); + + if (type == ARPHRD_ETHER) + parse_ethernet(ret, inp); + + /* convert raw header to string */ + return parse_mac2str(ret, + ikey_get_ptr(&inp[KEY_RAW_MAC]), + KEY_MAC_ADDR, + ikey_get_u16(&inp[KEY_RAW_MACLEN])); } diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c index 2172d93..7f7bea5 100644 --- a/filter/ulogd_filter_IP2BIN.c +++ b/filter/ulogd_filter_IP2BIN.c @@ -114,29 +114,14 @@ static struct ulogd_key ip2bin_keys[] = { }; -static char ipbin_array[MAX_KEY-START_KEY][IPADDR_LENGTH]; +static char ipbin_array[MAX_KEY - START_KEY + 1][IPADDR_LENGTH]; -/** - * Convert IPv4 address (as 32-bit unsigned integer) to IPv6 address: - * add 96 bits prefix "::ffff:" to get IPv6 address "::ffff:a.b.c.d". - */ -static inline void uint32_to_ipv6(const uint32_t ipv4, struct in6_addr *ipv6) -{ - ipv6->s6_addr32[0] = 0x00000000; - ipv6->s6_addr32[1] = 0x00000000; - ipv6->s6_addr32[2] = htonl(0xffff); - ipv6->s6_addr32[3] = ipv4; -} - -static int ip2bin(struct ulogd_key* inp, int index, int oindex) +static int ip2bin(struct ulogd_key *inp, int index, int oindex) { char family = ikey_get_u8(&inp[KEY_OOB_FAMILY]); char convfamily = family; - unsigned char *addr8; struct in6_addr *addr; struct in6_addr ip4_addr; - char *buffer; - int i, written; if (family == AF_BRIDGE) { if (!pp_is_valid(inp, KEY_OOB_PROTOCOL)) { @@ -176,23 +161,7 @@ static int ip2bin(struct ulogd_key* inp, int index, int oindex) return ULOGD_IRET_ERR; } - buffer = ipbin_array[oindex]; - /* format IPv6 to BINARY(16) as "0x..." */ - buffer[0] = '0'; - buffer[1] = 'x'; - buffer += 2; - addr8 = &addr->s6_addr[0]; - for (i = 0; i < 4; i++) { - written = sprintf(buffer, "%02x%02x%02x%02x", - addr8[0], addr8[1], addr8[2], addr8[3]); - if (written != 2 * 4) { - buffer[0] = 0; - return ULOGD_IRET_ERR; - } - buffer += written; - addr8 += 4; - } - buffer[0] = 0; + format_ipv6(ipbin_array[oindex], IPADDR_LENGTH, addr); return ULOGD_IRET_OK; } @@ -205,20 +174,20 @@ static int interp_ip2bin(struct ulogd_pluginstance *pi) int fret; /* Iter on all addr fields */ - for(i = START_KEY; i < MAX_KEY; i++) { + for(i = START_KEY; i <= MAX_KEY; i++) { if (pp_is_valid(inp, i)) { - fret = ip2bin(inp, i, i-START_KEY); + fret = ip2bin(inp, i, i - START_KEY); if (fret != ULOGD_IRET_OK) return fret; - okey_set_ptr(&ret[i-START_KEY], - ipbin_array[i-START_KEY]); + okey_set_ptr(&ret[i - START_KEY], + ipbin_array[i - START_KEY]); } } return ULOGD_IRET_OK; } -static struct ulogd_plugin ip2bin_pluging = { +static struct ulogd_plugin ip2bin_plugin = { .name = "IP2BIN", .input = { .keys = ip2bin_inp, @@ -238,5 +207,5 @@ void __attribute__ ((constructor)) init(void); void init(void) { - ulogd_register_plugin(&ip2bin_pluging); + ulogd_register_plugin(&ip2bin_plugin); } diff --git a/filter/ulogd_filter_IP2HBIN.c b/filter/ulogd_filter_IP2HBIN.c index 087e824..081616e 100644 --- a/filter/ulogd_filter_IP2HBIN.c +++ b/filter/ulogd_filter_IP2HBIN.c @@ -153,19 +153,18 @@ static int interp_ip2hbin(struct ulogd_pluginstance *pi) } /* Iter on all addr fields */ - for(i = START_KEY; i < MAX_KEY; i++) { + for(i = START_KEY; i <= MAX_KEY; i++) { if (pp_is_valid(inp, i)) { switch (convfamily) { case AF_INET: - okey_set_u32(&ret[i-START_KEY], - ntohl(ikey_get_u32(&inp[i]))); + okey_set_u32(&ret[i - START_KEY], + ntohl(ikey_get_u32(&inp[i]))); break; case AF_INET6: - okey_set_ptr(&ret[i-START_KEY], - (struct in6_addr *)ikey_get_u128(&inp[i])); + okey_set_u128(&ret[i - START_KEY], + ikey_get_u128(&inp[i])); break; default: - ; break; } } diff --git a/filter/ulogd_filter_IP2STR.c b/filter/ulogd_filter_IP2STR.c index 66324b0..4d05368 100644 --- a/filter/ulogd_filter_IP2STR.c +++ b/filter/ulogd_filter_IP2STR.c @@ -137,7 +137,7 @@ static struct ulogd_key ip2str_keys[] = { }, }; -static char ipstr_array[MAX_KEY-START_KEY][IPADDR_LENGTH]; +static char ipstr_array[MAX_KEY - START_KEY + 1][IPADDR_LENGTH]; static int ip2str(struct ulogd_key *inp, int index, int oindex) { @@ -197,10 +197,10 @@ static int interp_ip2str(struct ulogd_pluginstance *pi) /* Iter on all addr fields */ for (i = START_KEY; i <= MAX_KEY; i++) { if (pp_is_valid(inp, i)) { - fret = ip2str(inp, i, i-START_KEY); + fret = ip2str(inp, i, i - START_KEY); if (fret != ULOGD_IRET_OK) return fret; - okey_set_ptr(&ret[i-START_KEY], + okey_set_ptr(&ret[i - START_KEY], ipstr_array[i-START_KEY]); } } diff --git a/filter/ulogd_filter_PWSNIFF.c b/filter/ulogd_filter_PWSNIFF.c index 934ff0e..ef9e021 100644 --- a/filter/ulogd_filter_PWSNIFF.c +++ b/filter/ulogd_filter_PWSNIFF.c @@ -35,10 +35,14 @@ #define DEBUGP(format, args...) #endif - #define PORT_POP3 110 #define PORT_FTP 21 +enum pwsniff_output_keys { + PWSNIFF_OUT_KEY_USER, + PWSNIFF_OUT_KEY_PASS, +}; + static uint16_t pwsniff_ports[] = { PORT_POP3, PORT_FTP, @@ -116,21 +120,17 @@ static int interp_pwsniff(struct ulogd_pluginstance *pi) if (len) { char *ptr; - ptr = (char *) malloc(len+1); + ptr = strndup((char *)begp, len); if (!ptr) return ULOGD_IRET_ERR; - strncpy(ptr, (char *)begp, len); - ptr[len] = '\0'; - okey_set_ptr(&ret[0], ptr); + okey_set_ptr(&ret[PWSNIFF_OUT_KEY_USER], ptr); } if (pw_len) { char *ptr; - ptr = (char *) malloc(pw_len+1); + ptr = strndup((char *)pw_begp, pw_len); if (!ptr) return ULOGD_IRET_ERR; - strncpy(ptr, (char *)pw_begp, pw_len); - ptr[pw_len] = '\0'; - okey_set_ptr(&ret[1], ptr); + okey_set_ptr(&ret[PWSNIFF_OUT_KEY_PASS], ptr); } return ULOGD_IRET_OK; } diff --git a/include/libipulog/Makefile.am b/include/libipulog/Makefile.am index a98f941..80d16b1 100644 --- a/include/libipulog/Makefile.am +++ b/include/libipulog/Makefile.am @@ -1,2 +1 @@ - noinst_HEADERS = libipulog.h diff --git a/include/ulogd/Makefile.am b/include/ulogd/Makefile.am index 5e6aa75..e4b41c4 100644 --- a/include/ulogd/Makefile.am +++ b/include/ulogd/Makefile.am @@ -1,2 +1 @@ - noinst_HEADERS = conffile.h db.h ipfix_protocol.h linuxlist.h ulogd.h printpkt.h printflow.h common.h linux_rbtree.h timer.h slist.h hash.h jhash.h addr.h diff --git a/include/ulogd/jhash.h b/include/ulogd/jhash.h index 38b8780..e5ca287 100644 --- a/include/ulogd/jhash.h +++ b/include/ulogd/jhash.h @@ -66,18 +66,18 @@ static inline u32 jhash(const void *key, u32 length, u32 initval) c += length; switch (len) { - case 11: c += ((u32)k[10]<<24); - case 10: c += ((u32)k[9]<<16); - case 9 : c += ((u32)k[8]<<8); - case 8 : b += ((u32)k[7]<<24); - case 7 : b += ((u32)k[6]<<16); - case 6 : b += ((u32)k[5]<<8); - case 5 : b += k[4]; - case 4 : a += ((u32)k[3]<<24); - case 3 : a += ((u32)k[2]<<16); - case 2 : a += ((u32)k[1]<<8); - case 1 : a += k[0]; - }; + case 11: c += ((u32)k[10]<<24); // fall through + case 10: c += ((u32)k[9]<<16); // fall through + case 9 : c += ((u32)k[8]<<8); // fall through + case 8 : b += ((u32)k[7]<<24); // fall through + case 7 : b += ((u32)k[6]<<16); // fall through + case 6 : b += ((u32)k[5]<<8); // fall through + case 5 : b += k[4]; // fall through + case 4 : a += ((u32)k[3]<<24); // fall through + case 3 : a += ((u32)k[2]<<16); // fall through + case 2 : a += ((u32)k[1]<<8); // fall through + case 1 : a += k[0]; // fall through + } __jhash_mix(a,b,c); diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h index 1636a8c..c7cf402 100644 --- a/include/ulogd/ulogd.h +++ b/include/ulogd/ulogd.h @@ -18,6 +18,7 @@ #include <signal.h> /* need this because of extension-sighandler */ #include <sys/types.h> #include <inttypes.h> +#include <netinet/in.h> #include <string.h> #include <config.h> @@ -28,11 +29,6 @@ /* types without length */ #define ULOGD_RET_NONE 0x0000 -#define __packed __attribute__((packed)) -#define __noreturn __attribute__((noreturn)) -#define __cold __attribute__((cold)) - -#define __packed __attribute__((packed)) #define ULOGD_RET_INT8 0x0001 #define ULOGD_RET_INT16 0x0002 @@ -139,36 +135,42 @@ static inline void okey_set_b(struct ulogd_key *key, uint8_t value) { key->u.value.b = value; key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.b); } static inline void okey_set_u8(struct ulogd_key *key, uint8_t value) { key->u.value.ui8 = value; key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.ui8); } static inline void okey_set_u16(struct ulogd_key *key, uint16_t value) { key->u.value.ui16 = value; key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.ui16); } static inline void okey_set_u32(struct ulogd_key *key, uint32_t value) { key->u.value.ui32 = value; key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.ui32); } static inline void okey_set_u64(struct ulogd_key *key, uint64_t value) { key->u.value.ui64 = value; key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.ui64); } static inline void okey_set_u128(struct ulogd_key *key, const void *value) { - memcpy(key->u.value.ui128, value, 16); + memcpy(key->u.value.ui128, value, sizeof(key->u.value.ui128)); key->flags |= ULOGD_RETF_VALID; + key->len = sizeof(key->u.value.ui128); } static inline void okey_set_ptr(struct ulogd_key *key, void *value) @@ -207,6 +209,46 @@ static inline void *ikey_get_ptr(struct ulogd_key *key) return key->u.source->u.value.ptr; } +/** + * Convert IPv4 address (as 32-bit unsigned integer) to IPv6 address: add 96-bit + * prefix "::ffff" to get IPv6 address "::ffff:a.b.c.d". + */ +static inline struct in6_addr * +uint32_to_ipv6(uint32_t ipv4, struct in6_addr *ipv6) +{ + static const uint8_t IPV4_IN_IPV6_PREFIX[12] = { + [10] = 0xff, + [11] = 0xff, + }; + uint8_t *p = ipv6->s6_addr; + + memcpy(p, IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX)); + p += sizeof(IPV4_IN_IPV6_PREFIX); + memcpy(p, &ipv4, sizeof(ipv4)); + + return ipv6; +} + +static inline void +format_ipv6(char *buf, size_t size, const struct in6_addr *ipv6) +{ + unsigned i = 0; + + if (size > 2 + sizeof (*ipv6) * 2) { + buf[i++] = '0'; + buf[i++] = 'x'; + + for (unsigned j = 0; i < sizeof(*ipv6); j += 4, i += 8) { + sprintf(buf + i, "%02hhx%02hhx%02hhx%02hhx", + ipv6->s6_addr[j + 0], + ipv6->s6_addr[j + 1], + ipv6->s6_addr[j + 2], + ipv6->s6_addr[j + 3]); + } + } + buf[i] = '\0'; +} + struct ulogd_pluginstance_stack; struct ulogd_pluginstance; @@ -299,8 +341,9 @@ void ulogd_register_plugin(struct ulogd_plugin *me); /* allocate a new ulogd_key */ struct ulogd_key *alloc_ret(const uint16_t type, const char*); -/* write a message to the daemons' logfile */ -void __ulogd_log(int level, char *file, int line, const char *message, ...); +/* write a message to the daemon's logfile */ +void __ulogd_log(int level, char *file, int line, const char *message, ...) + __attribute__((format(printf, 4, 5))); /* macro for logging including filename and line number */ #define ulogd_log(level, format, args...) \ __ulogd_log(level, __FILE__, __LINE__, format, ## args) @@ -313,6 +356,7 @@ void __ulogd_log(int level, char *file, int line, const char *message, ...); #define SET_NEEDED(x) (x.flags |= ULOGD_RETF_NEEDED) #define GET_FLAGS(res, x) (res[x].u.source->flags) +#define GET_LENGTH(res, x) (res[x].u.source->len) #define pp_is_valid(res, x) \ (res[x].u.source && (GET_FLAGS(res, x) & ULOGD_RETF_VALID)) diff --git a/input/Makefile.am b/input/Makefile.am index 5ffef1b..668fc2b 100644 --- a/input/Makefile.am +++ b/input/Makefile.am @@ -1,2 +1,9 @@ +if BUILD_NFCT + OPT_SUBDIR_FLOW = flow +endif -SUBDIRS = packet flow sum +if BUILD_NFACCT + OPT_SUBDIR_SUM = sum +endif + +SUBDIRS = packet $(OPT_SUBDIR_FLOW) $(OPT_SUBDIR_SUM) diff --git a/input/flow/Makefile.am b/input/flow/Makefile.am index 0e07a7d..a556b4e 100644 --- a/input/flow/Makefile.am +++ b/input/flow/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include ${LIBNETFILTER_CONNTRACK_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +AM_CPPFLAGS += ${LIBNETFILTER_CONNTRACK_CFLAGS} -if BUILD_NFCT -pkglib_LTLIBRARIES = ulogd_inpflow_NFCT.la # ulogd_inpflow_IPFIX.la +pkglib_LTLIBRARIES = ulogd_inpflow_NFCT.la ulogd_inpflow_NFCT_la_SOURCES = ulogd_inpflow_NFCT.c -ulogd_inpflow_NFCT_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS) -endif - -#ulogd_inpflow_IPFIX_la_SOURCES = ulogd_inpflow_IPFIX.c -#ulogd_inpflow_IPFIX_la_LDFLAGS = -avoid-version -module +ulogd_inpflow_NFCT_la_LDFLAGS = -avoid-version -module +ulogd_inpflow_NFCT_la_LIBADD = $(LIBNETFILTER_CONNTRACK_LIBS) diff --git a/input/packet/Makefile.am b/input/packet/Makefile.am index 1c3151d..851c608 100644 --- a/input/packet/Makefile.am +++ b/input/packet/Makefile.am @@ -1,23 +1,25 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include ${LIBNETFILTER_LOG_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +AM_CPPFLAGS += ${LIBNETFILTER_LOG_CFLAGS} ${LIBNETFILTER_CONNTRACK_CFLAGS} pkglib_LTLIBRARIES = ulogd_inppkt_UNIXSOCK.la +ulogd_inppkt_UNIXSOCK_la_SOURCES = ulogd_inppkt_UNIXSOCK.c +ulogd_inppkt_UNIXSOCK_la_LDFLAGS = -avoid-version -module + if BUILD_ULOG pkglib_LTLIBRARIES += ulogd_inppkt_ULOG.la + +ulogd_inppkt_ULOG_la_SOURCES = ulogd_inppkt_ULOG.c +ulogd_inppkt_ULOG_la_LDFLAGS = -avoid-version -module +ulogd_inppkt_ULOG_la_LIBADD = ../../libipulog/libipulog.la endif if BUILD_NFLOG pkglib_LTLIBRARIES += ulogd_inppkt_NFLOG.la -endif ulogd_inppkt_NFLOG_la_SOURCES = ulogd_inppkt_NFLOG.c -ulogd_inppkt_NFLOG_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_LOG_LIBS) - -ulogd_inppkt_ULOG_la_SOURCES = ulogd_inppkt_ULOG.c -ulogd_inppkt_ULOG_la_LDFLAGS = -avoid-version -module -ulogd_inppkt_ULOG_la_LIBADD = ../../libipulog/libipulog.la - -ulogd_inppkt_UNIXSOCK_la_SOURCES = ulogd_inppkt_UNIXSOCK.c -ulogd_inppkt_UNIXSOCK_la_LDFLAGS = -avoid-version -module +ulogd_inppkt_NFLOG_la_LDFLAGS = -avoid-version -module +ulogd_inppkt_NFLOG_la_LIBADD = $(LIBNETFILTER_LOG_LIBS) \ + $(LIBNETFILTER_CONNTRACK_LIBS) +endif diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c index a367959..4fdeb12 100644 --- a/input/packet/ulogd_inppkt_NFLOG.c +++ b/input/packet/ulogd_inppkt_NFLOG.c @@ -12,6 +12,13 @@ #include <ulogd/ulogd.h> #include <libnfnetlink/libnfnetlink.h> #include <libnetfilter_log/libnetfilter_log.h> +#ifdef BUILD_NFCT +#include <libmnl/libmnl.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#else +struct nf_conntrack; +#endif + #ifndef NFLOG_GROUP_DEFAULT #define NFLOG_GROUP_DEFAULT 0 @@ -33,7 +40,7 @@ struct nflog_input { /* configuration entries */ static struct config_keyset libulog_kset = { - .num_ces = 11, + .num_ces = 12, .ces = { { .key = "bufsize", @@ -102,6 +109,12 @@ static struct config_keyset libulog_kset = { .options = CONFIG_OPT_NONE, .u.value = 0, }, + { + .key = "attach_conntrack", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = 0, + }, } }; @@ -116,6 +129,7 @@ static struct config_keyset libulog_kset = { #define nlsockbufmaxsize_ce(x) (x->ces[8]) #define nlthreshold_ce(x) (x->ces[9]) #define nltimeout_ce(x) (x->ces[10]) +#define attach_conntrack_ce(x) (x->ces[11]) enum nflog_keys { NFLOG_KEY_RAW_MAC = 0, @@ -141,6 +155,7 @@ enum nflog_keys { NFLOG_KEY_RAW_MAC_SADDR, NFLOG_KEY_RAW_MAC_ADDRLEN, NFLOG_KEY_RAW, + NFLOG_KEY_RAW_CT, }; static struct ulogd_key output_keys[] = { @@ -312,11 +327,52 @@ static struct ulogd_key output_keys[] = { .flags = ULOGD_RETF_NONE, .name = "raw", }, + [NFLOG_KEY_RAW_CT] = { + .type = ULOGD_RET_RAW, + .flags = ULOGD_RETF_NONE, + .name = "ct", + }, }; +struct nf_conntrack *build_ct(struct nfgenmsg *nfmsg) +{ +#ifdef BUILD_NFCT + struct nlmsghdr *nlh = + (struct nlmsghdr *)((void *)nfmsg - sizeof(*nlh)); + struct nlattr *attr, *ctattr = NULL; + struct nf_conntrack *ct; + + mnl_attr_for_each(attr, nlh, sizeof(struct nfgenmsg)) { + if (mnl_attr_get_type(attr) == NFULA_CT) { + ctattr = attr; + break; + } + } + if (!ctattr) + return NULL; + + ct = nfct_new(); + if (!ct) { + ulogd_log(ULOGD_ERROR, "failed to allocate nfct\n"); + return NULL; + } + if (nfct_payload_parse(mnl_attr_get_payload(ctattr), + mnl_attr_get_payload_len(ctattr), + nfmsg->nfgen_family, ct) < 0) { + ulogd_log(ULOGD_ERROR, "failed to parse nfct payload\n"); + nfct_destroy(ct); + return NULL; + } + + return ct; +#else + return NULL; +#endif +} + static inline int interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, - struct nflog_data *ldata) + struct nflog_data *ldata, struct nf_conntrack *ct) { struct ulogd_key *ret = upi->output.keys; @@ -397,6 +453,9 @@ interp_packet(struct ulogd_pluginstance *upi, uint8_t pf_family, okey_set_ptr(&ret[NFLOG_KEY_RAW], ldata); + if (ct != NULL) + okey_set_ptr(&ret[NFLOG_KEY_RAW_CT], ct); + ulogd_propagate_results(upi); return 0; } @@ -471,16 +530,25 @@ static int msg_cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg, { struct ulogd_pluginstance *upi = data; struct ulogd_pluginstance *npi = NULL; + void *ct = build_ct(nfmsg); int ret = 0; /* since we support the re-use of one instance in several * different stacks, we duplicate the message to let them know */ llist_for_each_entry(npi, &upi->plist, plist) { - ret = interp_packet(npi, nfmsg->nfgen_family, nfa); + ret = interp_packet(npi, nfmsg->nfgen_family, nfa, ct); if (ret != 0) - return ret; + goto release_ct; } - return interp_packet(upi, nfmsg->nfgen_family, nfa); + ret = interp_packet(upi, nfmsg->nfgen_family, nfa, ct); + +release_ct: +#ifdef BUILD_NFCT + if (ct != NULL) + nfct_destroy(ct); +#endif + + return ret; } static int configure(struct ulogd_pluginstance *upi, @@ -595,8 +663,10 @@ static int start(struct ulogd_pluginstance *upi) flags = 0; if (seq_ce(upi->config_kset).u.value != 0) flags = NFULNL_CFG_F_SEQ; - if (seq_ce(upi->config_kset).u.value != 0) + if (seq_global_ce(upi->config_kset).u.value != 0) flags |= NFULNL_CFG_F_SEQ_GLOBAL; + if (attach_conntrack_ce(upi->config_kset).u.value != 0) + flags |= NFULNL_CFG_F_CONNTRACK; if (flags) { if (nflog_set_flags(ui->nful_gh, flags) < 0) ulogd_log(ULOGD_ERROR, "unable to set flags 0x%x\n", diff --git a/input/packet/ulogd_inppkt_UNIXSOCK.c b/input/packet/ulogd_inppkt_UNIXSOCK.c index 39944bf..f1d1534 100644 --- a/input/packet/ulogd_inppkt_UNIXSOCK.c +++ b/input/packet/ulogd_inppkt_UNIXSOCK.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <inttypes.h> #include <unistd.h> #include <stdlib.h> #include <netinet/ether.h> @@ -370,7 +371,7 @@ struct ulogd_unixsock_option_t { static int handle_packet(struct ulogd_pluginstance *upi, struct ulogd_unixsock_packet_t *pkt, uint16_t total_len) { char *data = NULL; - struct iphdr *ip; + unsigned int ip_version = pkt->payload.version; struct ulogd_key *ret = upi->output.keys; uint8_t oob_family; uint16_t payload_len; @@ -386,22 +387,22 @@ static int handle_packet(struct ulogd_pluginstance *upi, struct ulogd_unixsock_p payload_len = ntohs(pkt->payload_length); - ip = &pkt->payload; - if (ip->version == 4) + if (ip_version == 4) oob_family = AF_INET; - else if (ip->version == 6) + else if (ip_version == 6) oob_family = AF_INET6; - else oob_family = 0; + else + oob_family = 0; okey_set_u8(&ret[UNIXSOCK_KEY_OOB_FAMILY], oob_family); - okey_set_ptr(&ret[UNIXSOCK_KEY_RAW_PCKT], ip); + okey_set_ptr(&ret[UNIXSOCK_KEY_RAW_PCKT], &pkt->payload); okey_set_u32(&ret[UNIXSOCK_KEY_RAW_PCKTLEN], payload_len); /* options */ if (total_len > payload_len + sizeof(uint16_t)) { /* option starts at the next aligned address after the payload */ new_offset = USOCK_ALIGN(payload_len); - options_start = (void*)ip + new_offset; + options_start = (void*)&pkt->payload + new_offset; data = options_start; total_len -= (options_start - (char*)pkt); @@ -459,7 +460,7 @@ static int handle_packet(struct ulogd_pluginstance *upi, struct ulogd_unixsock_p "ulogd2: unknown option %d\n", option_number); break; - }; + } } } @@ -473,35 +474,31 @@ static int handle_packet(struct ulogd_pluginstance *upi, struct ulogd_unixsock_p static int _create_unix_socket(const char *unix_path) { + struct sockaddr_un server_sock = { .sun_family = AF_UNIX }; int ret = -1; - struct sockaddr_un server_sock; int s; - struct stat st_dummy; - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s < 0) { + if (strlen(unix_path) >= sizeof(server_sock.sun_path)) { ulogd_log(ULOGD_ERROR, - "ulogd2: could not create unix socket\n"); + "ulogd2: unix socket path '%s' too long\n", + unix_path); return -1; } - server_sock.sun_family = AF_UNIX; - strncpy(server_sock.sun_path, unix_path, sizeof(server_sock.sun_path)); - server_sock.sun_path[sizeof(server_sock.sun_path)-1] = '\0'; + strcpy(server_sock.sun_path, unix_path); - if (stat(unix_path, &st_dummy) == 0 && st_dummy.st_size > 0) { + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) { ulogd_log(ULOGD_ERROR, - "ulogd2: unix socket \'%s\' already exists\n", - unix_path); - close(s); + "ulogd2: could not create unix socket\n"); return -1; } ret = bind(s, (struct sockaddr *)&server_sock, sizeof(server_sock)); if (ret < 0) { ulogd_log(ULOGD_ERROR, - "ulogd2: could not bind to unix socket \'%s\'\n", - server_sock.sun_path); + "ulogd2: could not bind to unix socket '%s'\n", + server_sock.sun_path); close(s); return -1; } @@ -509,8 +506,8 @@ static int _create_unix_socket(const char *unix_path) ret = listen(s, 10); if (ret < 0) { ulogd_log(ULOGD_ERROR, - "ulogd2: could not bind to unix socket \'%s\'\n", - server_sock.sun_path); + "ulogd2: could not listen to unix socket '%s'\n", + server_sock.sun_path); close(s); return -1; } @@ -632,9 +629,9 @@ static int unixsock_instance_read_cb(int fd, unsigned int what, void *param) packet_sig = ntohl(unixsock_packet->marker); if (packet_sig != ULOGD_SOCKET_MARK) { ulogd_log(ULOGD_ERROR, - "ulogd2: invalid packet marked received " - "(read %lx, expected %lx), closing socket.\n", - packet_sig, ULOGD_SOCKET_MARK); + "ulogd2: invalid packet marked received " + "(read %" PRIx32 ", expected %" PRIx32 "), closing socket.\n", + packet_sig, ULOGD_SOCKET_MARK); _disconnect_client(ui); return -1; @@ -663,13 +660,13 @@ static int unixsock_instance_read_cb(int fd, unsigned int what, void *param) } } else { - ulogd_log(ULOGD_DEBUG, " We have %d bytes, but need %d. Requesting more\n", - ui->unixsock_buf_avail, needed_len + sizeof(uint32_t)); + ulogd_log(ULOGD_DEBUG, " We have %u bytes, but need %zu. Requesting more\n", + ui->unixsock_buf_avail, needed_len + sizeof(uint32_t)); return 0; } /* handle_packet has shifted data in buffer */ - }; + } return 0; } diff --git a/input/sum/Makefile.am b/input/sum/Makefile.am index b6ddb4d..b24af7b 100644 --- a/input/sum/Makefile.am +++ b/input/sum/Makefile.am @@ -1,8 +1,9 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include $(LIBNETFILTER_ACCT_CFLAGS) $(LIBMNL_CFLAGS) -AM_CFLAGS = ${regular_CFLAGS} -if BUILD_NFACCT +include $(top_srcdir)/Make_global.am + +AM_CPPFLAGS += $(LIBNETFILTER_ACCT_CFLAGS) $(LIBMNL_CFLAGS) + pkglib_LTLIBRARIES = ulogd_inpflow_NFACCT.la + ulogd_inpflow_NFACCT_la_SOURCES = ulogd_inpflow_NFACCT.c ulogd_inpflow_NFACCT_la_LDFLAGS = -avoid-version -module ulogd_inpflow_NFACCT_la_LIBADD = $(LIBMNL_LIBS) $(LIBNETFILTER_ACCT_LIBS) -endif diff --git a/libipulog/Makefile.am b/libipulog/Makefile.am index 111cd48..708975a 100644 --- a/libipulog/Makefile.am +++ b/libipulog/Makefile.am @@ -1,6 +1,4 @@ - -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am noinst_LTLIBRARIES = libipulog.la diff --git a/output/Makefile.am b/output/Makefile.am index 7ba8217..cdb49df 100644 --- a/output/Makefile.am +++ b/output/Makefile.am @@ -1,8 +1,35 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include ${LIBNETFILTER_ACCT_CFLAGS} \ - ${LIBNETFILTER_CONNTRACK_CFLAGS} ${LIBNETFILTER_LOG_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +if HAVE_PCAP + OPT_SUBDIR_PCAP = pcap +endif + +if HAVE_MYSQL + OPT_SUBDIR_MYSQL = mysql +endif + +if HAVE_PGSQL + OPT_SUBDIR_PGSQL = pgsql +endif + +if HAVE_SQLITE3 + OPT_SUBDIR_SQLITE3 = sqlite3 +endif + +if HAVE_DBI + OPT_SUBDIR_DBI = dbi +endif + +SUBDIRS = $(OPT_SUBDIR_PCAP) \ + $(OPT_SUBDIR_MYSQL) \ + $(OPT_SUBDIR_PGSQL) \ + $(OPT_SUBDIR_SQLITE3) \ + $(OPT_SUBDIR_DBI) \ + ipfix + +include $(top_srcdir)/Make_global.am -SUBDIRS= pcap mysql pgsql sqlite3 dbi ipfix +AM_CPPFLAGS += ${LIBNETFILTER_ACCT_CFLAGS} \ + ${LIBNETFILTER_CONNTRACK_CFLAGS} \ + ${LIBNETFILTER_LOG_CFLAGS} pkglib_LTLIBRARIES = ulogd_output_LOGEMU.la ulogd_output_SYSLOG.la \ ulogd_output_OPRINT.la ulogd_output_GPRINT.la \ diff --git a/output/dbi/Makefile.am b/output/dbi/Makefile.am index f413cab..9a618b1 100644 --- a/output/dbi/Makefile.am +++ b/output/dbi/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include $(DBI_INC) -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_DBI +AM_CPPFLAGS += $(libdbi_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_DBI.la ulogd_output_DBI_la_SOURCES = ulogd_output_DBI.c ../../util/db.c -ulogd_output_DBI_la_LIBADD = ${DBI_LIB} +ulogd_output_DBI_la_LIBADD = $(libdbi_LIBS) ulogd_output_DBI_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/dbi/ulogd_output_DBI.c b/output/dbi/ulogd_output_DBI.c index d2a9682..88af7a1 100644 --- a/output/dbi/ulogd_output_DBI.c +++ b/output/dbi/ulogd_output_DBI.c @@ -29,6 +29,8 @@ #define DEBUGP(x, args...) #endif +static dbi_inst libdbi_instance; + struct dbi_instance { struct db_instance db_inst; @@ -89,15 +91,6 @@ static struct config_keyset dbi_kset = { #define dbtype_ce(x) (x->ces[DB_CE_NUM+6]) -/* lower-cases s in place */ -static void str_tolower(char *s) -{ - while(*s) { - *s = tolower(*s); - s++; - } -} - /* find out which columns the table has */ static int get_columns_dbi(struct ulogd_pluginstance *upi) { @@ -129,8 +122,7 @@ static int get_columns_dbi(struct ulogd_pluginstance *upi) upi->input.num_keys = dbi_result_get_numfields(pi->result); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); @@ -138,28 +130,26 @@ static int get_columns_dbi(struct ulogd_pluginstance *upi) return -ENOMEM; } - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); - for (ui=1; ui<=upi->input.num_keys; ui++) { - char buf[ULOGD_MAX_KEYLEN+1]; - char *underscore; - const char* field_name = dbi_result_get_field_name(pi->result, ui); + const char *field_name = dbi_result_get_field_name(pi->result, ui); + char *cp; if (!field_name) break; - /* replace all underscores with dots */ - strncpy(buf, field_name, ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) - *underscore = '.'; - - str_tolower(buf); + snprintf(upi->input.keys[ui - 1].name, + sizeof(upi->input.keys[ui - 1].name), + "%s", field_name); - DEBUGP("field '%s' found: ", buf); + /* down-case and replace all underscores with dots */ + for (cp = upi->input.keys[ui - 1].name; *cp; cp++) { + if (*cp == '_') + *cp = '.'; + else + *cp = tolower(*cp); + } - /* add it to list of input keys */ - strncpy(upi->input.keys[ui-1].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found: ", upi->input.keys[ui - 1].name); } /* ID is a sequence */ @@ -177,7 +167,6 @@ static int close_db_dbi(struct ulogd_pluginstance *upi) ulogd_log(ULOGD_DEBUG, "dbi: closing connection\n"); dbi_conn_close(pi->dbh); pi->dbh = NULL; - //dbi_shutdown(); return 0; } @@ -187,9 +176,9 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) { struct dbi_instance *pi = (struct dbi_instance *) upi->private; char *server = host_ce(upi->config_kset).u.string; - char *user = user_ce(upi->config_kset).u.string; - char *pass = pass_ce(upi->config_kset).u.string; - char *db = db_ce(upi->config_kset).u.string; + char *user = user_ce(upi->config_kset).u.string; + char *pass = pass_ce(upi->config_kset).u.string; + char *db = db_ce(upi->config_kset).u.string; char *dbtype = dbtype_ce(upi->config_kset).u.string; dbi_driver driver; int ret; @@ -199,14 +188,14 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) ulogd_log(ULOGD_ERROR, "Opening connection for db type %s\n", dbtype); - driver = dbi_driver_open(dbtype); + driver = dbi_driver_open_r(dbtype, libdbi_instance); if (driver == NULL) { ulogd_log(ULOGD_ERROR, "unable to load driver for db type %s\n", dbtype); close_db_dbi(upi); return -1; } - pi->dbh = dbi_conn_new(dbtype); + pi->dbh = dbi_conn_new_r(dbtype, libdbi_instance); if (pi->dbh == NULL) { ulogd_log(ULOGD_ERROR, "unable to initialize db type %s\n", dbtype); @@ -214,13 +203,13 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) return -1; } - if (server) + if (server[0]) dbi_conn_set_option(pi->dbh, "host", server); - if (user) + if (user[0]) dbi_conn_set_option(pi->dbh, "username", user); - if (pass) + if (pass[0]) dbi_conn_set_option(pi->dbh, "password", pass); - if (db) + if (db[0]) dbi_conn_set_option(pi->dbh, "dbname", db); ret = dbi_conn_connect(pi->dbh); @@ -247,18 +236,20 @@ static int escape_string_dbi(struct ulogd_pluginstance *upi, } ret = dbi_conn_quote_string_copy(pi->dbh, src, &newstr); - if (ret <= 2) + if (ret == 0) { + *dst = '\0'; return 0; + } /* dbi_conn_quote_string_copy returns a quoted string, * but __interp_db already quotes the string * So we return a string without the quotes */ - strncpy(dst,newstr+1,ret-2); - dst[ret-2] = '\0'; + memcpy(dst, newstr + 1, ret - 2); + dst[ret - 2] = '\0'; free(newstr); - return (ret-2); + return ret - 2; } static int execute_dbi(struct ulogd_pluginstance *upi, @@ -320,11 +311,14 @@ static struct ulogd_plugin dbi_plugin = { .version = VERSION, }; -void __attribute__ ((constructor)) init(void); - -void init(void) +void __attribute__ ((constructor)) init(void) { - dbi_initialize(NULL); + dbi_initialize_r(NULL, &libdbi_instance); ulogd_register_plugin(&dbi_plugin); } + +void __attribute__ ((destructor)) fini(void) +{ + dbi_shutdown_r(libdbi_instance); +} diff --git a/output/ipfix/Makefile.am b/output/ipfix/Makefile.am index cacda26..882de85 100644 --- a/output/ipfix/Makefile.am +++ b/output/ipfix/Makefile.am @@ -1,5 +1,6 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(regular_CFLAGS) +include $(top_srcdir)/Make_global.am + +noinst_HEADERS = ipfix.h pkglib_LTLIBRARIES = ulogd_output_IPFIX.la diff --git a/output/ipfix/ipfix.c b/output/ipfix/ipfix.c index 4bb432a..e0b3440 100644 --- a/output/ipfix/ipfix.c +++ b/output/ipfix/ipfix.c @@ -8,8 +8,6 @@ /* These forward declarations are needed since ulogd.h doesn't like to be the first */ #include <ulogd/linuxlist.h> -#define __packed __attribute__((packed)) - #include "ipfix.h" #include <ulogd/ulogd.h> @@ -85,8 +83,7 @@ struct ipfix_msg *ipfix_msg_alloc(size_t len, uint32_t oid, int tid) (len < IPFIX_HDRLEN + IPFIX_SET_HDRLEN)) return NULL; - msg = malloc(sizeof(struct ipfix_msg) + len); - memset(msg, 0, sizeof(struct ipfix_msg)); + msg = calloc(1, sizeof(struct ipfix_msg) + len); msg->tid = tid; msg->end = msg->data + len; msg->tail = msg->data + IPFIX_HDRLEN; @@ -95,7 +92,6 @@ struct ipfix_msg *ipfix_msg_alloc(size_t len, uint32_t oid, int tid) /* Initialize message header */ hdr = ipfix_msg_hdr(msg); - memset(hdr, 0, IPFIX_HDRLEN); hdr->version = htons(IPFIX_VERSION); hdr->oid = htonl(oid); diff --git a/output/ipfix/ipfix.h b/output/ipfix/ipfix.h index 93945fb..b0f3ae6 100644 --- a/output/ipfix/ipfix.h +++ b/output/ipfix/ipfix.h @@ -19,7 +19,7 @@ struct ipfix_hdr { uint32_t seqno; uint32_t oid; /* Observation Domain ID */ uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_HDRLEN sizeof(struct ipfix_hdr) @@ -32,7 +32,7 @@ struct ipfix_templ_hdr { uint16_t tid; uint16_t cnt; uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_TEMPL_HDRLEN(nfields) sizeof(struct ipfix_templ_hdr) + (sizeof(uint16_t) * 2 * nfields) @@ -42,7 +42,7 @@ struct ipfix_set_hdr { uint16_t id; uint16_t len; uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_SET_HDRLEN sizeof(struct ipfix_set_hdr) @@ -67,7 +67,7 @@ struct vy_ipfix_data { uint16_t dport; uint8_t l4_proto; uint32_t aid; /* Application ID */ -} __packed; +} __attribute__((packed)); #define VY_IPFIX_SID 256 diff --git a/output/ipfix/ulogd_output_IPFIX.c b/output/ipfix/ulogd_output_IPFIX.c index 5b59003..1c0f730 100644 --- a/output/ipfix/ulogd_output_IPFIX.c +++ b/output/ipfix/ulogd_output_IPFIX.c @@ -198,7 +198,8 @@ static int send_msgs(struct ulogd_pluginstance *pi) struct ipfix_priv *priv = (struct ipfix_priv *) &pi->private; struct llist_head *curr, *tmp; struct ipfix_msg *msg; - int ret = ULOGD_IRET_OK, sent; + int ret = ULOGD_IRET_OK; + ssize_t sent; llist_for_each_prev(curr, &priv->list) { msg = llist_entry(curr, struct ipfix_msg, link); @@ -212,8 +213,8 @@ static int send_msgs(struct ulogd_pluginstance *pi) /* TODO handle short send() for other protocols */ if ((size_t) sent < ipfix_msg_len(msg)) - ulogd_log(ULOGD_ERROR, "short send: %d < %d\n", - sent, ipfix_msg_len(msg)); + ulogd_log(ULOGD_ERROR, "short send: %zd < %zu\n", + sent, ipfix_msg_len(msg)); } llist_for_each_safe(curr, tmp, &priv->list) { @@ -242,7 +243,7 @@ static int ipfix_ufd_cb(int fd, unsigned what, void *arg) ulogd_log(ULOGD_INFO, "connection reset by peer\n"); ulogd_unregister_fd(&priv->ufd); } else - ulogd_log(ULOGD_INFO, "unexpected data (%d bytes)\n", nread); + ulogd_log(ULOGD_INFO, "unexpected data (%zd bytes)\n", nread); } return 0; @@ -425,6 +426,9 @@ static int ipfix_interp(struct ulogd_pluginstance *pi) if (!(GET_FLAGS(pi->input.keys, InIpSaddr) & ULOGD_RETF_VALID)) return ULOGD_IRET_OK; + if (GET_LENGTH(pi->input.keys, InIpSaddr) != sizeof(data->saddr)) + return ULOGD_IRET_OK; + oid = oid_ce(pi->config_kset).u.value; mtu = mtu_ce(pi->config_kset).u.value; send_template = send_template_ce(pi->config_kset).u.string; diff --git a/output/mysql/Makefile.am b/output/mysql/Makefile.am index c24208c..69d9839 100644 --- a/output/mysql/Makefile.am +++ b/output/mysql/Makefile.am @@ -1,12 +1,9 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include $(MYSQL_INC) -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am -if HAVE_MYSQL +AM_CPPFLAGS += $(libmysqlclient_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_MYSQL.la ulogd_output_MYSQL_la_SOURCES = ulogd_output_MYSQL.c ../../util/db.c -ulogd_output_MYSQL_la_LIBADD = ${MYSQL_LIB} +ulogd_output_MYSQL_la_LIBADD = $(libmysqlclient_LIBS) ulogd_output_MYSQL_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/mysql/ulogd_output_MYSQL.c b/output/mysql/ulogd_output_MYSQL.c index 643320c..9727e30 100644 --- a/output/mysql/ulogd_output_MYSQL.c +++ b/output/mysql/ulogd_output_MYSQL.c @@ -127,30 +127,26 @@ static int get_columns_mysql(struct ulogd_pluginstance *upi) upi->input.num_keys = mysql_num_fields(result); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); return -ENOMEM; } - - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); for (i = 0; (field = mysql_fetch_field(result)); i++) { - char buf[ULOGD_MAX_KEYLEN+1]; char *underscore; + snprintf(upi->input.keys[i].name, + sizeof(upi->input.keys[i].name), + "%s", field->name); + /* replace all underscores with dots */ - strncpy(buf, field->name, ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) + for (underscore = upi->input.keys[i].name; + (underscore = strchr(underscore, '_')); ) *underscore = '.'; - DEBUGP("field '%s' found\n", buf); - - /* add it to list of input keys */ - strncpy(upi->input.keys[i].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found\n", upi->input.keys[i].name); } /* MySQL Auto increment ... ID :) */ upi->input.keys[0].flags |= ULOGD_KEYF_INACTIVE; diff --git a/output/pcap/Makefile.am b/output/pcap/Makefile.am index c1723a6..b5064ea 100644 --- a/output/pcap/Makefile.am +++ b/output/pcap/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_PCAP +AM_CPPFLAGS += $(libpcap_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_PCAP.la ulogd_output_PCAP_la_SOURCES = ulogd_output_PCAP.c ulogd_output_PCAP_la_LIBADD = ${libpcap_LIBS} ulogd_output_PCAP_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/pcap/ulogd_output_PCAP.c b/output/pcap/ulogd_output_PCAP.c index e7798f2..19ce47f 100644 --- a/output/pcap/ulogd_output_PCAP.c +++ b/output/pcap/ulogd_output_PCAP.c @@ -220,33 +220,26 @@ static int append_create_outfile(struct ulogd_pluginstance *upi) { struct pcap_instance *pi = (struct pcap_instance *) &upi->private; char *filename = upi->config_kset->ces[0].u.string; - struct stat st_dummy; - int exist = 0; - - if (stat(filename, &st_dummy) == 0 && st_dummy.st_size > 0) - exist = 1; - - if (!exist) { - pi->of = fopen(filename, "w"); - if (!pi->of) { - ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", - filename, - strerror(errno)); - return -EPERM; - } - if (!write_pcap_header(pi)) { - ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n", - strerror(errno)); - return -ENOSPC; - } - } else { - pi->of = fopen(filename, "a"); - if (!pi->of) { - ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", - filename, - strerror(errno)); - return -EPERM; - } + struct stat st_of; + FILE *of; + + of = fopen(filename, "a"); + if (!of) { + ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", + filename, + strerror(errno)); + return -EPERM; + } + + if (pi->of) + fclose(pi->of); + pi->of = of; + + if (fstat(fileno(pi->of), &st_of) == 0 && st_of.st_size == 0 && + !write_pcap_header(pi)) { + ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n", + strerror(errno)); + return -ENOSPC; } return 0; @@ -254,12 +247,9 @@ static int append_create_outfile(struct ulogd_pluginstance *upi) static void signal_pcap(struct ulogd_pluginstance *upi, int signal) { - struct pcap_instance *pi = (struct pcap_instance *) &upi->private; - switch (signal) { case SIGHUP: ulogd_log(ULOGD_NOTICE, "reopening capture file\n"); - fclose(pi->of); append_create_outfile(upi); break; default: diff --git a/output/pgsql/Makefile.am b/output/pgsql/Makefile.am index bdaf1d2..c78a773 100644 --- a/output/pgsql/Makefile.am +++ b/output/pgsql/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(PQINCPATH) -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_PGSQL +AM_CPPFLAGS += $(libpq_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_PGSQL.la ulogd_output_PGSQL_la_SOURCES = ulogd_output_PGSQL.c ../../util/db.c -ulogd_output_PGSQL_la_LIBADD = ${PQLIBS} +ulogd_output_PGSQL_la_LIBADD = $(libpq_LIBS) ulogd_output_PGSQL_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/pgsql/ulogd_output_PGSQL.c b/output/pgsql/ulogd_output_PGSQL.c index fda289e..04c2665 100644 --- a/output/pgsql/ulogd_output_PGSQL.c +++ b/output/pgsql/ulogd_output_PGSQL.c @@ -181,8 +181,7 @@ static int get_columns_pgsql(struct ulogd_pluginstance *upi) upi->input.num_keys = PQntuples(pi->pgres); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); @@ -190,22 +189,19 @@ static int get_columns_pgsql(struct ulogd_pluginstance *upi) return -ENOMEM; } - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); - for (i = 0; i < PQntuples(pi->pgres); i++) { - char buf[ULOGD_MAX_KEYLEN+1]; char *underscore; + snprintf(upi->input.keys[i].name, + sizeof(upi->input.keys[i].name), + "%s", PQgetvalue(pi->pgres, i, 0)); + /* replace all underscores with dots */ - strncpy(buf, PQgetvalue(pi->pgres, i, 0), ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) + for (underscore = upi->input.keys[i].name; + (underscore = strchr(underscore, '_')); ) *underscore = '.'; - DEBUGP("field '%s' found: ", buf); - - /* add it to list of input keys */ - strncpy(upi->input.keys[i].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found\n", upi->input.keys[i].name); } /* ID (starting by '.') is a sequence */ @@ -236,48 +232,38 @@ static int open_db_pgsql(struct ulogd_pluginstance *upi) char *schema = NULL; char pgbuf[128]; - if (!connstr) { - char *server = host_ce(upi->config_kset).u.string; - unsigned int port = port_ce(upi->config_kset).u.value; - char *user = user_ce(upi->config_kset).u.string; - char *pass = pass_ce(upi->config_kset).u.string; - char *db = db_ce(upi->config_kset).u.string; + if (!connstr[0]) { + char *server = host_ce(upi->config_kset).u.string; + unsigned int port = port_ce(upi->config_kset).u.value; + char *user = user_ce(upi->config_kset).u.string; + char *pass = pass_ce(upi->config_kset).u.string; + char *db = db_ce(upi->config_kset).u.string; + char *cp; /* 80 is more than what we need for the fixed parts below */ len = 80 + strlen(user) + strlen(db); /* hostname and and password are the only optionals */ - if (server) + if (server[0]) len += strlen(server); - if (pass) + if (pass[0]) len += strlen(pass); if (port) len += 20; - connstr = (char *) malloc(len); + cp = connstr = malloc(len); if (!connstr) return -ENOMEM; - connstr[0] = '\0'; - if (server && strlen(server) > 0) { - strcpy(connstr, " host="); - strcat(connstr, server); - } + if (server[0]) + cp += sprintf(cp, "host=%s ", server); - if (port) { - char portbuf[20]; - snprintf(portbuf, sizeof(portbuf), " port=%u", port); - strcat(connstr, portbuf); - } + if (port) + cp += sprintf(cp, "port=%u ", port); - strcat(connstr, " dbname="); - strcat(connstr, db); - strcat(connstr, " user="); - strcat(connstr, user); + cp += sprintf(cp, "dbname=%s user=%s", db, user); - if (pass) { - strcat(connstr, " password="); - strcat(connstr, pass); - } + if (pass[0]) + cp += sprintf(cp, " password=%s", pass); } pi->dbh = PQconnectdb(connstr); if (PQstatus(pi->dbh) != CONNECTION_OK) { diff --git a/output/sqlite3/Makefile.am b/output/sqlite3/Makefile.am index 62af267..72fd1a6 100644 --- a/output/sqlite3/Makefile.am +++ b/output/sqlite3/Makefile.am @@ -1,12 +1,9 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include ${libsqlite3_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am -if HAVE_SQLITE3 +AM_CPPFLAGS += ${libsqlite3_CFLAGS} pkglib_LTLIBRARIES = ulogd_output_SQLITE3.la ulogd_output_SQLITE3_la_SOURCES = ulogd_output_SQLITE3.c ../../util/db.c ulogd_output_SQLITE3_la_LIBADD = ${libsqlite3_LIBS} ulogd_output_SQLITE3_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/sqlite3/ulogd_output_SQLITE3.c b/output/sqlite3/ulogd_output_SQLITE3.c index 20ceb3b..6aeb7a3 100644 --- a/output/sqlite3/ulogd_output_SQLITE3.c +++ b/output/sqlite3/ulogd_output_SQLITE3.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string.h> #include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> #include <sqlite3.h> @@ -48,7 +49,7 @@ struct field { TAILQ_ENTRY(field) link; - char name[ULOGD_MAX_KEYLEN]; + char name[ULOGD_MAX_KEYLEN + 1]; struct ulogd_key *key; }; @@ -104,11 +105,14 @@ add_row(struct ulogd_pluginstance *pi) ret = sqlite3_finalize(priv->p_stmt); priv->p_stmt = NULL; - if (ret == SQLITE_SCHEMA) - sqlite3_createstmt(pi); - else { + if (ret != SQLITE_SCHEMA) { ulogd_log(ULOGD_ERROR, "SQLITE3: step: %s\n", - sqlite3_errmsg(priv->dbh)); + sqlite3_errmsg(priv->dbh)); + goto err_reset; + } + if (sqlite3_createstmt(pi) < 0) { + ulogd_log(ULOGD_ERROR, + "SQLITE3: Could not create statement.\n"); goto err_reset; } } @@ -142,6 +146,10 @@ sqlite3_interp(struct ulogd_pluginstance *pi) } switch (f->key->type) { + case ULOGD_RET_BOOL: + ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b); + break; + case ULOGD_RET_INT8: ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i8); break; @@ -155,7 +163,7 @@ sqlite3_interp(struct ulogd_pluginstance *pi) break; case ULOGD_RET_INT64: - ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i64); + ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.i64); break; case ULOGD_RET_UINT8: @@ -171,17 +179,20 @@ sqlite3_interp(struct ulogd_pluginstance *pi) break; case ULOGD_RET_IPADDR: - case ULOGD_RET_UINT64: - ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64); + if (k_ret->len == sizeof(struct in_addr)) + ret = sqlite3_bind_int(priv->p_stmt, i, + k_ret->u.value.ui32); + else + ret = sqlite3_bind_null(priv->p_stmt, i); break; - case ULOGD_RET_BOOL: - ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b); + case ULOGD_RET_UINT64: + ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64); break; case ULOGD_RET_STRING: ret = sqlite3_bind_text(priv->p_stmt, i, k_ret->u.value.ptr, - strlen(k_ret->u.value.ptr), SQLITE_STATIC); + strlen(k_ret->u.value.ptr), SQLITE_STATIC); break; default: @@ -214,10 +225,8 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) { struct sqlite3_priv *priv = (void *)pi->private; struct field *f; - char buf[ULOGD_MAX_KEYLEN]; - char *underscore; - char *stmt_pos; int i, cols = 0; + char *stmt_pos; if (priv->stmt != NULL) free(priv->stmt); @@ -226,31 +235,21 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) ulogd_log(ULOGD_ERROR, "SQLITE3: out of memory\n"); return -1; } + stmt_pos = priv->stmt; - sprintf(priv->stmt, "insert into %s (", table_ce(pi)); - stmt_pos = priv->stmt + strlen(priv->stmt); + stmt_pos += sprintf(stmt_pos, "insert into %s (", table_ce(pi)); tailq_for_each(f, priv->fields, link) { - strncpy(buf, f->name, ULOGD_MAX_KEYLEN); - - while ((underscore = strchr(buf, '.'))) - *underscore = '_'; - - sprintf(stmt_pos, "%s,", buf); - stmt_pos = priv->stmt + strlen(priv->stmt); - + stmt_pos += sprintf(stmt_pos, "%s,", f->name); cols++; } *(stmt_pos - 1) = ')'; - sprintf(stmt_pos, " values ("); - stmt_pos = priv->stmt + strlen(priv->stmt); + stmt_pos += sprintf(stmt_pos, " values ("); - for (i = 0; i < cols - 1; i++) { - sprintf(stmt_pos,"?,"); - stmt_pos += 2; - } + for (i = 0; i < cols - 1; i++) + stmt_pos += sprintf(stmt_pos, "?,"); sprintf(stmt_pos, "?)"); ulogd_log(ULOGD_DEBUG, "%s: stmt='%s'\n", pi->id, priv->stmt); @@ -260,8 +259,8 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) sqlite3_prepare(priv->dbh, priv->stmt, -1, &priv->p_stmt, 0); if (priv->p_stmt == NULL) { ulogd_log(ULOGD_ERROR, "SQLITE3: prepare: %s\n", - sqlite3_errmsg(priv->dbh)); - return 1; + sqlite3_errmsg(priv->dbh)); + return -1; } DEBUGP("statement prepared.\n"); @@ -273,10 +272,15 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) static struct ulogd_key * ulogd_find_key(struct ulogd_pluginstance *pi, const char *name) { + char buf[ULOGD_MAX_KEYLEN + 1] = ""; unsigned int i; + /* replace all underscores with dots */ + for (i = 0; i < sizeof(buf) - 1 && name[i]; ++i) + buf[i] = name[i] != '_' ? name[i] : '.'; + for (i = 0; i < pi->input.num_keys; i++) { - if (strcmp(pi->input.keys[i].name, name) == 0) + if (strcmp(pi->input.keys[i].name, buf) == 0) return &pi->input.keys[i]; } @@ -305,9 +309,6 @@ static int sqlite3_init_db(struct ulogd_pluginstance *pi) { struct sqlite3_priv *priv = (void *)pi->private; - char buf[ULOGD_MAX_KEYLEN]; - char *underscore; - struct field *f; sqlite3_stmt *schema_stmt; int col, num_cols; @@ -327,23 +328,24 @@ sqlite3_init_db(struct ulogd_pluginstance *pi) } for (col = 0; col < num_cols; col++) { - strncpy(buf, sqlite3_column_name(schema_stmt, col), ULOGD_MAX_KEYLEN); - - /* replace all underscores with dots */ - while ((underscore = strchr(buf, '_')) != NULL) - *underscore = '.'; - - DEBUGP("field '%s' found\n", buf); + struct field *f; /* prepend it to the linked list */ if ((f = calloc(1, sizeof(struct field))) == NULL) { ulogd_log(ULOGD_ERROR, "SQLITE3: out of memory\n"); return -1; } - strncpy(f->name, buf, ULOGD_MAX_KEYLEN); + snprintf(f->name, sizeof(f->name), + "%s", sqlite3_column_name(schema_stmt, col)); + + DEBUGP("field '%s' found\n", f->name); - if ((f->key = ulogd_find_key(pi, buf)) == NULL) + if ((f->key = ulogd_find_key(pi, f->name)) == NULL) { + ulogd_log(ULOGD_ERROR, + "SQLITE3: unknown input key: %s\n", f->name); + free(f); return -1; + } TAILQ_INSERT_TAIL(&priv->fields, f, link); } @@ -394,7 +396,10 @@ sqlite3_start(struct ulogd_pluginstance *pi) } /* create and prepare the actual insert statement */ - sqlite3_createstmt(pi); + if (sqlite3_createstmt(pi) < 0) { + ulogd_log(ULOGD_ERROR, "SQLITE3: Could not create statement.\n"); + return -1; + } return 0; } diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c index bc7aa34..37829fa 100644 --- a/output/ulogd_output_GPRINT.c +++ b/output/ulogd_output_GPRINT.c @@ -27,6 +27,8 @@ #include <time.h> #include <errno.h> #include <inttypes.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> @@ -69,12 +71,6 @@ static struct config_keyset gprint_kset = { }, }; -#define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] - static int gprint_interp(struct ulogd_pluginstance *upi) { struct gprint_priv *opi = (struct gprint_priv *) &upi->private; @@ -127,13 +123,15 @@ static int gprint_interp(struct ulogd_pluginstance *upi) case ULOGD_RET_INT8: case ULOGD_RET_INT16: case ULOGD_RET_INT32: + case ULOGD_RET_INT64: ret = snprintf(buf+size, rem, "%s=", key->name); if (ret < 0) break; rem -= ret; size += ret; - ret = snprintf(buf+size, rem, "%d,", key->u.value.i32); + ret = snprintf(buf+size, rem, "%" PRId64 ",", + key->u.value.i64); if (ret < 0) break; rem -= ret; @@ -156,20 +154,36 @@ static int gprint_interp(struct ulogd_pluginstance *upi) rem -= ret; size += ret; break; - case ULOGD_RET_IPADDR: + case ULOGD_RET_IPADDR: { + struct in6_addr ipv6addr; + struct in_addr ipv4addr; + int family; + void *addr; + ret = snprintf(buf+size, rem, "%s=", key->name); if (ret < 0) break; rem -= ret; size += ret; - ret = snprintf(buf+size, rem, "%u.%u.%u.%u,", - NIPQUAD(key->u.value.ui32)); - if (ret < 0) + if (key->len == sizeof(ipv6addr)) { + memcpy(ipv6addr.s6_addr, key->u.value.ui128, + sizeof(ipv6addr.s6_addr)); + addr = &ipv6addr; + family = AF_INET6; + } else { + ipv4addr.s_addr = key->u.value.ui32; + addr = &ipv4addr; + family = AF_INET; + } + if (!inet_ntop(family, addr, buf + size, rem)) break; + ret = strlen(buf + size); + rem -= ret; size += ret; break; + } default: /* don't know how to interpret this key. */ break; @@ -249,7 +263,7 @@ static int gprint_fini(struct ulogd_pluginstance *pi) static struct ulogd_plugin gprint_plugin = { .name = "GPRINT", .input = { - .type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, + .type = ULOGD_DTYPE_RAW | ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, }, .output = { .type = ULOGD_DTYPE_SINK, diff --git a/output/ulogd_output_JSON.c b/output/ulogd_output_JSON.c index 6edfa90..f80d0e2 100644 --- a/output/ulogd_output_JSON.c +++ b/output/ulogd_output_JSON.c @@ -33,6 +33,10 @@ #include <ulogd/conffile.h> #include <jansson.h> +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX 108 +#endif + #ifndef ULOGD_JSON_DEFAULT #define ULOGD_JSON_DEFAULT "/var/log/ulogd.json" #endif @@ -146,23 +150,21 @@ static void close_socket(struct json_priv *op) { static int _connect_socket_unix(struct ulogd_pluginstance *pi) { + const char *socket_path = file_ce(pi->config_kset).u.string; struct json_priv *op = (struct json_priv *) &pi->private; - struct sockaddr_un u_addr; + struct sockaddr_un u_addr = { .sun_family = AF_UNIX }; int sfd; close_socket(op); - ulogd_log(ULOGD_DEBUG, "connecting to unix:%s\n", - file_ce(pi->config_kset).u.string); + ulogd_log(ULOGD_DEBUG, "connecting to unix:%s\n", socket_path); + strcpy(u_addr.sun_path, socket_path); sfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sfd == -1) { + if (sfd == -1) return -1; - } - u_addr.sun_family = AF_UNIX; - strncpy(u_addr.sun_path, file_ce(pi->config_kset).u.string, - sizeof(u_addr.sun_path) - 1); - if (connect(sfd, (struct sockaddr *) &u_addr, sizeof(struct sockaddr_un)) == -1) { + + if (connect(sfd, (struct sockaddr *) &u_addr, sizeof(u_addr)) == -1) { close(sfd); return -1; } @@ -269,14 +271,14 @@ static int json_interp_file(struct ulogd_pluginstance *upi, char *buf) return ULOGD_IRET_OK; } -#define MAX_LOCAL_TIME_STRING 38 +#define MAX_LOCAL_TIME_STRING 80 static int json_interp(struct ulogd_pluginstance *upi) { struct json_priv *opi = (struct json_priv *) &upi->private; + char *dvc, *buf, *tmp; unsigned int i; - char *buf; - int buflen; + size_t buflen; json_t *msg; msg = json_object(); @@ -302,11 +304,12 @@ static int json_interp(struct ulogd_pluginstance *upi) now = time(NULL); t = localtime_r(&now, &result); if (unlikely(*opi->cached_tz = '\0' || t->tm_gmtoff != opi->cached_gmtoff)) { + int gmtoff = t->tm_gmtoff % 86400; + int gmtoff_hours = gmtoff / 3600; + int gmtoff_minutes = abs(gmtoff) / 60 % 60; + snprintf(opi->cached_tz, sizeof(opi->cached_tz), - "%c%02d%02d", - t->tm_gmtoff > 0 ? '+' : '-', - abs(t->tm_gmtoff) / 60 / 60, - abs(t->tm_gmtoff) / 60 % 60); + "%+03d%02d", gmtoff_hours, gmtoff_minutes); } if (pp_is_valid(inp, opi->usec_idx)) { @@ -332,12 +335,8 @@ static int json_interp(struct ulogd_pluginstance *upi) json_object_set_new(msg, "timestamp", json_string(timestr)); } - if (upi->config_kset->ces[JSON_CONF_DEVICE].u.string) { - char *dvc = upi->config_kset->ces[JSON_CONF_DEVICE].u.string; - json_object_set_new(msg, "dvc", json_string(dvc)); - } - - + dvc = upi->config_kset->ces[JSON_CONF_DEVICE].u.string; + json_object_set_new(msg, "dvc", json_string(dvc)); for (i = 0; i < upi->input.num_keys; i++) { struct ulogd_key *key = upi->input.keys[i].u.source; @@ -365,6 +364,9 @@ static int json_interp(struct ulogd_pluginstance *upi) case ULOGD_RET_INT32: json_object_set_new(msg, field_name, json_integer(key->u.value.i32)); break; + case ULOGD_RET_INT64: + json_object_set_new(msg, field_name, json_integer(key->u.value.i64)); + break; case ULOGD_RET_UINT8: if ((upi->config_kset->ces[JSON_CONF_BOOLEAN_LABEL].u.value != 0) && (!strcmp(key->name, "raw.label"))) { @@ -391,7 +393,6 @@ static int json_interp(struct ulogd_pluginstance *upi) } } - buf = json_dumps(msg, 0); json_decref(msg); if (buf == NULL) { @@ -399,13 +400,15 @@ static int json_interp(struct ulogd_pluginstance *upi) return ULOGD_IRET_ERR; } buflen = strlen(buf); - buf = realloc(buf, sizeof(char)*(buflen+2)); - if (buf == NULL) { + tmp = realloc(buf, buflen + sizeof("\n")); + if (tmp == NULL) { + free(buf); ulogd_log(ULOGD_ERROR, "Could not create message\n"); return ULOGD_IRET_ERR; } - strncat(buf, "\n", 1); - buflen++; + buf = tmp; + buf[buflen++] = '\n'; + buf[buflen] = '\0'; if (opi->mode == JSON_MODE_FILE) return json_interp_file(upi, buf); @@ -430,9 +433,33 @@ static void reopen_file(struct ulogd_pluginstance *upi) } } +static int validate_unix_socket(struct ulogd_pluginstance *upi) +{ + const char *socket_path = file_ce(upi->config_kset).u.string; + + if (!socket_path[0]) { + ulogd_log(ULOGD_ERROR, "missing unix socket path"); + return -1; + } + if (strlen(socket_path) >= UNIX_PATH_MAX) { + ulogd_log(ULOGD_ERROR, "unix socket path `%s' is longer than %u\n", + file_ce(upi->config_kset).u.string, UNIX_PATH_MAX); + return -1; + } + + return 0; +} + static void reopen_socket(struct ulogd_pluginstance *upi) { + struct json_priv *op = (struct json_priv *) &upi->private; + ulogd_log(ULOGD_NOTICE, "JSON: reopening socket\n"); + + if (op->mode == JSON_MODE_UNIX && + validate_unix_socket(upi) < 0) + return; + if (_connect_socket(upi) < 0) { ulogd_log(ULOGD_ERROR, "can't open JSON " "socket: %s\n", @@ -505,9 +532,8 @@ static int json_init_socket(struct ulogd_pluginstance *upi) { struct json_priv *op = (struct json_priv *) &upi->private; - if (host_ce(upi->config_kset).u.string == NULL) - return -1; - if (port_ce(upi->config_kset).u.string == NULL) + if (op->mode == JSON_MODE_UNIX && + validate_unix_socket(upi) < 0) return -1; op->sock = -1; diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c index 6fde445..13934ff 100644 --- a/output/ulogd_output_OPRINT.c +++ b/output/ulogd_output_OPRINT.c @@ -24,6 +24,8 @@ #include <string.h> #include <errno.h> #include <inttypes.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> @@ -31,18 +33,6 @@ #define ULOGD_OPRINT_DEFAULT "/var/log/ulogd_oprint.log" #endif -#define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] - -#define HIPQUAD(addr) \ - ((unsigned char *)&addr)[3], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[0] - struct oprint_priv { FILE *of; }; @@ -59,38 +49,61 @@ static int oprint_interp(struct ulogd_pluginstance *upi) if (!ret) ulogd_log(ULOGD_NOTICE, "no result for %s ?!?\n", upi->input.keys[i].name); - + if (!IS_VALID(*ret)) continue; fprintf(opi->of,"%s=", ret->name); switch (ret->type) { - case ULOGD_RET_STRING: - fprintf(opi->of, "%s\n", - (char *) ret->u.value.ptr); - break; - case ULOGD_RET_BOOL: - case ULOGD_RET_INT8: - case ULOGD_RET_INT16: - case ULOGD_RET_INT32: - fprintf(opi->of, "%d\n", ret->u.value.i32); - break; - case ULOGD_RET_UINT8: - case ULOGD_RET_UINT16: - case ULOGD_RET_UINT32: - fprintf(opi->of, "%u\n", ret->u.value.ui32); + case ULOGD_RET_STRING: + fprintf(opi->of, "%s\n", (char *) ret->u.value.ptr); + break; + case ULOGD_RET_BOOL: + case ULOGD_RET_INT8: + case ULOGD_RET_INT16: + case ULOGD_RET_INT32: + fprintf(opi->of, "%d\n", ret->u.value.i32); + break; + case ULOGD_RET_INT64: + fprintf(opi->of, "%" PRId64 "\n", ret->u.value.i64); + break; + case ULOGD_RET_UINT8: + case ULOGD_RET_UINT16: + case ULOGD_RET_UINT32: + fprintf(opi->of, "%u\n", ret->u.value.ui32); + break; + case ULOGD_RET_UINT64: + fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64); + break; + case ULOGD_RET_IPADDR: { + char addrbuf[INET6_ADDRSTRLEN + 1] = ""; + struct in6_addr ipv6addr; + struct in_addr ipv4addr; + int family; + void *addr; + + if (ret->len == sizeof(ipv6addr)) { + memcpy(ipv6addr.s6_addr, ret->u.value.ui128, + sizeof(ipv6addr.s6_addr)); + addr = &ipv6addr; + family = AF_INET6; + } else { + ipv4addr.s_addr = ret->u.value.ui32; + addr = &ipv4addr; + family = AF_INET; + } + if (!inet_ntop(family, addr, addrbuf, sizeof(addrbuf))) break; - case ULOGD_RET_UINT64: - fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64); - break; - case ULOGD_RET_IPADDR: - fprintf(opi->of, "%u.%u.%u.%u\n", - HIPQUAD(ret->u.value.ui32)); - break; - case ULOGD_RET_NONE: - fprintf(opi->of, "<none>\n"); - break; - default: fprintf(opi->of, "default\n"); + + fprintf(opi->of, "%s\n", addrbuf); + break; + } + case ULOGD_RET_NONE: + fprintf(opi->of, "<none>\n"); + break; + default: + fprintf(opi->of, "default\n"); + break; } } if (upi->config_kset->ces[1].u.value != 0) diff --git a/output/ulogd_output_XML.c b/output/ulogd_output_XML.c index ba33739..44af596 100644 --- a/output/ulogd_output_XML.c +++ b/output/ulogd_output_XML.c @@ -109,7 +109,7 @@ xml_output_flow(struct ulogd_key *inp, char *buf, ssize_t size) if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -126,7 +126,7 @@ xml_output_packet(struct ulogd_key *inp, char *buf, ssize_t size) if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -143,7 +143,7 @@ xml_output_sum(struct ulogd_key *inp, char *buf, ssize_t size) NFACCT_SNPRINTF_F_TIME); if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -155,14 +155,25 @@ static int xml_output(struct ulogd_pluginstance *upi) struct ulogd_key *inp = upi->input.keys; struct xml_priv *opi = (struct xml_priv *) &upi->private; static char buf[4096]; - int ret = -1; + int ret = -1, tmp = 0; - if (pp_is_valid(inp, KEY_CT)) - ret = xml_output_flow(inp, buf, sizeof(buf)); - else if (pp_is_valid(inp, KEY_PCKT)) - ret = xml_output_packet(inp, buf, sizeof(buf)); - else if (pp_is_valid(inp, KEY_SUM)) - ret = xml_output_sum(inp, buf, sizeof(buf)); + if (pp_is_valid(inp, KEY_PCKT)) { + ret = xml_output_packet(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + tmp += ret; + } + if (pp_is_valid(inp, KEY_CT)) { + ret = xml_output_flow(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + tmp += ret; + } + if (pp_is_valid(inp, KEY_SUM)) { + ret = xml_output_sum(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + } if (ret < 0) return ULOGD_IRET_ERR; @@ -314,7 +325,7 @@ static struct ulogd_plugin xml_plugin = { .input = { .keys = xml_inp, .num_keys = ARRAY_SIZE(xml_inp), - .type = ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, + .type = ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM | ULOGD_DTYPE_RAW, }, .output = { .type = ULOGD_DTYPE_SINK, diff --git a/src/Makefile.am b/src/Makefile.am index 998e776..7a12a72 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,8 +1,8 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -DULOGD_CONFIGFILE="\"$(sysconfdir)/ulogd.conf\"" \ - -DULOGD_LOGFILE_DEFAULT="\"$(localstatedir)/log/ulogd.log\"" -AM_CFLAGS = ${regular_CFLAGS} +AM_CPPFLAGS += -DULOGD_CONFIGFILE='"$(sysconfdir)/ulogd.conf"' \ + -DULOGD_LOGFILE_DEFAULT='"$(localstatedir)/log/ulogd.log"' \ + -DULOGD2_LIBDIR='"$(ulogd2libdir)"' sbin_PROGRAMS = ulogd diff --git a/src/ulogd.c b/src/ulogd.c index 9cd64e8..6c5ff9a 100644 --- a/src/ulogd.c +++ b/src/ulogd.c @@ -661,12 +661,11 @@ pluginstance_alloc_init(struct ulogd_plugin *pl, char *pi_id, } size += pl->input.num_keys * sizeof(struct ulogd_key); size += pl->output.num_keys * sizeof(struct ulogd_key); - pi = malloc(size); + pi = calloc(1, size); if (!pi) return NULL; /* initialize */ - memset(pi, 0, size); INIT_LLIST_HEAD(&pi->list); INIT_LLIST_HEAD(&pi->plist); pi->plugin = pl; @@ -965,7 +964,6 @@ static int create_stack(const char *option) load_all_plugins(); if (!buf) { - ulogd_log(ULOGD_ERROR, ""); ret = -ENOMEM; goto out_buf; } @@ -1136,7 +1134,7 @@ static int parse_conffile(const char *section, struct config_keyset *ce) "section \"%s\" not found\n", section); break; case -ERRTOOLONG: - if (config_errce->key) + if (config_errce) ulogd_log(ULOGD_ERROR, "string value too long for key \"%s\"\n", config_errce->key); @@ -1336,6 +1334,15 @@ static void stop_pluginstances() (*pi->plugin->stop)(pi); pi->private[0] = 0; } + + /* NB: plugin->stop() might access other plugin instances, + * so we cannot free right away. + */ + } + } + + llist_for_each_entry(stack, &ulogd_pi_stacks, stack_list) { + llist_for_each_entry_safe(pi, npi, &stack->list, list) { free(pi); } } @@ -1570,7 +1577,7 @@ int main(int argc, char* argv[]) if (daemonize){ if (daemon(0, 0) < 0) { ulogd_log(ULOGD_FATAL, "can't daemonize: %s (%d)\n", - errno, strerror(errno)); + strerror(errno), errno); warn_and_exit(daemonize); } } diff --git a/ulogd.conf.in b/ulogd.conf.in index 99cfc24..9a04bf7 100644 --- a/ulogd.conf.in +++ b/ulogd.conf.in @@ -65,7 +65,7 @@ logfile="/var/log/ulogd.log" #stack=log2:NFLOG,base1:BASE,mark1:MARK,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU # this is a stack for packet-based logging via GPRINT -#stack=log1:NFLOG,gp1:GPRINT +#stack=log1:NFLOG,base1:BASE,gp1:GPRINT # this is a stack for flow-based logging via LOGEMU #stack=ct1:NFCT,ip2str1:IP2STR,print1:PRINTFLOW,emu1:LOGEMU @@ -67,7 +67,6 @@ static int sql_createstmt(struct ulogd_pluginstance *upi) unsigned int i; char *table = table_ce(upi->config_kset).u.string; char *procedure = procedure_ce(upi->config_kset).u.string; - char *stmt_val = NULL; if (mi->stmt) free(mi->stmt); @@ -96,30 +95,33 @@ static int sql_createstmt(struct ulogd_pluginstance *upi) if (strncasecmp(procedure,"INSERT", strlen("INSERT")) == 0 && (procedure[strlen("INSERT")] == '\0' || procedure[strlen("INSERT")] == ' ')) { - char buf[ULOGD_MAX_KEYLEN]; - char *underscore; + char *stmt_val = mi->stmt; if(procedure[6] == '\0') { /* procedure == "INSERT" */ if (mi->schema) - sprintf(mi->stmt, "insert into %s.%s (", mi->schema, table); + stmt_val += sprintf(stmt_val, + "insert into %s.%s (", + mi->schema, table); else - sprintf(mi->stmt, "insert into %s (", table); - } - else - sprintf(mi->stmt, "%s (", procedure); - - stmt_val = mi->stmt + strlen(mi->stmt); + stmt_val += sprintf(stmt_val, + "insert into %s (", table); + } else + stmt_val += sprintf(stmt_val, "%s (", procedure); for (i = 0; i < upi->input.num_keys; i++) { + char *underscore; + if (upi->input.keys[i].flags & ULOGD_KEYF_INACTIVE) continue; - strncpy(buf, upi->input.keys[i].name, ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '.'))) + underscore = stmt_val; + + stmt_val += sprintf(stmt_val, "%s,", + upi->input.keys[i].name); + + while ((underscore = strchr(underscore, '.'))) *underscore = '_'; - sprintf(stmt_val, "%s,", buf); - stmt_val = mi->stmt + strlen(mi->stmt); } *(stmt_val - 1) = ')'; @@ -226,9 +228,8 @@ int ulogd_db_start(struct ulogd_pluginstance *upi) di->ring.size, di->ring.length); /* init start of query for each element */ for(i = 0; i < di->ring.size; i++) { - strncpy(di->ring.ring + di->ring.length * i + 1, - di->stmt, - strlen(di->stmt)); + strcpy(di->ring.ring + di->ring.length * i + 1, + di->stmt); } /* init cond & mutex */ ret = pthread_cond_init(&di->ring.cond, NULL); @@ -343,6 +344,9 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start) } switch (res->type) { + case ULOGD_RET_BOOL: + sprintf(stmt_ins, "'%d',", res->u.value.b); + break; case ULOGD_RET_INT8: sprintf(stmt_ins, "%d,", res->u.value.i8); break; @@ -362,16 +366,24 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start) sprintf(stmt_ins, "%u,", res->u.value.ui16); break; case ULOGD_RET_IPADDR: - /* fallthrough when logging IP as uint32_t */ + if (res->len == sizeof(struct in_addr)) + sprintf(stmt_ins, "%u,", res->u.value.ui32); + else { + struct in6_addr ipv6; + char addrbuf[2 + sizeof(ipv6) * 2 + 1]; + + memcpy(ipv6.s6_addr, res->u.value.ui128, + sizeof(ipv6.s6_addr)); + format_ipv6(addrbuf, sizeof(addrbuf), &ipv6); + sprintf(stmt_ins, "%s,", addrbuf); + } + break; case ULOGD_RET_UINT32: sprintf(stmt_ins, "%u,", res->u.value.ui32); break; case ULOGD_RET_UINT64: sprintf(stmt_ins, "%" PRIu64 ",", res->u.value.ui64); break; - case ULOGD_RET_BOOL: - sprintf(stmt_ins, "'%d',", res->u.value.b); - break; case ULOGD_RET_STRING: *(stmt_ins++) = '\''; if (res->u.value.ptr) { @@ -388,6 +400,7 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start) case ULOGD_RET_RAW: ulogd_log(ULOGD_NOTICE, "Unsupported RAW type is unsupported in SQL output"); + break; default: ulogd_log(ULOGD_NOTICE, "unknown type %d for %s\n", @@ -402,14 +415,17 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start) static int __add_to_backlog(struct ulogd_pluginstance *upi, const char *stmt, unsigned int len) { struct db_instance *di = (struct db_instance *) &upi->private; + unsigned int query_size; struct db_stmt *query; /* check if we are using backlog */ if (di->backlog_memcap == 0) return 0; + query_size = sizeof(*query) + len + 1; + /* check len against backlog */ - if (len + di->backlog_memusage > di->backlog_memcap) { + if (query_size + di->backlog_memcap - di->backlog_memusage) { if (di->backlog_full == 0) ulogd_log(ULOGD_ERROR, "Backlog is full starting to reject events.\n"); @@ -417,7 +433,7 @@ static int __add_to_backlog(struct ulogd_pluginstance *upi, const char *stmt, un return -1; } - query = malloc(sizeof(struct db_stmt)); + query = malloc(sizeof(*query)); if (query == NULL) return -1; @@ -429,7 +445,7 @@ static int __add_to_backlog(struct ulogd_pluginstance *upi, const char *stmt, un return -1; } - di->backlog_memusage += len + sizeof(struct db_stmt); + di->backlog_memusage += query_size; di->backlog_full = 0; llist_add_tail(&query->list, &di->backlog); @@ -487,7 +503,7 @@ static int __treat_backlog(struct ulogd_pluginstance *upi) di->driver->close_db(upi); return _init_reconnect(upi); } else { - di->backlog_memusage -= query->len + sizeof(struct db_stmt); + di->backlog_memusage -= sizeof(*query) + query->len + 1; llist_del(&query->list); free(query->stmt); free(query); diff --git a/util/printpkt.c b/util/printpkt.c index 69a47ca..09a2194 100644 --- a/util/printpkt.c +++ b/util/printpkt.c @@ -260,11 +260,12 @@ static int printpkt_ipv4(struct ulogd_key *res, char *buf) ikey_get_u16(&res[KEY_ICMP_ECHOSEQ])); break; case ICMP_PARAMETERPROB: + paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]); buf_cur += sprintf(buf_cur, "PARAMETER=%u ", - ikey_get_u32(&res[KEY_ICMP_GATEWAY]) >> 24); + *(uint8_t *) &paddr); break; case ICMP_REDIRECT: - paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]), + paddr = ikey_get_u32(&res[KEY_ICMP_GATEWAY]); buf_cur += sprintf(buf_cur, "GATEWAY=%s ", inet_ntop(AF_INET, &paddr, @@ -355,6 +356,9 @@ static int printpkt_ipv6(struct ulogd_key *res, char *buf) break; } break; + default: + buf_cur += sprintf(buf_cur, "PROTO=%u ", + ikey_get_u8(&res[KEY_IP6_NEXTHDR])); } return buf_cur - buf; @@ -471,7 +475,7 @@ int printpkt_print(struct ulogd_key *res, char *buf) buf_cur += sprintf(buf_cur, "GID=%u ", ikey_get_u32(&res[KEY_OOB_GID])); if (pp_is_valid(res, KEY_OOB_MARK)) - buf_cur += sprintf(buf_cur, "MARK=%x ", + buf_cur += sprintf(buf_cur, "MARK=0x%x ", ikey_get_u32(&res[KEY_OOB_MARK])); strcat(buf_cur, "\n"); |