suricata
source-ipfw.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2014 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Nick Rogness <nick@rogness.net>
22  * \author Eric Leblond <eric@regit.org>
23  *
24  * IPFW packet acquisition support
25  */
26 
27 #include "suricata-common.h"
28 #include "suricata.h"
29 #include "decode.h"
30 #include "packet-queue.h"
31 #include "threads.h"
32 #include "threadvars.h"
33 #include "tm-queuehandlers.h"
34 #include "tm-threads.h"
35 #include "source-ipfw.h"
36 #include "util-debug.h"
37 #include "conf.h"
38 #include "util-byte.h"
39 #include "util-privs.h"
40 #include "util-datalink.h"
41 #include "util-device.h"
42 #include "runmodes.h"
43 
44 #define IPFW_ACCEPT 0
45 #define IPFW_DROP 1
46 
47 #define IPFW_SOCKET_POLL_MSEC 300
48 
49 #ifndef IP_MAXPACKET
50 #define IP_MAXPACKET 65535
51 #endif
52 
53 #ifndef IPFW
54 /* Handle the case if --enable-ipfw was not used
55  *
56  */
57 
58 TmEcode NoIPFWSupportExit(ThreadVars *, const void *, void **);
59 
61 {
62 
63  tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW";
64  tmm_modules[TMM_RECEIVEIPFW].ThreadInit = NoIPFWSupportExit;
69 }
70 
72 {
73  tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW";
74  tmm_modules[TMM_VERDICTIPFW].ThreadInit = NoIPFWSupportExit;
78 }
79 
81 {
82  tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW";
83  tmm_modules[TMM_DECODEIPFW].ThreadInit = NoIPFWSupportExit;
89 }
90 
91 TmEcode NoIPFWSupportExit(ThreadVars *tv, const void *initdata, void **data)
92 {
93 
94  SCLogError(SC_ERR_IPFW_NOSUPPORT,"Error creating thread %s: you do not have support for ipfw "
95  "enabled please recompile with --enable-ipfw", tv->name);
96  exit(EXIT_FAILURE);
97 }
98 
99 #else /* We have IPFW compiled in */
100 
101 extern int max_pending_packets;
102 
103 /**
104  * \brief Structure to hold thread specific variables.
105  */
106 typedef struct IPFWThreadVars_
107 {
108  /* data link type for the thread, probably not needed */
109  int datalink;
110 
111  /* this one should be not changing after init */
112  uint16_t port_num;
113  /* position into the NFQ queue var array */
114  uint16_t ipfw_index;
115 
116  /* counters */
117  uint32_t pkts;
118  uint64_t bytes;
119  uint32_t errs;
120  uint32_t accepted;
121  uint32_t dropped;
123 
124 static IPFWThreadVars ipfw_t[IPFW_MAX_QUEUE];
125 static IPFWQueueVars ipfw_q[IPFW_MAX_QUEUE];
126 static uint16_t receive_port_num = 0;
127 static SCMutex ipfw_init_lock;
128 
129 /* IPFW Prototypes */
130 static void *IPFWGetQueue(int number);
131 static TmEcode ReceiveIPFWThreadInit(ThreadVars *, const void *, void **);
132 static TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot);
133 static void ReceiveIPFWThreadExitStats(ThreadVars *, void *);
134 static TmEcode ReceiveIPFWThreadDeinit(ThreadVars *, void *);
135 
136 static TmEcode IPFWSetVerdict(ThreadVars *, IPFWThreadVars *, Packet *);
137 static TmEcode VerdictIPFW(ThreadVars *, Packet *, void *);
138 static TmEcode VerdictIPFWThreadInit(ThreadVars *, const void *, void **);
139 static void VerdictIPFWThreadExitStats(ThreadVars *, void *);
140 static TmEcode VerdictIPFWThreadDeinit(ThreadVars *, void *);
141 
142 static TmEcode DecodeIPFWThreadInit(ThreadVars *, const void *, void **);
143 static TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data);
144 static TmEcode DecodeIPFW(ThreadVars *, Packet *, void *);
145 
146 /**
147  * \brief Registration Function for RecieveIPFW.
148  * \todo Unit tests are needed for this module.
149  */
151 {
152  SCMutexInit(&ipfw_init_lock, NULL);
153 
154  tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW";
155  tmm_modules[TMM_RECEIVEIPFW].ThreadInit = ReceiveIPFWThreadInit;
157  tmm_modules[TMM_RECEIVEIPFW].PktAcqLoop = ReceiveIPFWLoop;
159  tmm_modules[TMM_RECEIVEIPFW].ThreadExitPrintStats = ReceiveIPFWThreadExitStats;
160  tmm_modules[TMM_RECEIVEIPFW].ThreadDeinit = ReceiveIPFWThreadDeinit;
163  SC_CAP_NET_BROADCAST; /** \todo untested */
165 }
166 
167 /**
168  * \brief Registration Function for VerdictIPFW.
169  * \todo Unit tests are needed for this module.
170  */
172 {
173  tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW";
174  tmm_modules[TMM_VERDICTIPFW].ThreadInit = VerdictIPFWThreadInit;
175  tmm_modules[TMM_VERDICTIPFW].Func = VerdictIPFW;
176  tmm_modules[TMM_VERDICTIPFW].ThreadExitPrintStats = VerdictIPFWThreadExitStats;
177  tmm_modules[TMM_VERDICTIPFW].ThreadDeinit = VerdictIPFWThreadDeinit;
179  SC_CAP_NET_BIND_SERVICE; /** \todo untested */
180 }
181 
182 /**
183  * \brief Registration Function for DecodeIPFW.
184  * \todo Unit tests are needed for this module.
185  */
187 {
188  tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW";
189  tmm_modules[TMM_DECODEIPFW].ThreadInit = DecodeIPFWThreadInit;
190  tmm_modules[TMM_DECODEIPFW].Func = DecodeIPFW;
192  tmm_modules[TMM_DECODEIPFW].ThreadDeinit = DecodeIPFWThreadDeinit;
194 }
195 
196 static inline void IPFWMutexInit(IPFWQueueVars *nq)
197 {
198  char *active_runmode = RunmodeGetActive();
199 
200  if (active_runmode && !strcmp("workers", active_runmode)) {
201  nq->use_mutex = 0;
202  SCLogInfo("IPFW running in 'workers' runmode, will not use mutex.");
203  } else {
204  nq->use_mutex = 1;
205  }
206  if (nq->use_mutex)
207  SCMutexInit(&nq->socket_lock, NULL);
208 }
209 
210 static inline void IPFWMutexLock(IPFWQueueVars *nq)
211 {
212  if (nq->use_mutex)
213  SCMutexLock(&nq->socket_lock);
214 }
215 
216 static inline void IPFWMutexUnlock(IPFWQueueVars *nq)
217 {
218  if (nq->use_mutex)
220 }
221 
222 TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot)
223 {
224  SCEnter();
225 
226  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
227  IPFWQueueVars *nq = NULL;
228  uint8_t pkt[IP_MAXPACKET];
229  int pktlen=0;
230  struct pollfd IPFWpoll;
231  struct timeval IPFWts;
232  Packet *p = NULL;
233 
234  nq = IPFWGetQueue(ptv->ipfw_index);
235  if (nq == NULL) {
236  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Can't get thread variable");
238  }
239 
240  SCLogInfo("Thread '%s' will run on port %d (item %d)",
241  tv->name, nq->port_num, ptv->ipfw_index);
242  while (1) {
243  if (unlikely(suricata_ctl_flags != 0)) {
245  }
246 
247  IPFWpoll.fd = nq->fd;
248  IPFWpoll.events = POLLRDNORM;
249  /* Poll the socket for status */
250  if ( (poll(&IPFWpoll, 1, IPFW_SOCKET_POLL_MSEC)) > 0) {
251  if (!(IPFWpoll.revents & (POLLRDNORM | POLLERR)))
252  continue;
253  }
254 
255  if ((pktlen = recvfrom(nq->fd, pkt, sizeof(pkt), 0,
256  (struct sockaddr *)&nq->ipfw_sin,
257  &nq->ipfw_sinlen)) == -1) {
258  /* We received an error on socket read */
259  if (errno == EINTR || errno == EWOULDBLOCK) {
260  /* Nothing for us to process */
261  continue;
262  } else {
264  "Read from IPFW divert socket failed: %s",
265  strerror(errno));
267  }
268  }
269  /* We have a packet to process */
270  memset (&IPFWts, 0, sizeof(struct timeval));
271  gettimeofday(&IPFWts, NULL);
272 
273  /* make sure we have at least one packet in the packet pool, to prevent
274  * us from alloc'ing packets at line rate */
275  PacketPoolWait();
276 
278  if (p == NULL) {
280  }
282 
283  SCLogDebug("Received Packet Len: %d", pktlen);
284 
285  p->ts.tv_sec = IPFWts.tv_sec;
286  p->ts.tv_usec = IPFWts.tv_usec;
287 
288  ptv->pkts++;
289  ptv->bytes += pktlen;
290 
291  p->datalink = ptv->datalink;
292 
293  p->ipfw_v.ipfw_index = ptv->ipfw_index;
294 
295  PacketCopyData(p, pkt, pktlen);
296  SCLogDebug("Packet info: pkt_len: %" PRIu32 " (pkt %02x, pkt_data %02x)",
297  GET_PKT_LEN(p), *pkt, *(GET_PKT_DATA(p)));
298 
299  if (TmThreadsSlotProcessPkt(tv, ((TmSlot *) slot)->slot_next, p)
300  != TM_ECODE_OK) {
302  }
303 
305  }
306 
308 }
309 
310 /**
311  * \brief Init function for RecieveIPFW.
312  *
313  * This is a setup function for recieving packets
314  * via ipfw divert, binds a socket, and prepares to
315  * to read from it.
316  *
317  * \param tv pointer to ThreadVars
318  * \param initdata pointer to the divert port passed from the user
319  * \param data pointer gets populated with IPFWThreadVars
320  *
321  */
322 TmEcode ReceiveIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
323 {
324  struct timeval timev;
325  IPFWThreadVars *ntv = (IPFWThreadVars *) initdata;
326  IPFWQueueVars *nq = IPFWGetQueue(ntv->ipfw_index);
327 
328  sigset_t sigs;
329  sigfillset(&sigs);
330  pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
331 
332  SCEnter();
333 
334  IPFWMutexInit(nq);
335  /* We need a divert socket to play with */
336 #ifdef PF_DIVERT
337  if ((nq->fd = socket(PF_DIVERT, SOCK_RAW, 0)) == -1) {
338 #else
339  if ((nq->fd = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
340 #endif
341  SCLogError(SC_ERR_IPFW_SOCK,"Can't create divert socket: %s", strerror(errno));
343  }
344 
345  /* set a timeout to the socket so we can check for a signal
346  * in case we don't get packets for a longer period. */
347  timev.tv_sec = 1;
348  timev.tv_usec = 0;
349 
350  if (setsockopt(nq->fd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)) == -1) {
351  SCLogError(SC_ERR_IPFW_SETSOCKOPT,"Can't set IPFW divert socket timeout: %s", strerror(errno));
353  }
354 
355  nq->ipfw_sinlen=sizeof(nq->ipfw_sin);
356  memset(&nq->ipfw_sin, 0, nq->ipfw_sinlen);
357  nq->ipfw_sin.sin_family = PF_INET;
358  nq->ipfw_sin.sin_addr.s_addr = INADDR_ANY;
359  nq->ipfw_sin.sin_port = htons(nq->port_num);
360 
361  /* Bind that SOB */
362  if (bind(nq->fd, (struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) {
363  SCLogError(SC_ERR_IPFW_BIND,"Can't bind divert socket on port %d: %s",nq->port_num,strerror(errno));
365  }
366 
367  ntv->datalink = DLT_RAW;
368  DatalinkSetGlobalType(DLT_RAW);
369 
370  *data = (void *)ntv;
371 
373 }
374 
375 /**
376  * \brief This function prints stats to the screen at exit.
377  * \todo Unit tests are needed for this module.
378  * \param tv pointer to ThreadVars
379  * \param data pointer that gets cast into IPFWThreadVars for ptv
380  */
381 void ReceiveIPFWThreadExitStats(ThreadVars *tv, void *data)
382 {
383  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
384 
385  SCEnter();
386 
387  SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "",
388  tv->name, ptv->pkts, ptv->bytes, ptv->errs);
389  SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32 "",
390  tv->name, ptv->accepted, ptv->dropped);
391 
392 
393  SCReturn;
394 }
395 
396 /**
397  * \brief DeInit function closes divert socket at exit.
398  * \todo Unit tests are needed for this module.
399  * \param tv pointer to ThreadVars
400  * \param data pointer that gets cast into IPFWThreadVars for ptv
401  */
402 TmEcode ReceiveIPFWThreadDeinit(ThreadVars *tv, void *data)
403 {
404  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
405  IPFWQueueVars *nq = IPFWGetQueue(ptv->ipfw_index);
406 
407  SCEnter();
408 
409  /* Attempt to shut the socket down...close instead? */
410  if (shutdown(nq->fd, SHUT_RD) < 0) {
411  SCLogWarning(SC_WARN_IPFW_UNBIND,"Unable to disable ipfw socket: %s",strerror(errno));
413  }
414 
416 }
417 
418 /**
419  * \brief This function passes off to link type decoders.
420  * \todo Unit tests are needed for this module.
421  *
422  * DecodeIPFW decodes packets from IPFW and passes
423  * them off to the proper link type decoder.
424  *
425  * \param tv pointer to ThreadVars
426  * \param p pointer to the current packet
427  * \param data pointer that gets cast into IPFWThreadVars for ptv
428  */
429 TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data)
430 {
431  IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
432  IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
434 
435  SCEnter();
436 
438 
439  /* update counters */
441 
442  /* Process IP packets */
443  if (IPV4_GET_RAW_VER(ip4h) == 4) {
444  if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
445  return TM_ECODE_FAILED;
446  }
447  SCLogDebug("DecodeIPFW ip4 processing");
449 
450  } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
451  if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
452  return TM_ECODE_FAILED;
453  }
454  SCLogDebug("DecodeIPFW ip6 processing");
456 
457  } else {
458  /* We don't support anything besides IP packets for now, bridged packets? */
459  SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p));
461  }
462 
464 
466 }
467 
468 /**
469  * \brief This function initializes the DecodeThreadVariables
470  *
471  *
472  * \param tv pointer to ThreadVars
473  * \param initdata pointer for passing in args
474  * \param data pointer that gets cast into IPFWThreadVars for ptv
475  */
476 TmEcode DecodeIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
477 {
478  DecodeThreadVars *dtv = NULL;
480 
481  if (dtv == NULL)
483 
485 
486  *data = (void *)dtv;
487 
489 }
490 
491 TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data)
492 {
493  if (data != NULL)
494  DecodeThreadVarsFree(tv, data);
496 }
497 
498 /**
499  * \brief This function sets the Verdict and processes the packet
500  *
501  *
502  * \param tv pointer to ThreadVars
503  * \param p pointer to the Packet
504  */
505 TmEcode IPFWSetVerdict(ThreadVars *tv, IPFWThreadVars *ptv, Packet *p)
506 {
507  uint32_t verdict;
508 #if 0
509  struct pollfd IPFWpoll;
510 #endif
511  IPFWQueueVars *nq = NULL;
512 
513  SCEnter();
514 
515  if (p == NULL) {
516  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Packet is NULL");
518  }
519 
520  nq = IPFWGetQueue(p->ipfw_v.ipfw_index);
521  if (nq == NULL) {
522  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "No thread found");
524  }
525 
526 #if 0
527  IPFWpoll.fd = nq->fd;
528  IPFWpoll.events = POLLWRNORM;
529 #endif
530 
531  if (PacketTestAction(p, ACTION_DROP)) {
532  verdict = IPFW_DROP;
533  } else {
534  verdict = IPFW_ACCEPT;
535  }
536 
537  if (verdict == IPFW_ACCEPT) {
538  SCLogDebug("IPFW Verdict is to Accept");
539  ptv->accepted++;
540 
541  /* For divert sockets, accepting means writing the
542  * packet back to the socket for ipfw to pick up
543  */
544  SCLogDebug("IPFWSetVerdict writing to socket %d, %p, %u", nq->fd, GET_PKT_DATA(p),GET_PKT_LEN(p));
545 
546 #if 0
547  while ((poll(&IPFWpoll,1,IPFW_SOCKET_POLL_MSEC)) < 1) {
548  /* Did we receive a signal to shutdown */
550  SCLogInfo("Received ThreadShutdown: IPFW divert socket writing interrupted");
552  }
553  }
554 #endif
555 
556  IPFWMutexLock(nq);
557  if (sendto(nq->fd, GET_PKT_DATA(p), GET_PKT_LEN(p), 0,(struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) {
558  int r = errno;
559  switch (r) {
560  default:
561  SCLogWarning(SC_WARN_IPFW_XMIT,"Write to ipfw divert socket failed: %s",strerror(r));
562  IPFWMutexUnlock(nq);
564  case EHOSTDOWN:
565  case ENETDOWN:
566  break;
567  }
568  }
569 
570  IPFWMutexUnlock(nq);
571 
572  SCLogDebug("Sent Packet back into IPFW Len: %d",GET_PKT_LEN(p));
573 
574  } /* end IPFW_ACCEPT */
575 
576 
577  if (verdict == IPFW_DROP) {
578  SCLogDebug("IPFW SetVerdict is to DROP");
579  ptv->dropped++;
580 
581  /** \todo For divert sockets, dropping means not writing the packet back to the socket.
582  * Need to see if there is some better way to free the packet from the queue */
583 
584  } /* end IPFW_DROP */
585 
587 }
588 
589 
590 /**
591  * \brief This function handles the Verdict processing
592  * \todo Unit tests are needed for this module.
593  *
594  *
595  * \param tv pointer to ThreadVars
596  * \param p pointer to the Packet
597  * \param data pointer that gets cast into IPFWThreadVars for ptv
598  */
599 TmEcode VerdictIPFW(ThreadVars *tv, Packet *p, void *data)
600 {
601  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
602  TmEcode retval = TM_ECODE_OK;
603 
604  SCEnter();
605 
606  /* can't verdict a "fake" packet */
607  if (p->flags & PKT_PSEUDO_STREAM_END) {
609  }
610 
611  /* This came from NFQ.
612  * if this is a tunnel packet we check if we are ready to verdict
613  * already. */
614  if (IS_TUNNEL_PKT(p)) {
615  bool verdict = VerdictTunnelPacket(p);
616 
617  /* don't verdict if we are not ready */
618  if (verdict == true) {
619  SCLogDebug("Setting verdict on tunnel");
620  retval = IPFWSetVerdict(tv, ptv, p->root ? p->root : p);
621  }
622  } else {
623  /* no tunnel, verdict normally */
624  SCLogDebug("Setting verdict on non-tunnel");
625  retval = IPFWSetVerdict(tv, ptv, p);
626  } /* IS_TUNNEL_PKT end */
627 
628  SCReturnInt(retval);
629 }
630 
631 /**
632  * \brief This function initializes the VerdictThread
633  *
634  *
635  * \param t pointer to ThreadVars
636  * \param initdata pointer for passing in args
637  * \param data pointer that gets cast into IPFWThreadVars for ptv
638  */
639 TmEcode VerdictIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
640 {
641 
642  IPFWThreadVars *ptv = NULL;
643 
644  SCEnter();
645 
646  /* Setup Thread vars */
647  if ( (ptv = SCMalloc(sizeof(IPFWThreadVars))) == NULL)
649  memset(ptv, 0, sizeof(IPFWThreadVars));
650 
651 
652  *data = (void *)ptv;
653 
655 }
656 
657 /**
658  * \brief This function deinitializes the VerdictThread
659  *
660  *
661  * \param tv pointer to ThreadVars
662  * \param data pointer that gets cast into IPFWThreadVars for ptv
663  */
664 TmEcode VerdictIPFWThreadDeinit(ThreadVars *tv, void *data)
665 {
666 
667  SCEnter();
668 
669  /* We don't need to do anything...not sure quite yet */
670 
671 
673 }
674 
675 /**
676  * \brief This function prints stats for the VerdictThread
677  *
678  *
679  * \param tv pointer to ThreadVars
680  * \param data pointer that gets cast into IPFWThreadVars for ptv
681  */
682 void VerdictIPFWThreadExitStats(ThreadVars *tv, void *data)
683 {
684  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
685  SCLogInfo("IPFW Processing: - (%s) Pkts accepted %" PRIu32 ", dropped %" PRIu32 "", tv->name, ptv->accepted, ptv->dropped);
686 }
687 
688 /**
689  * \brief Add an IPFW divert
690  *
691  * \param string with the queue name
692  *
693  * \retval 0 on success.
694  * \retval -1 on failure.
695  */
696 int IPFWRegisterQueue(char *queue)
697 {
698  IPFWThreadVars *ntv = NULL;
699  IPFWQueueVars *nq = NULL;
700  /* Extract the queue number from the specified command line argument */
701  uint16_t port_num = 0;
702  if ((StringParseUint16(&port_num, 10, strlen(queue), queue)) < 0)
703  {
704  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue number %s is not "
705  "valid", queue);
706  return -1;
707  }
708 
709  SCMutexLock(&ipfw_init_lock);
710  if (receive_port_num >= IPFW_MAX_QUEUE) {
712  "too much IPFW divert port registered (%d)",
713  receive_port_num);
714  SCMutexUnlock(&ipfw_init_lock);
715  return -1;
716  }
717  if (receive_port_num == 0) {
718  memset(&ipfw_t, 0, sizeof(ipfw_t));
719  memset(&ipfw_q, 0, sizeof(ipfw_q));
720  }
721 
722  ntv = &ipfw_t[receive_port_num];
723  ntv->ipfw_index = receive_port_num;
724 
725  nq = &ipfw_q[receive_port_num];
726  nq->port_num = port_num;
727  receive_port_num++;
728  SCMutexUnlock(&ipfw_init_lock);
729  LiveRegisterDeviceName(queue);
730 
731  SCLogDebug("Queue \"%s\" registered.", queue);
732  return 0;
733 }
734 
735 /**
736  * \brief Get a pointer to the IPFW queue at index
737  *
738  * \param number idx of the queue in our array
739  *
740  * \retval ptr pointer to the IPFWThreadVars at index
741  * \retval NULL on error
742  */
743 void *IPFWGetQueue(int number)
744 {
745  if (number >= receive_port_num)
746  return NULL;
747 
748  return (void *)&ipfw_q[number];
749 }
750 
751 /**
752  * \brief Get a pointer to the IPFW thread at index
753  *
754  * This function is temporary used as configuration parser.
755  *
756  * \param number idx of the queue in our array
757  *
758  * \retval ptr pointer to the IPFWThreadVars at index
759  * \retval NULL on error
760  */
761 void *IPFWGetThread(int number)
762 {
763  if (number >= receive_port_num)
764  return NULL;
765 
766  return (void *)&ipfw_t[number];
767 }
768 
769 #endif /* End ifdef IPFW */
770 
771 /* eof */
772 
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
util-byte.h
tm-threads.h
TmModuleReceiveIPFWRegister
void TmModuleReceiveIPFWRegister(void)
Registration Function for RecieveIPFW.
Definition: source-ipfw.c:150
IPFWQueueVars_::socket_lock
SCMutex socket_lock
Definition: source-ipfw.h:39
max_pending_packets
int max_pending_packets
Definition: suricata.c:222
IPV6_GET_RAW_VER
#define IPV6_GET_RAW_VER(ip6h)
Definition: decode-ipv6.h:62
ThreadVars_::name
char name[16]
Definition: threadvars.h:63
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:298
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1222
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
IPFWThreadVars_::dropped
uint32_t dropped
Definition: source-ipfw.c:121
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
Packet_::flags
uint32_t flags
Definition: decode.h:469
threads.h
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:336
SC_ERR_IPFW_NOSUPPORT
@ SC_ERR_IPFW_NOSUPPORT
Definition: util-error.h:109
Packet_::ipfw_v
IPFWPacketVars ipfw_v
Definition: decode.h:488
packet-queue.h
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
util-privs.h
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:138
SC_CAP_NET_BROADCAST
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:150
RunmodeGetActive
char * RunmodeGetActive(void)
Definition: runmodes.c:213
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
IPFW_MAX_QUEUE
#define IPFW_MAX_QUEUE
Definition: source-ipfw.h:28
THV_PAUSE
#define THV_PAUSE
Definition: threadvars.h:37
IPFW_DROP
#define IPFW_DROP
Definition: source-ipfw.c:45
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1225
SC_CAP_NET_BIND_SERVICE
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:526
IPFWThreadVars_::accepted
uint32_t accepted
Definition: source-ipfw.c:120
SC_ERR_IPFW_BIND
@ SC_ERR_IPFW_BIND
Definition: util-error.h:110
decode.h
util-device.h
util-debug.h
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:54
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
IPFWQueueVars_::fd
int fd
Definition: source-ipfw.h:38
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
PKT_PSEUDO_STREAM_END
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1171
SC_ERR_IPFW_SETSOCKOPT
@ SC_ERR_IPFW_SETSOCKOPT
Definition: util-error.h:258
SC_WARN_IPFW_UNBIND
@ SC_WARN_IPFW_UNBIND
Definition: util-error.h:116
TmModuleVerdictIPFWRegister
void TmModuleVerdictIPFWRegister(void)
Registration Function for VerdictIPFW.
Definition: source-ipfw.c:171
SCEnter
#define SCEnter(...)
Definition: util-debug.h:298
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:227
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:56
IPFWThreadVars_::errs
uint32_t errs
Definition: source-ipfw.c:119
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
THV_KILL
#define THV_KILL
Definition: threadvars.h:39
SC_CAP_NET_ADMIN
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:281
IPFWRegisterQueue
int IPFWRegisterQueue(char *queue)
Add an IPFW divert.
Definition: source-ipfw.c:696
IPFWQueueVars_::ipfw_sin
struct sockaddr_in ipfw_sin
Definition: source-ipfw.h:45
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:85
SCReturn
#define SCReturn
Definition: util-debug.h:300
IPV6Hdr_
Definition: decode-ipv6.h:32
Packet_
Definition: decode.h:434
TM_FLAG_DECODE_TM
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
DecodeIPV6
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv6.c:572
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:226
conf.h
source-ipfw.h
IPV4_GET_RAW_VER
#define IPV4_GET_RAW_VER(ip4h)
Definition: decode-ipv4.h:95
TmSlot_
Definition: tm-threads.h:52
TmEcode
TmEcode
Definition: tm-threads-common.h:81
IS_TUNNEL_PKT
#define IS_TUNNEL_PKT(p)
Definition: decode.h:963
IPFWThreadVars_::ipfw_index
uint16_t ipfw_index
Definition: source-ipfw.c:114
IPFWThreadVars
struct IPFWThreadVars_ IPFWThreadVars
Structure to hold thread specific variables.
TmModule_::name
const char * name
Definition: tm-modules.h:44
SC_WARN_IPFW_XMIT
@ SC_WARN_IPFW_XMIT
Definition: util-error.h:114
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:215
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:32
IP_MAXPACKET
#define IP_MAXPACKET
Definition: source-ipfw.c:50
IPV4Hdr_
Definition: decode-ipv4.h:72
tm-queuehandlers.h
IPFWQueueVars_::use_mutex
uint8_t use_mutex
Definition: source-ipfw.h:40
IPFWThreadVars_
Structure to hold thread specific variables.
Definition: source-ipfw.c:107
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:706
IPFW_SOCKET_POLL_MSEC
#define IPFW_SOCKET_POLL_MSEC
Definition: source-ipfw.c:47
suricata-common.h
IPFWGetThread
void * IPFWGetThread(int number)
Get a pointer to the IPFW thread at index.
Definition: source-ipfw.c:761
IPFW_ACCEPT
#define IPFW_ACCEPT
Definition: source-ipfw.c:44
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
IPFWThreadVars_::pkts
uint32_t pkts
Definition: source-ipfw.c:117
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
IPFWThreadVars_::datalink
int datalink
Definition: source-ipfw.c:109
TMM_RECEIVEIPFW
@ TMM_RECEIVEIPFW
Definition: tm-threads-common.h:49
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:31
TMM_VERDICTIPFW
@ TMM_VERDICTIPFW
Definition: tm-threads-common.h:48
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
threadvars.h
TmModuleDecodeIPFWRegister
void TmModuleDecodeIPFWRegister(void)
Registration Function for DecodeIPFW.
Definition: source-ipfw.c:186
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
Packet_::root
struct Packet_ * root
Definition: decode.h:619
IPFWQueueVars_::port_num
uint16_t port_num
Definition: source-ipfw.h:42
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:242
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:664
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:687
IPFWQueueVars_::ipfw_sinlen
socklen_t ipfw_sinlen
Definition: source-ipfw.h:46
IPFWThreadVars_::bytes
uint64_t bytes
Definition: source-ipfw.c:118
suricata.h
SC_ERR_IPFW_SOCK
@ SC_ERR_IPFW_SOCK
Definition: util-error.h:111
IPFWPacketVars_::ipfw_index
int ipfw_index
Definition: source-ipfw.h:33
TMM_DECODEIPFW
@ TMM_DECODEIPFW
Definition: tm-threads-common.h:47
IPFWQueueVars_
Definition: source-ipfw.h:37
LiveRegisterDeviceName
int LiveRegisterDeviceName(const char *dev)
Add a device for monitoring.
Definition: util-device.c:96
TmThreadsCheckFlag
int TmThreadsCheckFlag(ThreadVars *tv, uint32_t flag)
Check if a thread flag is set.
Definition: tm-threads.c:90
DecodeIPV4
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv4.c:528
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:230
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:302
SCMutex
#define SCMutex
Definition: threads-debug.h:114
IPFWThreadVars_::port_num
uint16_t port_num
Definition: source-ipfw.c:112
PacketGetFromQueueOrAlloc
Packet * PacketGetFromQueueOrAlloc(void)
Get a packet. We try to get a packet from the packetpool first, but if that is empty we alloc a packe...
Definition: decode.c:214
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:70
SC_WARN_IPFW_RECV
@ SC_WARN_IPFW_RECV
Definition: util-error.h:113
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:653
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:208