/**
 * \brief Sets up the fast pattern analyzer according to the config.
 *
 * \retval 1 If rule analyzer successfully enabled.
 * \retval 0 If not enabled.
 */
int SetupFPAnalyzer(void)
{
    int fp_engine_analysis_set = 0;

    if ((ConfGetBool("engine-analysis.rules-fast-pattern",
                     &fp_engine_analysis_set)) == 0) {
        return 0;
    }

    if (fp_engine_analysis_set == 0)
        return 0;

    char *log_dir;
    log_dir = ConfigGetLogDirectory();
    snprintf(log_path, sizeof(log_path), "%s/%s", log_dir,
             "rules_fast_pattern.txt");

    fp_engine_analysis_FD = fopen(log_path, "w");
    if (fp_engine_analysis_FD == NULL) {
        SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path,
                   strerror(errno));
        return 0;
    }

    SCLogInfo("Engine-Analysis for fast_pattern printed to file - %s",
              log_path);

    struct timeval tval;
    struct tm *tms;
    gettimeofday(&tval, NULL);
    struct tm local_tm;
    tms = SCLocalTime(tval.tv_sec, &local_tm);
    fprintf(fp_engine_analysis_FD, "----------------------------------------------"
            "---------------------\n");
    fprintf(fp_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- "
            "%02d:%02d:%02d\n",
            tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
            tms->tm_min, tms->tm_sec);
    fprintf(fp_engine_analysis_FD, "----------------------------------------------"
            "---------------------\n");

    memset(&fp_pattern_stats, 0, sizeof(fp_pattern_stats));
    return 1;
}
/**
 * \brief Register a new module.  To understand what exactly these utilities are
 *        needed for please look at the file comments.
 *
 * \param name A unique name to register the module with.  No module should have
 *             registered itself previously with this name.
 *
 * \retval handle A unique handle that is associated with this module and all
 *                future use of API would require supplying this handle.
 */
int SCCudaHlRegisterModule(const char *name)
{
    SCCudaHlModuleData *data = module_data;
    SCCudaHlModuleData *new_data = NULL;

    while (data != NULL &&
           strcmp(data->name, name) != 0) {
        data = data->next;
    }

    if (data != NULL) {
        SCLogInfo("Module \"%s\" already registered.  Returning the handle "
                  "for the already registered module", name);
        return data->handle;
    }

    /* the module is not already registered.  Register the module */
    new_data = SCMalloc(sizeof(SCCudaHlModuleData));
    if (unlikely(new_data == NULL)) {
        exit(EXIT_FAILURE);
    }
    memset(new_data, 0, sizeof(SCCudaHlModuleData));

    if ( (new_data->name = SCStrdup(name)) == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
        exit(EXIT_FAILURE);
    }

    new_data->handle = SCCudaHlGetUniqueHandle();

    /* first module to be registered */
    if (module_data == NULL) {
        module_data = new_data;
        return new_data->handle;
    }

    /* add this new module_data instance to the global module_data list */
    data = module_data;
    while (data->next != NULL)
        data = data->next;
    data->next = new_data;

    return new_data->handle;
}
int RunModeIdsAFPAutoFp(DetectEngineCtx *de_ctx)
{
    SCEnter();

/* We include only if AF_PACKET is enabled */
#ifdef HAVE_AF_PACKET
    int ret;
    char *live_dev = NULL;

    RunModeInitialize();

    TimeModeSetLive();

    (void)ConfGet("af-packet.live-interface", &live_dev);

    SCLogDebug("live_dev %s", live_dev);

    if (AFPPeersListInit() != TM_ECODE_OK) {
        SCLogError(SC_ERR_RUNMODE, "Unable to init peers list.");
        exit(EXIT_FAILURE);
    }

    ret = RunModeSetLiveCaptureAutoFp(de_ctx,
                              ParseAFPConfig,
                              AFPConfigGeThreadsCount,
                              "ReceiveAFP",
                              "DecodeAFP", "RxAFP",
                              live_dev);
    if (ret != 0) {
        SCLogError(SC_ERR_RUNMODE, "Unable to start runmode");
        exit(EXIT_FAILURE);
    }

    /* In IPS mode each threads must have a peer */
    if (AFPPeersListCheck() != TM_ECODE_OK) {
        SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer.");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("RunModeIdsAFPAutoFp initialised");
#endif /* HAVE_AF_PACKET */

    SCReturnInt(0);
}
/**
 * \brief Parses the Reference Config file and updates the
 *        DetectionEngineCtx->reference_conf_ht with the Reference information.
 *
 * \param de_ctx Pointer to the Detection Engine Context.
 */
static void SCRConfParseFile(DetectEngineCtx *de_ctx)
{
    char line[1024];
    uint8_t i = 1;

    while (fgets(line, sizeof(line), fd) != NULL) {
        if (SCRConfIsLineBlankOrComment(line))
            continue;

        SCRConfAddReference(line, de_ctx);
        i++;
    }

#ifdef UNITTESTS
    SCLogInfo("Added \"%d\" reference types from the reference.config file",
              de_ctx->reference_conf_ht->count);
#endif /* UNITTESTS */
    return;
}
Beispiel #5
0
/**
 *  \internal
 *
 *  \brief Store the waldo file based on the file_id
 *
 *  \param path full path for the waldo file
 */
static void LogFilestoreLogStoreWaldo(const char *path) {
    char line[16] = "";

    if (SC_ATOMIC_GET(file_id) == 0) {
        SCReturn;
    }

    FILE *fp = fopen(path, "w");
    if (fp == NULL) {
        SCLogInfo("couldn't open waldo: %s", strerror(errno));
        SCReturn;
    }

    snprintf(line, sizeof(line), "%u\n", SC_ATOMIC_GET(file_id));
    if (fwrite(line, strlen(line), 1, fp) != 1) {
        SCLogError(SC_ERR_FWRITE, "fwrite failed: %s", strerror(errno));
    }
    fclose(fp);
}
/**
 *  \brief Main PCAP file reading Loop function
 */
TmEcode PcapFileDispatch(PcapFileFileVars *ptv)
{
    SCEnter();

    int packet_q_len = 64;
    int r;
    TmEcode loop_result = TM_ECODE_OK;
    strlcpy(pcap_filename, ptv->filename, sizeof(pcap_filename));

    while (loop_result == TM_ECODE_OK) {
        if (suricata_ctl_flags & SURICATA_STOP) {
            SCReturnInt(TM_ECODE_OK);
        }

        /* make sure we have at least one packet in the packet pool, to prevent
         * us from alloc'ing packets at line rate */
        PacketPoolWait();

        /* Right now we just support reading packets one at a time. */
        r = pcap_dispatch(ptv->pcap_handle, packet_q_len,
                          (pcap_handler)PcapFileCallbackLoop, (u_char *)ptv);
        if (unlikely(r == -1)) {
            SCLogError(SC_ERR_PCAP_DISPATCH, "error code %" PRId32 " %s for %s",
                       r, pcap_geterr(ptv->pcap_handle), ptv->filename);
            if (ptv->shared->cb_result == TM_ECODE_FAILED) {
                SCReturnInt(TM_ECODE_FAILED);
            }
            loop_result = TM_ECODE_DONE;
        } else if (unlikely(r == 0)) {
            SCLogInfo("pcap file %s end of file reached (pcap err code %" PRId32 ")",
                      ptv->filename, r);
            ptv->shared->files++;
            loop_result = TM_ECODE_DONE;
        } else if (ptv->shared->cb_result == TM_ECODE_FAILED) {
            SCLogError(SC_ERR_PCAP_DISPATCH,
                       "Pcap callback PcapFileCallbackLoop failed for %s", ptv->filename);
            loop_result = TM_ECODE_FAILED;
        }
        StatsSyncCountersIfSignalled(ptv->shared->tv);
    }

    SCReturnInt(loop_result);
}
Beispiel #7
0
static void LogFilestoreLogCloseMetaFile(const File *ff)
{
    char filename[PATH_MAX] = "";
    snprintf(filename, sizeof(filename), "%s/file.%u",
            g_logfile_base_dir, ff->file_id);
    char metafilename[PATH_MAX] = "";
    snprintf(metafilename, sizeof(metafilename), "%s.meta", filename);
    FILE *fp = fopen(metafilename, "a");
    if (fp != NULL) {
        fprintf(fp, "MAGIC:             %s\n",
                ff->magic ? ff->magic : "<unknown>");

        switch (ff->state) {
            case FILE_STATE_CLOSED:
                fprintf(fp, "STATE:             CLOSED\n");
#ifdef HAVE_NSS
                if (ff->flags & FILE_MD5) {
                    fprintf(fp, "MD5:               ");
                    size_t x;
                    for (x = 0; x < sizeof(ff->md5); x++) {
                        fprintf(fp, "%02x", ff->md5[x]);
                    }
                    fprintf(fp, "\n");
                }
#endif
                break;
            case FILE_STATE_TRUNCATED:
                fprintf(fp, "STATE:             TRUNCATED\n");
                break;
            case FILE_STATE_ERROR:
                fprintf(fp, "STATE:             ERROR\n");
                break;
            default:
                fprintf(fp, "STATE:             UNKNOWN\n");
                break;
        }
        fprintf(fp, "SIZE:              %"PRIu64"\n", ff->size);

        fclose(fp);
    } else {
        SCLogInfo("opening %s failed: %s", metafilename, strerror(errno));
    }
}
void
SCProfilingSghDump(DetectEngineCtx *de_ctx)
{
    FILE *fp;
    struct timeval tval;
    struct tm *tms;
    struct tm local_tm;

    if (profiling_sghs_enabled == 0)
        return;

    gettimeofday(&tval, NULL);
    tms = SCLocalTime(tval.tv_sec, &local_tm);

    if (profiling_sghs_output_to_file == 1) {
        SCLogDebug("file %s mode %s", profiling_file_name, profiling_file_mode);

        fp = fopen(profiling_file_name, profiling_file_mode);

        if (fp == NULL) {
            SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name,
                       strerror(errno));
            return;
        }
    } else {
        fp = stdout;
    }

    fprintf(fp, "  ----------------------------------------------"
            "------------------------------------------------------"
            "----------------------------\n");
    fprintf(fp, "  Date: %" PRId32 "/%" PRId32 "/%04d -- "
            "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900,
            tms->tm_hour,tms->tm_min, tms->tm_sec);

    DoDump(de_ctx->profile_sgh_ctx, fp, "rule groups");

    fprintf(fp,"\n");
    if (fp != stdout)
        fclose(fp);

    SCLogInfo("Done dumping rulegroup profiling data.");
}
Beispiel #9
0
/**
 *  \brief Used to check if all threads have finished their initialization.  On
 *         finding an un-initialized thread, it waits till that thread completes
 *         its initialization, before proceeding to the next thread.
 *
 *  \retval TM_ECODE_OK all initialized properly
 *  \retval TM_ECODE_FAILED failure
 */
TmEcode TmThreadWaitOnThreadInit(void)
{
    ThreadVars *tv = NULL;
    int i = 0;
    uint16_t mgt_num = 0;
    uint16_t ppt_num = 0;

    for (i = 0; i < TVT_MAX; i++) {
        tv = tv_root[i];
        while (tv != NULL) {
            char started = FALSE;
            while (started == FALSE) {
                if (TmThreadsCheckFlag(tv, THV_INIT_DONE)) {
                    started = TRUE;
                } else {
                    /* sleep a little to give the thread some
                     * time to finish initialization */
                    usleep(100);
                }

                if (TmThreadsCheckFlag(tv, THV_FAILED)) {
                    SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" failed to "
                            "initialize.", tv->name);
                    return TM_ECODE_FAILED;
                }
                if (TmThreadsCheckFlag(tv, THV_CLOSED)) {
                    SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" closed on "
                            "initialization.", tv->name);
                    return TM_ECODE_FAILED;
                }
            }

            if (i == TVT_MGMT) mgt_num++;
            else if (i == TVT_PPT) ppt_num++;

            tv = tv->next;
        }
    }

    SCLogInfo("all %"PRIu16" packet processing threads, %"PRIu16" management "
           "threads initialized, engine started.", ppt_num, mgt_num);
    return TM_ECODE_OK;
}
Beispiel #10
0
void RegisterSMB2Parsers(void)
{
    /** SMB2 */
    const char *proto_name = "smb2";

    if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
        AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB2, STREAM_TOSERVER, SMB2Parse);
        AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB2, STREAM_TOCLIENT, SMB2Parse);
        AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SMB2, SMB2StateAlloc, SMB2StateFree);
    } else {
        SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
                  "still on.", proto_name);
    }

#ifdef UNITTESTS
    AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SMB2, SMB2ParserRegisterTests);
#endif
    return;
}
Beispiel #11
0
static TmEcode LogFilestoreLogThreadInit(ThreadVars *t, const void *initdata, void **data)
{
    LogFilestoreLogThread *aft = SCMalloc(sizeof(LogFilestoreLogThread));
    if (unlikely(aft == NULL))
        return TM_ECODE_FAILED;
    memset(aft, 0, sizeof(LogFilestoreLogThread));

    if (initdata == NULL)
    {
        SCLogDebug("Error getting context for LogFileStore. \"initdata\" argument NULL");
        SCFree(aft);
        return TM_ECODE_FAILED;
    }

    /* Use the Ouptut Context (file pointer and mutex) */
    aft->file_ctx = ((OutputCtx *)initdata)->data;

    struct stat stat_buf;
    if (stat(g_logfile_base_dir, &stat_buf) != 0) {
        int ret;
        // coverity[toctou : FALSE]
        ret = SCMkDir(g_logfile_base_dir, S_IRWXU|S_IXGRP|S_IRGRP);
        if (ret != 0) {
            int err = errno;
            if (err != EEXIST) {
                SCLogError(SC_ERR_LOGDIR_CONFIG,
                        "Cannot create file drop directory %s: %s",
                        g_logfile_base_dir, strerror(err));
                exit(EXIT_FAILURE);
            }
        } else {
            SCLogInfo("Created file drop directory %s",
                    g_logfile_base_dir);
        }

    }

    aft->counter_max_hits = StatsRegisterCounter("file_store.open_files_max_hit", t);

    *data = (void *)aft;
    return TM_ECODE_OK;
}
/**
 * \brief Parses the Classification Config file and updates the
 *        DetectionEngineCtx->class_conf_ht with the Classtype information.
 *
 * \param de_ctx Pointer to the Detection Engine Context.
 */
void SCClassConfParseFile(DetectEngineCtx *de_ctx)
{
    char line[1024];
    uint8_t i = 1;

    while (fgets(line, sizeof(line), fd) != NULL) {
        if (SCClassConfIsLineBlankOrComment(line))
            continue;

        SCClassConfAddClasstype(line, i, de_ctx);
        i++;
    }

#ifdef UNITTESTS
    SCLogInfo("Added \"%d\" classification types from the classification file",
              de_ctx->class_conf_ht->count);
#endif

    return;
}
Beispiel #13
0
void StreamMsgQueuesDeinit(char quiet)
{
    if (quiet == FALSE) {
        if (stream_msg_pool->max_outstanding > stream_msg_pool->allocated)
            SCLogInfo("TCP segment chunk pool had a peak use of %u chunks, "
                    "more than the prealloc setting of %u",
                    stream_msg_pool->max_outstanding, stream_msg_pool->allocated);
    }

    SCMutexLock(&stream_msg_pool_mutex);
    PoolFree(stream_msg_pool);
    SCMutexUnlock(&stream_msg_pool_mutex);

#ifdef DEBUG
    SCMutexDestroy(&stream_pool_memuse_mutex);

    if (quiet == FALSE)
        SCLogDebug("stream_pool_memuse %"PRIu64", stream_pool_memcnt %"PRIu64"", stream_pool_memuse, stream_pool_memcnt);
#endif
}
Beispiel #14
0
void GlobalInits()
{
    memset(trans_q, 0, sizeof(trans_q));
    memset(data_queues, 0, sizeof(data_queues));

    /* Initialize the trans_q mutex */
    int blah;
    int r = 0;
    for(blah=0;blah<256;blah++) {
        r |= SCMutexInit(&trans_q[blah].mutex_q, NULL);
        r |= SCCondInit(&trans_q[blah].cond_q, NULL);

        r |= SCMutexInit(&data_queues[blah].mutex_q, NULL);
        r |= SCCondInit(&data_queues[blah].cond_q, NULL);
   }

    if (r != 0) {
        SCLogInfo("Trans_Q Mutex not initialized correctly");
        exit(EXIT_FAILURE);
    }
}
/**
 * \brief Register the keyword profiling counters.
 *
 * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules.
 */
void
SCProfilingKeywordInitCounters(DetectEngineCtx *de_ctx)
{
    de_ctx->profile_keyword_ctx = SCProfilingKeywordInitCtx();
    BUG_ON(de_ctx->profile_keyword_ctx == NULL);

    de_ctx->profile_keyword_ctx->data = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
    BUG_ON(de_ctx->profile_keyword_ctx->data == NULL);
    memset(de_ctx->profile_keyword_ctx->data, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);

    int i;
    for (i = 0; i < DETECT_SM_LIST_MAX; i++) {
        de_ctx->profile_keyword_ctx_per_list[i] = SCProfilingKeywordInitCtx();
        BUG_ON(de_ctx->profile_keyword_ctx_per_list[i] == NULL);
        de_ctx->profile_keyword_ctx_per_list[i]->data = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
        BUG_ON(de_ctx->profile_keyword_ctx_per_list[i]->data == NULL);
        memset(de_ctx->profile_keyword_ctx_per_list[i]->data, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
    }

    SCLogInfo("Registered %"PRIu32" keyword profiling counters.", DETECT_TBLSIZE);
}
Beispiel #16
0
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;
}
Beispiel #17
0
void RegisterOracle11gParsers(void) {
    char *proto_name = "oracle11g";
	if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
		AppLayerProtoDetectRegisterProtocol(ALPROTO_ORACLE11G, proto_name);
		if (RunmodeIsUnittests()) {
			AppLayerProtoDetectPPRegister(IPPROTO_TCP, "1521",
					ALPROTO_ORACLE11G, 0,
					ORACLE11G_HEADER_SIZE, /* FIXME */
					STREAM_TOSERVER, Oracle11gProbingParser);
		} else {
			int have_cfg = AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
					proto_name, ALPROTO_ORACLE11G, 0,
					ORACLE11G_HEADER_SIZE, /* FIXME */
					Oracle11gProbingParser);
			if (!have_cfg) {
				return;
			}
		}
	} else {
		SCLogInfo("Protocol detection and parser disabled for %s protocol", proto_name);
		return;
	}

    if (AppLayerParserConfParserEnabled("oracle11g", proto_name)) {
        AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_ORACLE11G, STREAM_TOSERVER, Oracle11gParseClientRecord);
        AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_ORACLE11G, STREAM_TOCLIENT, Oracle11gParseServerRecord);
        AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_ORACLE11G, Oracle11gStateAlloc, Oracle11gStateFree);

        AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_ORACLE11G, Oracle11gGetTx);
        AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_ORACLE11G, Oracle11gGetTxCnt);
        AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP,
                ALPROTO_ORACLE11G, Oracle11gGetAlstateProgressCompletionStatus);
        AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_ORACLE11G, Oracle11gGetAlstateProgress);
    }

#ifdef UNITTESTS
    AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP,  ALPROTO_Oracle11G, Oracle11gParserRegisterTests);
#endif
    return;
}
Beispiel #18
0
void HTPParseMemcap()
{
    char *conf_val;

    /** set config values for memcap, prealloc and hash_size */
    if ((ConfGet("app-layer.protocols.http.memcap", &conf_val)) == 1)
    {
        if (ParseSizeStringU64(conf_val, &htp_config_memcap) < 0) {
            SCLogError(SC_ERR_SIZE_PARSE, "Error parsing http.memcap "
                       "from conf file - %s.  Killing engine",
                       conf_val);
            exit(EXIT_FAILURE);
        }
        SCLogInfo("HTTP memcap: %"PRIu64, htp_config_memcap);
    } else {
        /* default to unlimited */
        htp_config_memcap = 0;
    }

    SC_ATOMIC_INIT(htp_memuse);
    SC_ATOMIC_INIT(htp_memcap);
}
Beispiel #19
0
/**
 * \brief   Drop the previliges of the main thread
 */
void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
{
    if (sc_set_caps == FALSE)
        return;

    capng_clear(CAPNG_SELECT_BOTH);

    switch (run_mode) {
        case RUNMODE_PCAP_DEV:
        case RUNMODE_AFP_DEV:
            capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                    CAP_NET_RAW,            /* needed for pcap live mode */
                    CAP_SYS_NICE,
                    CAP_NET_ADMIN,
                    -1);
            break;
        case RUNMODE_PFRING:
            capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                    CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_NICE,
                    -1);
            break;
        case RUNMODE_NFQ:
            capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                    CAP_NET_ADMIN,          /* needed for nfqueue inline mode */
                    CAP_SYS_NICE,
                    -1);
            break;
    }

    if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP |
            CAPNG_CLEAR_BOUNDING) < 0)
    {
        SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "capng_change_id for main thread"
                " failed");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("dropped the caps for main thread");
}
Beispiel #20
0
int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
        uint8_t *pkt, uint16_t len, PacketQueue *pq, enum DecodeTunnelProto proto)
{
    switch (proto) {
        case DECODE_TUNNEL_PPP:
            return DecodePPP(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_IPV4:
            return DecodeIPV4(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_IPV6:
            return DecodeIPV6(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_VLAN:
            return DecodeVLAN(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_ETHERNET:
            return DecodeEthernet(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_ERSPAN:
            return DecodeERSPAN(tv, dtv, p, pkt, len, pq);
        default:
            SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
            break;
    }
    return TM_ECODE_OK;
}
Beispiel #21
0
TmEcode AlertUnifiedAlertThreadDeinit(ThreadVars *t, void *data)
{
    AlertUnifiedAlertThread *aun = (AlertUnifiedAlertThread *)data;
    if (aun == NULL) {
        goto error;
    }

    if (!(aun->file_ctx->flags & LOGFILE_ALERTS_PRINTED)) {
        SCLogInfo("Alert unified1 alert module wrote %"PRIu64" alerts",
                aun->file_ctx->alerts);

        /* Do not print it for each thread */
        aun->file_ctx->flags |= LOGFILE_ALERTS_PRINTED;
    }
    /* clear memory */
    memset(aun, 0, sizeof(AlertUnifiedAlertThread));
    SCFree(aun);
    return TM_ECODE_OK;

error:
    return TM_ECODE_FAILED;
}
Beispiel #22
0
static int MemcmpTest17 (void)
{
#ifdef PROFILING
    uint64_t ticks_start = 0;
    uint64_t ticks_end = 0;
    char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL };
    char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL };

    int t = 0;
    int i, j;
    int r4 = 0;

    printf("\n");

    ticks_start = UtilCpuGetTicks();
    for (t = 0; t < TEST_RUNS; t++) {
        for (i = 0; a[i] != NULL; i++) {
            // printf("a[%d] = %s\n", i, a[i]);
            size_t alen = strlen(a[i]) - 1;

            for (j = 0; b[j] != NULL; j++) {
                // printf("b[%d] = %s\n", j, b[j]);
                size_t blen = strlen(b[j]) - 1;

                r4 += SCMemcmpLowercase((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen);
            }
        }
    }
    ticks_end = UtilCpuGetTicks();
    printf("SCMemcmpLowercase(%d) \t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS);
    SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start);

    printf("r4 %d\n", r4);
    if (r4 != (51 * TEST_RUNS))
        return 0;
#endif
    return 1;
}
TmEcode InitPcapFile(PcapFileFileVars *pfv)
{
    char errbuf[PCAP_ERRBUF_SIZE] = "";

    if(unlikely(pfv->filename == NULL)) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "Filename was null");
        SCReturnInt(TM_ECODE_FAILED);
    }

    pfv->pcap_handle = pcap_open_offline(pfv->filename, errbuf);
    if (pfv->pcap_handle == NULL) {
        SCLogError(SC_ERR_FOPEN, "%s", errbuf);
        SCReturnInt(TM_ECODE_FAILED);
    }

    if (pfv->shared != NULL && pfv->shared->bpf_string != NULL) {
        SCLogInfo("using bpf-filter \"%s\"", pfv->shared->bpf_string);

        if (pcap_compile(pfv->pcap_handle, &pfv->filter, pfv->shared->bpf_string, 1, 0) < 0) {
            SCLogError(SC_ERR_BPF, "bpf compilation error %s for %s",
                       pcap_geterr(pfv->pcap_handle), pfv->filename);
            SCReturnInt(TM_ECODE_FAILED);
        }

        if (pcap_setfilter(pfv->pcap_handle, &pfv->filter) < 0) {
            SCLogError(SC_ERR_BPF,"could not set bpf filter %s for %s",
                       pcap_geterr(pfv->pcap_handle), pfv->filename);
            SCReturnInt(TM_ECODE_FAILED);
        }
    }

    pfv->datalink = pcap_datalink(pfv->pcap_handle);
    SCLogDebug("datalink %" PRId32 "", pfv->datalink);

    Decoder temp;
    TmEcode validated = ValidateLinkType(pfv->datalink, &temp);
    SCReturnInt(validated);
}
Beispiel #24
0
/**
 * \brief This function passes off to link type decoders.
 * \todo Unit tests are needed for this module.
 *
 * DecodeIPFW reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param tv pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into IPFWThreadVars for ptv
 * \param pq pointer to the PacketQueue
 */
TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    SCEnter();

    /* XXX HACK: flow timeout can call us for injected pseudo packets
     *           see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
    if (p->flags & PKT_PSEUDO_STREAM_END)
        return TM_ECODE_OK;

    /* update counters */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));

    /* Process IP packets */
    if (IPV4_GET_RAW_VER(ip4h) == 4) {
        SCLogDebug("DecodeIPFW ip4 processing");
        DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
        SCLogDebug("DecodeIPFW ip6 processing");
        DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else {
        /* We don't support anything besides IP packets for now, bridged packets? */
        SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p));
       SCReturnInt(TM_ECODE_FAILED);
    }

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Beispiel #25
0
/**
 * \brief Restarts the thread sent as the argument
 *
 * \param tv Pointer to the thread instance(tv) to be restarted
 */
static void TmThreadRestartThread(ThreadVars *tv)
{
    if (tv->restarted >= THV_MAX_RESTARTS) {
        printf("Warning: thread restarts exceeded threshhold limit for thread"
               "\"%s\"\n", tv->name);
        /* makes sense to reset the tv_aof to engine_exit?! */
        // tv->aof = THV_ENGINE_EXIT;
        return;
    }

    TmThreadsUnsetFlag(tv, THV_CLOSED);
    TmThreadsUnsetFlag(tv, THV_FAILED);

    if (TmThreadSpawn(tv) != TM_ECODE_OK) {
        SCLogError(SC_ERR_THREAD_SPAWN, "thread \"%s\" failed to spawn", tv->name);
        exit(EXIT_FAILURE);
    }

    tv->restarted++;
    SCLogInfo("thread \"%s\" restarted\n", tv->name);

    return;
}
Beispiel #26
0
/**
 * \brief Get a particular cuda profile specified as arg.
 *
 * \param profile_name Name of the the profile to retrieve.
 *
 * \retval Data associated with the profile.
 */
void *SCCudaHlGetProfile(char *profile_name)
{
    SCCudaHlCudaProfile *profile = cuda_profiles;

    if (cuda_profiles == NULL ) {
        SCLogInfo("No cuda profile registered");
        return NULL;
    }

    if (profile_name == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "argument profile NULL");
        return NULL;
    }

    while (profile != NULL && strcasecmp(profile->name, profile_name) != 0) {
        profile = profile->next;
    }

    if (profile != NULL)
        return profile->data;
    else
        return NULL;
}
Beispiel #27
0
int RunModeIdsPfringWorkers(DetectEngineCtx *de_ctx)
{
    SCEnter();

/* We include only if pfring is enabled */
#ifdef HAVE_PFRING
    int ret;
    char *live_dev = NULL;
    ConfigIfaceParserFunc tparser;

    RunModeInitialize();

    TimeModeSetLive();

    ret = GetDevAndParser(&live_dev, &tparser);
    if (ret != 0) {
        SCLogError(SC_ERR_MISSING_CONFIG_PARAM,
                "Unable to get parser and interface params");
        exit(EXIT_FAILURE);
    }

    ret = RunModeSetLiveCaptureWorkers(de_ctx,
                              tparser,
                              PfringConfigGeThreadsCount,
                              "ReceivePfring",
                              "DecodePfring", "RxPFR",
                              live_dev);
    if (ret != 0) {
        SCLogError(SC_ERR_RUNMODE, "Runmode start failed");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("RunModeIdsPfringWorkers initialised");
#endif /* HAVE_PFRING */

    return 0;
}
Beispiel #28
0
void PacketPoolInit(void)
{
    extern intmax_t max_pending_packets;

#ifndef TLS
    TmqhPacketPoolInit();
#endif

    PktPool *my_pool = GetThreadPacketPool();

#ifdef DEBUG_VALIDATION
    BUG_ON(my_pool->initialized);
    my_pool->initialized = 1;
    my_pool->destroyed = 0;
#endif /* DEBUG_VALIDATION */

    SCMutexInit(&my_pool->return_stack.mutex, NULL);
    SCCondInit(&my_pool->return_stack.cond, NULL);
    SC_ATOMIC_INIT(my_pool->return_stack.sync_now);

    /* pre allocate packets */
    SCLogDebug("preallocating packets... packet size %" PRIuMAX "",
               (uintmax_t)SIZE_OF_PACKET);
    int i = 0;
    for (i = 0; i < max_pending_packets; i++) {
        Packet *p = PacketGetFromAlloc();
        if (unlikely(p == NULL)) {
            SCLogError(SC_ERR_FATAL, "Fatal error encountered while allocating a packet. Exiting...");
            exit(EXIT_FAILURE);
        }
        PacketPoolStorePacket(p);
    }
    SCLogInfo("preallocated %"PRIiMAX" packets. Total memory %"PRIuMAX"",
            max_pending_packets, (uintmax_t)(max_pending_packets*SIZE_OF_PACKET));

}
Beispiel #29
0
int GetIfaceRSSQueuesNum(const char *pcap_dev)
{
#if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS
    struct ifreq ifr;
    struct ethtool_rxnfc nfccmd;
    int fd;

    (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) {
        SCLogWarning(SC_ERR_SYSCALL,
                "Failure when opening socket for ioctl: %s (%d)",
                strerror(errno), errno);
        return -1;
    }

    nfccmd.cmd = ETHTOOL_GRXRINGS;
    ifr.ifr_data = (void*) &nfccmd;

    if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
        if (errno != ENOTSUP) {
            SCLogWarning(SC_ERR_SYSCALL,
                         "Failure when trying to get number of RSS queue ioctl for '%s': %s (%d)",
                         pcap_dev, strerror(errno), errno);
        }
        close(fd);
        return 0;
    }
    close(fd);
    SCLogInfo("Found %d RX RSS queues for '%s'", (int)nfccmd.data,
            pcap_dev);
    return (int)nfccmd.data;
#else
    return 0;
#endif
}
Beispiel #30
0
/**
 * \brief   Process a DAG record into a TM packet buffer.
 * \param   prec pointer to a DAG record.
 * \param
 */
static inline TmEcode ProcessErfDagRecord(ErfDagThreadVars *ewtn, char *prec)
{
    SCEnter();

    int wlen = 0;
    int rlen = 0;
    int hdr_num = 0;
    char hdr_type = 0;
    dag_record_t  *dr = (dag_record_t*)prec;
    erf_payload_t *pload;
    Packet *p;

    hdr_type = dr->type;
    wlen = ntohs(dr->wlen);
    rlen = ntohs(dr->rlen);

    /* count extension headers */
    while (hdr_type & 0x80) {
        if (rlen < (dag_record_size + (hdr_num * 8))) {
            SCLogError(SC_ERR_UNIMPLEMENTED,
                       "Insufficient captured packet length.");
            SCReturnInt(TM_ECODE_FAILED);
        }
        hdr_type = prec[(dag_record_size + (hdr_num * 8))];
        hdr_num++;
    }

    /* Check that the whole frame was captured */
    if (rlen < (dag_record_size + (8 * hdr_num) + 2 + wlen)) {
        SCLogInfo("Incomplete frame captured.");
        SCReturnInt(TM_ECODE_OK);
    }

    /* skip over extension headers */
    pload = (erf_payload_t *)(prec + dag_record_size + (8 * hdr_num));

    p = PacketGetFromQueueOrAlloc();
    if (p == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC,
                   "Failed to allocate a Packet on stream: %d, DAG: %s",
                   ewtn->dagstream, ewtn->dagname);
        SCReturnInt(TM_ECODE_FAILED);
    }
    PKT_SET_SRC(p, PKT_SRC_WIRE);

    SET_PKT_LEN(p, wlen);
    p->datalink = LINKTYPE_ETHERNET;

    /* Take into account for link type Ethernet ETH frame starts
     * after ther ERF header + pad.
     */
    if (unlikely(PacketCopyData(p, pload->eth.dst, GET_PKT_LEN(p)))) {
        TmqhOutputPacketpool(ewtn->tv, p);
        SCReturnInt(TM_ECODE_FAILED);
    }

    /* Convert ERF time to timeval - from libpcap. */
    uint64_t ts = dr->ts;
    p->ts.tv_sec = ts >> 32;
    ts = (ts & 0xffffffffULL) * 1000000;
    ts += 0x80000000; /* rounding */
    p->ts.tv_usec = ts >> 32;
    if (p->ts.tv_usec >= 1000000) {
        p->ts.tv_usec -= 1000000;
        p->ts.tv_sec++;
    }

    SCPerfCounterIncr(ewtn->packets, ewtn->tv->sc_perf_pca);
    ewtn->bytes += wlen;

    if (TmThreadsSlotProcessPkt(ewtn->tv, ewtn->slot, p) != TM_ECODE_OK) {
        TmqhOutputPacketpool(ewtn->tv, p);
        SCReturnInt(TM_ECODE_FAILED);
    }

    SCReturnInt(TM_ECODE_OK);
}