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;
109 uint16_t capture_kernel_packets;
110 uint16_t capture_kernel_drops;
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
318 if (active_runmode && !strcmp(
"workers", active_runmode))
323 #define T_DATA_SIZE 70000
325 if (ntv->data == NULL) {
350 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
352 SCLogDebug(
"closing nflog group %d", ntv->group);
353 if (nflog_unbind_pf(ntv->h, AF_INET) < 0) {
354 FatalError(
"nflog_unbind_pf() for AF_INET failed");
357 if (nflog_unbind_pf(ntv->h, AF_INET6) < 0) {
358 FatalError(
"nflog_unbind_pf() for AF_INET6 failed");
362 nflog_unbind_group(ntv->gh);
371 if (ntv->data != NULL) {
391 static int NFLOGSetnlbufsiz(
void *data,
unsigned int size)
394 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
396 if (size < ntv->nlbufsiz_max) {
397 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
401 SCLogWarning(
"Maximum buffer size (%d) in NFLOG has been "
402 "reached. Please, consider raising "
403 "`buffer-size` and `max-size` in nflog configuration",
424 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
428 ntv->slot = ((
TmSlot *) slot)->slot_next;
430 fd = nflog_fd(ntv->h);
444 rv = recv(fd, ntv->data, ntv->datalen, 0);
447 if (errno == EINTR || errno == EWOULDBLOCK) {
450 }
else if (errno == ENOBUFS) {
451 if (!ntv->nful_overrun_warned) {
452 int s = ntv->nlbufsiz * 2;
453 if (NFLOGSetnlbufsiz((
void *)ntv, s)) {
455 "increasing buffer size "
459 ntv->nful_overrun_warned = 1;
464 SCLogWarning(
"Read from NFLOG fd failed: %s", strerror(errno));
469 ret = nflog_handle_packet(ntv->h, ntv->data, rv);
471 SCLogWarning(
"nflog_handle_packet error %" PRId32
"", ret);
484 void ReceiveNFLOGThreadExitStats(
ThreadVars *
tv,
void *data)
487 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
489 SCLogNotice(
"(%s) Pkts %" PRIu32
", Bytes %" PRIu64
"",
490 tv->
name, ntv->pkts, ntv->bytes);