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 =
SCMalloc(
sizeof(NFLOGThreadVars));
227 memset(ntv, 0,
sizeof(NFLOGThreadVars));
230 ntv->group = nflconfig->
group;
231 ntv->nlbufsiz = nflconfig->
nlbufsiz;
234 ntv->qtimeout = nflconfig->
qtimeout;
237 ntv->h = nflog_open();
238 if (ntv->h == NULL) {
244 SCLogDebug(
"binding netfilter_log as nflog handler for AF_INET and AF_INET6");
246 if (nflog_bind_pf(ntv->h, AF_INET) < 0) {
247 FatalError(
"nflog_bind_pf() for AF_INET failed");
249 if (nflog_bind_pf(ntv->h, AF_INET6) < 0) {
250 FatalError(
"nflog_bind_pf() for AF_INET6 failed");
253 ntv->gh = nflog_bind_group(ntv->h, ntv->group);
260 if (nflog_set_mode(ntv->gh, NFULNL_COPY_PACKET, 0xFFFF) < 0) {
266 nflog_callback_register(ntv->gh, &NFLOGCallback, (
void *)ntv);
268 if (ntv->nlbufsiz < ntv->nlbufsiz_max)
269 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
271 SCLogError(
"Maximum buffer size (%d) in NFLOG "
277 if (nflog_set_qthresh(ntv->gh, ntv->qthreshold) >= 0)
278 SCLogDebug(
"NFLOG netlink queue threshold has been set to %d",
281 SCLogDebug(
"NFLOG netlink queue threshold can't be set to %d",
284 if (nflog_set_timeout(ntv->gh, ntv->qtimeout) >= 0)
285 SCLogDebug(
"NFLOG netlink queue timeout has been set to %d",
288 SCLogDebug(
"NFLOG netlink queue timeout can't be set to %d",
292 if (ntv->livedev == NULL) {
300 struct timeval timev;
304 int fd = nflog_fd(ntv->h);
305 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timev,
sizeof(timev)) == -1) {
311 #ifdef PACKET_STATISTICS
319 if (active_runmode && !strcmp(
"workers", active_runmode))
324 #define T_DATA_SIZE 70000
326 if (ntv->data == NULL) {
351 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
353 SCLogDebug(
"closing nflog group %d", ntv->group);
354 if (nflog_unbind_pf(ntv->h, AF_INET) < 0) {
355 FatalError(
"nflog_unbind_pf() for AF_INET failed");
358 if (nflog_unbind_pf(ntv->h, AF_INET6) < 0) {
359 FatalError(
"nflog_unbind_pf() for AF_INET6 failed");
363 nflog_unbind_group(ntv->gh);
372 if (ntv->data != NULL) {
392 static int NFLOGSetnlbufsiz(
void *data,
unsigned int size)
395 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
397 if (size < ntv->nlbufsiz_max) {
398 ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz);
402 SCLogWarning(
"Maximum buffer size (%d) in NFLOG has been "
403 "reached. Please, consider raising "
404 "`buffer-size` and `max-size` in nflog configuration",
425 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
429 ntv->slot = ((
TmSlot *) slot)->slot_next;
431 fd = nflog_fd(ntv->h);
445 rv = recv(fd, ntv->data, ntv->datalen, 0);
448 if (errno == EINTR || errno == EWOULDBLOCK) {
451 }
else if (errno == ENOBUFS) {
452 if (!ntv->nful_overrun_warned) {
453 int s = ntv->nlbufsiz * 2;
454 if (NFLOGSetnlbufsiz((
void *)ntv, s)) {
456 "increasing buffer size "
460 ntv->nful_overrun_warned = 1;
465 SCLogWarning(
"Read from NFLOG fd failed: %s", strerror(errno));
470 ret = nflog_handle_packet(ntv->h, ntv->data, rv);
472 SCLogWarning(
"nflog_handle_packet error %" PRId32
"", ret);
485 void ReceiveNFLOGThreadExitStats(
ThreadVars *
tv,
void *data)
488 NFLOGThreadVars *ntv = (NFLOGThreadVars *)data;
490 SCLogNotice(
"(%s) Pkts %" PRIu32
", Bytes %" PRIu64
"",
491 tv->
name, ntv->pkts, ntv->bytes);