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-device.h"
41 #include "runmodes.h"
42 
43 #define IPFW_ACCEPT 0
44 #define IPFW_DROP 1
45 
46 #define IPFW_SOCKET_POLL_MSEC 300
47 
48 #ifndef IP_MAXPACKET
49 #define IP_MAXPACKET 65535
50 #endif
51 
52 #ifndef IPFW
53 /* Handle the case if --enable-ipfw was not used
54  *
55  */
56 
57 TmEcode NoIPFWSupportExit(ThreadVars *, const void *, void **);
58 
60 {
61 
62  tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW";
63  tmm_modules[TMM_RECEIVEIPFW].ThreadInit = NoIPFWSupportExit;
69 }
70 
72 {
73  tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW";
74  tmm_modules[TMM_VERDICTIPFW].ThreadInit = NoIPFWSupportExit;
79 }
80 
82 {
83  tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW";
84  tmm_modules[TMM_DECODEIPFW].ThreadInit = NoIPFWSupportExit;
91 }
92 
93 TmEcode NoIPFWSupportExit(ThreadVars *tv, const void *initdata, void **data)
94 {
95 
96  SCLogError(SC_ERR_IPFW_NOSUPPORT,"Error creating thread %s: you do not have support for ipfw "
97  "enabled please recompile with --enable-ipfw", tv->name);
98  exit(EXIT_FAILURE);
99 }
100 
101 #else /* We have IPFW compiled in */
102 
103 extern int max_pending_packets;
104 
105 /**
106  * \brief Structure to hold thread specific variables.
107  */
108 typedef struct IPFWThreadVars_
109 {
110  /* data link type for the thread, probably not needed */
111  int datalink;
112 
113  /* this one should be not changing after init */
114  uint16_t port_num;
115  /* position into the NFQ queue var array */
116  uint16_t ipfw_index;
117 
118  /* counters */
119  uint32_t pkts;
120  uint64_t bytes;
121  uint32_t errs;
122  uint32_t accepted;
123  uint32_t dropped;
125 
126 static IPFWThreadVars ipfw_t[IPFW_MAX_QUEUE];
127 static IPFWQueueVars ipfw_q[IPFW_MAX_QUEUE];
128 static uint16_t receive_port_num = 0;
129 static SCMutex ipfw_init_lock;
130 
131 /* IPFW Prototypes */
132 void *IPFWGetQueue(int number);
133 TmEcode ReceiveIPFWThreadInit(ThreadVars *, const void *, void **);
135 TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot);
136 void ReceiveIPFWThreadExitStats(ThreadVars *, void *);
138 
141 TmEcode VerdictIPFWThreadInit(ThreadVars *, const void *, void **);
142 void VerdictIPFWThreadExitStats(ThreadVars *, void *);
144 
145 TmEcode DecodeIPFWThreadInit(ThreadVars *, const void *, void **);
146 TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data);
148 
149 /**
150  * \brief Registration Function for RecieveIPFW.
151  * \todo Unit tests are needed for this module.
152  */
154 {
155  SCMutexInit(&ipfw_init_lock, NULL);
156 
157  tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW";
166  SC_CAP_NET_BROADCAST; /** \todo untested */
169 }
170 
171 /**
172  * \brief Registration Function for VerdictIPFW.
173  * \todo Unit tests are needed for this module.
174  */
176 {
177  tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW";
183  SC_CAP_NET_BIND_SERVICE; /** \todo untested */
185 }
186 
187 /**
188  * \brief Registration Function for DecodeIPFW.
189  * \todo Unit tests are needed for this module.
190  */
192 {
193  tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW";
200 }
201 
202 static inline void IPFWMutexInit(IPFWQueueVars *nq)
203 {
204  char *active_runmode = RunmodeGetActive();
205 
206  if (active_runmode && !strcmp("workers", active_runmode)) {
207  nq->use_mutex = 0;
208  SCLogInfo("IPFW running in 'workers' runmode, will not use mutex.");
209  } else {
210  nq->use_mutex = 1;
211  }
212  if (nq->use_mutex)
213  SCMutexInit(&nq->socket_lock, NULL);
214 }
215 
216 static inline void IPFWMutexLock(IPFWQueueVars *nq)
217 {
218  if (nq->use_mutex)
219  SCMutexLock(&nq->socket_lock);
220 }
221 
222 static inline void IPFWMutexUnlock(IPFWQueueVars *nq)
223 {
224  if (nq->use_mutex)
226 }
227 
228 TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot)
229 {
230  SCEnter();
231 
232  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
233  IPFWQueueVars *nq = NULL;
234  uint8_t pkt[IP_MAXPACKET];
235  int pktlen=0;
236  struct pollfd IPFWpoll;
237  struct timeval IPFWts;
238  Packet *p = NULL;
239 
240  nq = IPFWGetQueue(ptv->ipfw_index);
241  if (nq == NULL) {
242  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Can't get thread variable");
244  }
245 
246  SCLogInfo("Thread '%s' will run on port %d (item %d)",
247  tv->name, nq->port_num, ptv->ipfw_index);
248  while (1) {
249  if (unlikely(suricata_ctl_flags != 0)) {
251  }
252 
253  IPFWpoll.fd = nq->fd;
254  IPFWpoll.events = POLLRDNORM;
255  /* Poll the socket for status */
256  if ( (poll(&IPFWpoll, 1, IPFW_SOCKET_POLL_MSEC)) > 0) {
257  if (!(IPFWpoll.revents & (POLLRDNORM | POLLERR)))
258  continue;
259  }
260 
261  if ((pktlen = recvfrom(nq->fd, pkt, sizeof(pkt), 0,
262  (struct sockaddr *)&nq->ipfw_sin,
263  &nq->ipfw_sinlen)) == -1) {
264  /* We received an error on socket read */
265  if (errno == EINTR || errno == EWOULDBLOCK) {
266  /* Nothing for us to process */
267  continue;
268  } else {
270  "Read from IPFW divert socket failed: %s",
271  strerror(errno));
273  }
274  }
275  /* We have a packet to process */
276  memset (&IPFWts, 0, sizeof(struct timeval));
277  gettimeofday(&IPFWts, NULL);
278 
279  /* make sure we have at least one packet in the packet pool, to prevent
280  * us from alloc'ing packets at line rate */
281  PacketPoolWait();
282 
284  if (p == NULL) {
286  }
288 
289  SCLogDebug("Received Packet Len: %d", pktlen);
290 
291  p->ts.tv_sec = IPFWts.tv_sec;
292  p->ts.tv_usec = IPFWts.tv_usec;
293 
294  ptv->pkts++;
295  ptv->bytes += pktlen;
296 
297  p->datalink = ptv->datalink;
298 
299  p->ipfw_v.ipfw_index = ptv->ipfw_index;
300 
301  PacketCopyData(p, pkt, pktlen);
302  SCLogDebug("Packet info: pkt_len: %" PRIu32 " (pkt %02x, pkt_data %02x)",
303  GET_PKT_LEN(p), *pkt, *(GET_PKT_DATA(p)));
304 
305  if (TmThreadsSlotProcessPkt(tv, ((TmSlot *) slot)->slot_next, p)
306  != TM_ECODE_OK) {
307  TmqhOutputPacketpool(tv, p);
309  }
310 
312  }
313 
315 }
316 
317 /**
318  * \brief Init function for RecieveIPFW.
319  *
320  * This is a setup function for recieving packets
321  * via ipfw divert, binds a socket, and prepares to
322  * to read from it.
323  *
324  * \param tv pointer to ThreadVars
325  * \param initdata pointer to the divert port passed from the user
326  * \param data pointer gets populated with IPFWThreadVars
327  *
328  */
329 TmEcode ReceiveIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
330 {
331  struct timeval timev;
332  int flag;
333  IPFWThreadVars *ntv = (IPFWThreadVars *) initdata;
335 
336  sigset_t sigs;
337  sigfillset(&sigs);
338  pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
339 
340  SCEnter();
341 
342  IPFWMutexInit(nq);
343  /* We need a divert socket to play with */
344  if ((nq->fd = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
345  SCLogError(SC_ERR_IPFW_SOCK,"Can't create divert socket: %s", strerror(errno));
347  }
348 
349  /* set a timeout to the socket so we can check for a signal
350  * in case we don't get packets for a longer period. */
351  timev.tv_sec = 1;
352  timev.tv_usec = 0;
353 
354  if (setsockopt(nq->fd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)) == -1) {
355  SCLogError(SC_ERR_IPFW_SETSOCKOPT,"Can't set IPFW divert socket timeout: %s", strerror(errno));
357  }
358 
359  /* set SO_BROADCAST on the divert socket, otherwise sendto()
360  * returns EACCES when reinjecting broadcast packets. */
361  flag = 1;
362 
363  if (setsockopt(nq->fd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) == -1) {
364  SCLogError(SC_ERR_IPFW_SETSOCKOPT,"Can't set IPFW divert socket broadcast flag: %s", strerror(errno));
366  }
367 
368  nq->ipfw_sinlen=sizeof(nq->ipfw_sin);
369  memset(&nq->ipfw_sin, 0, nq->ipfw_sinlen);
370  nq->ipfw_sin.sin_family = PF_INET;
371  nq->ipfw_sin.sin_addr.s_addr = INADDR_ANY;
372  nq->ipfw_sin.sin_port = htons(nq->port_num);
373 
374  /* Bind that SOB */
375  if (bind(nq->fd, (struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) {
376  SCLogError(SC_ERR_IPFW_BIND,"Can't bind divert socket on port %d: %s",nq->port_num,strerror(errno));
378  }
379 
380  ntv->datalink = DLT_RAW;
381 
382  *data = (void *)ntv;
383 
385 }
386 
387 /**
388  * \brief This function prints stats to the screen at exit.
389  * \todo Unit tests are needed for this module.
390  * \param tv pointer to ThreadVars
391  * \param data pointer that gets cast into IPFWThreadVars for ptv
392  */
394 {
395  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
396 
397  SCEnter();
398 
399  SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "",
400  tv->name, ptv->pkts, ptv->bytes, ptv->errs);
401  SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32 "",
402  tv->name, ptv->accepted, ptv->dropped);
403 
404 
405  SCReturn;
406 }
407 
408 /**
409  * \brief DeInit function closes divert socket at exit.
410  * \todo Unit tests are needed for this module.
411  * \param tv pointer to ThreadVars
412  * \param data pointer that gets cast into IPFWThreadVars for ptv
413  */
415 {
416  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
418 
419  SCEnter();
420 
421  /* Attempt to shut the socket down...close instead? */
422  if (shutdown(nq->fd, SHUT_RD) < 0) {
423  SCLogWarning(SC_WARN_IPFW_UNBIND,"Unable to disable ipfw socket: %s",strerror(errno));
425  }
426 
428 }
429 
430 /**
431  * \brief This function passes off to link type decoders.
432  * \todo Unit tests are needed for this module.
433  *
434  * DecodeIPFW reads packets from the PacketQueue and passes
435  * them off to the proper link type decoder.
436  *
437  * \param tv pointer to ThreadVars
438  * \param p pointer to the current packet
439  * \param data pointer that gets cast into IPFWThreadVars for ptv
440  * \param pq pointer to the PacketQueue
441  */
442 TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
443 {
444  IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
445  IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
446  DecodeThreadVars *dtv = (DecodeThreadVars *)data;
447 
448  SCEnter();
449 
450  /* XXX HACK: flow timeout can call us for injected pseudo packets
451  * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
452  if (p->flags & PKT_PSEUDO_STREAM_END)
453  return TM_ECODE_OK;
454 
455  /* update counters */
456  DecodeUpdatePacketCounters(tv, dtv, p);
457 
458  /* Process IP packets */
459  if (IPV4_GET_RAW_VER(ip4h) == 4) {
460  if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
461  return TM_ECODE_FAILED;
462  }
463  SCLogDebug("DecodeIPFW ip4 processing");
464  DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
465 
466  } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
467  if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
468  return TM_ECODE_FAILED;
469  }
470  SCLogDebug("DecodeIPFW ip6 processing");
471  DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
472 
473  } else {
474  /* We don't support anything besides IP packets for now, bridged packets? */
475  SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p));
477  }
478 
479  PacketDecodeFinalize(tv, dtv, p);
480 
482 }
483 
484 /**
485  * \brief This function initializes the DecodeThreadVariables
486  *
487  *
488  * \param tv pointer to ThreadVars
489  * \param initdata pointer for passing in args
490  * \param data pointer that gets cast into IPFWThreadVars for ptv
491  */
492 TmEcode DecodeIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
493 {
494  DecodeThreadVars *dtv = NULL;
495  dtv = DecodeThreadVarsAlloc(tv);
496 
497  if (dtv == NULL)
499 
501 
502  *data = (void *)dtv;
503 
505 }
506 
508 {
509  if (data != NULL)
510  DecodeThreadVarsFree(tv, data);
512 }
513 
514 /**
515  * \brief This function sets the Verdict and processes the packet
516  *
517  *
518  * \param tv pointer to ThreadVars
519  * \param p pointer to the Packet
520  */
522 {
523  uint32_t verdict;
524 #if 0
525  struct pollfd IPFWpoll;
526 #endif
527  IPFWQueueVars *nq = NULL;
528 
529  SCEnter();
530 
531  if (p == NULL) {
532  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Packet is NULL");
534  }
535 
536  nq = IPFWGetQueue(p->ipfw_v.ipfw_index);
537  if (nq == NULL) {
538  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "No thread found");
540  }
541 
542 #if 0
543  IPFWpoll.fd = nq->fd;
544  IPFWpoll.events = POLLWRNORM;
545 #endif
546 
548  verdict = IPFW_DROP;
549  } else {
550  verdict = IPFW_ACCEPT;
551  }
552 
553  if (verdict == IPFW_ACCEPT) {
554  SCLogDebug("IPFW Verdict is to Accept");
555  ptv->accepted++;
556 
557  /* For divert sockets, accepting means writing the
558  * packet back to the socket for ipfw to pick up
559  */
560  SCLogDebug("IPFWSetVerdict writing to socket %d, %p, %u", nq->fd, GET_PKT_DATA(p),GET_PKT_LEN(p));
561 
562 #if 0
563  while ((poll(&IPFWpoll,1,IPFW_SOCKET_POLL_MSEC)) < 1) {
564  /* Did we receive a signal to shutdown */
566  SCLogInfo("Received ThreadShutdown: IPFW divert socket writing interrupted");
568  }
569  }
570 #endif
571 
572  IPFWMutexLock(nq);
573  if (sendto(nq->fd, GET_PKT_DATA(p), GET_PKT_LEN(p), 0,(struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) {
574  int r = errno;
575  switch (r) {
576  default:
577  SCLogWarning(SC_WARN_IPFW_XMIT,"Write to ipfw divert socket failed: %s",strerror(r));
578  IPFWMutexUnlock(nq);
580  case EHOSTDOWN:
581  case ENETDOWN:
582  break;
583  }
584  }
585 
586  IPFWMutexUnlock(nq);
587 
588  SCLogDebug("Sent Packet back into IPFW Len: %d",GET_PKT_LEN(p));
589 
590  } /* end IPFW_ACCEPT */
591 
592 
593  if (verdict == IPFW_DROP) {
594  SCLogDebug("IPFW SetVerdict is to DROP");
595  ptv->dropped++;
596 
597  /** \todo For divert sockets, dropping means not writing the packet back to the socket.
598  * Need to see if there is some better way to free the packet from the queue */
599 
600  } /* end IPFW_DROP */
601 
603 }
604 
605 
606 /**
607  * \brief This function handles the Verdict processing
608  * \todo Unit tests are needed for this module.
609  *
610  *
611  * \param tv pointer to ThreadVars
612  * \param p pointer to the Packet
613  * \param data pointer that gets cast into IPFWThreadVars for ptv
614  * \param pq pointer for the Packet Queue access (Not used)
615  */
616 TmEcode VerdictIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
617 {
618  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
619  TmEcode retval = TM_ECODE_OK;
620 
621  SCEnter();
622 
623  /* can't verdict a "fake" packet */
624  if (p->flags & PKT_PSEUDO_STREAM_END) {
626  }
627 
628  /* This came from NFQ.
629  * if this is a tunnel packet we check if we are ready to verdict
630  * already. */
631  if (IS_TUNNEL_PKT(p)) {
632  bool verdict = VerdictTunnelPacket(p);
633 
634  /* don't verdict if we are not ready */
635  if (verdict == true) {
636  SCLogDebug("Setting verdict on tunnel");
637  retval = IPFWSetVerdict(tv, ptv, p->root ? p->root : p);
638  }
639  } else {
640  /* no tunnel, verdict normally */
641  SCLogDebug("Setting verdict on non-tunnel");
642  retval = IPFWSetVerdict(tv, ptv, p);
643  } /* IS_TUNNEL_PKT end */
644 
645  SCReturnInt(retval);
646 }
647 
648 /**
649  * \brief This function initializes the VerdictThread
650  *
651  *
652  * \param t pointer to ThreadVars
653  * \param initdata pointer for passing in args
654  * \param data pointer that gets cast into IPFWThreadVars for ptv
655  */
656 TmEcode VerdictIPFWThreadInit(ThreadVars *tv, const void *initdata, void **data)
657 {
658 
659  IPFWThreadVars *ptv = NULL;
660 
661  SCEnter();
662 
663  /* Setup Thread vars */
664  if ( (ptv = SCMalloc(sizeof(IPFWThreadVars))) == NULL)
666  memset(ptv, 0, sizeof(IPFWThreadVars));
667 
668 
669  *data = (void *)ptv;
670 
672 }
673 
674 /**
675  * \brief This function deinitializes the VerdictThread
676  *
677  *
678  * \param tv pointer to ThreadVars
679  * \param data pointer that gets cast into IPFWThreadVars for ptv
680  */
682 {
683 
684  SCEnter();
685 
686  /* We don't need to do anything...not sure quite yet */
687 
688 
690 }
691 
692 /**
693  * \brief This function prints stats for the VerdictThread
694  *
695  *
696  * \param tv pointer to ThreadVars
697  * \param data pointer that gets cast into IPFWThreadVars for ptv
698  */
700 {
701  IPFWThreadVars *ptv = (IPFWThreadVars *)data;
702  SCLogInfo("IPFW Processing: - (%s) Pkts accepted %" PRIu32 ", dropped %" PRIu32 "", tv->name, ptv->accepted, ptv->dropped);
703 }
704 
705 /**
706  * \brief Add an IPFW divert
707  *
708  * \param string with the queue name
709  *
710  * \retval 0 on success.
711  * \retval -1 on failure.
712  */
713 int IPFWRegisterQueue(char *queue)
714 {
715  IPFWThreadVars *ntv = NULL;
716  IPFWQueueVars *nq = NULL;
717  /* Extract the queue number from the specified command line argument */
718  uint16_t port_num = 0;
719  if ((ByteExtractStringUint16(&port_num, 10, strlen(queue), queue)) < 0)
720  {
721  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue number %s is not "
722  "valid", queue);
723  return -1;
724  }
725 
726  SCMutexLock(&ipfw_init_lock);
727  if (receive_port_num >= IPFW_MAX_QUEUE) {
729  "too much IPFW divert port registered (%d)",
730  receive_port_num);
731  SCMutexUnlock(&ipfw_init_lock);
732  return -1;
733  }
734  if (receive_port_num == 0) {
735  memset(&ipfw_t, 0, sizeof(ipfw_t));
736  memset(&ipfw_q, 0, sizeof(ipfw_q));
737  }
738 
739  ntv = &ipfw_t[receive_port_num];
740  ntv->ipfw_index = receive_port_num;
741 
742  nq = &ipfw_q[receive_port_num];
743  nq->port_num = port_num;
744  receive_port_num++;
745  SCMutexUnlock(&ipfw_init_lock);
746  LiveRegisterDeviceName(queue);
747 
748  SCLogDebug("Queue \"%s\" registered.", queue);
749  return 0;
750 }
751 
752 /**
753  * \brief Get a pointer to the IPFW queue at index
754  *
755  * \param number idx of the queue in our array
756  *
757  * \retval ptr pointer to the IPFWThreadVars at index
758  * \retval NULL on error
759  */
760 void *IPFWGetQueue(int number)
761 {
762  if (number >= receive_port_num)
763  return NULL;
764 
765  return (void *)&ipfw_q[number];
766 }
767 
768 /**
769  * \brief Get a pointer to the IPFW thread at index
770  *
771  * This function is temporary used as configuration parser.
772  *
773  * \param number idx of the queue in our array
774  *
775  * \retval ptr pointer to the IPFWThreadVars at index
776  * \retval NULL on error
777  */
778 void *IPFWGetThread(int number)
779 {
780  if (number >= receive_port_num)
781  return NULL;
782 
783  return (void *)&ipfw_t[number];
784 }
785 
786 #endif /* End ifdef IPFW */
787 
788 /* eof */
789 
void VerdictIPFWThreadExitStats(ThreadVars *, void *)
This function prints stats for the VerdictThread.
Definition: source-ipfw.c:699
#define SCMutex
TmEcode IPFWSetVerdict(ThreadVars *, IPFWThreadVars *, Packet *)
This function sets the Verdict and processes the packet.
Definition: source-ipfw.c:521
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
int IPFWRegisterQueue(char *queue)
Add an IPFW divert.
Definition: source-ipfw.c:713
TmEcode DecodeIPFWThreadInit(ThreadVars *, const void *, void **)
This function initializes the DecodeThreadVariables.
Definition: source-ipfw.c:492
TmEcode VerdictIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
This function handles the Verdict processing.
Definition: source-ipfw.c:616
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:592
#define SCLogDebug(...)
Definition: util-debug.h:335
uint32_t dropped
Definition: source-ipfw.c:123
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
uint8_t cap_flags
Definition: tm-modules.h:67
struct sockaddr_in ipfw_sin
Definition: source-ipfw.h:45
IPFWPacketVars ipfw_v
Definition: decode.h:460
uint16_t port_num
Definition: source-ipfw.c:114
uint8_t flags
Definition: tm-modules.h:70
#define PACKET_TEST_ACTION(p, a)
Definition: decode.h:860
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:114
#define unlikely(expr)
Definition: util-optimize.h:35
#define IP_MAXPACKET
Definition: source-ipfw.c:49
TmEcode(* Func)(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
Definition: tm-modules.h:52
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:453
void * IPFWGetThread(int number)
Get a pointer to the IPFW thread at index.
Definition: source-ipfw.c:778
uint8_t use_mutex
Definition: source-ipfw.h:40
TmEcode DecodeIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
This function passes off to link type decoders.
Definition: source-ipfw.c:442
#define IS_TUNNEL_PKT(p)
Definition: decode.h:884
TmEcode ReceiveIPFWThreadInit(ThreadVars *, const void *, void **)
Init function for RecieveIPFW.
Definition: source-ipfw.c:329
uint16_t port_num
Definition: source-ipfw.h:42
void ReceiveIPFWThreadExitStats(ThreadVars *, void *)
This function prints stats to the screen at exit.
Definition: source-ipfw.c:393
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:201
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
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:176
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data)
Definition: source-ipfw.c:507
#define SCMutexLock(mut)
#define IPV4_GET_RAW_VER(ip4h)
Definition: decode-ipv4.h:94
char * RunmodeGetActive(void)
Definition: runmodes.c:189
#define IPFW_DROP
Definition: source-ipfw.c:44
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1134
int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:264
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:532
socklen_t ipfw_sinlen
Definition: source-ipfw.h:46
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv6.c:584
#define SCMutexUnlock(mut)
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
int max_pending_packets
Definition: suricata.c:215
#define IPV6_GET_RAW_VER(ip6h)
Definition: decode-ipv6.h:62
uint32_t accepted
Definition: source-ipfw.c:122
TmEcode VerdictIPFWThreadInit(ThreadVars *, const void *, void **)
This function initializes the VerdictThread.
Definition: source-ipfw.c:656
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
void(* RegisterTests)(void)
Definition: tm-modules.h:65
TmEcode ReceiveIPFWThreadDeinit(ThreadVars *, void *)
DeInit function closes divert socket at exit.
Definition: source-ipfw.c:414
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
#define SCEnter(...)
Definition: util-debug.h:337
struct IPFWThreadVars_ IPFWThreadVars
Structure to hold thread specific variables.
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1093
#define SCMutexInit(mut, mutattrs)
#define SCReturnInt(x)
Definition: util-debug.h:341
SCMutex socket_lock
Definition: source-ipfw.h:39
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
#define THV_PAUSE
Definition: threadvars.h:37
#define THV_KILL
Definition: threadvars.h:39
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
TmEcode VerdictIPFWThreadDeinit(ThreadVars *, void *)
This function deinitializes the VerdictThread.
Definition: source-ipfw.c:681
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
void PacketPoolWait(void)
const char * name
Definition: tm-modules.h:44
void TmModuleReceiveIPFWRegister(void)
Registration Function for RecieveIPFW.
Definition: source-ipfw.c:153
#define SCMalloc(a)
Definition: util-mem.h:166
#define IPFW_SOCKET_POLL_MSEC
Definition: source-ipfw.c:46
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
#define IPFW_ACCEPT
Definition: source-ipfw.c:43
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:269
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.h:73
uint16_t ipfw_index
Definition: source-ipfw.c:116
void * IPFWGetQueue(int number)
Get a pointer to the IPFW queue at index.
Definition: source-ipfw.c:760
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:136
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
TmEcode ReceiveIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
int TmThreadsCheckFlag(ThreadVars *tv, uint16_t flag)
Check if a thread flag is set.
Definition: tm-threads.c:90
#define GET_PKT_DATA(p)
Definition: decode.h:223
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:558
TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot)
Definition: source-ipfw.c:228
char name[16]
Definition: threadvars.h:59
#define IPFW_MAX_QUEUE
Definition: source-ipfw.h:28
#define SCReturn
Definition: util-debug.h:339
Per thread variable structure.
Definition: threadvars.h:57
void TmModuleDecodeIPFWRegister(void)
Registration Function for DecodeIPFW.
Definition: source-ipfw.c:191
#define GET_PKT_LEN(p)
Definition: decode.h:222
uint64_t bytes
Definition: source-ipfw.c:120
#define ACTION_DROP
uint32_t flags
Definition: decode.h:441
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:618
int PacketCopyData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:258
Structure to hold thread specific variables.
Definition: source-ipfw.c:108
void TmModuleVerdictIPFWRegister(void)
Registration Function for VerdictIPFW.
Definition: source-ipfw.c:175
int LiveRegisterDeviceName(const char *dev)
Add a device for monitoring.
Definition: util-device.c:82
struct Packet_ * root
Definition: decode.h:577