diff options
-rw-r--r-- | .gitignore | 8 | ||||
-rw-r--r-- | Make_global.am | 2 | ||||
-rw-r--r-- | Makefile.am | 8 | ||||
-rwxr-xr-x | autogen.sh | 39 | ||||
-rw-r--r-- | configure.ac | 71 | ||||
-rw-r--r-- | doxygen.cfg.in | 184 | ||||
-rw-r--r-- | doxygen/Makefile.am | 39 | ||||
-rwxr-xr-x | doxygen/build_man.sh | 227 | ||||
-rw-r--r-- | doxygen/doxygen.cfg.in | 24 | ||||
-rw-r--r-- | include/Makefile.am | 1 | ||||
-rw-r--r-- | include/libnetfilter_log/libipulog.h | 4 | ||||
-rw-r--r-- | include/libnetfilter_log/libnetfilter_log.h | 5 | ||||
-rw-r--r-- | libnetfilter_log.pc.in | 6 | ||||
-rw-r--r-- | libnetfilter_log_libipulog.pc.in | 16 | ||||
-rw-r--r-- | src/Makefile.am | 21 | ||||
-rw-r--r-- | src/libipulog_compat.c | 39 | ||||
-rw-r--r-- | src/libnetfilter_log.c | 293 | ||||
-rw-r--r-- | src/nlmsg.c | 67 | ||||
-rw-r--r-- | utils/Makefile.am | 14 | ||||
-rw-r--r-- | utils/nf-log.c | 8 | ||||
-rw-r--r-- | utils/nfulnl_test.c | 73 | ||||
-rw-r--r-- | utils/ulog_test.c | 15 |
22 files changed, 755 insertions, 409 deletions
@@ -1,3 +1,6 @@ +*~ +.\#* +\#*\# .deps/ .libs/ Makefile @@ -13,5 +16,8 @@ Makefile.in /configure /libtool -/doxygen.cfg +/doxygen/doxygen.cfg +/doxygen/doxyfile.stamp +/doxygen/man/ +/doxygen/html/ /*.pc diff --git a/Make_global.am b/Make_global.am index 9bc8ea1..4d5bec9 100644 --- a/Make_global.am +++ b/Make_global.am @@ -1,2 +1,2 @@ -AM_CPPFLAGS = -I${top_srcdir}/include ${LIBNFNETLINK_CFLAGS} ${LIBMNL_CFLAGS} +AM_CPPFLAGS = -I${top_srcdir}/include AM_CFLAGS = -Wall diff --git a/Makefile.am b/Makefile.am index 9a1cbcb..46b14f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,8 @@ -SUBDIRS = include src utils +SUBDIRS = include src utils doxygen ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = $(man_MANS) Make_global.am - -man_MANS = #nfnetlink_log.3 nfnetlink_log.7 +EXTRA_DIST = Make_global.am pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libnetfilter_log.pc +pkgconfig_DATA = libnetfilter_log.pc libnetfilter_log_libipulog.pc @@ -1,39 +1,12 @@ #!/bin/sh -e -include () -{ - # If we keep a copy of the kernel header in the SVN tree, we'll have - # to worry about synchronization issues forever. Instead, we just copy - # the headers that we need from the lastest kernel version at autogen - # stage. +BUILD_MAN=doxygen/build_man.sh - INCLUDEDIR=${KERNEL_DIR:-/lib/modules/`uname -r`/build}/include/linux - if [ -f $INCLUDEDIR/netfilter/nfnetlink_log.h ] - then - TARGET=include/libnetfilter_log/linux_nfnetlink_log.h - echo "Copying nfnetlink_log.h to linux_nfnetlink_log.h" - cp $INCLUDEDIR/netfilter/nfnetlink_log.h $TARGET - TEMP=`tempfile` - sed 's/linux\/netfilter\/nfnetlink.h/libnfnetlink\/linux_nfnetlink.h/g' $TARGET > $TEMP - # Add aligned_u64 definition after #define _NFNETLINK_LOG_H - awk '{ - if ( $0 == "#define _NFNETLINK_LOG_H" ) { - print $0 - getline - print $0 - print "#ifndef aligned_u64" - print "#define aligned_u64 unsigned long long __attribute__((aligned(8)))" - print "#endif" - } +# Allow to override build_man.sh url for local testing +# E.g. export NFQ_URL=file:///usr/src/libnetfilter_queue +curl ${NFQ_URL:-https://git.netfilter.org/libnetfilter_queue/plain}/$BUILD_MAN\ + -o$BUILD_MAN +chmod a+x $BUILD_MAN - print $0 - }' $TEMP > $TARGET - else - echo "can't find nfnetlink_log.h kernel file in $INCLUDEDIR" - exit 1 - fi -} - -[ "x$1" = "xdistrib" ] && include autoreconf -fi rm -Rf autom4te.cache diff --git a/configure.ac b/configure.ac index c914e00..aeb89e5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,21 +1,37 @@ dnl Process this file with autoconf to create configure. -AC_INIT([libnetfilter_log], [1.0.1]) +AC_INIT([libnetfilter_log], [1.0.2]) AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_HOST AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([-Wall foreign subdir-objects - tar-pax no-dist-gzip dist-bzip2 1.6]) + tar-pax no-dist-gzip dist-xz 1.6]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AC_ARG_ENABLE([html-doc], + AS_HELP_STRING([--enable-html-doc], [Enable html documentation]), + [], [enable_html_doc=no]) +AM_CONDITIONAL([BUILD_HTML], [test "$enable_html_doc" = yes]) +AS_IF([test "$enable_html_doc" = yes], + [AC_SUBST(GEN_HTML, YES)], + [AC_SUBST(GEN_HTML, NO)]) + +AC_ARG_ENABLE([man-pages], + AS_HELP_STRING([--disable-man-pages], + [Disable man page documentation]), + [], [enable_man_pages=yes]) +AM_CONDITIONAL([BUILD_MAN], [test "$enable_man_pages" = yes]) +AS_IF([test "$enable_man_pages" = yes], + [AC_SUBST(GEN_MAN, YES)], + [AC_SUBST(GEN_MAN, NO)]) + AC_PROG_CC AM_PROG_CC_C_O -AC_DISABLE_STATIC -AM_PROG_LIBTOOL +LT_INIT([disable-static]) AC_PROG_INSTALL AC_PROG_LN_S @@ -25,18 +41,53 @@ case "$host" in esac AC_ARG_WITH([ipulog], - AC_HELP_STRING([--without-ipulog], [don't build libipulog compat library])) + AS_HELP_STRING([--without-ipulog], [don't build libipulog compat library])) AM_CONDITIONAL([BUILD_IPULOG], [test "x$with_ipulog" != xno]) dnl Dependencies -PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= 0.0.41]) -PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3]) +AC_SUBST([LIBNFNETLINK_MIN_VERSION], [0.0.41]) +AC_SUBST([LIBMNL_MIN_VERSION], [1.0.3]) + +PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= ${LIBNFNETLINK_MIN_VERSION}]) +PKG_CHECK_MODULES([LIBMNL], [libmnl >= ${LIBMNL_MIN_VERSION}]) PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 1.0.2], [HAVE_LNFCT=1], [HAVE_LNFCT=0]) AM_CONDITIONAL([BUILD_NFCT], [test "$HAVE_LNFCT" -eq 1]) +AS_IF([test "$enable_man_pages" = no -a "$enable_html_doc" = no], + [with_doxygen=no], [with_doxygen=yes]) + +AS_IF([test "x$with_doxygen" != xno], [ + AC_CHECK_PROGS([DOXYGEN], [doxygen], [""]) + AC_CHECK_PROGS([DOT], [dot], [""]) + AS_IF([test "x$DOT" != "x"], + [AC_SUBST(HAVE_DOT, YES)], + [AC_SUBST(HAVE_DOT, NO)]) +]) + +AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) +AS_IF([test "x$DOXYGEN" = x], [ + AS_IF([test "x$with_doxygen" != xno], [ + dnl Only run doxygen Makefile if doxygen installed + AC_MSG_WARN([Doxygen not found - not building documentation]) + enable_html_doc=no + enable_man_pages=no + ]) +]) + dnl Output the makefile -AC_CONFIG_FILES([Makefile src/Makefile include/Makefile - include/libnetfilter_log/Makefile utils/Makefile libnetfilter_log.pc - doxygen.cfg]) +AC_CONFIG_FILES([Makefile + src/Makefile + include/Makefile + include/libnetfilter_log/Makefile + utils/Makefile + libnetfilter_log.pc + libnetfilter_log_libipulog.pc + doxygen/Makefile + doxygen/doxygen.cfg]) AC_OUTPUT + +echo " +libnetfilter_log configuration: +man pages: ${enable_man_pages} +html docs: ${enable_html_doc}" diff --git a/doxygen.cfg.in b/doxygen.cfg.in deleted file mode 100644 index 37bfa7c..0000000 --- a/doxygen.cfg.in +++ /dev/null @@ -1,184 +0,0 @@ -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = @PACKAGE@ -PROJECT_NUMBER = @VERSION@ -OUTPUT_DIRECTORY = doxygen -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -TYPEDEF_HIDES_STRUCT = NO -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -INPUT = . -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.c -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_BUNDLE_ID = org.doxygen.Project -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -GENERATE_MAN = YES -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -GENERATE_AUTOGEN_DEF = NO -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -CLASS_DIAGRAMS = YES -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = YES -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -SEARCHENGINE = NO diff --git a/doxygen/Makefile.am b/doxygen/Makefile.am new file mode 100644 index 0000000..582db4e --- /dev/null +++ b/doxygen/Makefile.am @@ -0,0 +1,39 @@ +if HAVE_DOXYGEN + +doc_srcs = $(top_srcdir)/src/libnetfilter_log.c\ + $(top_srcdir)/src/nlmsg.c\ + $(top_srcdir)/src/libipulog_compat.c + +doxyfile.stamp: $(doc_srcs) Makefile + rm -rf html man + doxygen doxygen.cfg >/dev/null + +if BUILD_MAN + $(abs_top_srcdir)/doxygen/build_man.sh +endif + + touch doxyfile.stamp + +CLEANFILES = doxyfile.stamp + +all-local: doxyfile.stamp +clean-local: + rm -rf man html +install-data-local: +if BUILD_MAN + mkdir -p $(DESTDIR)$(mandir)/man3 + cp --no-dereference --preserve=links,mode,timestamps man/man3/*.3\ + $(DESTDIR)$(mandir)/man3/ +endif +if BUILD_HTML + mkdir -p $(DESTDIR)$(htmldir) + cp --no-dereference --preserve=links,mode,timestamps html/*\ + $(DESTDIR)$(htmldir) +endif + +# make distcheck needs uninstall-local +uninstall-local: + rm -rf $(DESTDIR)$(mandir) man html doxyfile.stamp $(DESTDIR)$(htmldir) +endif + +EXTRA_DIST = build_man.sh diff --git a/doxygen/build_man.sh b/doxygen/build_man.sh new file mode 100755 index 0000000..852c7b8 --- /dev/null +++ b/doxygen/build_man.sh @@ -0,0 +1,227 @@ +#!/bin/bash -p + +# Script to process man pages output by doxygen. +# We need to use bash for its associative array facility. +# (`bash -p` prevents import of functions from the environment). + +declare -A renamed_page + +main(){ + set -e + cd man/man3; rm -f _* + count_real_pages + rename_real_pages + make_symlinks + post_process +} + +count_real_pages(){ + page_count=0 + # + # Count "real" man pages (i.e. not generated by MAN_LINKS) + # MAN_LINKS pages are 1-liners starting .so + # Method: list files in descending order of size, + # looking for the first 1-liner + # + for i in $(ls -S) + do head -n1 $i | grep -E -q '^\.so' && break + page_count=$(($page_count + 1)) + done + first_link=$(($page_count + 1)) +} + +rename_real_pages(){ + for i in $(ls -S | head -n$page_count) + do for j in $(ls -S | tail -n+$first_link) + do grep -E -q $i$ $j && break + done + mv -f $i $j + renamed_page[$i]=$j + done +} + +make_symlinks(){ + for j in $(ls -S | tail -n+$first_link) + do ln -sf ${renamed_page[$(cat $j | cut -f2 -d/)]} $j + done +} + +post_process(){ + make_temp_files + # + # DIAGNOSTIC / DEVELOPMENT CODE + # set -x and restrict processing to keep_me: un-comment to activate + # Change keep_me as required + # + #keep_me=nfq_icmp_get_hdr.3;\ + #do_diagnostics;\ + # + # Work through the "real" man pages + for target in $(ls -S | head -n$page_count) + do mygrep "^\\.SH \"Function Documentation" $target + # Next file if this isn't a function page + [ $linnum -ne 0 ] || continue + + del_modules + del_bogus_synopsis + fix_name_line + move_synopsis + del_empty_det_desc + del_def_at_lines + fix_double_blanks + + # Fix rendering of verbatim "\n" (in code snippets) + sed -i 's/\\n/\\\\n/' $target + + done + + remove_temp_files +} + +fix_double_blanks(){ + linnum=1 + # + # Older versions of man display a blank line on encountering "\fB\fP"; + # newer versions of man do not. + # doxygen emits "\fB\fP" on seeing "\par" on a line by itself. + # "\par" gives us double-spacing in the web doc, which we want, but double- + # spacing looks odd in a man page so remove "\fB\fP". + # + while [ $linnum -ne 0 ] + do mygrep \\\\fB\\\\fP $target + [ $linnum -eq 0 ] || delete_lines $linnum $linnum + done +} + +del_def_at_lines(){ + linnum=1 + while [ $linnum -ne 0 ] + do mygrep "^Definition at line [[:digit:]]* of file" $target + [ $linnum -eq 0 ] || delete_lines $(($linnum - 1)) $linnum + done +} + +# Only invoked if you un-comment the 2 diagnostic / development lines above +do_diagnostics(){ + mv $keep_me xxx + rm *.3 + mv xxx $keep_me + page_count=1 + set -x +} + +del_empty_det_desc(){ + mygrep "^\\.SH \"Function Documentation" $target + i=$linnum + mygrep "^\\.SH \"Detailed Description" $target + [ $linnum -ne 0 ] || return 0 + [ $(($i - $linnum)) -eq 3 ] || return 0 + # A 1-line Detailed Description is also 3 lines long, + # but the 3rd line is not empty + i=$(($i -1)) + [ $(tail -n+$i $target | head -n1 | wc -c) -le 2 ] || return 0 + delete_lines $linnum $i +} + +move_synopsis(){ + mygrep "SH SYNOPSIS" $target + [ $linnum -ne 0 ] || return 0 + i=$linnum + # If this is a doxygen-created synopsis, leave it. + # (We haven't inserted our own one in the source yet) + mygrep "^\\.SS \"Functions" $target + [ $i -gt $linnum ] || return 0 + + mygrep "^\\.SH \"Function Documentation" $target + j=$(($linnum - 1)) + head -n$(($j - 1)) $target | tail -n$(($linnum - $i - 1)) >$fileC + delete_lines $i $j + mygrep "^\\.SS \"Functions" $target + head -n$(($linnum - 1)) $target >$fileA + tail -n+$(($linnum + 1)) $target >$fileB + cat $fileA $fileC $fileB >$target +} + +fix_name_line(){ + all_funcs="" + + # Search a shortened version of the page in case there are .RI lines later + mygrep "^\\.SH \"Function Documentation" $target + head -n$linnum $target >$fileC + + while : + do mygrep ^\\.RI $fileC + [ $linnum -ne 0 ] || break + # Discard this entry + tail -n+$(($linnum + 1)) $fileC >$fileB + cp $fileB $fileC + + func=$(cat $fileG | cut -f2 -d\\ | cut -c3-) + [ -z "$all_funcs" ] && all_funcs=$func ||\ + all_funcs="$all_funcs, $func" + done + # For now, assume name is at line 5 + head -n4 $target >$fileA + desc=$(head -n5 $target | tail -n1 | cut -f3- -d" ") + tail -n+6 $target >$fileB + cat $fileA >$target + echo "$all_funcs \\- $desc" >>$target + cat $fileB >>$target +} + +del_modules(){ + mygrep "^\.SS \"Modules" $target + [ $linnum -ne 0 ] || return 0 + i=$linnum + mygrep "^\\.SS \"Functions" $target + delete_lines $i $(($linnum - 1)) +} + +del_bogus_synopsis(){ + mygrep "SH SYNOPSIS" $target + # + # doxygen 1.8.20 inserts its own SYNOPSIS line but there is no mention + # in the documentation or git log what to do with it. + # So get rid of it + # + [ $linnum -ne 0 ] || return 0 + i=$linnum + # Look for the next one + tail -n+$(($i + 1)) $target >$fileC;\ + mygrep "SH SYNOPSIS" $fileC + [ $linnum -ne 0 ] || return 0 + + mygrep "^\\.SS \"Functions" $target + delete_lines $i $(($linnum - 1)) +} + +# Delete lines $1 through $2 from $target +delete_lines(){ + head -n$(($1 - 1)) $target >$fileA + tail -n+$(($2 +1)) $target >$fileB + cat $fileA $fileB >$target +} + +mygrep(){ + set +e + grep -En "$1" $2 2>/dev/null >$fileH + [ $? -ne 0 ] && linnum=0 ||\ + { head -n1 $fileH >$fileG; linnum=$(cat $fileG | cut -f1 -d:); } + set -e +} + +make_temp_files(){ + temps="A B C G H" + for i in $temps + do declare -g file$i=$(mktemp) + done +} + +remove_temp_files(){ + for i in $temps + do j=file$i + rm ${!j} + done +} + +main diff --git a/doxygen/doxygen.cfg.in b/doxygen/doxygen.cfg.in new file mode 100644 index 0000000..ff67c36 --- /dev/null +++ b/doxygen/doxygen.cfg.in @@ -0,0 +1,24 @@ +# Difference with default Doxyfile 1.8.20 +PROJECT_NAME = @PACKAGE@ +PROJECT_NUMBER = @VERSION@ +ABBREVIATE_BRIEF = +FULL_PATH_NAMES = NO +TAB_SIZE = 8 +OPTIMIZE_OUTPUT_FOR_C = YES +INPUT = @abs_top_srcdir@/src +FILE_PATTERNS = *.c +RECURSIVE = YES +EXCLUDE_SYMBOLS = nflog_g_handle \ + nflog_handle \ + ipulog_errmap_t \ + ipulog_handle +EXAMPLE_PATTERNS = +SOURCE_BROWSER = YES +ALPHABETICAL_INDEX = NO +GENERATE_LATEX = NO +LATEX_CMD_NAME = latex +GENERATE_MAN = @GEN_MAN@ +GENERATE_HTML = @GEN_HTML@ +MAN_LINKS = YES +HAVE_DOT = @HAVE_DOT@ +SEARCHENGINE = NO diff --git a/include/Makefile.am b/include/Makefile.am index 5077115..4d984df 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,3 +1,4 @@ SUBDIRS = libnetfilter_log +noinst_HEADERS = internal.h diff --git a/include/libnetfilter_log/libipulog.h b/include/libnetfilter_log/libipulog.h index 4d87913..8fba03a 100644 --- a/include/libnetfilter_log/libipulog.h +++ b/include/libnetfilter_log/libipulog.h @@ -12,7 +12,7 @@ extern "C" { #endif /* FIXME: glibc sucks */ -#ifndef MSG_TRUNC +#ifndef MSG_TRUNC #define MSG_TRUNC 0x20 #endif @@ -55,7 +55,7 @@ const char *ipulog_strerror(int errcode); void ipulog_perror(const char *s); -enum +enum { IPULOG_ERR_NONE = 0, IPULOG_ERR_IMPL, diff --git a/include/libnetfilter_log/libnetfilter_log.h b/include/libnetfilter_log/libnetfilter_log.h index 6192fa3..ee9121f 100644 --- a/include/libnetfilter_log/libnetfilter_log.h +++ b/include/libnetfilter_log/libnetfilter_log.h @@ -49,7 +49,7 @@ extern int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags); extern int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh); extern int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz); -extern int nflog_callback_register(struct nflog_g_handle *gh, +extern int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb, void *data); extern int nflog_handle_packet(struct nflog_handle *h, char *buf, int len); @@ -82,13 +82,14 @@ enum { NFLOG_XML_PHYSDEV = (1 << 4), NFLOG_XML_PAYLOAD = (1 << 5), NFLOG_XML_TIME = (1 << 6), + NFLOG_XML_CTID = (1 << 7), NFLOG_XML_ALL = ~0U, }; extern int nflog_snprintf_xml(char *buf, size_t len, struct nflog_data *tb, int flags); extern struct nlmsghdr * -nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum); +nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t gnum); extern int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range); extern int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd); extern int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr); diff --git a/libnetfilter_log.pc.in b/libnetfilter_log.pc.in index a4b2f3b..14d16ed 100644 --- a/libnetfilter_log.pc.in +++ b/libnetfilter_log.pc.in @@ -6,11 +6,11 @@ libdir=@libdir@ includedir=@includedir@ Name: libnetfilter_log -Description: netfilter userspace packet logging library +Description: Netfilter userspace packet logging library URL: http://netfilter.org/projects/libnetfilter_log/ Version: @VERSION@ -Requires: libnfnetlink +Requires.private: libnfnetlink >= @LIBNFNETLINK_MIN_VERSION@, \ + libmnl >= @LIBMNL_MIN_VERSION@ Conflicts: Libs: -L${libdir} -lnetfilter_log -Libs.private: @LIBNFNETLINK_LIBS@ Cflags: -I${includedir} diff --git a/libnetfilter_log_libipulog.pc.in b/libnetfilter_log_libipulog.pc.in new file mode 100644 index 0000000..3596790 --- /dev/null +++ b/libnetfilter_log_libipulog.pc.in @@ -0,0 +1,16 @@ +# libnetfilter_log_libipulog pkg-config file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libnetfilter_log_libipulog +Description: Netfilter ULOG userspace compat library +URL: http://netfilter.org/projects/libnetfilter_log/ +Version: @VERSION@ +Requires.private: libnetfilter_log >= @VERSION@, \ + libnfnetlink >= @LIBNFNETLINK_MIN_VERSION@ +Conflicts: +Libs: -L${libdir} -lnetfilter_log_libipulog +Cflags: -I${includedir} diff --git a/src/Makefile.am b/src/Makefile.am index 335c393..c0f5286 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,22 +18,25 @@ # set age to 0. # </snippet> # -LIBVERSION=2:0:1 +LIBVERSION = 3:0:2 +IPULOG_LIBVERSION = 1:0:0 include ${top_srcdir}/Make_global.am lib_LTLIBRARIES = libnetfilter_log.la -libnetfilter_log_la_LDFLAGS = -Wc,-nostartfiles \ - -version-info $(LIBVERSION) -libnetfilter_log_la_SOURCES = libnetfilter_log.c nlmsg.c -libnetfilter_log_la_LIBADD = ${LIBNFNETLINK_LIBS} ${LIBMNL_LIBS} +libnetfilter_log_la_CPPFLAGS = ${AM_CPPFLAGS} ${LIBNFNETLINK_CFLAGS} ${LIBMNL_CFLAGS} +libnetfilter_log_la_LDFLAGS = -Wc,-nostartfiles \ + -version-info $(LIBVERSION) +libnetfilter_log_la_SOURCES = libnetfilter_log.c nlmsg.c +libnetfilter_log_la_LIBADD = ${LIBNFNETLINK_LIBS} ${LIBMNL_LIBS} if BUILD_IPULOG lib_LTLIBRARIES += libnetfilter_log_libipulog.la -libnetfilter_log_libipulog_la_LDFLAGS = -Wc,-nostartfiles \ - -version-info 1:0:0 -libnetfilter_log_libipulog_la_LIBADD = libnetfilter_log.la ${LIBNFNETLINK_LIBS} -libnetfilter_log_libipulog_la_SOURCES = libipulog_compat.c +libnetfilter_log_libipulog_la_CPPFLAGS = ${AM_CPPFLAGS} ${LIBNFNETLINK_CFLAGS} +libnetfilter_log_libipulog_la_LDFLAGS = -Wc,-nostartfiles \ + -version-info $(IPULOG_LIBVERSION) +libnetfilter_log_libipulog_la_LIBADD = libnetfilter_log.la ${LIBNFNETLINK_LIBS} +libnetfilter_log_libipulog_la_SOURCES = libipulog_compat.c endif diff --git a/src/libipulog_compat.c b/src/libipulog_compat.c index 2d5b23a..4efa501 100644 --- a/src/libipulog_compat.c +++ b/src/libipulog_compat.c @@ -4,6 +4,7 @@ #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> +#include <net/if.h> #include <netinet/in.h> #include <libnfnetlink/libnfnetlink.h> #include <libnetfilter_log/libnetfilter_log.h> @@ -31,7 +32,7 @@ static const struct ipulog_errmap_t { int errcode; const char *message; -} ipulog_errmap[] = +} ipulog_errmap[] = { { IPULOG_ERR_NONE, "No error" }, { IPULOG_ERR_IMPL, "Not implemented yet" }, @@ -90,16 +91,15 @@ struct ipulog_handle *ipulog_create_handle(uint32_t gmask, struct ipulog_handle *h; unsigned int group = gmask2group(gmask); - h = malloc(sizeof(*h)+PAYLOAD_SIZE); + h = calloc(1, sizeof(*h)+PAYLOAD_SIZE); if (! h) { ipulog_errno = IPULOG_ERR_HANDLE; return NULL; } - memset(h, 0, sizeof(*h)); h->nfulh = nflog_open(); if (!h->nfulh) goto out_free; - + /* bind_pf returns EEXIST if we are already registered */ rv = nflog_bind_pf(h->nfulh, AF_INET); if (rv < 0 && rv != -EEXIST) @@ -133,10 +133,9 @@ ulog_packet_msg_t *ipulog_get_packet(struct ipulog_handle *h, struct nfulnl_msg_packet_hdr *hdr; if (!h->last_nlh) { - printf("first\n"); nlh = nfnl_get_msg_first(nflog_nfnlh(h->nfulh), buf, len); }else { -next_msg: printf("next\n"); +next_msg: nlh = nfnl_get_msg_next(nflog_nfnlh(h->nfulh), buf, len); } h->last_nlh = nlh; @@ -146,7 +145,7 @@ next_msg: printf("next\n"); nfnl_parse_attr(tb, NFULA_MAX, NFM_NFA(NLMSG_DATA(nlh)), NFM_PAYLOAD(nlh)); - + if (!tb[NFULA_PACKET_HDR-1]) goto next_msg; @@ -159,21 +158,30 @@ next_msg: printf("next\n"); else h->upmsg.mark = 0; - if (tb[NFULA_TIMESTAMP]) { - /* FIXME: 64bit network-to-host */ - h->upmsg.timestamp_sec = h->upmsg.timestamp_usec = 0; + if (tb[NFULA_TIMESTAMP-1]) { + struct nfulnl_msg_packet_timestamp *ts; + ts = NFA_DATA(tb[NFULA_TIMESTAMP-1]); + + h->upmsg.timestamp_sec = __be64_to_cpu(ts->sec); + h->upmsg.timestamp_usec = __be64_to_cpu(ts->usec); } else h->upmsg.timestamp_sec = h->upmsg.timestamp_usec = 0; if (tb[NFULA_IFINDEX_INDEV-1]) { - /* FIXME: ifindex lookup */ - h->upmsg.indev_name[0] = '\0'; + void *indev_ptr = NFA_DATA(tb[NFULA_IFINDEX_INDEV-1]); + uint32_t indev_idx = ntohl(*(uint32_t *)indev_ptr); + + if (!if_indextoname(indev_idx, h->upmsg.indev_name)) + h->upmsg.indev_name[0] = '\0'; } else h->upmsg.indev_name[0] = '\0'; if (tb[NFULA_IFINDEX_OUTDEV-1]) { - /* FIXME: ifindex lookup */ - h->upmsg.outdev_name[0] = '\0'; + void *outdev_ptr = NFA_DATA(tb[NFULA_IFINDEX_OUTDEV-1]); + uint32_t outdev_idx = ntohl(*(uint32_t *)outdev_ptr); + + if (!if_indextoname(outdev_idx, h->upmsg.outdev_name)) + h->upmsg.outdev_name[0] = '\0'; } else h->upmsg.outdev_name[0] = '\0'; @@ -198,7 +206,7 @@ next_msg: printf("next\n"); h->upmsg.data_len = NFA_PAYLOAD(tb[NFULA_PAYLOAD-1]); } else h->upmsg.data_len = 0; - + return &h->upmsg; } @@ -223,4 +231,3 @@ void ipulog_perror(const char *s) fprintf(stderr, ": %s", strerror(errno)); fputc('\n', stderr); } - diff --git a/src/libnetfilter_log.c b/src/libnetfilter_log.c index 567049c..cb09384 100644 --- a/src/libnetfilter_log.c +++ b/src/libnetfilter_log.c @@ -4,7 +4,7 @@ * (C) 2005, 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 + * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation (or any later at your option) * * This program is distributed in the hope that it will be useful, @@ -33,6 +33,9 @@ #include <libnfnetlink/libnfnetlink.h> #include <libnetfilter_log/libnetfilter_log.h> +#include <libmnl/libmnl.h> +#include <linux/netfilter/nfnetlink_conntrack.h> + /** * \mainpage * @@ -82,7 +85,7 @@ struct nflog_g_handle int nflog_errno; /*********************************************************************** - * low level stuff + * low level stuff ***********************************************************************/ static void del_gh(struct nflog_g_handle *gh) @@ -182,15 +185,15 @@ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h) * * Here's a little code snippet that binds to the group 100: * \verbatim - printf("binding this socket to group 0\n"); - qh = nflog_bind_group(h, 0); - if (!qh) { - fprintf(stderr, "no handle for grup 0\n"); + printf("binding this socket to group 100\n"); + gh = nflog_bind_group(h, 100); + if (!gh) { + fprintf(stderr, "no handle for group 100\n"); exit(1); } printf("setting copy_packet mode\n"); - if (nflog_set_mode(qh, NFULNL_COPY_PACKET, 0xffff) < 0) { + if (nflog_set_mode(gh, NFULNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "can't set packet copy mode\n"); exit(1); } @@ -207,22 +210,37 @@ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h) } \endverbatim * - * Data and information about the packet can be fetch by using message parsing - * functions (See \link Parsing \endlink). + * Data and information about the packet can be fetched by using message parsing + * \htmlonly + functions (See <a class="el" href="group__Parsing.html">Parsing</a>). +\endhtmlonly + * \manonly +functions. +.PP +\fBSee also:\fP +.RS 4 +\fBLibrarySetup\fP man page (\fBman nflog_open\fP) +.br +\fBParsing\fP man page (\fBman nflog_get_gid\fP) +.RE +.PP +.SH SYNOPSIS +.nf +\fB +#include <stddef.h> +#include <libnetfilter_log/libnetfilter_log.h> +\endmanonly * @{ */ /** * nflog_fd - get the file descriptor associated with the nflog handler - * \param log handler obtained via call to nflog_open() + * \param h handler obtained via call to nflog_open() * * \return a file descriptor for the netlink connection associated with the * given log connection handle. The file descriptor can then be used for * receiving the logged packets for processing. * - * This function returns a file descriptor that can be used for communication - * over the netlink connection associated with the given log connection - * handle. */ int nflog_fd(struct nflog_handle *h) { @@ -238,14 +256,13 @@ struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh) struct nflog_handle *h; int err; - h = malloc(sizeof(*h)); + h = calloc(1, sizeof(*h)); if (!h) return NULL; - memset(h, 0, sizeof(*h)); h->nfnlh = nfnlh; - h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG, + h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG, NFULNL_MSG_MAX, 0); if (!h->nfnlssh) { /* FIXME: nflog_errno */ @@ -280,7 +297,9 @@ out_free: * it by calling nflog_close(). A new netlink connection is obtained internally * and associated with the log connection handle returned. * - * \return a pointer to a new log handle or NULL on failure. + * \return a pointer to a new log handle or NULL on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ struct nflog_handle *nflog_open(void) { @@ -307,6 +326,20 @@ struct nflog_handle *nflog_open(void) * @} */ +/** + * \addtogroup Log + * @{ + */ + +/** + * nflog_callback_register - register function to process packets + * + * \param gh Netfilter log group handle obtained by call to nflog_bind_group() + * \param cb callback function to call for each logged packet + * \param data custom data to pass to the callback function + \return 0 + */ + int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb, void *data) { @@ -316,17 +349,42 @@ int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb, return 0; } +/** + * nflog_handle_packet - handle a packet received from the nflog subsystem + * \param h Netfilter log handle obtained via call to nflog_open() + * \param buf nflog data received from the kernel + * \param len length of packet data in buffer + * + * Triggers an associated callback for each packet contained in \b buf. + * Data can be read from the queue using nflog_fd() and \b recv(). + * See example code in the Detailed Description. + * \return 0 on success, -1 if either the callback returned -ve or \b buf + * contains corrupt data. \b errno is not reliably set: + * caller should zeroise first if interested. + */ + int nflog_handle_packet(struct nflog_handle *h, char *buf, int len) { return nfnl_handle_packet(h->nfnlh, buf, len); } /** + * @} + */ + +/** * \addtogroup LibrarySetup * * When the program has finished with libnetfilter_log, it has to call * the nflog_close() function to release all associated resources. * + * \manonly +.SH SYNOPSIS +.nf +\fB +#include <netinet/in.h> +#include <libnetfilter_log/libnetfilter_log.h> +\endmanonly * @{ */ @@ -336,7 +394,9 @@ int nflog_handle_packet(struct nflog_handle *h, char *buf, int len) * * This function closes the nflog handler and free associated resources. * - * \return 0 on success, non-zero on failure. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * as for __close__(2) */ int nflog_close(struct nflog_handle *h) { @@ -353,7 +413,9 @@ int nflog_close(struct nflog_handle *h) * Binds the given log connection handle to process packets belonging to * the given protocol family (ie. PF_INET, PF_INET6, etc). * - * \return integer inferior to 0 in case of failure + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * \b EOPNOTSUPP Not running as root */ int nflog_bind_pf(struct nflog_handle *h, uint16_t pf) { @@ -368,6 +430,9 @@ int nflog_bind_pf(struct nflog_handle *h, uint16_t pf) * * Unbinds the given nflog handle from processing packets belonging * to the given protocol family. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * \b EOPNOTSUPP Not running as root */ int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf) { @@ -388,21 +453,27 @@ int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf) * \param h Netfilter log handle obtained via call to nflog_open() * \param num the number of the group to bind to * - * \return a nflog_g_handle pointing to the newly created group + * \return an nflog_g_handle for the newly created group or NULL on failure. + * \par Errors + * \b EBUSY This process has already binded to the group + * \n + * \b EOPNOTSUPP Request rejected by kernel. Another process has already + * binded to the group, or this process is not running as root */ struct nflog_g_handle * nflog_bind_group(struct nflog_handle *h, uint16_t num) { struct nflog_g_handle *gh; - - if (find_gh(h, num)) + + if (find_gh(h, num)) { + errno = EBUSY; return NULL; - - gh = malloc(sizeof(*gh)); + } + + gh = calloc(1, sizeof(*gh)); if (!gh) return NULL; - memset(gh, 0, sizeof(*gh)); gh->h = h; gh->id = num; @@ -428,7 +499,9 @@ nflog_bind_group(struct nflog_handle *h, uint16_t num) * nflog_unbind_group - unbind a group handle. * \param gh Netfilter log group handle obtained via nflog_bind_group() * - * \return -1 in case of error and errno is explicity in case of error. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_unbind_group(struct nflog_g_handle *gh) { @@ -443,7 +516,7 @@ int nflog_unbind_group(struct nflog_g_handle *gh) /** * nflog_set_mode - set the amount of packet data that nflog copies to userspace - * \param qh Netfilter log handle obtained by call to nflog_bind_group(). + * \param gh Netfilter log group handle obtained by call to nflog_bind_group(). * \param mode the part of the packet that we are interested in * \param range size of the packet that we want to get * @@ -454,7 +527,9 @@ int nflog_unbind_group(struct nflog_g_handle *gh) * - NFULNL_COPY_META - copy only packet metadata * - NFULNL_COPY_PACKET - copy entire packet * - * \return -1 on error; >= otherwise. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_set_mode(struct nflog_g_handle *gh, uint8_t mode, uint32_t range) @@ -479,15 +554,17 @@ int nflog_set_mode(struct nflog_g_handle *gh, /** * nflog_set_timeout - set the maximum time to push log buffer for this group - * \param gh Netfilter log handle obtained by call to nflog_bind_group(). + * \param gh Netfilter log group handle obtained by call to nflog_bind_group(). * \param timeout Time to wait until the log buffer is pushed to userspace * - * This function allows to set the maximum time that nflog waits until it + * This function allows one to set the maximum time that nflog waits until it * pushes the log buffer to userspace if no new logged packets have occured. * Basically, nflog implements a buffer to reduce the computational cost * of delivering the log message to userspace. * - * \return -1 in case of error and errno is explicity set. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout) { @@ -506,13 +583,15 @@ int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout) /** * nflog_set_qthresh - set the maximum amount of logs in buffer for this group - * \param gh Netfilter log handle obtained by call to nflog_bind_group(). + * \param gh Netfilter log group handle obtained by call to nflog_bind_group(). * \param qthresh Maximum number of log entries * * This function determines the maximum number of log entries in the buffer * until it is pushed to userspace. * - * \return -1 in case of error and errno is explicity set. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh) { @@ -531,17 +610,19 @@ int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh) /** * nflog_set_nlbufsiz - set the size of the nflog buffer for this group - * \param gh Netfilter log handle obtained by call to nflog_bind_group(). + * \param gh Netfilter log group handle obtained by call to nflog_bind_group(). * \param nlbufsiz Size of the nflog buffer * * This function sets the size (in bytes) of the buffer that is used to * stack log messages in nflog. * - * NOTE: The use of this function is strongly discouraged. The default + * \warning The use of this function is strongly discouraged. The default * buffer size (which is one memory page) provides the optimum results * in terms of performance. Do not use this function in your applications. * - * \return -1 in case of error and errno is explicity set. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz) { @@ -567,15 +648,18 @@ int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz) /** * nflog_set_flags - set the nflog flags for this group - * \param gh Netfilter log handle obtained by call to nflog_bind_group(). + * \param gh Netfilter log group handle obtained by call to nflog_bind_group(). * \param flags Flags that you want to set * * There are two existing flags: * * - NFULNL_CFG_F_SEQ: This enables local nflog sequence numbering. * - NFULNL_CFG_F_SEQ_GLOBAL: This enables global nflog sequence numbering. + * - NFULNL_CFG_F_CONNTRACK: This enables to acquire related conntrack. * - * \return -1 in case of error and errno is explicity set. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags) { @@ -598,6 +682,13 @@ int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags) /** * \defgroup Parsing Message parsing functions + * \manonly +.SH SYNOPSIS +.nf +\fB +#include <stddef.h> +#include <libnetfilter_log/libnetfilter_log.h> +\endmanonly * @{ */ @@ -612,8 +703,8 @@ int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags) * The nfulnl_msg_packet_hdr structure is defined in libnetfilter_log.h as: *\verbatim struct nfulnl_msg_packet_hdr { - uint16_t hw_protocol; // hw protocol (network order) - uint8_t hook; // netfilter hook + uint16_t hw_protocol; // hw protocol (network order) + uint8_t hook; // netfilter hook uint8_t _pad; } __attribute__ ((packed)); \endverbatim @@ -673,9 +764,11 @@ uint32_t nflog_get_nfmark(struct nflog_data *nfad) * \param nfad Netlink packet data handle passed to callback function * \param tv structure to fill with timestamp info * - * Retrieves the received timestamp when the given logged packet. + * Retrieves the received timestamp from the given logged packet. * - * \return 0 on success, a negative value on failure. + * \return 0 on success, -1 on failure with \b errno set. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv) { @@ -700,8 +793,8 @@ int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv) * returned index is 0, the packet was locally generated or the input * interface is not known (ie. POSTROUTING?). * - * \warning all nflog_get_dev() functions return 0 if not set, since linux - * only allows ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1) + * \warning all nflog_get_dev() functions return 0 if not set, since Linux + * only allows ifindex >= 1, see net/core/dev.c:9819 (in 5.14.3) */ uint32_t nflog_get_indev(struct nflog_data *nfad) { @@ -710,6 +803,7 @@ uint32_t nflog_get_indev(struct nflog_data *nfad) /** * nflog_get_physindev - get the physical interface that the packet was received + * through * \param nfad Netlink packet data handle passed to callback function * * \return The index of the physical device the packet was received via. @@ -722,10 +816,10 @@ uint32_t nflog_get_physindev(struct nflog_data *nfad) } /** - * nflog_get_outdev - gets the interface that the packet will be routed out + * nflog_get_outdev - gets the interface that the packet will be routed to * \param nfad Netlink packet data handle passed to callback function * - * \return The index of the device the packet will be sent out. If the + * \return The index of the device the packet will be sent to. If the * returned index is 0, the packet is destined for localhost or the output * interface is not yet known (ie. PREROUTING?). */ @@ -735,15 +829,12 @@ uint32_t nflog_get_outdev(struct nflog_data *nfad) } /** - * nflog_get_physoutdev - get the physical interface that the packet output + * nflog_get_physoutdev - get the physical interface for packet output * \param nfad Netlink packet data handle passed to callback function * - * The index of the physical device the packet will be sent out. If the + * \return Index of physical device the packet will be routed to. If the * returned index is 0, the packet is destined for localhost or the * physical output interface is not yet known (ie. PREROUTING?). - * - * \return The index of physical interface that the packet output will be - * routed out. */ uint32_t nflog_get_physoutdev(struct nflog_data *nfad) { @@ -762,12 +853,16 @@ uint32_t nflog_get_physoutdev(struct nflog_data *nfad) * * The nfulnl_msg_packet_hw structure is defined in libnetfilter_log.h as: * \verbatim - struct nfulnl_msg_packet_hw { - uint16_t hw_addrlen; - uint16_t _pad; - uint8_t hw_addr[8]; - } __attribute__ ((packed)); + struct nfulnl_msg_packet_hw { + uint16_t hw_addrlen; // Network Byte Order + uint16_t _pad; + uint8_t hw_addr[8]; + } __attribute__ ((packed)); \endverbatim + * + * \return Pointer to struct nfulnl_msg_packet_hw from originating host + * or NULL if none available (e.g. locally-originated packet not for \b lo + * interface). */ struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad) { @@ -784,7 +879,7 @@ struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad) * data retrieved by this function will depend on the mode set with the * nflog_set_mode() function. * - * \return -1 on error, otherwise > 0. + * \return payload length, or -1 if this is not available */ int nflog_get_payload(struct nflog_data *nfad, char **data) { @@ -800,7 +895,7 @@ int nflog_get_payload(struct nflog_data *nfad, char **data) * \param nfad Netlink packet data handle passed to callback function * * \return the string prefix that is specified as argument to the iptables' - * NFLOG target. + * NFLOG target or NULL if this is not available. */ char *nflog_get_prefix(struct nflog_data *nfad) { @@ -808,10 +903,13 @@ char *nflog_get_prefix(struct nflog_data *nfad) } /** - * nflog_get_uid - get the UID of the user that has generated the packet + * nflog_get_uid - get the UID of the user that generated the packet * \param nfad Netlink packet data handle passed to callback function + * \param uid UID of the user that generated the packet, + * if the function returns zero * - * \return the UID of the user that has genered the packet, if any. + * \return 0 on success or -1 if UID was unavailable (\b uid + * is then invalid) */ int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid) { @@ -825,8 +923,11 @@ int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid) /** * nflog_get_gid - get the GID of the user that has generated the packet * \param nfad Netlink packet data handle passed to callback function + * \param gid GID of the user that generated the packet, + * if the function returns zero * - * \return the GID of the user that has genered the packet, if any. + * \return 0 on success or -1 if GID was unavailable (\b gid + * is then invalid) */ int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid) { @@ -840,10 +941,13 @@ int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid) /** * nflog_get_seq - get the local nflog sequence number * \param nfad Netlink packet data handle passed to callback function + * \param seq local nflog sequence number, + * if the function returns zero * * You must enable this via nflog_set_flags(). * - * \return the local nflog sequence number. + * \return 0 on success or -1 if sequence number was unavailable (\b seq + * is then invalid) */ int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq) { @@ -857,10 +961,13 @@ int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq) /** * nflog_get_seq_global - get the global nflog sequence number * \param nfad Netlink packet data handle passed to callback function + * \param seq global nflog sequence number, + * if the function returns zero * * You must enable this via nflog_set_flags(). * - * \return the global nflog sequence number. + * \return 0 on success or -1 if sequence number was unavailable (\b seq + * is then invalid) */ int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq) { @@ -872,6 +979,38 @@ int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq) } /** + * nflog_get_ct_id - get the conntrack id + * \param nfad Netlink packet data handle passed to callback function + * \param id conntrack id, if the function returns zero + * + * You must enable this via nflog_set_flags(). + * + * \return 0 on success or -1 if conntrack itself or its id was unavailable + */ +int nflog_get_ctid(struct nflog_data *nfad, uint32_t *id) +{ + struct nlattr *cta = (struct nlattr *)nfad->nfa[NFULA_CT - 1]; + struct nlattr *attr, *ida = NULL; + + if (!cta) + return -1; + + mnl_attr_for_each_nested(attr, cta) { + if (mnl_attr_get_type(attr) == CTA_ID) { + ida = attr; + break; + } + } + + if (!ida || mnl_attr_validate(ida, MNL_TYPE_U32) < 0) + return -1; + + *id = ntohl(mnl_attr_get_u32(ida)); + + return 0; +} + +/** * @} */ @@ -887,7 +1026,13 @@ do { \ } while (0) /** - * \defgroup Printing + * \defgroup Printing Printing + * \manonly +.SH SYNOPSIS +.nf +\fB +#include <libnetfilter_log/libnetfilter_log.h> +\endmanonly * @{ */ @@ -907,20 +1052,23 @@ do { \ * - NFLOG_XML_PHYSDEV: include the physical device information * - NFLOG_XML_PAYLOAD: include the payload (in hexadecimal) * - NFLOG_XML_TIME: include the timestamp + * - NFLOG_XML_CTID: include conntrack id * - NFLOG_XML_ALL: include all the logging information (all flags set) * - * You can combine this flags with an binary OR. + * You can combine these flags with a bitwise OR. * * \return -1 in case of failure, otherwise the length of the string that * would have been printed into the buffer (in case that there is enough * room in it). See snprintf() return value for more information. + * \par Errors + * from underlying calls, in exceptional circumstances */ int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags) { - struct nfulnl_msg_packet_hdr *ph; - struct nfulnl_msg_packet_hw *hwph; - uint32_t mark, ifi; int size, offset = 0, len = 0, ret; + struct nfulnl_msg_packet_hw *hwph; + struct nfulnl_msg_packet_hdr *ph; + uint32_t mark, ifi, ctid; char *data; size = snprintf(buf + offset, rem, "<log>"); @@ -1039,6 +1187,15 @@ int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags) SNPRINTF_FAILURE(size, rem, offset, len); } + if (flags & NFLOG_XML_CTID) { + ret = nflog_get_ctid(tb, &ctid); + if (ret >= 0) { + size = snprintf(buf + offset, rem, + "<ctid>%u</ctid>", ctid); + SNPRINTF_FAILURE(size, rem, offset, len); + } + } + ret = nflog_get_payload(tb, &data); if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) { int i; diff --git a/src/nlmsg.c b/src/nlmsg.c index 3ebb364..587a046 100644 --- a/src/nlmsg.c +++ b/src/nlmsg.c @@ -14,22 +14,29 @@ /** * \defgroup nlmsg Netlink message helper functions + * \manonly +.SH SYNOPSIS +.nf +\fB +#include <netinet/in.h> +#include <libnetfilter_log/libnetfilter_log.h> +\endmanonly * @{ */ /** - * nflog_nlmsg_put_header - reserve and prepare room for nflog Netlink header - * \param buf memory already allocated to store the Netlink header - * \param type message type one of the enum nfulnl_msg_types - * \param family protocol family to be an object of - * \param qnum queue number to be an object of + * nflog_nlmsg_put_header - populate memory buffer with nflog Netlink headers + * \param buf pointer to memory buffer + * \param type either NFULNL_MSG_PACKET or NFULNL_MSG_CONFIG (enum nfulnl_msg_types) + * \param family protocol family + * \param gnum group number * - * This function creates Netlink header in the memory buffer passed - * as parameter that will send to nfnetlink log. This function - * returns a pointer to the Netlink header structure. + * Initialises _buf_ to start with a netlink header for the log subsystem + * followed by an nfnetlink header with the log group + * \return pointer to created Netlink header structure */ struct nlmsghdr * -nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum) +nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t gnum) { struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); struct nfgenmsg *nfg; @@ -40,19 +47,19 @@ nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum) nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); nfg->nfgen_family = family; nfg->version = NFNETLINK_V0; - nfg->res_id = htons(qnum); + nfg->res_id = htons(gnum); return nlh; } /** * nflog_attr_put_cfg_mode - add a mode attribute to nflog netlink message - * \param nlh pointer to the netlink message - * \param mode copy mode defined in linux/netfilter/nfnetlink_log.h + * \param nlh pointer to netlink message + * \param mode copy mode: NFULNL_COPY_NONE, NFULNL_COPY_META or + * NFULNL_COPY_PACKET * \param range copy range * - * this function returns -1 and errno is explicitly set on error. - * On success, this function returns 1. + * \return 0 */ int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range) { @@ -68,12 +75,11 @@ int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range) } /** - * nflog_attr_put_cfg_cmd - add a cmd attribute to nflog netlink message - * \param nlh pointer to the netlink message - * \param cmd command one of the enum nfulnl_msg_config_cmds + * nflog_attr_put_cfg_cmd - add a command attribute to nflog netlink message + * \param nlh pointer to netlink message + * \param cmd one of the enum nfulnl_msg_config_cmds * - * this function returns -1 and errno is explicitly set on error. - * On success, this function returns 1. + * \return 0 */ int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd) { @@ -148,11 +154,10 @@ static int nflog_parse_attr_cb(const struct nlattr *attr, void *data) /** * nflog_nlmsg_parse - set nlattrs from netlink message - * \param nlh netlink message that you want to read. - * \param attr pointer to the array of nlattr which size is NFULA_MAX + 1 + * \param nlh pointer to netlink message + * \param attr pointer to an array of nlattr of size NFULA_MAX + 1 * - * This function returns MNL_CB_ERROR if any error occurs, or MNL_CB_OK on - * success. + * \return 0 */ int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr) { @@ -164,12 +169,12 @@ int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr) * nflog_nlmsg_snprintf - print a nflog nlattrs to a buffer * \param buf buffer used to build the printable nflog * \param bufsiz size of the buffer - * \param nlh netlink message (to get queue num in the futuer) - * \param attr pointer to a nflog attrs + * \param nlh pointer to netlink message (to get queue num in the future) + * \param attr pointer to an array of nlattr of size NFULA_MAX + 1 * \param type print message type in enum nflog_output_type * \param flags The flag that tell what to print into the buffer * - * This function supports the following type - flags: + * This function supports the following types / flags: * * type: NFLOG_OUTPUT_XML * - NFLOG_XML_PREFIX: include the string prefix @@ -181,12 +186,12 @@ int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr) * - NFLOG_XML_TIME: include the timestamp * - NFLOG_XML_ALL: include all the logging information (all flags set) * - * You can combine this flags with an binary OR. + * You can combine these flags with a bitwise OR. * - * this function returns -1 and errno is explicitly set in case of - * failure, otherwise the length of the string that would have been - * printed into the buffer (in case that there is enough room in - * it). See snprintf() return value for more information. + * \return -1 on failure else same as snprintf + * \par Errors + * __EOPNOTSUPP__ _type_ is unsupported (i.e. not __NFLOG_OUTPUT_XML__) + * \sa __snprintf__(3) */ int nflog_nlmsg_snprintf(char *buf, size_t bufsiz, const struct nlmsghdr *nlh, struct nlattr **attr, enum nflog_output_type type, diff --git a/utils/Makefile.am b/utils/Makefile.am index 4afd91b..94afb26 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -4,20 +4,18 @@ check_PROGRAMS = nfulnl_test nf-log nfulnl_test_SOURCES = nfulnl_test.c nfulnl_test_LDADD = ../src/libnetfilter_log.la -nfulnl_test_LDFLAGS = -dynamic -nf_log_SOURCES = nf-log.c -nf_log_LDADD = ../src/libnetfilter_log.la -lmnl -nf_log_LDFLAGS = -dynamic +nf_log_SOURCES = nf-log.c +nf_log_LDADD = ../src/libnetfilter_log.la $(LIBMNL_LIBS) +nf_log_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMNL_CFLAGS) if BUILD_NFCT -nf_log_LDFLAGS += $(LIBNETFILTER_CONNTRACK_LIBS) -nf_log_CPPFLAGS = ${AM_CPPFLAGS} ${LIBNETFILTER_CONNTRACK_CFLAGS} -DBUILD_NFCT +nf_log_LDADD += $(LIBNETFILTER_CONNTRACK_LIBS) +nf_log_CPPFLAGS += $(LIBNETFILTER_CONNTRACK_CFLAGS) -DBUILD_NFCT endif if BUILD_IPULOG check_PROGRAMS += ulog_test ulog_test_SOURCES = ulog_test.c -ulog_test_LDADD = ../src/libnetfilter_log_libipulog.la ../src/libnetfilter_log.la -ulog_test_LDFLAGS = -dynamic +ulog_test_LDADD = ../src/libnetfilter_log_libipulog.la endif diff --git a/utils/nf-log.c b/utils/nf-log.c index ad8369c..e6832b0 100644 --- a/utils/nf-log.c +++ b/utils/nf-log.c @@ -144,13 +144,13 @@ int main(int argc, char *argv[]) char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; int ret; - unsigned int portid, qnum; + unsigned int portid, gnum; if (argc != 2) { printf("Usage: %s [queue_num]\n", argv[0]); exit(EXIT_FAILURE); } - qnum = atoi(argv[1]); + gnum = atoi(argv[1]); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { @@ -188,7 +188,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - nlh = nflog_nlmsg_put_header(buf, NFULNL_MSG_CONFIG, AF_INET, qnum); + nlh = nflog_nlmsg_put_header(buf, NFULNL_MSG_CONFIG, AF_INET, gnum); if (nflog_attr_put_cfg_cmd(nlh, NFULNL_CFG_CMD_BIND) < 0) { perror("nflog_attr_put_cfg_cmd"); exit(EXIT_FAILURE); @@ -199,7 +199,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - nlh = nflog_nlmsg_put_header(buf, NFULNL_MSG_CONFIG, AF_UNSPEC, qnum); + nlh = nflog_nlmsg_put_header(buf, NFULNL_MSG_CONFIG, AF_UNSPEC, gnum); if (nflog_attr_put_cfg_mode(nlh, NFULNL_COPY_PACKET, 0xffff) < 0) { perror("nflog_attr_put_cfg_mode"); exit(EXIT_FAILURE); diff --git a/utils/nfulnl_test.c b/utils/nfulnl_test.c index dd3091b..4f29f17 100644 --- a/utils/nfulnl_test.c +++ b/utils/nfulnl_test.c @@ -6,33 +6,50 @@ #include <libnetfilter_log/libnetfilter_log.h> -static int print_pkt(struct nflog_data *ldata) +static int print_pkt(struct nflog_data *nfad) { - struct nfulnl_msg_packet_hdr *ph = nflog_get_msg_packet_hdr(ldata); - uint32_t mark = nflog_get_nfmark(ldata); - uint32_t indev = nflog_get_indev(ldata); - uint32_t outdev = nflog_get_outdev(ldata); - char *prefix = nflog_get_prefix(ldata); + uint32_t outdev, indev, hw_addrlen; + struct nfulnl_msg_packet_hdr *ph; + struct nfulnl_msg_packet_hw *hw; + int payload_len; char *payload; - int payload_len = nflog_get_payload(ldata, &payload); - + char *prefix; + int i; + + ph = nflog_get_msg_packet_hdr(nfad); if (ph) { - printf("hw_protocol=0x%04x hook=%u ", + printf("hw_protocol=0x%04x hook=%u ", ntohs(ph->hw_protocol), ph->hook); } - printf("mark=%u ", mark); + hw = nflog_get_packet_hw(nfad); + if (hw) { + hw_addrlen = ntohs(hw->hw_addrlen); + printf("hw_addrlen=%d ", hw_addrlen); + + printf("hw_addr="); + for (i = 0; i < hw_addrlen - 1; i++) + printf("%02x:", hw->hw_addr[i]); + + printf("%02x ", hw->hw_addr[hw_addrlen - 1]); + } + printf("mark=%u ", nflog_get_nfmark(nfad)); + + indev = nflog_get_indev(nfad); if (indev > 0) printf("indev=%u ", indev); + outdev = nflog_get_outdev(nfad); if (outdev > 0) printf("outdev=%u ", outdev); - if (prefix) { + prefix = nflog_get_prefix(nfad); + if (prefix) printf("prefix=\"%s\" ", prefix); - } + + payload_len = nflog_get_payload(nfad, &payload); if (payload_len >= 0) printf("payload_len=%d ", payload_len); @@ -51,52 +68,52 @@ static int cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg, int main(int argc, char **argv) { struct nflog_handle *h; - struct nflog_g_handle *qh; - struct nflog_g_handle *qh100; + struct nflog_g_handle *gh; + struct nflog_g_handle *gh100; int rv, fd; char buf[4096]; h = nflog_open(); if (!h) { - fprintf(stderr, "error during nflog_open()\n"); + perror("nflog_open"); exit(1); } printf("unbinding existing nf_log handler for AF_INET (if any)\n"); if (nflog_unbind_pf(h, AF_INET) < 0) { - fprintf(stderr, "error nflog_unbind_pf()\n"); + perror("nflog_unbind_pf"); exit(1); } printf("binding nfnetlink_log to AF_INET\n"); if (nflog_bind_pf(h, AF_INET) < 0) { - fprintf(stderr, "error during nflog_bind_pf()\n"); + perror("nflog_bind_pf"); exit(1); } printf("binding this socket to group 0\n"); - qh = nflog_bind_group(h, 0); - if (!qh) { - fprintf(stderr, "no handle for grup 0\n"); + gh = nflog_bind_group(h, 0); + if (!gh) { + perror("nflog_bind_group 0"); exit(1); } printf("binding this socket to group 100\n"); - qh100 = nflog_bind_group(h, 100); - if (!qh100) { - fprintf(stderr, "no handle for group 100\n"); + gh100 = nflog_bind_group(h, 100); + if (!gh100) { + perror("nflog_bind_group 100"); exit(1); } printf("setting copy_packet mode\n"); - if (nflog_set_mode(qh, NFULNL_COPY_PACKET, 0xffff) < 0) { - fprintf(stderr, "can't set packet copy mode\n"); + if (nflog_set_mode(gh, NFULNL_COPY_PACKET, 0xffff) < 0) { + perror("nflog_set_mode NFULNL_COPY_PACKET"); exit(1); } fd = nflog_fd(h); printf("registering callback for group 0\n"); - nflog_callback_register(qh, &cb, NULL); + nflog_callback_register(gh, &cb, NULL); printf("going into main loop\n"); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { @@ -107,9 +124,9 @@ int main(int argc, char **argv) } printf("unbinding from group 100\n"); - nflog_unbind_group(qh100); + nflog_unbind_group(gh100); printf("unbinding from group 0\n"); - nflog_unbind_group(qh); + nflog_unbind_group(gh); #ifdef INSANE /* norally, applications SHOULD NOT issue this command, diff --git a/utils/ulog_test.c b/utils/ulog_test.c index f3adec2..213a2bf 100644 --- a/utils/ulog_test.c +++ b/utils/ulog_test.c @@ -22,12 +22,19 @@ void handle_packet(ulog_packet_msg_t *pkt) { unsigned char *p; int i; - + printf("Hook=%u Mark=%lu len=%zu ", pkt->hook, pkt->mark, pkt->data_len); if (strlen(pkt->prefix)) printf("Prefix=%s ", pkt->prefix); - + if (strlen(pkt->indev_name)) + printf("Input device=%s ", pkt->indev_name); + if (strlen(pkt->outdev_name)) + printf("Output device=%s ", pkt->outdev_name); + if (pkt->timestamp_sec || pkt->timestamp_usec) + printf("Timestamp=%ld.%06lds ", + pkt->timestamp_sec, pkt->timestamp_usec); + if (pkt->mac_len) { printf("mac="); @@ -56,7 +63,7 @@ int main(int argc, char *argv[]) buf = malloc(MYBUFSIZ); if (!buf) exit(1); - + /* create ipulog handle */ h = ipulog_create_handle(ipulog_group2gmask(atoi(argv[2])), 65535); if (!h) @@ -80,7 +87,7 @@ int main(int argc, char *argv[]) handle_packet(upkt); } } - + /* just to give it a cleaner look */ ipulog_destroy_handle(h); return 0; |