summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2013-03-12 05:44:12 +0000
committerPablo Neira Ayuso <pablo@netfilter.org>2013-04-02 00:08:49 +0200
commit1ac30c97c339957b6e3c5cf571de7bc38c827730 (patch)
treed00e6f632b49a2a3ffcae1aa8d38701db9e1ee33
parente0a0dd703b3448f0f07fc59b7232bf1f1cce7b86 (diff)
utils: nfbpf_compile
A BPF compiler to convert tcpdump expressions to the decimal format accepted by the libxt_bpf. Generate a file and pass that to iptables: nfbpf_compile RAW 'udp dst port 9000' > test.bpf iptables -A OUTPUT -m bpf --bytecode-file test.bpf -j LOG Or pass the output directly to iptables using backticks: iptables -A INPUT -m bpf --bytecode \ "`./nfbpf_compile RAW 'udp dst port 9000'" -j LOG This utility depends on libpcap. The library is only compiled if the option --enable-bpf-compiler is explicitly passed to ./configure and libpcap is found. Pablo has mangled the original patch to rename the utility to nfbpf_compile. Also modified the output to match exactly what -m bpf --bytecode needs. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac4
-rw-r--r--utils/Makefile.am14
-rw-r--r--utils/nfbpf_compile.c55
4 files changed, 71 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am
index 6400ba41..c38d3600 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,9 +10,7 @@ endif
if ENABLE_LIBIPQ
SUBDIRS += libipq
endif
-if HAVE_LIBNFNETLINK
SUBDIRS += utils
-endif
# Depends on libxtables:
SUBDIRS += extensions
# Depends on extensions/libext.a:
diff --git a/configure.ac b/configure.ac
index 2ba5cecb..06204665 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,9 @@ AC_ARG_ENABLE([devel],
[enable_devel="$enableval"], [enable_devel="yes"])
AC_ARG_ENABLE([libipq],
AS_HELP_STRING([--enable-libipq], [Build and install libipq]))
+AC_ARG_ENABLE([bpf-compiler],
+ AS_HELP_STRING([--enable-bpf-compiler], [Build bpf compiler]),
+ [enable_bpfc="yes"])
AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
@@ -88,6 +91,7 @@ AM_CONDITIONAL([ENABLE_IPV6], [test "$enable_ipv6" = "yes"])
AM_CONDITIONAL([ENABLE_LARGEFILE], [test "$enable_largefile" = "yes"])
AM_CONDITIONAL([ENABLE_DEVEL], [test "$enable_devel" = "yes"])
AM_CONDITIONAL([ENABLE_LIBIPQ], [test "$enable_libipq" = "yes"])
+AM_CONDITIONAL([ENABLE_BPFC], [test "$enable_bpfc" = "yes"])
PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
[nfnetlink=1], [nfnetlink=0])
diff --git a/utils/Makefile.am b/utils/Makefile.am
index f1bbfc52..bfafd1d0 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -4,7 +4,17 @@ AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include \
-I${top_srcdir}/include ${libnfnetlink_CFLAGS}
-sbin_PROGRAMS = nfnl_osf
-pkgdata_DATA = pf.os
+sbin_PROGRAMS =
+pkgdata_DATA =
+
+if HAVE_LIBNFNETLINK
+sbin_PROGRAMS += nfnl_osf
+pkgdata_DATA += pf.os
nfnl_osf_LDADD = -lnfnetlink
+endif
+
+if ENABLE_BPFC
+sbin_PROGRAMS += nfbpf_compile
+nfbpf_compile_LDADD = -lpcap
+endif
diff --git a/utils/nfbpf_compile.c b/utils/nfbpf_compile.c
new file mode 100644
index 00000000..2c46c7b0
--- /dev/null
+++ b/utils/nfbpf_compile.c
@@ -0,0 +1,55 @@
+/*
+ * BPF program compilation tool
+ *
+ * Generates decimal output, similar to `tcpdump -ddd ...`.
+ * Unlike tcpdump, will generate for any given link layer type.
+ *
+ * Written by Willem de Bruijn (willemb@google.com)
+ * Copyright Google, Inc. 2013
+ * Licensed under the GNU General Public License version 2 (GPLv2)
+*/
+
+#include <pcap.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ struct bpf_program program;
+ struct bpf_insn *ins;
+ int i, dlt = DLT_RAW;
+
+ if (argc < 2 || argc > 3) {
+ fprintf(stderr, "Usage: %s [link] '<program>'\n\n"
+ " link is a pcap linklayer type:\n"
+ " one of EN10MB, RAW, SLIP, ...\n\n"
+ "Examples: %s RAW 'tcp and greater 100'\n"
+ " %s EN10MB 'ip proto 47'\n'",
+ argv[0], argv[0], argv[0]);
+ return 1;
+ }
+
+ if (argc == 3) {
+ dlt = pcap_datalink_name_to_val(argv[1]);
+ if (dlt == -1) {
+ fprintf(stderr, "Unknown datalinktype: %s\n", argv[1]);
+ return 1;
+ }
+ }
+
+ if (pcap_compile_nopcap(65535, dlt, &program, argv[argc - 1], 1,
+ PCAP_NETMASK_UNKNOWN)) {
+ fprintf(stderr, "Compilation error\n");
+ return 1;
+ }
+
+ printf("%d,", program.bf_len);
+ ins = program.bf_insns;
+ for (i = 0; i < program.bf_len-1; ++ins, ++i)
+ printf("%u %u %u %u,", ins->code, ins->jt, ins->jf, ins->k);
+
+ printf("%u %u %u %u\n", ins->code, ins->jt, ins->jf, ins->k);
+
+ pcap_freecode(&program);
+ return 0;
+}
+