63 SCLogError(
"Error creating thread %s: you do not have support for nflog "
64 "enabled please recompile with --enable-nflog",
76 void ReceiveNFLOGThreadExitStats(
ThreadVars *,
void *);
82 static int runmode_workers;
85 typedef struct NFLOGThreadVars_ {
94 uint32_t nlbufsiz_max;
98 struct nflog_handle *h;
99 struct nflog_g_handle *gh;
102 int nful_overrun_warned;
145 static int NFLOGCallback(
struct nflog_g_handle *gh,
struct nfgenmsg *msg,
146 struct nflog_data *nfa,
void *data)
148 NFLOGThreadVars *ntv = (NFLOGThreadVars *) data;
149 struct nfulnl_msg_packet_hdr *ph;
160 ph = nflog_get_msg_packet_hdr(nfa);
162 p->nflog_v.hw_protocol = ph->hw_protocol;
165 p->nflog_v.ifi = nflog_get_indev(nfa);
166 p->nflog_v.ifo = nflog_get_outdev(nfa);
168 ret = nflog_get_payload(nfa, &payload);
174 }
else if (runmode_workers)
178 }
else if (ret == -1)
182 ret = nflog_get_timestamp(nfa, &
tv);
184 memset(&
tv, 0,
sizeof(
tv));
185 gettimeofday(&
tv, NULL);
197 if (TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) !=
TM_ECODE_OK) {
217 if (initdata == NULL) {
222 NFLOGThreadVars *ntv =
SCCalloc(1,
sizeof(NFLOGThreadVars));
229 ntv->group = nflconfig->
group;
230 ntv->nlbufsiz = nflconfig->
nlbufsiz;
233 ntv->qtimeout = nflconfig->
qtimeout;
236 ntv->h = nflog_open();
237 if (ntv->h == NULL) {
243 SCLogDebug(
"binding netfilter_log as nflog handler for AF_INET and AF_INET6");
245 if (nflog_bind_pf(ntv->h, AF_INET) < 0) {
246 FatalError(
"nflog_bind_pf() for AF_INET failed");
248 if (nflog_bind_pf(ntv->h, AF_INET6) < 0) {
249 FatalError(
"nflog_bind_pf() for AF_INET6 failed");
252 ntv->gh = nflog_bind_group(ntv->h, ntv->group);
259 if (nflog_set_mode(ntv->gh, NFULNL_COPY_PACKET, 0xFFFF) < 0) {
265 nflog_callback_register(ntv->gh, &NFLOGCallback, (
void *)ntv);
267 if (ntv->nlbufsiz < ntv->nlbufsiz_max)
268 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
270 SCLogError(
"Maximum buffer size (%d) in NFLOG "
276 if (nflog_set_qthresh(ntv->gh, ntv->qthreshold) >= 0)
277 SCLogDebug(
"NFLOG netlink queue threshold has been set to %d",
280 SCLogDebug(
"NFLOG netlink queue threshold can't be set to %d",
283 if (nflog_set_timeout(ntv->gh, ntv->qtimeout) >= 0)
284 SCLogDebug(
"NFLOG netlink queue timeout has been set to %d",
287 SCLogDebug(
"NFLOG netlink queue timeout can't be set to %d",
291 if (ntv->livedev == NULL) {
299 struct timeval timev;
303 int fd = nflog_fd(ntv->h);
304 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timev,
sizeof(timev)) == -1) {
310 #ifdef PACKET_STATISTICS
316 if (active_runmode && !strcmp(
"workers", active_runmode))
321 #define T_DATA_SIZE 70000
323 if (ntv->data == NULL) {
348 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
350 SCLogDebug(
"closing nflog group %d", ntv->group);
351 if (nflog_unbind_pf(ntv->h, AF_INET) < 0) {
352 FatalError(
"nflog_unbind_pf() for AF_INET failed");
355 if (nflog_unbind_pf(ntv->h, AF_INET6) < 0) {
356 FatalError(
"nflog_unbind_pf() for AF_INET6 failed");
360 nflog_unbind_group(ntv->gh);
369 if (ntv->data != NULL) {
389 static int NFLOGSetnlbufsiz(
void *data,
unsigned int size)
392 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
394 if (size < ntv->nlbufsiz_max) {
395 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
399 SCLogWarning(
"Maximum buffer size (%d) in NFLOG has been "
400 "reached. Please, consider raising "
401 "`buffer-size` and `max-size` in nflog configuration",
422 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
426 ntv->slot = ((
TmSlot *) slot)->slot_next;
428 fd = nflog_fd(ntv->h);
442 rv = recv(fd, ntv->data, ntv->datalen, 0);
445 if (errno == EINTR || errno == EWOULDBLOCK) {
448 }
else if (errno == ENOBUFS) {
449 if (!ntv->nful_overrun_warned) {
450 int s = ntv->nlbufsiz * 2;
451 if (NFLOGSetnlbufsiz((
void *)ntv, s)) {
453 "increasing buffer size "
457 ntv->nful_overrun_warned = 1;
462 SCLogWarning(
"Read from NFLOG fd failed: %s", strerror(errno));
467 ret = nflog_handle_packet(ntv->h, ntv->data, rv);
469 SCLogWarning(
"nflog_handle_packet error %" PRId32
"", ret);
482 void ReceiveNFLOGThreadExitStats(
ThreadVars *
tv,
void *data)
485 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
487 SCLogNotice(
"(%s) Pkts %" PRIu32
", Bytes %" PRIu64
"",
488 tv->
name, ntv->pkts, ntv->bytes);