/** * \brief NFQ receive module stats printing function */ void ReceiveNFQThreadExitStats(ThreadVars *tv, void *data) { NFQThreadVars *ntv = (NFQThreadVars *)data; NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); #ifdef COUNTERS SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "", tv->name, nq->pkts, nq->bytes, nq->errs); SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32", Replaced %"PRIu32, tv->name, nq->accepted, nq->dropped, nq->replaced); #endif }
/** * \brief This function prints stats to the screen at exit. * \todo Unit tests are needed for this module. * \param tv pointer to ThreadVars * \param data pointer that gets cast into IPFWThreadVars for ptv */ void ReceiveIPFWThreadExitStats(ThreadVars *tv, void *data) { IPFWThreadVars *ptv = (IPFWThreadVars *)data; SCEnter(); SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "", tv->name, ptv->pkts, ptv->bytes, ptv->errs); SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32 "", tv->name, ptv->accepted, ptv->dropped); SCReturn; }
/** \brief SCLogRedisWriteAsync() writes string to redis output in async mode * \param file_ctx Log file context allocated by caller * \param string Buffer to output */ static int SCLogRedisWriteAsync(LogFileCtx *file_ctx, const char *string, size_t string_len) { SCLogRedisContext *ctx = file_ctx->redis; if (! ctx->connected) { if (SCConfLogReopenAsyncRedis(file_ctx) == -1) { return -1; } if (ctx->tried == 0) { SCLogNotice("Trying to connect to Redis"); } SCLogAsyncRedisSendEcho(ctx); } if (!ctx->connected) { return -1; } if (ctx->async == NULL) { return -1; } redisAsyncCommand(ctx->async, SCRedisAsyncCommandCallback, file_ctx, "%s %s %s", file_ctx->redis_setup.command, file_ctx->redis_setup.key, string); event_base_loop(ctx->ev_base, EVLOOP_NONBLOCK); return 0; }
/** * \brief Print some stats to the log at program exit. * * \param tv Pointer to ThreadVars. * \param data Pointer to data, ErfFileThreadVars. */ void NapatechStreamThreadExitStats(ThreadVars *tv, void *data) { NapatechThreadVars *ntv = (NapatechThreadVars *)data; double percent = 0; if (ntv->drops > 0) percent = (((double) ntv->drops) / (ntv->pkts+ntv->drops)) * 100; SCLogNotice("Stream: %lu; Packets: %"PRIu64"; Drops: %"PRIu64" (%5.2f%%); Bytes: %"PRIu64, ntv->stream_id, ntv->pkts, ntv->drops, percent, ntv->bytes); }
void DetectTemplateBufferRegister(void) { if (ConfGetNode("app-layer.protocols.template") == NULL) { return; } sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].name = "template_buffer"; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].desc = "Template content modififier to match on the template buffers"; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].alproto = ALPROTO_TEMPLATE; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].Setup = DetectTemplateBufferSetup; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].RegisterTests = DetectTemplateBufferRegisterTests; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_PAYLOAD; SCLogNotice("Template application layer detect registered."); }
/** \brief SCRedisAsyncEchoCommandCallback() Callback for an ECHO command reply * This is used to check if redis is connected. * \param ac redis async context * \param r redis reply * \param privvata opaque datq with pointer to LogFileCtx */ static void SCRedisAsyncEchoCommandCallback(redisAsyncContext *ac, void *r, void *privdata) { redisReply *reply = r; SCLogRedisContext * ctx = privdata; if (reply) { if (ctx->connected == 0) { SCLogNotice("Connected to Redis."); ctx->connected = 1; ctx->tried = 0; } } else { ctx->connected = 0; if (ctx->tried == 0) { SCLogWarning(SC_ERR_SOCKET, "Failed to connect to Redis... (will keep trying)"); } ctx->tried = time(NULL); } event_base_loopbreak(ctx->ev_base); }
void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data) { SCEnter(); PcapFileThreadVars *ptv = (PcapFileThreadVars *)data; if (pcap_g.conf_checksum_mode == CHECKSUM_VALIDATION_AUTO && pcap_g.cnt < CHECKSUM_SAMPLE_COUNT && SC_ATOMIC_GET(pcap_g.invalid_checksums)) { uint64_t chrate = pcap_g.cnt / SC_ATOMIC_GET(pcap_g.invalid_checksums); if (chrate < CHECKSUM_INVALID_RATIO) SCLogWarning(SC_ERR_INVALID_CHECKSUM, "1/%" PRIu64 "th of packets have an invalid checksum," " consider setting pcap-file.checksum-checks variable to no" " or use '-k none' option on command line.", chrate); else SCLogInfo("1/%" PRIu64 "th of packets have an invalid checksum", chrate); } SCLogNotice("Pcap-file module read %" PRIu32 " packets, %" PRIu64 " bytes", ptv->pkts, ptv->bytes); return; }
int DetectEngineInspectTemplateBuffer(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) { TemplateTransaction *tx = (TemplateTransaction *)txv; int ret = 0; if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) { ret = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f, tx->request_buffer, tx->request_buffer_len, 0, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); } else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) { ret = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f, tx->response_buffer, tx->response_buffer_len, 0, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); } SCLogNotice("Returning %d.", ret); return ret; }
/** * \brief Attempt to reconnect a disconnected (or never-connected) Unix domain socket. * \retval 1 if it is now connected; otherwise 0 */ static int SCLogUnixSocketReconnect(LogFileCtx *log_ctx) { int disconnected = 0; if (log_ctx->fp) { SCLogWarning(SC_ERR_SOCKET, "Write error on Unix socket \"%s\": %s; reconnecting...", log_ctx->filename, strerror(errno)); fclose(log_ctx->fp); log_ctx->fp = NULL; log_ctx->reconn_timer = 0; disconnected = 1; } struct timeval tv; uint64_t now; gettimeofday(&tv, NULL); now = (uint64_t)tv.tv_sec * 1000; now += tv.tv_usec / 1000; /* msec resolution */ if (log_ctx->reconn_timer != 0 && (now - log_ctx->reconn_timer) < LOGFILE_RECONN_MIN_TIME) { /* Don't bother to try reconnecting too often. */ return 0; } log_ctx->reconn_timer = now; log_ctx->fp = SCLogOpenUnixSocketFp(log_ctx->filename, log_ctx->sock_type, 0); if (log_ctx->fp) { /* Connected at last (or reconnected) */ SCLogNotice("Reconnected socket \"%s\"", log_ctx->filename); } else if (disconnected) { SCLogWarning(SC_ERR_SOCKET, "Reconnect failed: %s (will keep trying)", strerror(errno)); } return log_ctx->fp ? 1 : 0; }
int OutputRegisterTxLogger(LoggerId id, const char *name, AppProto alproto, TxLogger LogFunc, OutputCtx *output_ctx, int tc_log_progress, int ts_log_progress, TxLoggerCondition LogCondition, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, void (*ThreadExitPrintStats)(ThreadVars *, void *)) { if (!(AppLayerParserIsTxAware(alproto))) { SCLogNotice("%s logger not enabled: protocol %s is disabled", name, AppProtoToString(alproto)); return -1; } OutputTxLogger *op = SCMalloc(sizeof(*op)); if (op == NULL) return -1; memset(op, 0x00, sizeof(*op)); op->alproto = alproto; op->LogFunc = LogFunc; op->LogCondition = LogCondition; op->output_ctx = output_ctx; op->name = name; op->logger_id = id; op->ThreadInit = ThreadInit; op->ThreadDeinit = ThreadDeinit; op->ThreadExitPrintStats = ThreadExitPrintStats; if (tc_log_progress < 0) { op->tc_log_progress = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOCLIENT); } else { op->tc_log_progress = tc_log_progress; } if (ts_log_progress < 0) { op->ts_log_progress = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOSERVER); } else { op->ts_log_progress = ts_log_progress; } if (list == NULL) { op->id = 1; list = op; } else { OutputTxLogger *t = list; while (t->next) t = t->next; if (t->id * 2 > UINT32_MAX) { SCLogError(SC_ERR_FATAL, "Too many loggers registered."); exit(EXIT_FAILURE); } op->id = t->id * 2; t->next = op; } SCLogDebug("OutputRegisterTxLogger happy"); return 0; }
/** * \brief Single thread version of the Pcap file processing. */ int RunModeFilePcapSingle(void) { const char *file = NULL; char tname[TM_THREAD_NAME_MAX]; if (ConfGet("pcap-file.file", &file) == 0) { SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf"); exit(EXIT_FAILURE); } RunModeInitialize(); TimeModeSetOffline(); PcapFileGlobalInit(); snprintf(tname, sizeof(tname), "%s#01", thread_name_single); /* create the threads */ ThreadVars *tv = TmThreadCreatePacketHandler(tname, "packetpool", "packetpool", "packetpool", "packetpool", "pktacqloop"); if (tv == NULL) { SCLogError(SC_ERR_RUNMODE, "threading setup failed"); exit(EXIT_FAILURE); } TmModule *tm_module = TmModuleGetByName("ReceivePcapFile"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, file); tm_module = TmModuleGetByName("DecodePcapFile"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, NULL); tm_module = TmModuleGetByName("FlowWorker"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, NULL); TmThreadSetCPU(tv, WORKER_CPU_SET); #ifndef AFLFUZZ_PCAP_RUNMODE if (TmThreadSpawn(tv) != TM_ECODE_OK) { SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); exit(EXIT_FAILURE); } #else /* in afl mode we don't spawn a new thread, but run the pipeline * in the main thread */ tv->tm_func(tv); int afl_runmode_exit_immediately = 0; (void)ConfGetBool("afl.exit_after_pcap", &afl_runmode_exit_immediately); if (afl_runmode_exit_immediately) { SCLogNotice("exit because of afl-runmode-exit-after-pcap commandline option"); exit(EXIT_SUCCESS); } #endif return 0; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *OutputJsonInitCtx(ConfNode *conf) { OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; if (unlikely(json_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); return NULL; } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "type"); if (output_s != NULL) { if (strcmp(output_s, "remote") == 0) { json_ctx->json_out = ALERT_REMOTE; } else if (strcmp(output_s, "file") == 0) { json_ctx->json_out = ALERT_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = ALERT_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = ALERT_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = ALERT_UNIX_STREAM; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } if (json_ctx->json_out == ALERT_REMOTE) { const char *host = ConfNodeLookupChildValue(conf, "host"); if(!host) { host="127.0.0.1"; } const char *port = ConfNodeLookupChildValue(conf, "port"); if(!port) { port="514"; } if(-1==ConnectToRemote(host , atoi(port))) { SCLogError(SC_ERR_INVALID_ARGUMENT, "creat socket failed: %s:%s\n", host , port); exit(EXIT_FAILURE); } SCLogNotice("connect to remote: %s:%s\n", host , port); } else if (json_ctx->json_out == ALERT_FILE || json_ctx->json_out == ALERT_UNIX_DGRAM || json_ctx->json_out == ALERT_UNIX_STREAM) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) { if (strcmp(format_s, "indent") == 0) { json_ctx->format = INDENT; } else if (strcmp(format_s, "compact") == 0) { json_ctx->format = COMPACT; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON format option: %s", format_s); exit(EXIT_FAILURE); } } } else if (json_out == ALERT_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-is: %s", sensor_id_s); exit(EXIT_FAILURE); } } format = json_ctx->format; json_out = json_ctx->json_out; } SCLogInfo("returning output_ctx %p", output_ctx); return output_ctx; }
void RegisterNFSUDPParsers(void) { const char *proto_name = "nfs"; /* Check if NFS TCP detection is enabled. If it does not exist in * the configuration file then it will be enabled by default. */ if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) { rs_nfs_init(&sfc); SCLogDebug("NFS UDP protocol detection enabled."); AppLayerProtoDetectRegisterProtocol(ALPROTO_NFS, proto_name); if (RunmodeIsUnittests()) { SCLogDebug("Unittest mode, registering default configuration."); AppLayerProtoDetectPPRegister(IPPROTO_UDP, NFS_DEFAULT_PORT, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, STREAM_TOSERVER, NFSProbingParserTS, NFSProbingParserTC); } else { if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP, proto_name, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, NFSProbingParserTS, NFSProbingParserTC)) { SCLogDebug("No NFS app-layer configuration, enabling NFS" " detection TCP detection on port %s.", NFS_DEFAULT_PORT); AppLayerProtoDetectPPRegister(IPPROTO_UDP, NFS_DEFAULT_PORT, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, STREAM_TOSERVER, NFSProbingParserTS, NFSProbingParserTC); } } } else { SCLogDebug("Protocol detecter and parser disabled for NFS."); return; } if (AppLayerParserConfParserEnabled("udp", proto_name)) { SCLogDebug("Registering NFS protocol parser."); /* Register functions for state allocation and freeing. A * state is allocated for every new NFS flow. */ AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_NFS, NFSStateAlloc, NFSStateFree); /* Register request parser for parsing frame from server to client. */ AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NFS, STREAM_TOSERVER, NFSParseRequest); /* Register response parser for parsing frames from server to client. */ AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NFS, STREAM_TOCLIENT, NFSParseResponse); /* Register a function to be called by the application layer * when a transaction is to be freed. */ AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_NFS, NFSStateTxFree); AppLayerParserRegisterLoggerFuncs(IPPROTO_UDP, ALPROTO_NFS, NFSGetTxLogged, NFSSetTxLogged); /* Register a function to return the current transaction count. */ AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_NFS, NFSGetTxCnt); /* Transaction handling. */ AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_NFS, NFSGetAlstateProgressCompletionStatus); AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_NFS, NFSGetStateProgress); AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_NFS, NFSGetTx); AppLayerParserRegisterGetTxIterator(IPPROTO_UDP, ALPROTO_NFS, RustNFSGetTxIterator); AppLayerParserRegisterGetFilesFunc(IPPROTO_UDP, ALPROTO_NFS, NFSGetFiles); /* What is this being registered for? */ AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_NFS, NFSGetTxDetectState, NFSSetTxDetectState); AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_NFS, NFSStateGetEventInfo); AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_NFS, NFSGetEvents); AppLayerParserRegisterDetectFlagsFuncs(IPPROTO_UDP, ALPROTO_NFS, NFSGetDetectFlags, NFSSetDetectFlags); } else { SCLogNotice("NFS protocol parsing disabled."); } #ifdef UNITTESTS AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_NFS, NFSUDPParserRegisterTests); #endif }