Bug #315 » 0001-Fix-PF_RING-off-by-one-error-when-dealing-with-a-ful.patch
| src/runmode-pfring.c | ||
|---|---|---|
|
static const char *default_mode_auto = NULL;
|
||
|
static const char *default_mode_autofp = NULL;
|
||
|
static const char *default_mode_single = NULL;
|
||
|
const char *RunModeIdsPfringGetDefaultMode(void)
|
||
|
{
|
||
| ... | ... | |
|
"from the same flow can be processed by any "
|
||
|
"detect thread",
|
||
|
RunModeIdsPfringAutoFp);
|
||
|
default_mode_single = "single";
|
||
|
RunModeRegisterNewRunMode(RUNMODE_PFRING, "single",
|
||
|
"All processing contained in a single thread, but you can spawn many of them",
|
||
|
RunModeIdsPfringSingle);
|
||
|
return;
|
||
|
}
|
||
| ... | ... | |
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* \brief Single thread version of the Pcap file processing.
|
||
|
*/
|
||
|
int RunModeIdsPfringSingle(DetectEngineCtx *de_ctx)
|
||
|
{
|
||
|
SCEnter();
|
||
|
/* We include only if pfring is enabled */
|
||
|
#ifdef HAVE_PFRING
|
||
|
char tname[12];
|
||
|
uint16_t cpu = 0;
|
||
|
RunModeInitialize();
|
||
|
TimeModeSetLive();
|
||
|
/* Available cpus */
|
||
|
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
|
||
|
/* start with cpu 1 so that if we're creating an odd number of detect
|
||
|
* threads we're not creating the most on CPU0. */
|
||
|
if (ncpus > 0)
|
||
|
cpu = 1;
|
||
|
int thread;
|
||
|
int pfring_threads = PfringConfGetThreads();
|
||
|
if (pfring_threads == 0) {
|
||
|
pfring_threads = 1;
|
||
|
}
|
||
|
/* create the threads */
|
||
|
for (thread = 0; thread < pfring_threads; thread++) {
|
||
|
snprintf(tname, sizeof(tname), "Pfring%"PRIu16, thread+1);
|
||
|
char *thread_name = SCStrdup(tname);
|
||
|
/* create the threads */
|
||
|
ThreadVars *tv = TmThreadCreatePacketHandler(thread_name,
|
||
|
"packetpool", "packetpool",
|
||
|
"packetpool","packetpool",
|
||
|
"varslot");
|
||
|
if (tv == NULL) {
|
||
|
printf("ERROR: TmThreadsCreate failed\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
TmModule *tm_module = TmModuleGetByName("ReceivePfring");
|
||
|
if (tm_module == NULL) {
|
||
|
printf("ERROR: TmModuleGetByName failed for ReceivePcap\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
TmVarSlotSetFuncAppend(tv, tm_module, thread_name);
|
||
|
tm_module = TmModuleGetByName("DecodePfring");
|
||
|
if (tm_module == NULL) {
|
||
|
printf("ERROR: TmModuleGetByName DecodePfring failed\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
TmVarSlotSetFuncAppend(tv, tm_module, NULL);
|
||
|
tm_module = TmModuleGetByName("StreamTcp");
|
||
|
if (tm_module == NULL) {
|
||
|
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
TmVarSlotSetFuncAppend(tv, tm_module, NULL);
|
||
|
tm_module = TmModuleGetByName("Detect");
|
||
|
if (tm_module == NULL) {
|
||
|
printf("ERROR: TmModuleGetByName Detect failed\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
TmVarSlotSetFuncAppend(tv, tm_module, (void *)de_ctx);
|
||
|
SetupOutputs(tv);
|
||
|
if (threading_set_cpu_affinity) {
|
||
|
TmThreadSetCPUAffinity(tv, (int)cpu);
|
||
|
/* If we have more than one core/cpu, the first PF_RING thread
|
||
|
* (at cpu 0) will have less priority (higher 'nice' value)
|
||
|
* In this case we will set the thread priority to +10 (default is 0)
|
||
|
*/
|
||
|
if (cpu == 0 && ncpus > 1) {
|
||
|
TmThreadSetThreadPriority(tv, PRIO_LOW);
|
||
|
} else if (ncpus > 1) {
|
||
|
TmThreadSetThreadPriority(tv, PRIO_MEDIUM);
|
||
|
}
|
||
|
}
|
||
|
if (TmThreadSpawn(tv) != TM_ECODE_OK) {
|
||
|
printf("ERROR: TmThreadSpawn failed\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
if ((cpu + 1) == ncpus)
|
||
|
cpu = 0;
|
||
|
else
|
||
|
cpu++;
|
||
|
}
|
||
|
#endif /* HAVE_PFRING */
|
||
|
return 0;
|
||
|
}
|
||
| src/runmode-pfring.h | ||
|---|---|---|
|
int RunModeIdsPfringAuto(DetectEngineCtx *);
|
||
|
int RunModeIdsPfringAutoFp(DetectEngineCtx *de_ctx);
|
||
|
int RunModeIdsPfringSingle(DetectEngineCtx *de_ctx);
|
||
|
void RunModeIdsPfringRegister(void);
|
||
|
const char *RunModeIdsPfringGetDefaultMode(void);
|
||
| src/source-pfring.c | ||
|---|---|---|
|
SCReturnInt(TM_ECODE_FAILED);
|
||
|
}
|
||
|
/* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */
|
||
|
/*
|
||
|
* Need to use default_packet_size as buff len, PF_RING does bounds checking here and truncates when src buffer is larger than user supplied buffer.
|
||
|
* Calling GET_PKT_DIRECT_MAX_SIZE() results in an off-by-one error resulting in the last byte in the payload being overwritten
|
||
|
* by the NULL terminator on a full frame.
|
||
|
*/
|
||
|
#ifdef HAVE_PFRING_RECV_UCHAR
|
||
|
int r = pfring_recv(ptv->pd, (u_char**)&GET_PKT_DIRECT_DATA(p),
|
||
|
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
|
||
|
(uint32_t)default_packet_size,
|
||
|
&hdr,
|
||
|
LIBPFRING_WAIT_FOR_INCOMING);
|
||
|
#else
|
||
|
int r = pfring_recv(ptv->pd, (char *)GET_PKT_DIRECT_DATA(p),
|
||
|
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
|
||
|
(uint32_t)default_packet_size,
|
||
|
&hdr,
|
||
|
LIBPFRING_WAIT_FOR_INCOMING);
|
||
|
#endif /* HAVE_PFRING_RECV_UCHAR */
|
||
| ... | ... | |
|
SCLogInfo("(%s) Pfring Total:%" PRIu64 " Recv:%" PRIu64 " Drop:%" PRIu64 " (%02.1f%%).", tv->name,
|
||
|
(uint64_t)pfring_s.recv + (uint64_t)pfring_s.drop, (uint64_t)pfring_s.recv,
|
||
|
(uint64_t)pfring_s.drop, ((float)pfring_s.drop/(float)(pfring_s.drop + pfring_s.recv))*100);
|
||
|
(uint64_t)pfring_s.drop, ((float)pfring_s.drop/(float)((uint64_t)pfring_s.drop + (uint64_t)pfring_s.recv))*100);
|
||
|
}
|
||
|
}
|
||