aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2015-07-10 10:02:39 +0000
committerTimo Teräs <timo.teras@iki.fi>2015-07-10 10:02:39 +0000
commitae0a68846daaa3b0bd7b25f42a15455f8f16fa7c (patch)
treeb306dd3b87e6b801d7120b0b58954e9eed01bd3f
parente2bffbbfbf403fb8b03b01fda7c6eae336240fe5 (diff)
downloadalpine_aports-ae0a68846daaa3b0bd7b25f42a15455f8f16fa7c.tar.bz2
alpine_aports-ae0a68846daaa3b0bd7b25f42a15455f8f16fa7c.tar.xz
alpine_aports-ae0a68846daaa3b0bd7b25f42a15455f8f16fa7c.zip
main/fprobe-ulog: migrate to nflog api
ULOG is no longer present in kernels we use. The compat library is deficient and does not support e.g. mapping of interface names or timestamps. This patch updates the code to use nflog natively and removes the ifindex to name mappings using syscalls so this improves performance too. (cherry picked from commit a7717ec784fd112e74ca5a5ddf6da8a59d742049) (cherry picked from commit 6c9d9325fe81174d7e1de61f3f49c88c2a7d194a)
-rw-r--r--main/fprobe-ulog/APKBUILD14
-rw-r--r--main/fprobe-ulog/fprobe-nflog.patch617
2 files changed, 626 insertions, 5 deletions
diff --git a/main/fprobe-ulog/APKBUILD b/main/fprobe-ulog/APKBUILD
index a97e014cd7..c1684c4c99 100644
--- a/main/fprobe-ulog/APKBUILD
+++ b/main/fprobe-ulog/APKBUILD
@@ -1,13 +1,13 @@
1# Maintainer: Leonardo Arena <rnalrd@alpinelinux.org> 1# Maintainer: Leonardo Arena <rnalrd@alpinelinux.org>
2pkgname=fprobe-ulog 2pkgname=fprobe-ulog
3pkgver=1.2 3pkgver=1.2
4pkgrel=1 4pkgrel=2
5pkgdesc="netfilter-based tool that collect network traffic" 5pkgdesc="netfilter-based tool that collect network traffic"
6url="https://github.com/opoplawski/fprobe-ulog" 6url="https://github.com/opoplawski/fprobe-ulog"
7arch="all" 7arch="all"
8license="GPL" 8license="GPL"
9depends= 9depends=
10makedepends="libnetfilter_log-dev" 10makedepends="libnfnetlink-dev libnetfilter_log-dev"
11install="" 11install=""
12subpackages="$pkgname-doc" 12subpackages="$pkgname-doc"
13source="https://github.com/opoplawski/fprobe-ulog/releases/download/v$pkgver/fprobe-ulog-$pkgver.tar.gz 13source="https://github.com/opoplawski/fprobe-ulog/releases/download/v$pkgver/fprobe-ulog-$pkgver.tar.gz
@@ -15,6 +15,7 @@ source="https://github.com/opoplawski/fprobe-ulog/releases/download/v$pkgver/fpr
15 fprobe-ulog.initd 15 fprobe-ulog.initd
16 fprobe-1.1-pidfile-sanity.patch 16 fprobe-1.1-pidfile-sanity.patch
17 fix-setuser.patch 17 fix-setuser.patch
18 fprobe-nflog.patch
18 " 19 "
19 20
20_builddir="$srcdir"/$pkgname-$pkgver 21_builddir="$srcdir"/$pkgname-$pkgver
@@ -55,14 +56,17 @@ md5sums="05408501ac17a664fda269a208efa087 fprobe-ulog-1.2.tar.gz
558aabfe548f2fb197a10c8ccfaa4d0a23 fprobe-ulog.confd 568aabfe548f2fb197a10c8ccfaa4d0a23 fprobe-ulog.confd
56d791e5d15be8fb59b22f7fa235b9f041 fprobe-ulog.initd 57d791e5d15be8fb59b22f7fa235b9f041 fprobe-ulog.initd
57f1316ad835c1a2b6565b4dc448b022df fprobe-1.1-pidfile-sanity.patch 58f1316ad835c1a2b6565b4dc448b022df fprobe-1.1-pidfile-sanity.patch
5827bfeb6c6cd7089240173a2829054d87 fix-setuser.patch" 5927bfeb6c6cd7089240173a2829054d87 fix-setuser.patch
60daeeac4f76b19e7ec7a579bcbb9b103c fprobe-nflog.patch"
59sha256sums="72a8c13001dd512acff9b85594dd29a435947072e20abefe85c29468a3967121 fprobe-ulog-1.2.tar.gz 61sha256sums="72a8c13001dd512acff9b85594dd29a435947072e20abefe85c29468a3967121 fprobe-ulog-1.2.tar.gz
607101091e238f5b0719a66f525f5bdc000ad593f492dd51896e2bd077fcada8f4 fprobe-ulog.confd 627101091e238f5b0719a66f525f5bdc000ad593f492dd51896e2bd077fcada8f4 fprobe-ulog.confd
613dfaa0a8e995ac2c3caa49a01ed570f83348fb3348d1a5106af5a80a1fc1f3d0 fprobe-ulog.initd 633dfaa0a8e995ac2c3caa49a01ed570f83348fb3348d1a5106af5a80a1fc1f3d0 fprobe-ulog.initd
62660531f8ba574f80835bb26390e47c2541a3c75985656d46a334c38bfaa4e362 fprobe-1.1-pidfile-sanity.patch 64660531f8ba574f80835bb26390e47c2541a3c75985656d46a334c38bfaa4e362 fprobe-1.1-pidfile-sanity.patch
63aa4b237750555323de29f6ddbc3f807dc507bd72564043e9dab6316dc3424123 fix-setuser.patch" 65aa4b237750555323de29f6ddbc3f807dc507bd72564043e9dab6316dc3424123 fix-setuser.patch
665e9dae31daabdc9916ccd3d50c95f41dbd58439b233e445e3accd161d0d29fbb fprobe-nflog.patch"
64sha512sums="c393c0705bd6c7cee998fccc48dede3568063b5130971f36c08f580c7678cf52fdf446c02cc4df3d5a2ead68cb2d14434e0847bfff27b6a0c5ef5ec7d6f61145 fprobe-ulog-1.2.tar.gz 67sha512sums="c393c0705bd6c7cee998fccc48dede3568063b5130971f36c08f580c7678cf52fdf446c02cc4df3d5a2ead68cb2d14434e0847bfff27b6a0c5ef5ec7d6f61145 fprobe-ulog-1.2.tar.gz
65388522863b5c77a334ee11bd771717d829448c85755b58088e22558b99a98514ac95ec3122cf3cb1ce7376f40ac0bae6bf1488dbd4ef60170c3ff83824988195 fprobe-ulog.confd 68388522863b5c77a334ee11bd771717d829448c85755b58088e22558b99a98514ac95ec3122cf3cb1ce7376f40ac0bae6bf1488dbd4ef60170c3ff83824988195 fprobe-ulog.confd
662c81ab715eea71beac21d4e4261464ed763464398e3fa4979eb8bd1f671d22916dffb64f051714b6460bb422924517979a3630139b478ddd258b2c28b3d73a14 fprobe-ulog.initd 692c81ab715eea71beac21d4e4261464ed763464398e3fa4979eb8bd1f671d22916dffb64f051714b6460bb422924517979a3630139b478ddd258b2c28b3d73a14 fprobe-ulog.initd
67e8d5103d2c12fffb913b327badf07e6ac3a0ad8b6e39e942c50dc7e472391b345006b7ee7b7d12a4613c351db2b4e88a6fbd17cfa0907c7c9010faeced3ff557 fprobe-1.1-pidfile-sanity.patch 70e8d5103d2c12fffb913b327badf07e6ac3a0ad8b6e39e942c50dc7e472391b345006b7ee7b7d12a4613c351db2b4e88a6fbd17cfa0907c7c9010faeced3ff557 fprobe-1.1-pidfile-sanity.patch
68981f8bf359f7f338a742eb605a09ff95a960231b98b80552d70f1637aea0ec061fddfd8fa004eef971143af52c88e3a8c7dd45605693f9035cb2c63ccfadb1ed fix-setuser.patch" 71981f8bf359f7f338a742eb605a09ff95a960231b98b80552d70f1637aea0ec061fddfd8fa004eef971143af52c88e3a8c7dd45605693f9035cb2c63ccfadb1ed fix-setuser.patch
72dbf186246b25f60a54a822d28e8463f1f4b17812e99ed9e4a76519506b6046ed41494e669ab70f8449923d0e7d43428b9417dc67642059b16fc9457b3dc70d3b fprobe-nflog.patch"
diff --git a/main/fprobe-ulog/fprobe-nflog.patch b/main/fprobe-ulog/fprobe-nflog.patch
new file mode 100644
index 0000000000..8b66a23433
--- /dev/null
+++ b/main/fprobe-ulog/fprobe-nflog.patch
@@ -0,0 +1,617 @@
1diff -ru fprobe-ulog-1.2.orig/src/Makefile.am fprobe-ulog-1.2/src/Makefile.am
2--- fprobe-ulog-1.2.orig/src/Makefile.am 2014-12-23 19:26:37.000000000 -0200
3+++ fprobe-ulog-1.2/src/Makefile.am 2015-07-10 11:23:21.839152998 -0300
4@@ -11,4 +11,4 @@
5
6 EXTRA_DIST = ${man_MANS}
7
8-fprobe_ulog_LDADD = -lnetfilter_log_libipulog
9+fprobe_ulog_LDADD = -lnetfilter_log -lnfnetlink
10diff -ru fprobe-ulog-1.2.orig/src/Makefile.in fprobe-ulog-1.2/src/Makefile.in
11--- fprobe-ulog-1.2.orig/src/Makefile.in 2014-12-23 20:02:22.000000000 -0200
12+++ fprobe-ulog-1.2/src/Makefile.in 2015-07-10 11:23:32.279250285 -0300
13@@ -293,7 +293,7 @@
14
15 man_MANS = fprobe-ulog.8
16 EXTRA_DIST = ${man_MANS}
17-fprobe_ulog_LDADD = -lnetfilter_log_libipulog
18+fprobe_ulog_LDADD = -lnetfilter_log -lnfnetlink
19 all: all-am
20
21 .SUFFIXES:
22diff -ru fprobe-ulog-1.2.orig/src/fprobe-ulog.c fprobe-ulog-1.2/src/fprobe-ulog.c
23--- fprobe-ulog-1.2.orig/src/fprobe-ulog.c 2015-07-10 11:22:29.668666836 -0300
24+++ fprobe-ulog-1.2/src/fprobe-ulog.c 2015-07-10 11:23:06.479009860 -0300
25@@ -27,14 +27,8 @@
26 #include <asm/types.h>
27 #include <sys/socket.h>
28 #include <linux/netlink.h>
29-#include <libnetfilter_log/libipulog.h>
30-struct ipulog_handle {
31- int fd;
32- u_int8_t blocking;
33- struct sockaddr_nl local;
34- struct sockaddr_nl peer;
35- struct nlmsghdr* last_nlhdr;
36-};
37+#include <libnfnetlink/libnfnetlink.h>
38+#include <libnetfilter_log/libnetfilter_log.h>
39
40 /* inet_*() (Linux, FreeBSD, Solaris), getpid() */
41 #include <sys/types.h>
42@@ -106,7 +100,6 @@
43 Uflag,
44 uflag,
45 vflag,
46- Xflag,
47 };
48
49 static struct getopt_parms parms[] = {
50@@ -129,7 +122,6 @@
51 {'U', MY_GETOPT_ARG_REQUIRED, 0, 0},
52 {'u', MY_GETOPT_ARG_REQUIRED, 0, 0},
53 {'v', MY_GETOPT_ARG_REQUIRED, 0, 0},
54- {'X', MY_GETOPT_ARG_REQUIRED, 0, 0},
55 {0, 0, 0, 0}
56 };
57
58@@ -208,21 +200,19 @@
59 static pid_t pid;
60 static int killed;
61 static int emit_timeout = EMIT_TIMEOUT, unpending_timeout = UNPENDING_TIMEOUT;
62-static struct ipulog_handle *ulog_handle;
63-static uint32_t ulog_gmask = 1;
64+static struct nflog_handle *nflog_handle;
65+static uint32_t nflog_gmask = 1;
66 static unsigned char *cap_buf;
67-static int nsnmp_rules;
68-static struct snmp_rule *snmp_rules;
69 static struct passwd *pw = 0;
70
71 void usage()
72 {
73 fprintf(stdout,
74- "fprobe-ulog: a NetFlow probe. Version %s\n"
75- "Usage: fprobe-ulog [options] remote:port[/[local][/type]] ...\n"
76+ "fprobe-nflog: a NetFlow probe. Version %s\n"
77+ "Usage: fprobe-nflog [options] remote:port[/[local][/type]] ...\n"
78 "\n"
79 "-h\t\tDisplay this help\n"
80- "-U <mask>\tULOG group bitwise mask [1]\n"
81+ "-U <mask>\tNFLOG group bitwise mask [1]\n"
82 "-s <seconds>\tHow often scan for expired flows [5]\n"
83 "-g <seconds>\tFragmented flow lifetime [30]\n"
84 "-d <seconds>\tIdle flow lifetime (inactive timer) [60]\n"
85@@ -275,13 +265,18 @@
86 }
87 }
88
89+static void timeval2time(struct timeval *tv, struct Time *t)
90+{
91+ t->sec = tv->tv_sec;
92+ t->usec = tv->tv_usec;
93+}
94+
95 void gettime(struct Time *now)
96 {
97 struct timeval t;
98
99 gettimeofday(&t, 0);
100- now->sec = t.tv_sec;
101- now->usec = t.tv_usec;
102+ timeval2time(&t, now);
103 }
104
105 inline time_t cmpmtime(struct Time *t1, struct Time *t2)
106@@ -302,21 +297,6 @@
107 else return hash(flow, sizeof(struct Flow_TL));
108 }
109
110-uint16_t snmp_index(char *name) {
111- uint32_t i;
112-
113- if (!*name) return 0;
114-
115- for (i = 0; (int) i < nsnmp_rules; i++) {
116- if (strncmp(snmp_rules[i].basename, name, snmp_rules[i].len)) continue;
117- return atoi(&name[snmp_rules[i].len]) + snmp_rules[i].base;
118- }
119-
120- if ((i = if_nametoindex(name))) return i;
121-
122- return -1;
123-}
124-
125 inline void copy_flow(struct Flow *src, struct Flow *dst)
126 {
127 dst->iif = src->iif;
128@@ -845,226 +825,230 @@
129 }
130 }
131
132-void *cap_thread()
133+static int fprobe_cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg,
134+ struct nflog_data *nfd, void *data)
135 {
136- struct ulog_packet_msg *ulog_msg;
137+ struct timeval tv;
138+ char *payload;
139 struct ip *nl;
140 void *tl;
141 struct Flow *flow;
142 int off_frag, psize;
143- ssize_t len;
144 #if ((DEBUG) & DEBUG_C)
145 char buf[64];
146 char logbuf[256];
147 #endif
148
149- while (!killed) {
150- len = ipulog_read(ulog_handle, cap_buf, CAPTURE_SIZE, 1);
151- if (len <= 0) {
152- my_log(LOG_ERR, "ipulog_read(): %s", ipulog_strerror(ipulog_errno));
153- continue;
154- }
155- while ((ulog_msg = ipulog_get_packet(ulog_handle, cap_buf, len))) {
156+ if (killed)
157+ return NFNL_CB_STOP;
158
159+ psize = nflog_get_payload(nfd, &payload);
160+ nl = (struct ip*) payload;
161 #if ((DEBUG) & DEBUG_C)
162- sprintf(logbuf, "C: %d", ulog_msg->data_len);
163+ sprintf(logbuf, "C: %d", psize);
164 #endif
165
166- nl = (void *) &ulog_msg->payload;
167- psize = ulog_msg->data_len;
168-
169- /* Sanity check */
170- if (psize < (signed) sizeof(struct ip) || nl->ip_v != 4) {
171+ /* Sanity check */
172+ if (psize < (signed) sizeof(struct ip) || nl->ip_v != 4) {
173 #if ((DEBUG) & DEBUG_C)
174- strcat(logbuf, " U");
175- my_log(LOG_DEBUG, "%s", logbuf);
176+ strcat(logbuf, " U");
177+ my_log(LOG_DEBUG, "%s", logbuf);
178 #endif
179 #if ((DEBUG) & DEBUG_I)
180- pkts_ignored++;
181+ pkts_ignored++;
182 #endif
183- continue;
184- }
185+ return NFNL_CB_CONTINUE;
186+ }
187
188- if (pending_head->flags) {
189+ if (pending_head->flags) {
190 #if ((DEBUG) & DEBUG_C) || defined MESSAGES
191- my_log(LOG_ERR,
192+ my_log(LOG_ERR,
193 # if ((DEBUG) & DEBUG_C)
194- "%s %s %s", logbuf,
195+ "%s %s %s", logbuf,
196 # else
197- "%s %s",
198+ "%s %s",
199 # endif
200- "pending queue full:", "packet lost");
201+ "pending queue full:", "packet lost");
202 #endif
203 #if ((DEBUG) & DEBUG_I)
204- pkts_lost_capture++;
205+ pkts_lost_capture++;
206 #endif
207- goto done;
208- }
209+ goto done;
210+ }
211
212 #if ((DEBUG) & DEBUG_I)
213- pkts_total++;
214+ pkts_total++;
215 #endif
216
217- flow = pending_head;
218+ flow = pending_head;
219
220- /* ?FIXME? Add sanity check for ip_len? */
221- flow->size = ntohs(nl->ip_len);
222+ /* ?FIXME? Add sanity check for ip_len? */
223+ flow->size = ntohs(nl->ip_len);
224 #if ((DEBUG) & DEBUG_I)
225- size_total += flow->size;
226+ size_total += flow->size;
227 #endif
228
229- flow->sip = nl->ip_src;
230- flow->dip = nl->ip_dst;
231- flow->iif = snmp_index(ulog_msg->indev_name);
232- flow->oif = snmp_index(ulog_msg->outdev_name);
233- flow->tos = mark_is_tos ? ulog_msg->mark : nl->ip_tos;
234- flow->proto = nl->ip_p;
235- flow->id = 0;
236- flow->tcp_flags = 0;
237- flow->pkts = 1;
238- flow->sizeF = 0;
239- flow->sizeP = 0;
240- /* Packets captured from OUTPUT table didn't contains valid timestamp */
241- if (ulog_msg->timestamp_sec) {
242- flow->ctime.sec = ulog_msg->timestamp_sec;
243- flow->ctime.usec = ulog_msg->timestamp_usec;
244- } else gettime(&flow->ctime);
245- flow->mtime = flow->ctime;
246-
247- off_frag = (ntohs(nl->ip_off) & IP_OFFMASK) << 3;
248-
249- /*
250- Offset (from network layer) to transport layer header/IP data
251- IOW IP header size ;-)
252-
253- ?FIXME?
254- Check ip_hl for valid value (>=5)? Maybe check CRC? No, thanks...
255- */
256- off_tl = nl->ip_hl << 2;
257- tl = (void *) nl + off_tl;
258-
259- /* THIS packet data size: data_size = total_size - ip_header_size*4 */
260- flow->sizeF = ntohs(nl->ip_len) - off_tl;
261- psize -= off_tl;
262- if ((signed) flow->sizeF < 0) flow->sizeF = 0;
263- if (psize > (signed) flow->sizeF) psize = flow->sizeF;
264+ flow->sip = nl->ip_src;
265+ flow->dip = nl->ip_dst;
266+ flow->iif = nflog_get_indev(nfd);
267+ flow->oif = nflog_get_outdev(nfd);
268+ flow->tos = mark_is_tos ? nflog_get_nfmark(nfd) : nl->ip_tos;
269+ flow->proto = nl->ip_p;
270+ flow->id = 0;
271+ flow->tcp_flags = 0;
272+ flow->pkts = 1;
273+ flow->sizeF = 0;
274+ flow->sizeP = 0;
275+ /* Packets captured from OUTPUT table didn't contains valid timestamp */
276+ if (nflog_get_timestamp(nfd, &tv) >= 0)
277+ timeval2time(&tv, &flow->ctime);
278+ else
279+ gettime(&flow->ctime);
280+ flow->mtime = flow->ctime;
281+
282+ off_frag = (ntohs(nl->ip_off) & IP_OFFMASK) << 3;
283+
284+ /*
285+ Offset (from network layer) to transport layer header/IP data
286+ IOW IP header size ;-)
287+
288+ ?FIXME?
289+ Check ip_hl for valid value (>=5)? Maybe check CRC? No, thanks...
290+ */
291+ off_tl = nl->ip_hl << 2;
292+ tl = (void *) nl + off_tl;
293+
294+ /* THIS packet data size: data_size = total_size - ip_header_size*4 */
295+ flow->sizeF = ntohs(nl->ip_len) - off_tl;
296+ psize -= off_tl;
297+ if ((signed) flow->sizeF < 0) flow->sizeF = 0;
298+ if (psize > (signed) flow->sizeF) psize = flow->sizeF;
299
300- if (ntohs(nl->ip_off) & (IP_MF | IP_OFFMASK)) {
301- /* Fragmented packet (IP_MF flag == 1 or fragment offset != 0) */
302+ if (ntohs(nl->ip_off) & (IP_MF | IP_OFFMASK)) {
303+ /* Fragmented packet (IP_MF flag == 1 or fragment offset != 0) */
304 #if ((DEBUG) & DEBUG_C)
305- strcat(logbuf, " F");
306+ strcat(logbuf, " F");
307 #endif
308 #if ((DEBUG) & DEBUG_I)
309- pkts_total_fragmented++;
310+ pkts_total_fragmented++;
311 #endif
312- flow->flags |= FLOW_FRAG;
313- flow->id = nl->ip_id;
314+ flow->flags |= FLOW_FRAG;
315+ flow->id = nl->ip_id;
316
317- if (!(ntohs(nl->ip_off) & IP_MF)) {
318- /* Packet whith IP_MF contains information about whole datagram size */
319- flow->flags |= FLOW_LASTFRAG;
320- /* size = frag_offset*8 + data_size */
321- flow->sizeP = off_frag + flow->sizeF;
322- }
323- }
324+ if (!(ntohs(nl->ip_off) & IP_MF)) {
325+ /* Packet whith IP_MF contains information about whole datagram size */
326+ flow->flags |= FLOW_LASTFRAG;
327+ /* size = frag_offset*8 + data_size */
328+ flow->sizeP = off_frag + flow->sizeF;
329+ }
330+ }
331
332 #if ((DEBUG) & DEBUG_C)
333- sprintf(buf, " %s@%u>", inet_ntoa(flow->sip), flow->iif);
334- strcat(logbuf, buf);
335- sprintf(buf, "%s@%u P:%x", inet_ntoa(flow->dip), flow->oif, flow->proto);
336- strcat(logbuf, buf);
337+ sprintf(buf, " %s@%u>", inet_ntoa(flow->sip), flow->iif);
338+ strcat(logbuf, buf);
339+ sprintf(buf, "%s@%u P:%x", inet_ntoa(flow->dip), flow->oif, flow->proto);
340+ strcat(logbuf, buf);
341 #endif
342
343- /*
344- Fortunately most interesting transport layer information fit
345- into first 8 bytes of IP data field (minimal nonzero size).
346- Thus we don't need actual packet reassembling to build whole
347- transport layer data. We only check the fragment offset for
348- zero value to find packet with this information.
349- */
350- if (!off_frag && psize >= 8) {
351- switch (flow->proto) {
352- case IPPROTO_TCP:
353- case IPPROTO_UDP:
354- flow->sp = ((struct udphdr *)tl)->uh_sport;
355- flow->dp = ((struct udphdr *)tl)->uh_dport;
356- goto tl_known;
357+ /*
358+ Fortunately most interesting transport layer information fit
359+ into first 8 bytes of IP data field (minimal nonzero size).
360+ Thus we don't need actual packet reassembling to build whole
361+ transport layer data. We only check the fragment offset for
362+ zero value to find packet with this information.
363+ */
364+ if (!off_frag && psize >= 8) {
365+ switch (flow->proto) {
366+ case IPPROTO_TCP:
367+ case IPPROTO_UDP:
368+ flow->sp = ((struct udphdr *)tl)->uh_sport;
369+ flow->dp = ((struct udphdr *)tl)->uh_dport;
370+ goto tl_known;
371
372 #ifdef ICMP_TRICK
373- case IPPROTO_ICMP:
374- flow->sp = htons(((struct icmp *)tl)->icmp_type);
375- flow->dp = htons(((struct icmp *)tl)->icmp_code);
376- goto tl_known;
377+ case IPPROTO_ICMP:
378+ flow->sp = htons(((struct icmp *)tl)->icmp_type);
379+ flow->dp = htons(((struct icmp *)tl)->icmp_code);
380+ goto tl_known;
381 #endif
382 #ifdef ICMP_TRICK_CISCO
383- case IPPROTO_ICMP:
384- flow->dp = *((int32_t *) tl);
385- goto tl_known;
386+ case IPPROTO_ICMP:
387+ flow->dp = *((int32_t *) tl);
388+ goto tl_known;
389 #endif
390
391- default:
392- /* Unknown transport layer */
393+ default:
394+ /* Unknown transport layer */
395 #if ((DEBUG) & DEBUG_C)
396- strcat(logbuf, " U");
397+ strcat(logbuf, " U");
398 #endif
399- flow->sp = 0;
400- flow->dp = 0;
401- break;
402+ flow->sp = 0;
403+ flow->dp = 0;
404+ break;
405
406- tl_known:
407+ tl_known:
408 #if ((DEBUG) & DEBUG_C)
409- sprintf(buf, " %d>%d", ntohs(flow->sp), ntohs(flow->dp));
410- strcat(logbuf, buf);
411+ sprintf(buf, " %d>%d", ntohs(flow->sp), ntohs(flow->dp));
412+ strcat(logbuf, buf);
413 #endif
414- flow->flags |= FLOW_TL;
415- }
416- }
417+ flow->flags |= FLOW_TL;
418+ }
419+ }
420
421- /* Check for tcp flags presence (including CWR and ECE). */
422- if (flow->proto == IPPROTO_TCP
423- && off_frag < 16
424- && psize >= 16 - off_frag) {
425- flow->tcp_flags = *((uint8_t *)(tl + 13 - off_frag));
426+ /* Check for tcp flags presence (including CWR and ECE). */
427+ if (flow->proto == IPPROTO_TCP
428+ && off_frag < 16
429+ && psize >= 16 - off_frag) {
430+ flow->tcp_flags = *((uint8_t *)(tl + 13 - off_frag));
431 #if ((DEBUG) & DEBUG_C)
432- sprintf(buf, " TCP:%x", flow->tcp_flags);
433- strcat(logbuf, buf);
434+ sprintf(buf, " TCP:%x", flow->tcp_flags);
435+ strcat(logbuf, buf);
436 #endif
437- }
438+ }
439
440 #if ((DEBUG) & DEBUG_C)
441- sprintf(buf, " => %x", (unsigned) flow);
442- strcat(logbuf, buf);
443- my_log(LOG_DEBUG, "%s", logbuf);
444+ sprintf(buf, " => %x", (unsigned) flow);
445+ strcat(logbuf, buf);
446+ my_log(LOG_DEBUG, "%s", logbuf);
447 #endif
448
449 #if ((DEBUG) & DEBUG_I)
450- pkts_pending++;
451- pending_queue_trace_candidate = pkts_pending - pkts_pending_done;
452- if (pending_queue_trace < pending_queue_trace_candidate)
453- pending_queue_trace = pending_queue_trace_candidate;
454+ pkts_pending++;
455+ pending_queue_trace_candidate = pkts_pending - pkts_pending_done;
456+ if (pending_queue_trace < pending_queue_trace_candidate)
457+ pending_queue_trace = pending_queue_trace_candidate;
458 #endif
459
460- /* Flow complete - inform unpending_thread() about it */
461- pending_head->flags |= FLOW_PENDING;
462- pending_head = pending_head->next;
463- done:
464- pthread_cond_signal(&unpending_cond);
465- }
466- }
467+ /* Flow complete - inform unpending_thread() about it */
468+ pending_head->flags |= FLOW_PENDING;
469+ pending_head = pending_head->next;
470+done:
471+ pthread_cond_signal(&unpending_cond);
472+
473+ return NFNL_CB_CONTINUE;
474+}
475+
476+void *cap_thread()
477+{
478+ while (nfnl_catch(nflog_nfnlh(nflog_handle)) != NFNL_CB_STOP)
479+ ;
480+
481 return 0;
482 }
483
484 int main(int argc, char **argv)
485 {
486 char errpbuf[512];
487- char *dhost, *dport, *lhost, *type = 0, *log_suffix = 0, *rule;
488+ char *dhost, *dport, *lhost, *type = 0, *log_suffix = 0;
489 int c, i, sock, memory_limit = 0;
490+ struct nflog_g_handle *gh;
491 struct addrinfo hints, *res;
492 struct sockaddr_in saddr;
493 pthread_attr_t tattr;
494 struct sigaction sigact;
495 static void *threads[THREADS - 1] = {&emit_thread, &scan_thread, &unpending_thread, &cap_thread};
496 struct timeval timeout;
497+ size_t s;
498
499 sched_min = sched_get_priority_min(SCHED);
500 sched_max = sched_get_priority_max(SCHED);
501@@ -1088,7 +1072,7 @@
502 }
503 }
504
505- if (parms[Uflag].count) ulog_gmask = atoi(parms[Uflag].arg);
506+ if (parms[Uflag].count) nflog_gmask = atoi(parms[Uflag].arg);
507 if (parms[sflag].count) scan_interval = atoi(parms[sflag].arg);
508 if (parms[gflag].count) frag_lifetime = atoi(parms[gflag].arg);
509 if (parms[dflag].count) inactive_lifetime = atoi(parms[dflag].arg);
510@@ -1156,31 +1140,6 @@
511 }
512 }
513 if (parms[mflag].count) memory_limit = atoi(parms[mflag].arg) << 10;
514- if (parms[Xflag].count) {
515- for(i = 0; parms[Xflag].arg[i]; i++)
516- if (parms[Xflag].arg[i] == ':') nsnmp_rules++;
517- if (!(snmp_rules = malloc(nsnmp_rules * sizeof(struct snmp_rule))))
518- goto err_malloc;
519- rule = strtok(parms[Xflag].arg, ":");
520- for (i = 0; rule; i++) {
521- snmp_rules[i].len = strlen(rule);
522- if (snmp_rules[i].len > IFNAMSIZ) {
523- fprintf(stderr, "Illegal %s\n", "interface basename");
524- exit(1);
525- }
526- strncpy(snmp_rules[i].basename, rule, snmp_rules[i].len);
527- if (!*(rule - 1)) *(rule - 1) = ',';
528- rule = strtok(NULL, ",");
529- if (!rule) {
530- fprintf(stderr, "Illegal %s\n", "SNMP rule");
531- exit(1);
532- }
533- snmp_rules[i].base = atoi(rule);
534- *(rule - 1) = ':';
535- rule = strtok(NULL, ":");
536- }
537- nsnmp_rules = i;
538- }
539 if (parms[tflag].count)
540 sscanf(parms[tflag].arg, "%d:%d", &emit_rate_bytes, &emit_rate_delay);
541 if (parms[aflag].count) {
542@@ -1266,16 +1225,34 @@
543 }
544
545 if (!(cap_buf = malloc(CAPTURE_SIZE))) goto err_malloc;
546- ulog_handle = ipulog_create_handle(ulog_gmask, CAPTURE_SIZE);
547- if (!ulog_handle) {
548- fprintf(stderr, "libipulog initialization error: %s",
549- ipulog_strerror(ipulog_errno));
550+ nflog_handle = nflog_open();
551+ if (!nflog_handle) {
552+ fprintf(stderr, "libnflog initialization error: %s",
553+ strerror(nflog_errno));
554 exit(1);
555 }
556- if (sockbufsize)
557- if (setsockopt(ulog_handle->fd, SOL_SOCKET, SO_RCVBUF,
558- &sockbufsize, sizeof(sockbufsize)) < 0)
559- fprintf(stderr, "setsockopt(): %s", strerror(errno));
560+
561+ if (sockbufsize &&
562+ nfnl_rcvbufsiz(nflog_nfnlh(nflog_handle), sockbufsize) == 0)
563+ fprintf(stderr, "nfnl_rcvbufsiz(): %s", strerror(errno));
564+
565+ if (nflog_bind_pf(nflog_handle, PF_INET) < 0) {
566+ fprintf(stderr, "libnflog failed to bind PF_INET %d: %s",
567+ i, strerror(nflog_errno));
568+ exit(1);
569+ }
570+
571+ for (s = 0; s < sizeof(nflog_gmask) * 8; s++) {
572+ if (!(nflog_gmask & (1UL << s)))
573+ continue;
574+ gh = nflog_bind_group(nflog_handle, s + 1);
575+ if (!gh) {
576+ fprintf(stderr, "libnflog failed to bind group %d: %s",
577+ i, strerror(nflog_errno));
578+ exit(1);
579+ }
580+ nflog_callback_register(gh, fprobe_cb, NULL);
581+ }
582
583 /* Daemonize (if log destination stdout-free) */
584
585@@ -1402,15 +1379,11 @@
586 my_log(LOG_INFO, "pid: %d", pid);
587 my_log(LOG_INFO, "options: u=%u s=%u g=%u d=%u e=%u n=%u a=%s "
588 "M=%d b=%u m=%u q=%u B=%u r=%u t=%u:%u c=%s u=%s v=%u l=%u%s",
589- ulog_gmask, scan_interval, frag_lifetime, inactive_lifetime, active_lifetime,
590+ nflog_gmask, scan_interval, frag_lifetime, inactive_lifetime, active_lifetime,
591 netflow->Version, inet_ntoa(saddr.sin_addr), mark_is_tos, bulk_quantity,
592 memory_limit >> 10, pending_queue_length, sockbufsize >> 10, schedp.sched_priority - 1,
593 emit_rate_bytes, emit_rate_delay, parms[cflag].count ? parms[cflag].arg : "",
594 parms[uflag].count ? parms[uflag].arg : "", verbosity, log_dest, log_suffix ? log_suffix : "");
595- for (i = 0; i < nsnmp_rules; i++) {
596- my_log(LOG_INFO, "SNMP rule #%d %s:%d",
597- i + 1, snmp_rules[i].basename, snmp_rules[i].base);
598- }
599 for (i = 0; i < npeers; i++) {
600 switch (peers[i].type) {
601 case PEER_MIRROR:
602diff -ru fprobe-ulog-1.2.orig/src/fprobe-ulog.h fprobe-ulog-1.2/src/fprobe-ulog.h
603--- fprobe-ulog-1.2.orig/src/fprobe-ulog.h 2005-01-29 21:30:41.000000000 -0200
604+++ fprobe-ulog-1.2/src/fprobe-ulog.h 2015-07-10 11:23:06.479009860 -0300
605@@ -117,12 +117,6 @@
606 uint32_t seq;
607 };
608
609-struct snmp_rule {
610- char basename[IFNAMSIZ];
611- int len;
612- int base;
613-} snmp_rule_t;
614-
615 #define PEER_MIRROR 0
616 #define PEER_ROTATE 1
617