diff options
-rw-r--r-- | .gitignore | 9 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rwxr-xr-x | autogen.sh | 8 | ||||
-rw-r--r-- | configure.ac | 52 | ||||
-rw-r--r-- | doxygen/Makefile.am | 39 | ||||
-rwxr-xr-x | doxygen/build_man.sh | 227 | ||||
-rw-r--r-- | doxygen/doxygen.cfg.in (renamed from doxygen.cfg.in) | 10 | ||||
-rw-r--r-- | include/libnetfilter_log/libnetfilter_log.h | 1 | ||||
-rw-r--r-- | libnetfilter_log.pc.in | 2 | ||||
-rw-r--r-- | libnetfilter_log_libipulog.pc.in | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/libipulog_compat.c | 3 | ||||
-rw-r--r-- | src/libnetfilter_log.c | 63 |
13 files changed, 394 insertions, 26 deletions
@@ -1,3 +1,6 @@ +*~ +.\#* +\#*\# .deps/ .libs/ Makefile @@ -13,6 +16,8 @@ Makefile.in /configure /libtool -/doxygen/ -/doxygen.cfg +/doxygen/doxygen.cfg +/doxygen/doxyfile.stamp +/doxygen/man/ +/doxygen/html/ /*.pc diff --git a/Makefile.am b/Makefile.am index c7b86f7..46b14f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = include src utils +SUBDIRS = include src utils doxygen ACLOCAL_AMFLAGS = -I m4 @@ -1,4 +1,12 @@ #!/bin/sh -e +BUILD_MAN=doxygen/build_man.sh + +# 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 + autoreconf -fi rm -Rf autom4te.cache diff --git a/configure.ac b/configure.ac index 85e49ed..aeb89e5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,20 +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 -LT_INIT([disable_static]) +LT_INIT([disable-static]) AC_PROG_INSTALL AC_PROG_LN_S @@ -37,6 +54,27 @@ 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 @@ -45,5 +83,11 @@ AC_CONFIG_FILES([Makefile utils/Makefile libnetfilter_log.pc libnetfilter_log_libipulog.pc - doxygen.cfg]) + 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/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.cfg.in b/doxygen/doxygen.cfg.in index dc2fddb..ff67c36 100644 --- a/doxygen.cfg.in +++ b/doxygen/doxygen.cfg.in @@ -1,12 +1,11 @@ # Difference with default Doxyfile 1.8.20 PROJECT_NAME = @PACKAGE@ PROJECT_NUMBER = @VERSION@ -OUTPUT_DIRECTORY = doxygen ABBREVIATE_BRIEF = FULL_PATH_NAMES = NO TAB_SIZE = 8 OPTIMIZE_OUTPUT_FOR_C = YES -INPUT = . +INPUT = @abs_top_srcdir@/src FILE_PATTERNS = *.c RECURSIVE = YES EXCLUDE_SYMBOLS = nflog_g_handle \ @@ -18,7 +17,8 @@ SOURCE_BROWSER = YES ALPHABETICAL_INDEX = NO GENERATE_LATEX = NO LATEX_CMD_NAME = latex -GENERATE_MAN = YES -HAVE_DOT = YES -DOT_TRANSPARENT = YES +GENERATE_MAN = @GEN_MAN@ +GENERATE_HTML = @GEN_HTML@ +MAN_LINKS = YES +HAVE_DOT = @HAVE_DOT@ SEARCHENGINE = NO diff --git a/include/libnetfilter_log/libnetfilter_log.h b/include/libnetfilter_log/libnetfilter_log.h index 16c4748..ee9121f 100644 --- a/include/libnetfilter_log/libnetfilter_log.h +++ b/include/libnetfilter_log/libnetfilter_log.h @@ -82,6 +82,7 @@ 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, }; diff --git a/libnetfilter_log.pc.in b/libnetfilter_log.pc.in index 9dbed77..14d16ed 100644 --- a/libnetfilter_log.pc.in +++ b/libnetfilter_log.pc.in @@ -9,7 +9,7 @@ Name: libnetfilter_log Description: Netfilter userspace packet logging library URL: http://netfilter.org/projects/libnetfilter_log/ Version: @VERSION@ -Requires.private: libnfnetlink >= @LIBNFNETLINK_MIN_VERSION@, +Requires.private: libnfnetlink >= @LIBNFNETLINK_MIN_VERSION@, \ libmnl >= @LIBMNL_MIN_VERSION@ Conflicts: Libs: -L${libdir} -lnetfilter_log diff --git a/libnetfilter_log_libipulog.pc.in b/libnetfilter_log_libipulog.pc.in index 1b7d17a..3596790 100644 --- a/libnetfilter_log_libipulog.pc.in +++ b/libnetfilter_log_libipulog.pc.in @@ -9,7 +9,7 @@ Name: libnetfilter_log_libipulog Description: Netfilter ULOG userspace compat library URL: http://netfilter.org/projects/libnetfilter_log/ Version: @VERSION@ -Requires.private: libnetfilter_log >= @VERSION@, +Requires.private: libnetfilter_log >= @VERSION@, \ libnfnetlink >= @LIBNFNETLINK_MIN_VERSION@ Conflicts: Libs: -L${libdir} -lnetfilter_log_libipulog diff --git a/src/Makefile.am b/src/Makefile.am index 203ca0c..c0f5286 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ # set age to 0. # </snippet> # -LIBVERSION = 2:0:1 +LIBVERSION = 3:0:2 IPULOG_LIBVERSION = 1:0:0 include ${top_srcdir}/Make_global.am diff --git a/src/libipulog_compat.c b/src/libipulog_compat.c index a0de3cb..4efa501 100644 --- a/src/libipulog_compat.c +++ b/src/libipulog_compat.c @@ -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; diff --git a/src/libnetfilter_log.c b/src/libnetfilter_log.c index 27a6a2d..339c961 100644 --- a/src/libnetfilter_log.c +++ b/src/libnetfilter_log.c @@ -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 * @@ -158,11 +161,6 @@ static int __nflog_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[], return gh->cb(gh, nfmsg, &nfldata, gh->data); } -static struct nfnl_callback pkt_cb = { - .call = &__nflog_rcv_pkt, - .attr_count = NFULA_MAX, -}; - /* public interface */ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h) @@ -252,6 +250,10 @@ struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh) { struct nflog_handle *h; int err; + struct nfnl_callback pkt_cb = { + .call = &__nflog_rcv_pkt, + .attr_count = NFULA_MAX, + }; h = calloc(1, sizeof(*h)); if (!h) @@ -554,7 +556,7 @@ int nflog_set_mode(struct nflog_g_handle *gh, * \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. @@ -652,6 +654,7 @@ int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz) * * - 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 0 on success, -1 on failure with \b errno set. * \par Errors @@ -975,6 +978,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; +} + +/** * @} */ @@ -1016,6 +1051,7 @@ 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 these flags with a bitwise OR. @@ -1028,10 +1064,10 @@ do { \ */ 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>"); @@ -1150,6 +1186,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; |