63 "enabled please recompile with --enable-nflog",
tv->
name);
74 void ReceiveNFLOGThreadExitStats(
ThreadVars *,
void *);
80 static int runmode_workers;
83 typedef struct NFLOGThreadVars_ {
92 uint32_t nlbufsiz_max;
96 struct nflog_handle *h;
97 struct nflog_g_handle *gh;
100 int nful_overrun_warned;
107 uint16_t capture_kernel_packets;
108 uint16_t capture_kernel_drops;
143 static int NFLOGCallback(
struct nflog_g_handle *gh,
struct nfgenmsg *
msg,
144 struct nflog_data *nfa,
void *data)
146 NFLOGThreadVars *ntv = (NFLOGThreadVars *) data;
147 struct nfulnl_msg_packet_hdr *ph;
158 ph = nflog_get_msg_packet_hdr(nfa);
160 p->nflog_v.hw_protocol = ph->hw_protocol;
163 p->nflog_v.ifi = nflog_get_indev(nfa);
164 p->nflog_v.ifo = nflog_get_outdev(nfa);
166 ret = nflog_get_payload(nfa, &payload);
172 }
else if (runmode_workers)
176 }
else if (ret == -1)
179 ret = nflog_get_timestamp(nfa, &p->
ts);
181 memset(&p->
ts, 0,
sizeof(
struct timeval));
182 gettimeofday(&p->
ts, NULL);
193 if (TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) !=
TM_ECODE_OK) {
213 if (initdata == NULL) {
218 NFLOGThreadVars *ntv =
SCMalloc(
sizeof(NFLOGThreadVars));
223 memset(ntv, 0,
sizeof(NFLOGThreadVars));
226 ntv->group = nflconfig->
group;
227 ntv->nlbufsiz = nflconfig->
nlbufsiz;
230 ntv->qtimeout = nflconfig->
qtimeout;
233 ntv->h = nflog_open();
234 if (ntv->h == NULL) {
240 SCLogDebug(
"binding netfilter_log as nflog handler for AF_INET and AF_INET6");
242 if (nflog_bind_pf(ntv->h, AF_INET) < 0) {
245 if (nflog_bind_pf(ntv->h, AF_INET6) < 0) {
249 ntv->gh = nflog_bind_group(ntv->h, ntv->group);
256 if (nflog_set_mode(ntv->gh, NFULNL_COPY_PACKET, 0xFFFF) < 0) {
262 nflog_callback_register(ntv->gh, &NFLOGCallback, (
void *)ntv);
264 if (ntv->nlbufsiz < ntv->nlbufsiz_max)
265 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
268 "has been reached", ntv->nlbufsiz);
272 if (nflog_set_qthresh(ntv->gh, ntv->qthreshold) >= 0)
273 SCLogDebug(
"NFLOG netlink queue threshold has been set to %d",
276 SCLogDebug(
"NFLOG netlink queue threshold can't be set to %d",
279 if (nflog_set_timeout(ntv->gh, ntv->qtimeout) >= 0)
280 SCLogDebug(
"NFLOG netlink queue timeout has been set to %d",
283 SCLogDebug(
"NFLOG netlink queue timeout can't be set to %d",
287 if (ntv->livedev == NULL) {
295 struct timeval timev;
299 int fd = nflog_fd(ntv->h);
300 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timev,
sizeof(timev)) == -1) {
302 "timeout: %s", strerror(errno));
305 #ifdef PACKET_STATISTICS
313 if (active_runmode && !strcmp(
"workers", active_runmode))
318 #define T_DATA_SIZE 70000
320 if (ntv->data == NULL) {
343 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
345 SCLogDebug(
"closing nflog group %d", ntv->group);
346 if (nflog_unbind_pf(ntv->h, AF_INET) < 0) {
350 if (nflog_unbind_pf(ntv->h, AF_INET6) < 0) {
355 nflog_unbind_group(ntv->gh);
364 if (ntv->data != NULL) {
384 static int NFLOGSetnlbufsiz(
void *data,
unsigned int size)
387 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
389 if (size < ntv->nlbufsiz_max) {
390 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
395 "Maximum buffer size (%d) in NFLOG has been "
396 "reached. Please, consider raising "
397 "`buffer-size` and `max-size` in nflog configuration",
418 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
422 ntv->slot = ((
TmSlot *) slot)->slot_next;
424 fd = nflog_fd(ntv->h);
434 rv = recv(fd, ntv->data, ntv->datalen, 0);
437 if (errno == EINTR || errno == EWOULDBLOCK) {
440 }
else if (errno == ENOBUFS) {
441 if (!ntv->nful_overrun_warned) {
442 int s = ntv->nlbufsiz * 2;
443 if (NFLOGSetnlbufsiz((
void *)ntv, s)) {
445 "We are losing events, "
446 "increasing buffer size "
447 "to %d", ntv->nlbufsiz);
449 ntv->nful_overrun_warned = 1;
455 "Read from NFLOG fd failed: %s",
461 ret = nflog_handle_packet(ntv->h, ntv->data, rv);
464 "nflog_handle_packet error %" PRId32
"", ret);
477 void ReceiveNFLOGThreadExitStats(
ThreadVars *
tv,
void *data)
480 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
482 SCLogNotice(
"(%s) Pkts %" PRIu32
", Bytes %" PRIu64
"",
483 tv->
name, ntv->pkts, ntv->bytes);