suricata
runmode-pcap-file.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 #include "suricata-common.h"
19 #include "tm-threads.h"
20 #include "conf.h"
21 #include "runmodes.h"
22 #include "runmode-pcap-file.h"
23 #include "output.h"
24 
25 #include "detect-engine.h"
26 #include "source-pcap-file.h"
27 
28 #include "util-debug.h"
29 #include "util-time.h"
30 #include "util-cpu.h"
31 #include "util-affinity.h"
32 
33 #include "util-runmodes.h"
34 
35 static const char *default_mode = NULL;
36 
38 {
39  return default_mode;
40 }
41 
43 {
45  "Single threaded pcap file mode",
47  default_mode = "autofp";
49  "Multi threaded pcap file mode. Packets from "
50  "each flow are assigned to a single detect thread, "
51  "unlike \"pcap-file-auto\" where packets from "
52  "the same flow can be processed by any detect "
53  "thread",
55 
56  return;
57 }
58 
59 /**
60  * \brief Single thread version of the Pcap file processing.
61  */
63 {
64  const char *file = NULL;
65  char tname[TM_THREAD_NAME_MAX];
66 
67  if (ConfGet("pcap-file.file", &file) == 0) {
68  SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf");
69  exit(EXIT_FAILURE);
70  }
71 
74 
76 
77  snprintf(tname, sizeof(tname), "%s#01", thread_name_single);
78 
79  /* create the threads */
81  "packetpool", "packetpool",
82  "packetpool", "packetpool",
83  "pktacqloop");
84  if (tv == NULL) {
85  SCLogError(SC_ERR_RUNMODE, "threading setup failed");
86  exit(EXIT_FAILURE);
87  }
88 
89  TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
90  if (tm_module == NULL) {
91  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap");
92  exit(EXIT_FAILURE);
93  }
94  TmSlotSetFuncAppend(tv, tm_module, file);
95 
96  tm_module = TmModuleGetByName("DecodePcapFile");
97  if (tm_module == NULL) {
98  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed");
99  exit(EXIT_FAILURE);
100  }
101  TmSlotSetFuncAppend(tv, tm_module, NULL);
102 
103  tm_module = TmModuleGetByName("FlowWorker");
104  if (tm_module == NULL) {
105  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed");
106  exit(EXIT_FAILURE);
107  }
108  TmSlotSetFuncAppend(tv, tm_module, NULL);
109 
111 
112 #ifndef AFLFUZZ_PCAP_RUNMODE
113  if (TmThreadSpawn(tv) != TM_ECODE_OK) {
114  SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
115  exit(EXIT_FAILURE);
116  }
117 #else
118  /* in afl mode we don't spawn a new thread, but run the pipeline
119  * in the main thread */
120  tv->tm_func(tv);
121  int afl_runmode_exit_immediately = 0;
122  (void)ConfGetBool("afl.exit_after_pcap", &afl_runmode_exit_immediately);
123  if (afl_runmode_exit_immediately) {
124  SCLogNotice("exit because of afl-runmode-exit-after-pcap commandline option");
125  exit(EXIT_SUCCESS);
126  }
127 #endif
128 
129  return 0;
130 }
131 
132 /**
133  * \brief RunModeFilePcapAutoFp set up the following thread packet handlers:
134  * - Receive thread (from pcap file)
135  * - Decode thread
136  * - Stream thread
137  * - Detect: If we have only 1 cpu, it will setup one Detect thread
138  * If we have more than one, it will setup num_cpus - 1
139  * starting from the second cpu available.
140  * - Outputs thread
141  * By default the threads will use the first cpu available
142  * except the Detection threads if we have more than one cpu.
143  *
144  * \retval 0 If all goes well. (If any problem is detected the engine will
145  * exit()).
146  */
148 {
149  SCEnter();
150  char tname[TM_THREAD_NAME_MAX];
151  char qname[TM_QUEUE_NAME_MAX];
152  uint16_t cpu = 0;
153  char *queues = NULL;
154  uint16_t thread;
155 
157 
158  const char *file = NULL;
159  if (ConfGet("pcap-file.file", &file) == 0) {
160  SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf");
161  exit(EXIT_FAILURE);
162  }
163  SCLogDebug("file %s", file);
164 
166 
168 
169  /* Available cpus */
170  uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
171 
172  /* start with cpu 1 so that if we're creating an odd number of detect
173  * threads we're not creating the most on CPU0. */
174  if (ncpus > 0)
175  cpu = 1;
176 
177  /* always create at least one thread */
178  int thread_max = TmThreadGetNbThreads(WORKER_CPU_SET);
179  if (thread_max == 0)
180  thread_max = ncpus * threading_detect_ratio;
181  if (thread_max < 1)
182  thread_max = 1;
183  if (thread_max > 1024)
184  thread_max = 1024;
185 
186  queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
187  if (queues == NULL) {
188  SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed");
189  exit(EXIT_FAILURE);
190  }
191 
192  snprintf(tname, sizeof(tname), "%s#01", thread_name_autofp);
193 
194  /* create the threads */
195  ThreadVars *tv_receivepcap =
197  "packetpool", "packetpool",
198  queues, "flow",
199  "pktacqloop");
200  SCFree(queues);
201 
202  if (tv_receivepcap == NULL) {
203  SCLogError(SC_ERR_FATAL, "threading setup failed");
204  exit(EXIT_FAILURE);
205  }
206  TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
207  if (tm_module == NULL) {
208  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap");
209  exit(EXIT_FAILURE);
210  }
211  TmSlotSetFuncAppend(tv_receivepcap, tm_module, file);
212 
213  tm_module = TmModuleGetByName("DecodePcapFile");
214  if (tm_module == NULL) {
215  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed");
216  exit(EXIT_FAILURE);
217  }
218  TmSlotSetFuncAppend(tv_receivepcap, tm_module, NULL);
219 
220  TmThreadSetCPU(tv_receivepcap, RECEIVE_CPU_SET);
221 
222  if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) {
223  SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
224  exit(EXIT_FAILURE);
225  }
226 
227  for (thread = 0; thread < (uint16_t)thread_max; thread++) {
228  snprintf(tname, sizeof(tname), "%s#%02u", thread_name_workers, thread+1);
229  snprintf(qname, sizeof(qname), "pickup%u", thread+1);
230 
231  SCLogDebug("tname %s, qname %s", tname, qname);
232  SCLogDebug("Assigning %s affinity to cpu %u", tname, cpu);
233 
234  ThreadVars *tv_detect_ncpu =
236  qname, "flow",
237  "packetpool", "packetpool",
238  "varslot");
239  if (tv_detect_ncpu == NULL) {
240  SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
241  exit(EXIT_FAILURE);
242  }
243 
244  tm_module = TmModuleGetByName("FlowWorker");
245  if (tm_module == NULL) {
246  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed");
247  exit(EXIT_FAILURE);
248  }
249  TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
250 
251  TmThreadSetGroupName(tv_detect_ncpu, "Detect");
252 
253  TmThreadSetCPU(tv_detect_ncpu, WORKER_CPU_SET);
254 
255  if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
256  SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
257  exit(EXIT_FAILURE);
258  }
259 
260  if ((cpu + 1) == ncpus)
261  cpu = 0;
262  else
263  cpu++;
264  }
265 
266  return 0;
267 }
void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, const void *data)
Appends a new entry to the slots.
Definition: tm-threads.c:821
int RunModeFilePcapAutoFp(void)
RunModeFilePcapAutoFp set up the following thread packet handlers:
TmEcode TmThreadSetCPU(ThreadVars *tv, uint8_t type)
Definition: tm-threads.c:1025
#define SCLogDebug(...)
Definition: util-debug.h:335
float threading_detect_ratio
Definition: runmodes.c:920
int TmThreadGetNbThreads(uint8_t type)
Definition: tm-threads.c:1041
void RunModeInitialize(void)
Definition: runmodes.c:925
void RunModeRegisterNewRunMode(int runmode, const char *name, const char *description, int(*RunModeFunc)(void))
Registers a new runmode.
Definition: runmodes.c:421
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as an boolen.
Definition: conf.c:517
const char * thread_name_single
Definition: runmodes.c:62
ThreadVars * TmThreadCreatePacketHandler(const char *name, const char *inq_name, const char *inqh_name, const char *outq_name, const char *outqh_name, const char *slots)
Creates and returns a TV instance for a Packet Processing Thread. This function doesn&#39;t support custo...
Definition: tm-threads.c:1237
void TmThreadSetGroupName(ThreadVars *tv, const char *name)
Definition: tm-threads.c:1824
void TimeModeSetOffline(void)
Definition: util-time.c:88
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
int RunModeFilePcapSingle(void)
Single thread version of the Pcap file processing.
const char * RunModeFilePcapGetDefaultMode(void)
void RunModeFilePcapRegister(void)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
char * RunmodeAutoFpCreatePickupQueuesString(int n)
create a queue string for autofp to pass to the flow queue handler.
Definition: util-runmodes.c:59
#define SCEnter(...)
Definition: util-debug.h:337
#define TM_QUEUE_NAME_MAX
Definition: tm-threads.h:47
#define SCFree(a)
Definition: util-mem.h:228
void *(* tm_func)(void *)
Definition: threadvars.h:83
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:269
const char * thread_name_autofp
Definition: runmodes.c:61
#define TM_THREAD_NAME_MAX
Definition: tm-threads.h:48
TmModule * TmModuleGetByName(const char *name)
get a tm module ptr by name
Definition: tm-modules.c:51
void PcapFileGlobalInit()
Per thread variable structure.
Definition: threadvars.h:57
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
Definition: util-cpu.c:99
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1867
const char * thread_name_workers
Definition: runmodes.c:63