| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
Hithero, ulogd has only fully supported handling ARP headers that are present in
`NFPROTO_BRIDGE` packets.
Add support for handling ARP packets in their own right.
Reported-by: Slavko <linux@slavino.sk>
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Netfilter has a set of `NFPROTO_*` constants for the protocol families that it
supports, in part because it supports protocols and pseudo-protocols that do not
have `PF_*` (and `AF_*`) constants. Currently, ulogd uses `AF_*` constants for
protocol families, because it does not support any families which do not have
`AF_*` constants. Switch to `NFPROTO_*` constants instead, so we can add ARP
support later.
In the IP2* filters, retain `AF_*` for address family variables.
Remove a stray semicolon.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
| |
IP2STR and IP2BIN do all family checks inside the for-loop that converts the
address fields, whereas IP2HBIN does the checks once before the loop. Refactor
the former to do as the latter.
Also, move all the remaining contents of the for-loops, apart from the
`pp_is_valid` checks, into `ip2*` functions.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`format_ipv6()` formats IPv6 addresses as hex-strings. However, sizing for the
output buffer is not done quite right.
The elements of the `ipbin_array` array in ulogd_filter_IP2BIN.c are sized using
a local macro, `IPADDR_LENGTH`, which is defined as 128, the number of bits in
an IPv6 address; this is much larger than necessary.
Define an appropriate macro and use that instead.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
| |
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
| |
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow the plugin to fetch data from a different network namespace. This
is possible by changing the network namespace before opening the netlink
socket, and immediately changing back to the original network namespace
once the socket is open. The number of nfct_open usages here warranted a
dedicated wrapper function.
If changing back to the original network namespace fails, ulogd will
log an error, but continue to run in a different network namespace than
it was started in, which may cause unexpected behaviour. But I don't see
a way to properly "escalate" it such that ulogd aborts entirely.
Also slightly adjust the error log messages to specify which socket
failed to open.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new namespace helper provides an internal stable interface for
plugins to use for switching various linux namespaces. Currently only
network namespaces are supported/implemented, but can easily be extended
if needed. autoconf will enable it automatically if the required symbols
are available. If ulogd is compiled without namespace support, the
functions will simply return an error, there is no need for conditional
compilation or special handling in plugin code.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
| |
Update library dependencies to latest available releases.
Add examples using nftables to the README file.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
The `struct ulogd_plugin` object names have trailing g's. Remove them.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
| |
The elements of the `ipstr_array` array are `IPADDR_LENGTH` bytes long where
`IPADDR_LENGTH` is a local macro defined as 128. However, this is the number of
bits in an IPv6 address, but the elements of `ipstr_array` only need to be big
enough to be used for the output of `inet_ntop`. Use the standard
`INET6_ADDRSTRLEN` macro instead.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
| |
The ULOG target was removed from linux kernel with 7200135bc1e6
("netfilter: kill ulog targets") aka v3.17, so remove the userspace
library for it. libnetfilter_log provides the same functionality for
NFLOG, and also a compatibility layer to use NFLOG through the libipulog
api.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
The ULOG target was removed from the linux kernel with 7200135bc1e6
("netfilter: kill ulog targets") aka v3.17, so remove the input plugin
for it. It's successor NFLOG should be used instead, which has its own
input plugin.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In polling mode during normal operation, as well as in event mode with
hashtable when an overrun occurs, the hashtable is fully re-synced
against conntrack. When removing flows from the hashtable that are no
longer in conntrack, there is no way to get the actual end timestamp of
the flow from conntrack because it is already gone. Since the last
conntrack data in the hashtable for these flows will never contain an
end timestamp in this case, set_timestamp_from_ct() will always fall
back to using the current time, aka when the plugin determines that the
flow disappeared from conntrack. That is only an approximation, but
should be good enough; and certainly more accurate than no end timestamp
at all.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In event mode the hashtable is optional, and sending SIGUSR2 to ulogd will
call get_ctr_zero().
The dump_reset_handler will try to update the hashtable regardless of
whether it is used (and thus initialized), which results in a segfault
if it isn't. Instead just short-circuit the handler, and skip any
further result processing because it's not used in this case anyway.
All flow counters in conntrack are reset regardless of the return value
of the handler/callback.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Until a6fbeb96e889 ("new configuration file syntax (Magnus Boden)")
this was already caught, and the enum member is still present.
Check if the for loop worked throught the whole array without hitting a
matching config option, and return with the unknown key error code.
Because there is no existing config_entry struct with that unknwon key
to use with the established config_errce pointer, allocate a new struct.
This potentially creates a memory leak if that config_entry is never
freed again, but for me that is acceptable in this rare case.
Since the memory allocation for the struct can fail, also reuse the old
out-of-memory error to indicate that.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
| |
These are now covered by the default implementation.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
| |
Provide a default implementation for the configure hook which simply
calls ulogd_parse_configfile(), so simple plugins only need to provide
the config_keyset. This also triggers an "unknown key" error if a
plugin defines no config_keyset (aka it has no options), but the config
file contains directives for it.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The `value` union member in `struct config_entry` is declared as `int`
since basically the beginning in e07722e46001 ("config stuff added").
The parsing was switched from the original `atoi()` in 015849995f7f
("Fix hexadecimal parsing in config file") to `strtoul()`.
Switch the function for parsing to the signed `strtol()` variant since
the result will be stored in a signed int, and it makes sense to support
negative numbers. Detect when `strtol()` does not properly consume the
whole argument and return a new format error. Also check the numerical
value to make sure the signed int does not overflow, in which case
a new range error is returned.
Unfortunately there is no `strtoi()` which would do the proper range
check itself, so the intermediate `long` and range-check for `int` is
required. I also considered changing the `value` union member from
`int` to `long`, which would make it possible to use the parsed value
as-is. But since this is part of the api towards plugins (including
third party) such a potentially breaking change felt unwarranted. This
also means that still only 16bit integer values are *guaranteed* to
work, although most platforms use bigger widths for int.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
Replace all usages of `config_parse_file()` in plugins with the new
`ulogd_parse_configfile()` function, adding error handling where it was
missing. I used the same codestyle as the surrounding code, which varies
between plugins.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Provide a new function `ulogd_parse_configfile()` in the public
interface, which wraps `parse_config_file()` to parse a section of the
config file and communicates found errors to the user. It can be used
as a drop-in replacement because arguments and return value are
compatible.
This relieves plugins of the need to translate the individual error
codes to human readable messages, and plugins are mostly interested if
there is any error, not what specific error.
This reuses the existing `parse_conffile()` function with slight
adjustments.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add two new dedicated fields to provide the ICMPv6 code and type. While
libnetfilter_conntrack uses the same attribute for both ICMPv4 and v6,
there are no version-agnostic ICMP IEs in IPFIX.
The fields are annotated with the appropriate IPFIX metadata, which is
currently not actually used anywhere. You may call it consistency,
future-proofing or cargo-culting.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a config directive is provided with a malformed argument (e.g.
`loglevel="1`), then the call to get_word() returns NULL and `wordbuf`
is left unchanged aka still contains the directive name. Unlike the
previous calls to get_word(), the return value is not checked here, and
processing continues with `args` pointing to the still unchanged
`wordbuf`. So `loglevel="1` is effectively parsed as
`loglevel=loglevel`.
Instead if no valid argument is found, ignore the directive and log a
warning.
Due to the way get_word() is implemented, this unfortunately will report
an empty argument (e.g. `loglevel=`) as malformed as well. Ideally that
should behave the same as `loglevel=""`, but I found no nice way to
achieve that. An empty argument is only useful in rare cases, so
treating it as malformed should be fine for now. That's still way better
than the previous broken "name as value" behaviour.
Fixes: e88384d9d5a1 ("added new generic get_word() function to do better parsing")
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
Consistently use the return jump to close the config file descriptor if
opened, to prevent it from leaking.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When deciding whether to call the stop hook of a plugin instance, only
two things are relevant: If the plugin actually has a stop hook defined,
and if the plugin instance is still used in a different stack. The
private data of a plugin instance is opaque to ulogd, so its size or
content are irrelevant to the stop-hook decision. And in the same vein
should ulogd never write to it.
The one-null-byte write could previously lead to an out-of-bounds write
on plugins with a stop hook and zero-size private data.
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I am not sure what this timer was meant to do. My best guess is to send
an ipfix message every second if there is data, as to make sure reports
go out in a timely manner. Otherwise a message is only sent when adding
another flow would go past the max mtu, which may take a while if there
isn't much (filtered) traffic.
Timers in ulogd only fire once; if they should fire repeatedly (which I
guess was the intention here), they need to be re-armed in the callback.
Because that wasn't done, the timer only fired once 1 second after
starting the plugin (when there is unlikely any data yet), and then
never again.
The timer is now re-armed in the callback to make it fire repeatedly
every second(ish). A macro is used to make sure the initial and re-arm
time interval is the same.
Fixes: 4f639231c83b ("IPFIX: Add IPFIX output plugin")
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
Do the same as the oprint plugin: let inet_ntop() write to a temporary
buffer, and then write that buffer content and the trailing comma to the
actual output buffer in one go.
Fixes: f04bf6794d11 ("gprint, oprint: use inet_ntop to format ip addresses")
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
| |
Fixes: 4bc3b22e426d ("NFCT: add `reliable' config option to enable reliable flow-based logging")
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The first argument to calloc() is the number of elements, the second is
the size of a single element. Having the arguments switched shouldn't
make any difference during runtime, but GCC warns about it when using
-Wcalloc-transposed-args [0].
[0] https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wcalloc-transposed-args
Signed-off-by: Corubba Smith <corubba@gmx.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
The old links were outdated for ages; let's bring the README in sync
with reality.
Signed-off-by: Harald Welte <laforge@gnumonks.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
| |
Move a `ULOGD_RET_BOOL` case for consistency.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
| |
Currently, the plug-in assumes that all IP addresses are 32-bit ipv4
addresses, so ipv6 addresses get truncated and inserted as garbage.
Insert nulls instead.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Hitherto we have bound ipv4 addresses as 64-bit ints and 64-bit ints as
32-bit.
Move a `ULOGD_RET_BOOL` case for consistency and fix some nearby
formatting.
Fix some nearby formatting.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
| |
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
| |
Replace hand-rolled ipv4-only formatting code in order to be able to
support ipv6 addresses. This also changes the byte-order expected by
oprint from HBO to NBO.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
This plug-in expects ipv4 addresses. Check the length of the key value
in order to filter out ipv6 addresses.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
By using `okey_set_u128` we keep track of the address size and
downstream plug-ins can distinguish the address family.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
| |
Keys of type `ULOGD_RET_IPADDR` may be ipv4 or ipv6. ARP protocol
addresses are 32-bits (i.e., ipv4). By using `okey_set_u32` we keep
track of the size and allow downstream plug-ins to handle them
correctly.
Reported-by: Robert O'Brien <robrien@foxtrot-research.com>
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
| |
Everywhere else ipv4 addresses are left in NBO until output. The only
exception is the IP2HBIN filter, which is explicitly intended to convert
from NBO to HBO.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
Replace comma with semicolon.
Fixes: d4cf078cb71a ("add ukey_* function for key assignation")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
| |
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
| |
Use a more modern alternative to bzip2.
Suggested-by: Jan Engelhardt <jengelh@inai.de>
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Invalid read of size 4
at 0x405F60: ulogd_unregister_fd (select.c:74)
by 0x4E4E3DF: ??? (in /usr/lib/ulogd/ulogd_inppkt_NFLOG.so)
by 0x405003: stop_pluginstances (ulogd.c:1335)
by 0x405003: sigterm_handler_task (ulogd.c:1383)
by 0x405153: call_signal_handler_tasks (ulogd.c:424)
by 0x405153: signal_channel_callback (ulogd.c:443)
by 0x406163: ulogd_select_main (select.c:105)
by 0x403CF3: ulogd_main_loop (ulogd.c:1070)
by 0x403CF3: main (ulogd.c:1649)
Problem is that ulogd_inppkt_NFLOG.c::stop() calls ulogd_unregister_fd()
which does llist_del(). This llist_del may touch ->prev pointer.
As the list element is in private data, we cannot do this llist_del
from stop_pluginstances().
Therefore, the free() process moved location after finishing ulogd_unregister_fd().
Signed-off-by: Kyuwon Shim <kyuwon.shim@alliedtelesis.co.nz>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If ulogd2 receives a signal it will attempt to re-open the pcap output
file. If this fails (because the permissions or ownership have changed
for example), the FILE pointer will be null and when the next packet
comes in, the null pointer will be passed to fwrite and ulogd will
crash.
Instead, assign the return value of `fopen` to a local variable, and
only close the existing stream if `fopen` succeeded.
Link: https://bugs.launchpad.net/ubuntu/+source/ulogd2/+bug/1429778
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
Instead of statting the file, and choosing the mode with which to open
it and whether to write the PCAP header based on the result, always open
it with mode "a" and _then_ stat it. This simplifies the flow-control
and avoids a race between statting and opening.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When using mysql_config and pcap_config to configure `CFLAGS`, one
requests the actual flags:
$mysql_config --cflags
$pcap_config --cflags
By constrast, when using pg_config, one requests the include-directory:
$pg_config --includedir
Therefore, the `-I` option has to be explicitly added.
Fixes: 20727ab8b9fc ("build: use pkg-config or pg_config for libpq")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
| |
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
Some of the output plug-ins don't handle 64-bit signed values.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
| |
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The types of `ip_totlen` in the `ulog` view and the `INSERT_IP_PACKET_FULL`
function are `integer`, but the column in the `ulog2` table is `smallint`. The
"total length" field of an IP packet is an unsigned 16-bit integer, whereas
`smallint` in PostgreSQL is a signed 16-bit integer type. Change the type of
`ulog2.ip_totlen` to `integer`.
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1556
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|