Commit 71e07938 authored by 's avatar

Added a generalized bpfcompiler library designed for building static

(non-algoritmic) filters.

Added the hardware DSM filtering/preclassification support for DAG cards.
BPF_FILTER function is now able to probram the hardware capturer to only
send interesting packets and thus lower the main CPU heating.

dagflib's PKT_COUNTER and BYTE_COUNTER are fixed for more DAG models.

Argument `internal' of mapid_apply_function() changed to bitwise `flags',
so mapidagdrv can instruct the dagflib's BPF_FILTER instance to give up
when it is needed.

For more info see updated mapi_dagflib(1) and bpf2dagdsm(1) manpages.

Fixed some apparent bugs and/or warnings in the code.


git-svn-id: file:///home/svn/mapi/trunk@1212 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 13f48d40
......@@ -10,3 +10,4 @@ description=Offline dag-capture
[dag]
ipf_loader_bin=dag_ipf_loader.sh
dsm_loader_bin=/path/to/dsm_loader
......@@ -289,9 +289,12 @@ AS_HELP_STRING([--enable-dag], [Enable support for Endace's DAG cards]),
esac], [dag=false])
AM_CONDITIONAL(DRIVER_DAG, test x$dag = xtrue)
AM_CONDITIONAL(BINARY_DAGFLIB, test x$dag = xtrue)
AM_CONDITIONAL(PRECLASSIFICATION, test x$dag = xtrue)
if test x$dag = xtrue; then
MAPI_CONF_DAG_ENTRY=$srcdir/config/mapi.conf.dag.entry
MAPI_FUNC_LIBS="${MAPI_FUNC_LIBS}:dagflib.so"
AC_DEFINE(PRECLASSIFICATION, 1, [hardware preliminary packet classification])
AC_DEFINE(WITH_DAG, 1, [if DAG cards are supported])
AC_MSG_RESULT(yes)
else
MAPI_CONF_DAG_ENTRY=/dev/null
......@@ -487,7 +490,7 @@ AS_HELP_STRING([--with-libdag=DIR], [Manual libdag path configuration, in case t
owd=`pwd`
if cd $withval; then withval=`pwd`; cd $owd; fi
DAGINC="-I$withval/include"
DAGLIB="-L$withval/lib -ldag -ldagconf -ldag37t -ldagema -lpthread"
DAGLIB="-L$withval/lib -ldag -ldagconf -ldagdsm -ladt -lm -ldag37t -ldagema -lpthread"
else
AC_MSG_ERROR(dagapi.h or libdag.a not found in $withval/include and $withval/lib)
fi
......@@ -497,15 +500,15 @@ AS_HELP_STRING([--with-libdag=DIR], [Manual libdag path configuration, in case t
[ if test x$dag = xtrue; then
if test -f ${prefix}/include/dagapi.h -a -f ${prefix}/lib/libdag.a; then
DAGINC="-I${prefix}/include"
DAGLIB="-L${prefix}/lib -ldag -ldagconf -ldag37t -ldagema -lpthread"
DAGLIB="-L${prefix}/lib -ldag -ldagconf -ldagdsm -ladt -lm -ldag37t -ldagema -lpthread"
elif test -f /usr/local/include/dagapi.h -a -f /usr/local/lib/libdag.a; then
DAGINC="-I${prefix}/include"
DAGLIB="-L${prefix}/lib -ldag -ldagconf -ldag37t -ldagema -lpthread"
DAGLIB="-L${prefix}/lib -ldag -ldagconf -ldagdsm -ladt -lm -ldag37t -ldagema -lpthread"
elif test -f /usr/include/dag/dagapi.h; then
DAGINC="-I/usr/include/dag"
DAGLIB="-ldag -ldagconf -ldag37t -ldagema -lpthread"
DAGLIB="-ldag -ldagconf -ldagdsm -ladt -lm -ldag37t -ldagema -lpthread"
elif test -f /usr/include/dagapi.h; then
DAGLIB="-ldag -ldagconf -ldag37t -ldagema -lpthread"
DAGLIB="-ldag -ldagconf -ldagdsm -ladt -lm -ldag37t -ldagema -lpthread"
else
AC_MSG_RESULT(no)
AC_MSG_ERROR([libdag not found])
......@@ -785,6 +788,8 @@ AC_CONFIG_FILES([
src/trackflib/Makefile
src/ipfixflib/Makefile
src/anonflib/Makefile
src/bpfcompiler/Makefile
src/bpfcompiler/pcap/Makefile
src/dagflib/Makefile
src/extraflib/Makefile
doc/Makefile
......
......@@ -26,7 +26,7 @@ clean:
rm -rf *.aux *.bbl *.blg *.log *.dvi *.toc *.lof mapitutor.ps *.bak man_mapi*tex
dist_man_MANS = mapi.3 mapi_stdflib.3 mapi_dagflib.3 mapi_extraflib.3 mapi_trackflib.3 mapi_anonflib.3
dist_man_MANS = mapi.3 mapi_stdflib.3 mapi_dagflib.3 mapi_extraflib.3 mapi_trackflib.3 mapi_anonflib.3 bpf2dagdsm.1
EXTRA_DIST = ipfixlib.txt \
mapi_functions_tutorial.pdf \
......
.TH "BPF2DAGDSM" 1 "April 2007"
.SH NAME
bpf2dagdsm \- convert multiple BPF expressions to Endace DSM filter XML specification
.SH "SYNOPSIS"
.ad l
.hy 0
.HP 10
\fBbpf2dagdsm\fR [\fI--max-filters=<number>\fR] [\fI--always-match\fR] <bpf_expressions_file >config.xml
.ad
.hy
.SH "DESCRIPTION"
Note: For complete understanding this text you should read the DAG card
documents first, particularly the one about \fBData Stream Management\fR
(DSM).
This program converts the Berkeley Packet Filter (\fBBPF\fR) expressions
(well-known as used by \fItcpdump\fR(8)) to \fBXML\fR filter configuration for
Endace \fBDAG\fR cards that are using the \fBDSM\fR classification. The
resulting XML file can be used as the input for Endace's
\fIdsm_loader\fR executable to program the hardware filter.
The input is expected on stdin; one complete BPF expression per line (empty
lines are ignored, but counted). Each expression is parsed, compiled into
internal node tree, transformed to Disjunctive Normal Form (DNF, that is
OR-of-ANDs) and broken down to atomic filters.
For each atomic filter one DAG hardware filter is used. The resulting single
XML configuration file (printed on stdout) describes all analyzed BPF
expressions.
After each group of <filter> elements is followed by the XML <!--comment-->
block. It contains lines like this one (started with special text tag):
$DAG-DSM-TAG$ bpf-index:3 filters-used:00110000
The `\fBbpf-line-number\fR' value is the number of the input line the BPF
expression was on. The `\fBfilters-used\fR' is the bit array describing the
association between the BPF expression and hardware filters. The filters are
indexed from zero on the left side. The line above says that the hardware
filters #2 and #3 was allocated for BPF expression on input line 3.
On the next comment line the originating BPF expression is copied (not
shown here).
The line tagged with $DAG-DSM-TAG$ helps the caller to quickly re-analyze the
XML output, construct the filter bitmasks and match triggered filters back with
BPF expressions. For easy parsing, both values on tagged line are preceded
by the colon (:) and followed by a tab character.
The entire XML configuration is finalized in the way that all packets matching
at least one hardware filter are passed to DAG stream 0 (first input stream).
Other packets are dropped, but see the option --always-match below for
exception.
.SH "OPTIONS"
.TP
\fB--max-filters=<number>\fR
When the caller knows the number of hardware filters supported by the DAG card
before calling the \fIbpf2dagdsm\fR, that number can be passed using this option.
When the total number of filters needed by analyzed configuration exceeds the
max-filters value, no XML output is printed. Instead the appropriate error
message is sent do stderr and return code is nonzero.
This is the safety measure, because the \fIdsm_loader\fR blindly loads
everything until all hardware filters are filled and omits the rest.
Then this damaged DAG card configuration is activated. This option allows for
detection of such error and skipping the call of \fIdsm_loader\fR.
.TP
\fB--always-match\fR
This options merely adds one final OR-able condition to the partials hardware
lookup table: the negation of the first defined filter.
The result is, that all packets (even those not matching the previous filters)
are also accepted (not filtered out by the DAG card). The triggered filters
can still be recognized by analyzing the ERF header. Using this option, the
DAG card stops filtering and becomes the packet classification machine.
.SH "RESTRICTIONS"
Unfortunately, only a subset of BPF expression features is implemented. This
is mainly due to the fact that the original BPF is a machine language,
processing the true algorithm for each examined packet. On the other hand,
DSM-driven hardware can only match static bitmasked filters. So all BPF
constructs that require "runtime" computation must have been omited.
Also currently the program is capable of generating only DAG filters using
symbolic XML elements (called "virtual" by Endace), not "raw" filters
containing direct maskable true/false values for every bit in the first 64
bytes of the packets captured. Therefore in the present time only the source
or destination IPv4 addresses of Ethernet frames can be matched. Additionally,
filters can specify TCP or UDP source or destination ports.
.SH "RETURN VALUE"
.TP
0
Entire XML filter successfully constructed and printed out.
.TP
!= 0
Error occured or help text printed. The problem is described on stderr.
.SH TODO
The program should be able to re-use duplicate filters, probably by comparing
their string representation generated by function print_node().
......@@ -2,40 +2,50 @@
.\" for a quick overview:
.\" nroff -man -Tascii mapi_dagflib.3 |less
.\"
.TH MAPI_DAGFLIB 3 "December, 2006"
.TH MAPI_DAGFLIB 3 "April 2007"
.SH NAME
MAPI dagflib \- Endace DAG Function Library
.SH SYNOPSIS
.nf
\fBINTERFACE\fP Selects packets from a specific DAG interface only
\fBDAGIPF_BPF_FILTER\fP Filters the packets of a flow using hardware
\fBBPF_FILTER\fP Filters the packets of a flow using the DSM hw filter
\fBDAGIPF_BPF_FILTER\fP Filters the packets of a flow using the IPF hw filter
\fBPKT_COUNTER\fP Keeps the number of frames seen by a network flow
\fBBYTE_COUNTER\fP Keeps the number of bytes seen by a network flow
\fBPKTBYTE_COUNTER\fP Atomic combination of PKT_COUNTER and BYTE_COUNTER
\fBPKTBYTE_COUNTER\fP Atomic combination of \fBPKT_COUNTER\fR and \fBBYTE_COUNTER\fR
.fi
.SH DESCRIPTION
This library provides functions intended to better use the capabilities of
the DAG capturing card hardware (produced by Endace), thus to alleviate the
main CPU burden. Once applied to DAG bound flow, the function from dagflib
is tried first. In case it cannot be installed, the correspondingly named
software function from stdflib is used instead (if existing). See
is tried first. In case it cannot be used for whatever reason, the
correspondingly named software function from stdflib is used instead
(if exists). See
.BR mapi_stdflib (3).
.BR INTERFACE ,
.B DAGIPF_BPF_FILTER
and
.B PKTBYTE_COUNTER
do not have a counterpart in stdflib, so the the failing
instantiation/initialization does not have where to fallback.
do not have a counterpart in stdflib, so the failing instantiation does not
have where to fallback.
The DAG version 4.3GE (with coprocessor) is supported so far.
For IPF filtering, the DAG version 4.3GE (with coprocessor) is currently
supported. DSM filtering is enabled for all DAG cards claiming DSM support
(e.g. DAG 6.2). The number of hardware filters is hardwired to 8. For more
information about DSM, see the
.BR bpf2dagdsm (1)
manpage from this package or Endace documentation.
To implement these unusual functions it was necessary to tweak several MAPI
internals.
.SH FUNCTIONS
.TP
.BI "INTERFACE (int " ifnumber ")"
Software function to pass only frames originating from the DAG interface
(AKA port) identified by
Software function (not touching the hardware) to pass only frames originating
from the DAG interface (AKA port) identified by
.IR ifnumber .
Even when this is software function, its existence in the flow is honoured
......@@ -44,6 +54,26 @@ by
(see below) functions installed later to the flow. Counting functions then
return statistics for the appropriate DAG interface only.
Type of results: \fBnone\fP.
.\"--------------------------------------------------------
.TP
.BI "BPF_FILTER (char *" expression ")"
Programs the DAG card's hardware DSM filter so in result, only packets matching the
filtering \fIexpression\fR (which is in the syntax used by \fBtcpdump\fR(8))
will pass over this func in the flow.
The \fIexpression\fR is compiled into a XML format and fed to Endace's utility
.BR dsm_loader (1)
executed on the background by mapid. The path to this binary is expected in the variable
.I dsm_loader_bin
in the section
.I [dag]
of the MAPI configuration file
.BR mapi.conf .
The \fBBPF_FILTER\fR implementation is rather tricky and is described below
under \fBDSM IMPLEMENTATION\fR.
Type of results: \fBnone\fP.
.\"--------------------------------------------------------
.TP
......@@ -118,6 +148,45 @@ below.
Type of results: 2 * \fBunsigned long long\fP.
.fi
.\"--------------------------------------------------------
.SH DSM IMPLEMENTATION
BPF expression compiler is needed, so MAPI carries one. For more details see
\fBbpf2dagdsm\fR(1) describing a program using the bpfcompiler library as well
as some notable language restrictions.
Each of the \fBBPF_FILTER\fR functions occupies one or more OR-ed hardware
filters in the DAG capturing card. There are 8 filters available.
Being in the DSM mode, the DAG card sends special "colored" ERF records
containing the bit-array describing which filters matched the packet.
Main reason to implement DSM in MAPI was to alleviate the load of the CPU
running mapid when monitoring thick pipes. The DAG filtering hardware should
always be instructed to pass only interesting packets to the software.
Interesting means that any active MAPI flow expressed the interest.
This requires special handling:
In simple case, when the sum of all successfully initialized dagflib
\fBBPF_FILTER\fR functions in all flows fit to 8 hardware filters, the DAG
capturing card is in the \fIfiltering\fR mode, providing only packets matching
any of the \fBBPF_FILTER\fR's \fIexpression\fR. Every function then decides
the matching condition according to ERF \fIcolor\fR (see above), because
it knows its filtering mask.
In other case (\fBBPF_FILTER\fR init error, incompatible leading software
function requesting all packets captured, etc.) the DSM filter is turned
into the \fIpreclassification\fR (AKA always-match) mode. Now the coloring
masking still works for successfully initialized dagflib \fBBPF_FILTER\fR
functions, but also packets not matching any filter are provided.
The complete filter inspecting all active flows is rebuilt in each
\fImapi_connect\fR() and \fImapi_close_flow\fR(). Also read-only building of
the entire filter is made upon the instantiation of dagflib's
\fBBPF_FILTER\fR when it is needed to decide whether the new function will
overflow the number of available hardware filters and therefore stdflib's
version should be used instead (of course, this leads to
\fIpreclassification\fR mode).
.\"--------------------------------------------------------
.SH STATUS API
The statistical functions
......@@ -125,7 +194,7 @@ The statistical functions
are implemented as getters of the DAG hardware
registers
.B kUint64AttributeRxFrames
and
(\fBkUint64AttributeGoodPackets\fR for DAG 6.2) and
.B kUint64AttributeRxBytes
(see
.I Configuration & Status API Programming Guide
......@@ -137,7 +206,7 @@ the counters for all interfaces are latched and the difference values from
the last reading are added to mapid internal counters. In respect to
preceding existence of
.B INTERFACE
function in the flow, appropriate value is returned.
function in the flow, appropriate sub-value is returned.
These function can be applied to the DAG-bound flow only in case no modifying or
filtering (except
......@@ -148,6 +217,8 @@ stdflib's counterparts in case the DAG Status API failed to initialize.
.SH BUGS
Please send bug reports to mapi@uninett.no
.SH "SEE ALSO"
.BR bpf2dagdsm (1),
.BR dsm_loader (1),
.BR mapi (3),
.BR mapi_stdflib (3),
.BR mapi_trackflib (3),
......
......@@ -11,13 +11,14 @@ BUILD_anonflib = anonflib
endif
if BINARY_DAGFLIB
BUILD_dagflib = dagflib
BUILD_bpfcompiler = bpfcompiler
endif
if BINARY_EXTRAFLIB
BUILD_extraflib = extraflib
endif
# common must be built first
SUBDIRS = common lib drivers stdflib \
SUBDIRS = common lib $(BUILD_bpfcompiler) drivers stdflib \
$(BUILD_trackflib) \
$(BUILD_ipfixflib) \
$(BUILD_anonflib) \
......
......@@ -424,10 +424,6 @@ static int anonymize_instance(mapidflib_function_instance_t *instance,
return MFUNCT_INVALID_ARGUMENT_4;
}
mapidlib_instance_t *i;
i = flow_mod->mi;
data=(struct anonymize_data *)malloc(sizeof(struct anonymize_data));
data->protocol=protocol;
data->field=field_description;
......
This product includes software developed by the University of California,
Lawrence Berkeley Laboratory and its contributors.
Petr Zejdl <zejdlp1@fel.cvut.cz>
Vlada Macek <macek@sandbox.cz>
LICENSE TERMS
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. Neither the name of the Company nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
ALTERNATIVELY, provided that this notice is retained in full, this
product may be distributed under the terms of the GNU General Public
License (GPL) version 2 or later, in which case the provisions
of the GPL apply INSTEAD OF those given above.
THIS SOFTWARE IS PROVIDED ``AS IS'', AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# set the include path found by configure
INCLUDES=-I..
# the library search path.
SUBDIRS = pcap
# install extraflib into $(prefix)/share/mapi/
libdir = $(pkgdatadir)
libbpfcompiler_la_LDFLAGS = -avoid-version -no-undefined
lib_LTLIBRARIES = libbpfcompiler.la
libbpfcompiler_la_LIBADD = pcap/libpcap.la
libbpfcompiler_la_SOURCES = bpf_compile.c bpf_compile.h bpf_grammar.c \
bpf_grammar.h bpf.h bpf_lexical.c bpf_node.c bpf_node.h bpf_pcap.h bpf_transform.c \
bpf_combo6.c bpf_dagdsm.c utils.c utils.h bpf_combo6.h bpf_dagdsm.h
noinst_PROGRAMS = bpftest
bin_PROGRAMS = bpf2dagdsm
bpftest_LDADD = libbpfcompiler.la
bpftest_SOURCES = bpftest.c
bpf2dagdsm_LDADD = libbpfcompiler.la
bpf2dagdsm_SOURCES = bpf2dagdsm.c
# bison should become something like $(BISON)
bpf_grammar.c bpf_grammar.h: bpf_grammar.y
bison -d -obpf_grammar.c bpf_grammar.y
# flex should become something like $(FLEX)
bpf_lexical.c: bpf_lexical.l
flex -obpf_lexical.c bpf_lexical.l
DISTCLEANFILES = bpf_grammar.c bpf_grammar.h bpf_lexical.c
This package provides a library to parse the subset of Berkeley Packet Filter
(BPF) expression language into the target independent node tree. Parser is
based on the libpcap library source.
Also some output routines are provided either:
1) to create a filter for COMBO6 network adaptors,
2) to create a XML configuration for Endace DAG network capturing cards using
the DSM filtering.
For more details see the manpage bpf2dagdsm.1 and script test_bpf2dagdsm for
example usage.
- Add support for config.h into source files and specially into pcap files
- Invesigate ARP/RARP (genhost_op src,dst offset)
- Memory leak in bpf_lexical.c
/*
*
* LICENSE TERMS
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this
* product may be distributed under the terms of the GNU General Public
* License (GPL) version 2 or later, in which case the provisions
* of the GPL apply INSTEAD OF those given above.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'', AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <stdarg.h>
#include "debug.h"
#include "utils.h"
#include "bpfcompiler.h"
#define FATAL(str, rest...) fatal("internal error in %s:%d: " str "\n", __FILE__, __LINE__, ## rest)
void fatal(const char *fmt, ...)
__attribute__((noreturn, format (printf, 1, 2)));
void fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(-1);
}
void usage(char *progname)
{
fprintf(stderr, "Usage: %s [--max-filters=<number>] [--always-match]\n", progname);
exit(100);
}
void parse_args(int argc, char **argv, int *max_filters, int *always_match)
{
int i;
*always_match = 0;
*max_filters = INT_MAX;
for (i=1; i<argc; i++) {
if (!strncmp("--max-filters=", argv[i], 14)) {
*max_filters = atoi(argv[i] + 14);
if (*max_filters < 1)
usage(argv[0]);
} else if (!strcmp("--always-match", argv[i])) {
(*always_match)++;
} else if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) {
usage(argv[0]);
} else
fatal("%s: Unknown or misformatted parameter '%s'. Use --help for help.\n", argv[0], argv[i]);
}
}
int main(int argc, char **argv)
{
char errbuf[BPF_ERRBUF_SIZE], inbuf[4096], *output;
int lineno = 0, max_filters, always_match, filter_count;
dagdsm_bpf_filter_t *filter = NULL;
parse_args(argc, argv, &max_filters, &always_match);
while (fgets(inbuf, sizeof(inbuf), stdin)) {
char *p = strchr(inbuf, '\n');
lineno++;
if (!p)
fatal("%s: Fatal error, the length of input line %d is above %d bytes.\n", argv[0], lineno, sizeof(inbuf)-1);
*p = '\0';
if (inbuf[0] == '\0')
continue;
/* Compile BPF filter */
if ((filter = dagdsm_bpf_compile(filter, inbuf, lineno, errbuf)) == NULL)
fatal("%s: Compilation error on input line %d: %s\n", argv[0], lineno, errbuf);
DEBUG_CMD3(fprintf(stderr, "line %d filtermask 0x%08x\n", lineno, dagdsm_bpf_get_last_usage_mask(filter)));
}
filter_count = dagdsm_bpf_get_filter_count(filter);
if (filter_count > max_filters)
fatal("%s: The number of filters needed (%d) exceeds the given limit (%d).\n", argv[0], filter_count, max_filters);
/* Write the filter to DAGDSM configuration output file. */
output = dagdsm_bpf_xprintf(filter, always_match);
/* Free resources allocated for the filter. */
if (filter != NULL)
dagdsm_bpf_free(filter);
printf(output);
free(output);
return EXIT_SUCCESS;
}
This diff is collapsed.
/*
*
* LICENSE TERMS
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this
* product may be distributed under the terms of the GNU General Public
* License (GPL) version 2 or later, in which case the provisions
* of the GPL apply INSTEAD OF those given above.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'', AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _BPF_COMBO6_H_
#define _BPF_COMBO6_H_
typedef struct combo6_filter {
int nrules; /* Number of rules in this (sub)filter */
char **rules; /* Rules in the text form */
int filter_output; /* Output 32-bit WORD for LUP */
int interface; /* Interface mask */
} combo6_filter_t;
struct combo6_bpf_filter {
int nfilters; /* Number of subfilters in this filter */
combo6_filter_t **filters; /* Stored filters */
int filter_default; /* Default 32-bit WORD for LUP */
};
#endif /* _BPF_COMBO6_H_ */
/*
*
* LICENSE TERMS
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this
* product may be distributed under the terms of the GNU General Public
* License (GPL) version 2 or later, in which case the provisions
* of the GPL apply INSTEAD OF those given above.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'', AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <stdarg.h>
#include <string.h>
#include "utils.h"
#include "bpfcompiler.h"
#include "bpf_compile.h"
#include "bpf_node.h"
/* Locals */
/*static*/ jmp_buf bpf_error_jmp;
/*static*/ int bpf_error_set = 0;
/*static*/ char *bpf_errbuf;
static node_t *root;
/* String list */
static string_t *string_head = NULL;
/*
* error handling
*/
void bpf_error(const char *fmt, ...)
{
va_list ap;
if (!bpf_error_set) {
fprintf(stderr, "bpfcompiler internal error: error function not set!\n");
exit(-1);
}
va_start(ap, fmt);
if (bpf_errbuf != NULL) {
(void)vsnprintf(bpf_errbuf, BPF_ERRBUF_SIZE, fmt, ap);
}
va_end(ap);
longjmp(bpf_error_jmp, 1);
}
/*
* syntax error
*/
inline void syntax()
{
bpf_error("syntax error in filter expression");
}