Пример #1
0
/**
 * \brief Removes this TV from tv_root based on its type
 *
 * \param tv   The tv instance to remove from the global tv list.
 * \param type Holds the type this TV belongs to.
 */
void TmThreadRemove(ThreadVars *tv, int type)
{
    SCMutexLock(&tv_root_lock);

    if (tv_root[type] == NULL) {
        SCMutexUnlock(&tv_root_lock);
        return;
    }

    ThreadVars *t = tv_root[type];
    while (t != tv) {
        t = t->next;
    }

    if (t != NULL) {
        if (t->prev != NULL)
            t->prev->next = t->next;
        if (t->next != NULL)
            t->next->prev = t->prev;

    if (t == tv_root[type])
        tv_root[type] = t->next;;
    }

    SCMutexUnlock(&tv_root_lock);

    return;
}
Пример #2
0
TmEcode ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) {
    SCMutexLock(&nfq_init_lock);

#ifndef OS_WIN32
    sigset_t sigs;
    sigfillset(&sigs);
    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
#endif /* OS_WIN32 */

    NFQThreadVars *ntv = (NFQThreadVars *) initdata;
    /* store the ThreadVars pointer in our NFQ thread context
     * as we will need it in our callback function */
    ntv->tv = tv;

    int r = NFQInitThread(ntv, (max_pending_packets * NFQ_BURST_FACTOR));
    if (r < 0) {
        SCLogError(SC_ERR_NFQ_THREAD_INIT, "nfq thread failed to initialize");

        SCMutexUnlock(&nfq_init_lock);
        exit(EXIT_FAILURE);
    }

#define T_DATA_SIZE 70000
    ntv->data = SCMalloc(T_DATA_SIZE);
    if (ntv->data == NULL) {
        SCMutexUnlock(&nfq_init_lock);
        return TM_ECODE_FAILED;
    }
    ntv->datalen = T_DATA_SIZE;
#undef T_DATA_SIZE

    *data = (void *)ntv;
    SCMutexUnlock(&nfq_init_lock);
    return TM_ECODE_OK;
}
Пример #3
0
/** \brief Return packet to Packet pool
 *
 */
void PacketPoolReturnPacket(Packet *p)
{
    PktPool *my_pool = GetThreadPacketPool();

    PACKET_RELEASE_REFS(p);

    PktPool *pool = p->pool;
    if (pool == NULL) {
        PacketFree(p);
        return;
    }
#ifdef DEBUG_VALIDATION
    BUG_ON(pool->initialized == 0);
    BUG_ON(pool->destroyed == 1);
    BUG_ON(my_pool->initialized == 0);
    BUG_ON(my_pool->destroyed == 1);
#endif /* DEBUG_VALIDATION */

    if (pool == my_pool) {
        /* Push back onto this thread's own stack, so no locking. */
        p->next = my_pool->head;
        my_pool->head = p;
    } else {
        PktPool *pending_pool = my_pool->pending_pool;
        if (pending_pool == NULL) {
            /* No pending packet, so store the current packet. */
            my_pool->pending_pool = pool;
            my_pool->pending_head = p;
            my_pool->pending_tail = p;
            my_pool->pending_count = 1;
        } else if (pending_pool == pool) {
            /* Another packet for the pending pool list. */
            p->next = my_pool->pending_head;
            my_pool->pending_head = p;
            my_pool->pending_count++;
            if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > MAX_PENDING_RETURN_PACKETS) {
                /* Return the entire list of pending packets. */
                SCMutexLock(&pool->return_stack.mutex);
                my_pool->pending_tail->next = pool->return_stack.head;
                pool->return_stack.head = my_pool->pending_head;
                SC_ATOMIC_RESET(pool->return_stack.sync_now);
                SCMutexUnlock(&pool->return_stack.mutex);
                SCCondSignal(&pool->return_stack.cond);
                /* Clear the list of pending packets to return. */
                my_pool->pending_pool = NULL;
                my_pool->pending_head = NULL;
                my_pool->pending_tail = NULL;
                my_pool->pending_count = 0;
            }
        } else {
            /* Push onto return stack for this pool */
            SCMutexLock(&pool->return_stack.mutex);
            p->next = pool->return_stack.head;
            pool->return_stack.head = p;
            SC_ATOMIC_RESET(pool->return_stack.sync_now);
            SCMutexUnlock(&pool->return_stack.mutex);
            SCCondSignal(&pool->return_stack.cond);
        }
    }
}
Пример #4
0
/**
 * \brief Appends this TV to tv_root based on its type
 *
 * \param type holds the type this TV belongs to.
 */
void TmThreadAppend(ThreadVars *tv, int type)
{
    SCMutexLock(&tv_root_lock);

    if (tv_root[type] == NULL) {
        tv_root[type] = tv;
        tv->next = NULL;
        tv->prev = NULL;

        //printf("TmThreadAppend: thread \'%s\' is the first thread in the list.\n", tv->name);
        SCMutexUnlock(&tv_root_lock);
        return;
    }

    ThreadVars *t = tv_root[type];

    while (t) {
        if (t->next == NULL) {
            t->next = tv;
            tv->prev = t;
            tv->next = NULL;
            break;
        }

        t = t->next;
    }

    SCMutexUnlock(&tv_root_lock);
    //printf("TmThreadAppend: thread \'%s\' is added to the list.\n", tv->name);
}
Пример #5
0
int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer)
{
    if (file_ctx->type == LOGFILE_TYPE_SYSLOG) {
        syslog(file_ctx->syslog_setup.alert_syslog_level, "%s",
                (const char *)MEMBUFFER_BUFFER(buffer));
    } else if (file_ctx->type == LOGFILE_TYPE_FILE ||
               file_ctx->type == LOGFILE_TYPE_UNIX_DGRAM ||
               file_ctx->type == LOGFILE_TYPE_UNIX_STREAM)
    {
        /* append \n for files only */
        MemBufferWriteString(buffer, "\n");
        SCMutexLock(&file_ctx->fp_mutex);
        file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer),
                        MEMBUFFER_OFFSET(buffer), file_ctx);
        SCMutexUnlock(&file_ctx->fp_mutex);
    }
#ifdef HAVE_LIBHIREDIS
    else if (file_ctx->type == LOGFILE_TYPE_REDIS) {
        SCMutexLock(&file_ctx->fp_mutex);
        LogFileWriteRedis(file_ctx, (const char *)MEMBUFFER_BUFFER(buffer),
                MEMBUFFER_OFFSET(buffer));
        SCMutexUnlock(&file_ctx->fp_mutex);
    }
#endif

    return 0;
}
Пример #6
0
/* same as 'simple' */
Packet *TmqhInputFlow(ThreadVars *tv)
{
    PacketQueue *q = &trans_q[tv->inq->id];

    SCPerfSyncCountersIfSignalled(tv, 0);

    SCMutexLock(&q->mutex_q);
    if (q->len == 0) {
        /* if we have no packets in queue, wait... */
#ifdef __tile__
        for (;;) {
            if (q->len > 0 || q->cond_q)
                break;
            SCMutexUnlock(&q->mutex_q);
            SCMutexLock(&q->mutex_q);
        }
#else
        SCCondWait(&q->cond_q, &q->mutex_q);
#endif
    }

    if (q->len > 0) {
        Packet *p = PacketDequeue(q);
        SCMutexUnlock(&q->mutex_q);
        return p;
    } else {
        /* return NULL if we have no pkt. Should only happen on signals. */
        SCMutexUnlock(&q->mutex_q);
        return NULL;
    }
}
Пример #7
0
void *CudaHandlerModuleGetData(const char *module_name, const char *data_name)
{
    SCMutexLock(&mutex);

    CudaHandlerModule *module = cudahl_modules;
    while (module != NULL && strcasecmp(module->name, module_name) != 0)
        module = module->next;
    if (module == NULL) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data "
                   "\"%s\" from module \"%s\" that hasn't been registered "
                   "yet.",  module_name, data_name);
        SCMutexUnlock(&mutex);
        return NULL;
    }

    CudaHandlerModuleData *data = module->module_data;
    while (data != NULL && (strcasecmp(data_name, data->name) != 0)) {
        data = data->next;
    }
    if (data == NULL) {
        SCLogInfo("Data \"%s\" already registered for this module \"%s\".  "
                  "Returning it.", data_name, module_name);
        SCMutexUnlock(&mutex);
        return NULL;
    }

    SCMutexUnlock(&mutex);
    return data->data;
}
Пример #8
0
/**
 *  \brief Initialize the "magic" context.
 */
int MagicInit(void)
{
    BUG_ON(g_magic_ctx != NULL);

    SCEnter();

    char *filename = NULL;
    FILE *fd = NULL;

    SCMutexInit(&g_magic_lock, NULL);
    SCMutexLock(&g_magic_lock);

    g_magic_ctx = magic_open(0);
    if (g_magic_ctx == NULL) {
        SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s",
                magic_error(g_magic_ctx));
        goto error;
    }

    (void)ConfGet("magic-file", &filename);


    if (filename != NULL) {
        if (strlen(filename) == 0) {
            /* set filename to NULL on *nix systems so magic_load uses system
             * default path (see man libmagic) */
            SCLogConfig("using system default magic-file");
            filename = NULL;
        }
        else {
            SCLogConfig("using magic-file %s", filename);

            if ( (fd = fopen(filename, "r")) == NULL) {
                SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
                        filename, strerror(errno));
                goto error;
            }
            fclose(fd);
        }
    }

    if (magic_load(g_magic_ctx, filename) != 0) {
        SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s",
                magic_error(g_magic_ctx));
        goto error;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(0);

error:
    if (g_magic_ctx != NULL) {
        magic_close(g_magic_ctx);
        g_magic_ctx = NULL;
    }

    SCMutexUnlock(&g_magic_lock);
    SCReturnInt(-1);
}
Пример #9
0
/** \internal
 *  \brief Get a host from the hash directly.
 *
 *  Called in conditions where the spare queue is empty and memcap is reached.
 *
 *  Walks the hash until a host can be freed. "host_prune_idx" atomic int makes
 *  sure we don't start at the top each time since that would clear the top of
 *  the hash leading to longer and longer search times under high pressure (observed).
 *
 *  \retval h host or NULL
 */
static Host *HostGetUsedHost(void) {
    uint32_t idx = SC_ATOMIC_GET(host_prune_idx) % host_config.hash_size;
    uint32_t cnt = host_config.hash_size;

    while (cnt--) {
        if (++idx >= host_config.hash_size)
            idx = 0;

        HostHashRow *hb = &host_hash[idx];
        if (hb == NULL)
            continue;

        if (HRLOCK_TRYLOCK(hb) != 0)
            continue;

        Host *h = hb->tail;
        if (h == NULL) {
            HRLOCK_UNLOCK(hb);
            continue;
        }

        if (SCMutexTrylock(&h->m) != 0) {
            HRLOCK_UNLOCK(hb);
            continue;
        }

        /** never prune a host that is used by a packets
         *  we are currently processing in one of the threads */
        if (SC_ATOMIC_GET(h->use_cnt) > 0) {
            HRLOCK_UNLOCK(hb);
            SCMutexUnlock(&h->m);
            continue;
        }

        /* remove from the hash */
        if (h->hprev != NULL)
            h->hprev->hnext = h->hnext;
        if (h->hnext != NULL)
            h->hnext->hprev = h->hprev;
        if (hb->head == h)
            hb->head = h->hnext;
        if (hb->tail == h)
            hb->tail = h->hprev;

        h->hnext = NULL;
        h->hprev = NULL;
        HRLOCK_UNLOCK(hb);

        HostClearMemory (h);

        SCMutexUnlock(&h->m);

        (void) SC_ATOMIC_ADD(host_prune_idx, (host_config.hash_size - cnt));
        return h;
    }

    return NULL;
}
Пример #10
0
/** \internal
 *  \brief Get a tracker from the hash directly.
 *
 *  Called in conditions where the spare queue is empty and memcap is reached.
 *
 *  Walks the hash until a tracker can be freed. "defragtracker_prune_idx" atomic int makes
 *  sure we don't start at the top each time since that would clear the top of
 *  the hash leading to longer and longer search times under high pressure (observed).
 *
 *  \retval dt tracker or NULL
 */
static DefragTracker *DefragTrackerGetUsedDefragTracker(void)
{
    uint32_t idx = SC_ATOMIC_GET(defragtracker_prune_idx) % defrag_config.hash_size;
    uint32_t cnt = defrag_config.hash_size;

    while (cnt--) {
        if (++idx >= defrag_config.hash_size)
            idx = 0;

        DefragTrackerHashRow *hb = &defragtracker_hash[idx];

        if (DRLOCK_TRYLOCK(hb) != 0)
            continue;

        DefragTracker *dt = hb->tail;
        if (dt == NULL) {
            DRLOCK_UNLOCK(hb);
            continue;
        }

        if (SCMutexTrylock(&dt->lock) != 0) {
            DRLOCK_UNLOCK(hb);
            continue;
        }

        /** never prune a tracker that is used by a packets
         *  we are currently processing in one of the threads */
        if (SC_ATOMIC_GET(dt->use_cnt) > 0) {
            DRLOCK_UNLOCK(hb);
            SCMutexUnlock(&dt->lock);
            continue;
        }

        /* remove from the hash */
        if (dt->hprev != NULL)
            dt->hprev->hnext = dt->hnext;
        if (dt->hnext != NULL)
            dt->hnext->hprev = dt->hprev;
        if (hb->head == dt)
            hb->head = dt->hnext;
        if (hb->tail == dt)
            hb->tail = dt->hprev;

        dt->hnext = NULL;
        dt->hprev = NULL;
        DRLOCK_UNLOCK(hb);

        DefragTrackerClearMemory(dt);

        SCMutexUnlock(&dt->lock);

        (void) SC_ATOMIC_ADD(defragtracker_prune_idx, (defrag_config.hash_size - cnt));
        return dt;
    }

    return NULL;
}
Пример #11
0
/**
 * \brief Adds a Function-Dependent(FD) filter
 *
 * \param Name of the function for which a FD filter has to be registered
 *
 * \retval  0 on success
 * \retval -1 on failure
 */
int SCLogAddFDFilter(const char *function)
{
    SCLogFDFilter *curr = NULL;
    SCLogFDFilter *prev = NULL;
    SCLogFDFilter *temp = NULL;

    if (sc_log_module_initialized != 1) {
        printf("Logging module not initialized.  Call SCLogInitLogModule() "
               "first before using the debug API\n");
        return -1;
    }

    if (function == NULL) {
        printf("Invalid argument supplied to SCLogAddFDFilter\n");
        return -1;
    }

    SCMutexLock(&sc_log_fd_filters_m);

    curr = sc_log_fd_filters;
    while (curr != NULL) {
        prev = curr;

        if (strcmp(function, curr->func) == 0) {

            SCMutexUnlock(&sc_log_fd_filters_m);
            return 0;
        }

        curr = curr->next;
    }

    if ( (temp = SCMalloc(sizeof(SCLogFDFilter))) == NULL) {
        printf("Error Allocating memory (SCMalloc)\n");
        exit(EXIT_FAILURE);
    }
    memset(temp, 0, sizeof(SCLogFDFilter));

    if ( (temp->func = SCStrdup(function)) == NULL) {
        printf("Error Allocating memory (SCStrdup)\n");
        exit(EXIT_FAILURE);
    }

    if (sc_log_fd_filters == NULL)
        sc_log_fd_filters = temp;
    /* clang thinks prev can be NULL, but it can't be unless
     * sc_log_fd_filters is also NULL which is handled here.
     * Doing this "fix" to shut clang up. */
    else if (prev != NULL)
        prev->next = temp;

    SCMutexUnlock(&sc_log_fd_filters_m);
    sc_log_fd_filters_present = 1;

    return 0;
}
Пример #12
0
CUcontext CudaHandlerModuleGetContext(const char *name, int device_id)
{
    SCMutexLock(&mutex);

    CudaHandlerModule *module = cudahl_modules;
    while (module != NULL && strcasecmp(module->name, name) != 0)
        module = module->next;
    if (module != NULL) {
        if (module->device_id != device_id) {
            SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module already "
                       "registered, but the new device_id is different "
                       "from the already registered device_id.");
            exit(EXIT_FAILURE);
        }
        SCMutexUnlock(&mutex);
        return module->context;
    }

    CudaHandlerModule *new_module = SCMalloc(sizeof(CudaHandlerModule));
    if (new_module == NULL)
        exit(EXIT_FAILURE);
    memset(new_module, 0, sizeof(CudaHandlerModule));
    new_module->device_id = device_id;
    new_module->name = SCStrdup(name);
    if (new_module->name == NULL)
        exit(EXIT_FAILURE);
    if (cudahl_modules == NULL) {
        cudahl_modules = new_module;
    } else {
        new_module->next = cudahl_modules;
        cudahl_modules = new_module;
    }

    if (no_of_cuda_contexts <= device_id) {
        cuda_contexts = SCRealloc(cuda_contexts, sizeof(CUcontext) * (device_id + 1));
        if (cuda_contexts == NULL)
            exit(EXIT_FAILURE);
        memset(cuda_contexts + no_of_cuda_contexts, 0,
               sizeof(CUcontext) * ((device_id + 1) - no_of_cuda_contexts));
        no_of_cuda_contexts = device_id + 1;
    }

    if (cuda_contexts[device_id] == 0) {
        SCCudaDevices *devices = SCCudaGetDeviceList();
        if (SCCudaCtxCreate(&cuda_contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC,
                            devices->devices[device_id]->device) == -1) {
            SCLogDebug("ctxcreate failure.");
            exit(EXIT_FAILURE);
        }
    }
    new_module->context = cuda_contexts[device_id];

    SCMutexUnlock(&mutex);
    return cuda_contexts[device_id];
}
Пример #13
0
/**
 * \brief Removes a Function-Dependent(FD) filter
 *
 * \param Name of the function for which a FD filter has to be unregistered
 *
 * \retval  0 on success(the filter was removed or the filter was not present)
 * \retval -1 on failure/error
 */
int SCLogRemoveFDFilter(const char *function)
{
    SCLogFDFilter *curr = NULL;
    SCLogFDFilter *prev = NULL;

    if (sc_log_module_initialized != 1) {
        printf("Logging module not initialized.  Call SCLogInitLogModule() "
               "first before using the debug API\n");
        return -1 ;
    }

    if (function == NULL) {
        printf("Invalid argument(s) supplied to SCLogRemoveFDFilter\n");
        return -1;
    }

    SCMutexLock(&sc_log_fd_filters_m);

    if (sc_log_fd_filters == NULL) {
        SCMutexUnlock(&sc_log_fd_filters_m);
        return 0;
    }

    curr = sc_log_fd_filters;
    prev = curr;
    while (curr != NULL) {
        if (strcmp(function, curr->func) == 0)
            break;

        prev = curr;
        curr = curr->next;
    }

    if (curr == NULL) {

        SCMutexUnlock(&sc_log_fd_filters_m);

        return 0;
    }

    if (sc_log_fd_filters == curr)
        sc_log_fd_filters = curr->next;
    else
        prev->next = curr->next;

    SCLogReleaseFDFilter(curr);

    SCMutexUnlock(&sc_log_fd_filters_m);

    if (sc_log_fd_filters == NULL)
        sc_log_fd_filters_present = 0;

    return 0;
}
Пример #14
0
void CudaHandlerAddCudaProfileFromConf(const char *name,
                                       void *(*Callback)(ConfNode *node),
                                       void (*Free)(void *))
{
    /* we don't do data validation */
    SCMutexLock(&mutex);

    CudaHandlerConfProfile *tmp_cp = conf_profiles;
    while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0)
        tmp_cp = tmp_cp->next;

    if (tmp_cp != NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "We already have a cuda conf "
                   "profile by the name \"%s\" registered.", name);
        exit(EXIT_FAILURE);
    }

    char tmp[200];
    int r = snprintf(tmp, sizeof(tmp), "%s%s", "cuda.", name);
    if (r < 0) {
        SCLogError(SC_ERR_FATAL, "snprintf failure.");
        exit(EXIT_FAILURE);
    } else if (r > (int)sizeof(tmp)) {
        SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
        exit(EXIT_FAILURE);
    }
    void *ctx = Callback(ConfGetNode(tmp));
    if (ctx == NULL) {
        SCMutexUnlock(&mutex);
        return;
    }

    CudaHandlerConfProfile *new_cp = SCMalloc(sizeof(CudaHandlerConfProfile));
    if (new_cp == NULL)
        exit(EXIT_FAILURE);
    memset(new_cp, 0, sizeof(CudaHandlerConfProfile));
    new_cp->name = SCStrdup(name);
    if (new_cp->name == NULL)
        exit(EXIT_FAILURE);
    new_cp->ctx = ctx;
    new_cp->Free = Free;

    if (conf_profiles == NULL) {
        conf_profiles = new_cp;
    } else {
        new_cp->next = conf_profiles;
        conf_profiles = new_cp;
    }

    SCMutexUnlock(&mutex);
    return;
}
Пример #15
0
/**
 * \test Test the deallocation of app layer parser memory on occurance of
 *       error in the parsing process.
 */
static int AppLayerParserTest01(void)
{
    AppLayerParserBackupParserTable();

    int result = 0;
    Flow *f = NULL;
    uint8_t testbuf[] = { 0x11 };
    uint32_t testlen = sizeof(testbuf);
    TcpSession ssn;
    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();

    memset(&ssn, 0, sizeof(ssn));

    /* Register the Test protocol state and parser functions */
    AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER,
                      TestProtocolParser);
    AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST,
                          TestProtocolStateAlloc, TestProtocolStateFree);

    f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
    if (f == NULL)
        goto end;
    f->protoctx = &ssn;
    f->alproto = ALPROTO_TEST;
    f->proto = IPPROTO_TCP;

    StreamTcpInitConfig(TRUE);

    SCMutexLock(&f->m);
    int r = AppLayerParserParse(alp_tctx, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF,
                           testbuf, testlen);
    if (r != -1) {
        printf("returned %" PRId32 ", expected -1: ", r);
        SCMutexUnlock(&f->m);
        goto end;
    }
    SCMutexUnlock(&f->m);

    if (!(f->flags & FLOW_NO_APPLAYER_INSPECTION)) {
        printf("flag should have been set, but is not: ");
        goto end;
    }

    result = 1;
 end:
    AppLayerParserRestoreParserTable();
    StreamTcpFreeConfig(TRUE);

    UTHFreeFlow(f);
    return result;
}
Пример #16
0
/**
 * \brief Updates a FD filter, based on whether the function that calls this
 *        function, is registered as a FD filter or not.  This is called by
 *        a function only before its exit.
 *
 * \param function Function_name from where the log_message originated
 *
 */
void SCLogCheckFDFilterExit(const char *function)
{
    SCLogFDFilter *curr = NULL;

    SCLogFDFilterThreadList *thread_list = NULL;

    //pid_t self = syscall(SYS_gettid);
    pthread_t self = pthread_self();

    if (sc_log_module_initialized != 1) {
        printf("Logging module not initialized.  Call SCLogInitLogModule() "
               "first before using the debug API\n");
        return;
    }

    SCMutexLock(&sc_log_fd_filters_m);

    curr = sc_log_fd_filters;

    while (curr != NULL) {
        if (strcmp(function, curr->func) == 0)
            break;

        curr = curr->next;
    }

    if (curr == NULL) {
        SCMutexUnlock(&sc_log_fd_filters_m);
        return;
    }

    SCMutexUnlock(&sc_log_fd_filters_m);

    SCMutexLock(&sc_log_fd_filters_tl_m);

    thread_list = sc_log_fd_filters_tl;
    while (thread_list != NULL) {
        if (pthread_equal(self, thread_list->t))
            break;

        thread_list = thread_list->next;
    }

    SCMutexUnlock(&sc_log_fd_filters_tl_m);

    if (thread_list != NULL)
        thread_list->entered--;

    return;
}
Пример #17
0
/**
 *  \brief Add a single Netfilter queue
 *
 *  \param string with the queue number
 *
 *  \retval 0 on success.
 *  \retval -1 on failure.
 */
int NFQRegisterQueue(const uint16_t number)
{
    NFQThreadVars *ntv = NULL;
    NFQQueueVars *nq = NULL;
    char queue[10] = { 0 };
    static bool many_queues_warned = false;
    uint16_t num_cpus = UtilCpuGetNumProcessorsOnline();

    if (g_nfq_t == NULL || g_nfq_q == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "NFQ context is not initialized");
        return -1;
    }

    SCMutexLock(&nfq_init_lock);
    if (!many_queues_warned && (receive_queue_num >= num_cpus)) {
        SCLogWarning(SC_WARN_UNCOMMON,
                     "using more Netfilter queues than %hu available CPU core(s) "
                     "may degrade performance",
                     num_cpus);
        many_queues_warned = true;
    }
    if (receive_queue_num >= NFQ_MAX_QUEUE) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "can not register more than %d Netfilter queues",
                   NFQ_MAX_QUEUE);
        SCMutexUnlock(&nfq_init_lock);
        return -1;
    }

    ntv = &g_nfq_t[receive_queue_num];
    ntv->nfq_index = receive_queue_num;

    nq = &g_nfq_q[receive_queue_num];
    nq->queue_num = number;
    receive_queue_num++;
    SCMutexUnlock(&nfq_init_lock);
    snprintf(queue, sizeof(queue) - 1, "NFQ#%hu", number);
    LiveRegisterDevice(queue);

    ntv->livedev = LiveGetDevice(queue);

    if (ntv->livedev == NULL) {
        SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
        return -1;
    }

    SCLogDebug("Queue %d registered.", number);
    return 0;
}
Пример #18
0
void CudaHandlerModuleStoreData(const char *module_name,
                                const char *data_name, void *data_ptr)
{
    SCMutexLock(&mutex);

    CudaHandlerModule *module = cudahl_modules;
    while (module != NULL && strcasecmp(module->name, module_name) != 0)
        module = module->next;
    if (module == NULL) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data "
                   "\"%s\" from module \"%s\" that hasn't been registered "
                   "yet.",  module_name, data_name);
        exit(EXIT_FAILURE);
    }

    CudaHandlerModuleData *data = module->module_data;
    while (data != NULL && (strcasecmp(data_name, data->name) != 0)) {
        data = data->next;
    }
    if (data != NULL) {
        SCLogWarning(SC_ERR_CUDA_HANDLER_ERROR, "Data \"%s\" already "
                     "registered for this module \"%s\".", data_name,
                     module_name);
        SCMutexUnlock(&mutex);
        goto end;
    }

    CudaHandlerModuleData *new_data = SCMalloc(sizeof(CudaHandlerModuleData));
    if (new_data == NULL)
        exit(EXIT_FAILURE);
    memset(new_data, 0, sizeof(CudaHandlerModuleData));
    new_data->name = SCStrdup(data_name);
    if (new_data->name == NULL)
        exit(EXIT_FAILURE);
    new_data->data = data_ptr;

    if (module->module_data == NULL) {
        module->module_data = new_data;
    } else {
        new_data->next = module->module_data;
        module->module_data = new_data;
    }

    SCMutexUnlock(&mutex);

 end:
    return;
}
Пример #19
0
/** \brief LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
 *  \param motcx pointer to the OutputCtx
 *  \retval int 1 if succesful, 0 if error
 *  */
int LogFileFreeCtx(LogFileCtx *lf_ctx)
{
    if (lf_ctx == NULL) {
        SCReturnInt(0);
    }

    if (lf_ctx->fp != NULL) {
        SCMutexLock(&lf_ctx->fp_mutex);
        lf_ctx->Close(lf_ctx);
        SCMutexUnlock(&lf_ctx->fp_mutex);
    }

    SCMutexDestroy(&lf_ctx->fp_mutex);

    if (lf_ctx->prefix != NULL) {
        SCFree(lf_ctx->prefix);
        lf_ctx->prefix_len = 0;
    }

    if(lf_ctx->filename != NULL)
        SCFree(lf_ctx->filename);

    if (lf_ctx->sensor_name)
        SCFree(lf_ctx->sensor_name);

    OutputUnregisterFileRotationFlag(&lf_ctx->rotation_flag);

    SCFree(lf_ctx);

    SCReturnInt(1);
}
Пример #20
0
/**
 * \brief select the queue to output in a round robin fashion.
 *
 * \param tv thread vars
 * \param p packet
 */
void TmqhOutputFlowRoundRobin(ThreadVars *tv, Packet *p)
{
    int32_t qid = 0;

    TmqhFlowCtx *ctx = (TmqhFlowCtx *)tv->outctx;

    /* if no flow we use the first queue,
     * should be rare */
    if (p->flow != NULL) {
        qid = SC_ATOMIC_GET(p->flow->autofp_tmqh_flow_qid);
        if (qid == -1) {
            qid = SC_ATOMIC_ADD(ctx->round_robin_idx, 1);
            if (qid >= ctx->size) {
                SC_ATOMIC_RESET(ctx->round_robin_idx);
                qid = 0;
            }
            (void) SC_ATOMIC_ADD(ctx->queues[qid].total_flows, 1);
            (void) SC_ATOMIC_SET(p->flow->autofp_tmqh_flow_qid, qid);
        }
    } else {
        qid = ctx->last++;

        if (ctx->last == ctx->size)
            ctx->last = 0;
    }
    (void) SC_ATOMIC_ADD(ctx->queues[qid].total_packets, 1);

    PacketQueue *q = ctx->queues[qid].q;
    SCMutexLock(&q->mutex_q);
    PacketEnqueue(q, p);
    SCCondSignal(&q->cond_q);
    SCMutexUnlock(&q->mutex_q);

    return;
}
Пример #21
0
TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
    int i;


    /* logging is useless if we don't have pcap number */
    if ((p->pcap_cnt != 0) && (p->alerts.cnt > 0)) {
        SCMutexLock(&aft->file_ctx->fp_mutex);
        /* only count logged alert */
        aft->file_ctx->alerts += p->alerts.cnt;
        for (i = 0; i < p->alerts.cnt; i++) {
            PacketAlert *pa = &p->alerts.alerts[i];

            fprintf(aft->file_ctx->fp, "%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%d:%d:%d:%d:0:0:%s\n",
                    p->pcap_cnt, pa->s->gid, pa->s->id, pa->s->rev,
                    pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0,
                    p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0,
                    p->flowflags & FLOW_PKT_TOCLIENT ? 1 : 0,
                    pa->s->msg);
        }
        SCMutexUnlock(&aft->file_ctx->fp_mutex);
    }

    return TM_ECODE_OK;
}
Пример #22
0
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) {
    char *js_s = json_dumps(js,
                            JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII|
#ifdef JSON_ESCAPE_SLASH
                            JSON_ESCAPE_SLASH
#else
                            0
#endif
                           );
    if (unlikely(js_s == NULL))
        return TM_ECODE_OK;

    SCMutexLock(&file_ctx->fp_mutex);
    if (json_out == ALERT_REMOTE) {
        MemBufferWriteString(buffer, "%s\n", js_s);
        SendToRemote((char *)MEMBUFFER_BUFFER(buffer),
                     MEMBUFFER_OFFSET(buffer));
    }
    else if (json_out == ALERT_SYSLOG) {
        syslog(alert_syslog_level, "%s", js_s);
    } else if (json_out == ALERT_FILE || json_out == ALERT_UNIX_DGRAM || json_out == ALERT_UNIX_STREAM) {
        MemBufferWriteString(buffer, "%s\n", js_s);
        file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer),
                        MEMBUFFER_OFFSET(buffer), file_ctx);
    }
    SCMutexUnlock(&file_ctx->fp_mutex);
    free(js_s);
    return 0;
}
Пример #23
0
/* add a flowbit to the flow */
static void FlowAlertSidAdd(Flow *f, uint32_t sid) {
    FlowAlertSid *fb = FlowAlertSidGet(f, sid);
    if (fb == NULL) {
        fb = SCMalloc(sizeof(FlowAlertSid));
        if (unlikely(fb == NULL))
            return;

        fb->type = DETECT_FLOWALERTSID;
        fb->sid = sid;
        fb->next = NULL;

        SCLogDebug("fb->type %u, sid %"PRIu32"", fb->type, fb->sid);
        GenericVarAppend(&f->flowvar, (GenericVar *)fb);
        SCLogDebug("fb->type %u, sid %"PRIu32"", fb->type, fb->sid);

        SCLogDebug("adding flowalertsid with sid %" PRIu32 " (%"PRIu32")", sid, fb->sid);
#ifdef FLOWALERTSID_STATS
        SCMutexLock(&flowbits_mutex);
       flowbits_added++;
        flowbits_memuse += sizeof(FlowAlertSid);
        if (flowbits_memuse > flowbits_memuse_max)
            flowbits_memuse_max = flowbits_memuse;
        SCMutexUnlock(&flowbits_mutex);
#endif /* FLOWALERTSID_STATS */
    }
}
Пример #24
0
/**
 * \brief Make the threshold logic for signatures
 *
 * \param de_ctx Dectection Context
 * \param tsh_ptr Threshold element
 * \param p Packet structure
 * \param s Signature structure
 *
 * \retval 2 silent match (no alert but apply actions)
 * \retval 1 alert on this event
 * \retval 0 do not alert on this event
 */
int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
        const DetectThresholdData *td, Packet *p, const Signature *s, PacketAlert *pa)
{
    SCEnter();

    int ret = 0;
    if (td == NULL) {
        SCReturnInt(0);
    }

    if (td->type == TYPE_SUPPRESS) {
        ret = ThresholdHandlePacketSuppress(p,td,s->id,s->gid);
    } else if (td->track == TRACK_SRC) {
        Host *src = HostGetHostFromHash(&p->src);
        if (src) {
            ret = ThresholdHandlePacketHost(src,p,td,s->id,s->gid,pa);
            HostRelease(src);
        }
    } else if (td->track == TRACK_DST) {
        Host *dst = HostGetHostFromHash(&p->dst);
        if (dst) {
            ret = ThresholdHandlePacketHost(dst,p,td,s->id,s->gid,pa);
            HostRelease(dst);
        }
    } else if (td->track == TRACK_RULE) {
        SCMutexLock(&de_ctx->ths_ctx.threshold_table_lock);
        ret = ThresholdHandlePacketRule(de_ctx,p,td,s,pa);
        SCMutexUnlock(&de_ctx->ths_ctx.threshold_table_lock);
    }

    SCReturnInt(ret);
}
Пример #25
0
void *CudaHandlerGetCudaProfile(const char *name)
{
    SCMutexLock(&mutex);

    CudaHandlerConfProfile *tmp_cp = conf_profiles;
    while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0)
        tmp_cp = tmp_cp->next;

    if (tmp_cp == NULL) {
        SCMutexUnlock(&mutex);
        return NULL;
    }

    SCMutexUnlock(&mutex);
    return tmp_cp->ctx;
}
Пример #26
0
/* Used by l7inspection to return msgs to pool */
void StreamMsgReturnToPool(StreamMsg *s)
{
    SCLogDebug("s %p", s);
    SCMutexLock(&stream_msg_pool_mutex);
    PoolReturn(stream_msg_pool, (void *)s);
    SCMutexUnlock(&stream_msg_pool_mutex);
}
Пример #27
0
/* Used by stream reassembler to get msgs */
StreamMsg *StreamMsgGetFromPool(void)
{
    SCMutexLock(&stream_msg_pool_mutex);
    StreamMsg *s = (StreamMsg *)PoolGet(stream_msg_pool);
    SCMutexUnlock(&stream_msg_pool_mutex);
    return s;
}
Пример #28
0
/**
 * \brief Prints the FG filters(both WL and BL).  Used for debugging purposes.
 *
 * \retval count The no of FG filters
 */
int SCLogPrintFDFilters(void)
{
    SCLogFDFilter *fdf = NULL;
    int count = 0;

    if (sc_log_module_initialized != 1) {
        printf("Logging module not initialized.  Call SCLogInitLogModule() "
               "first before using the debug API\n");
        return 0;
    }

#ifdef DEBUG
    printf("FD filters:\n");
#endif

    SCMutexLock(&sc_log_fd_filters_m);

    fdf = sc_log_fd_filters;
    while (fdf != NULL) {
#ifdef DEBUG
        printf("%s \n", fdf->func);
#endif
        fdf = fdf->next;
        count++;
    }

    SCMutexUnlock(&sc_log_fd_filters_m);

    return count;
}
Пример #29
0
/**
 *  \internal
 *
 *  \brief check all hosts in a hash row for timing out
 *
 *  \param hb host hash row *LOCKED*
 *  \param h last host in the hash row
 *  \param ts timestamp
 *
 *  \retval cnt timed out hosts
 */
static uint32_t HostHashRowTimeout(HostHashRow *hb, Host *h, struct timeval *ts)
{
    uint32_t cnt = 0;

    do {
        if (SCMutexTrylock(&h->m) != 0) {
            h = h->hprev;
            continue;
        }

        Host *next_host = h->hprev;

        /* check if the host is fully timed out and
         * ready to be discarded. */
        if (HostHostTimedOut(h, ts) == 1) {
            /* remove from the hash */
            if (h->hprev != NULL)
                h->hprev->hnext = h->hnext;
            if (h->hnext != NULL)
                h->hnext->hprev = h->hprev;
            if (hb->head == h)
                hb->head = h->hnext;
            if (hb->tail == h)
                hb->tail = h->hprev;

            h->hnext = NULL;
            h->hprev = NULL;

            HostClearMemory (h);

            /* no one is referring to this host, use_cnt 0, removed from hash
             * so we can unlock it and move it back to the spare queue. */
            SCMutexUnlock(&h->m);

            /* move to spare list */
            HostMoveToSpare(h);

            cnt++;
        } else {
            SCMutexUnlock(&h->m);
        }

        h = next_host;
    } while (h != NULL);

    return cnt;
}
Пример #30
0
TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    AlertDebugLogThread *aft = (AlertDebugLogThread *)data;
    int i;
    char timebuf[64];

    if (p->alerts.cnt == 0)
        return TM_ECODE_OK;

    MemBufferReset(aft->buffer);

    CreateTimeString(&p->ts, timebuf, sizeof(timebuf));

    MemBufferWriteString(aft->buffer,
                         "+================\n"
                         "TIME:              %s\n", timebuf);
    if (p->pcap_cnt > 0) {
        MemBufferWriteString(aft->buffer,
                             "PCAP PKT NUM:      %"PRIu64"\n", p->pcap_cnt);
    }
    MemBufferWriteString(aft->buffer,
                         "ALERT CNT:         %" PRIu32 "\n", p->alerts.cnt);

    for (i = 0; i < p->alerts.cnt; i++) {
        PacketAlert *pa = &p->alerts.alerts[i];
        if (unlikely(pa->s == NULL)) {
            continue;
        }

        MemBufferWriteString(aft->buffer,
                             "ALERT MSG [%02d]:    %s\n"
                             "ALERT GID [%02d]:    %" PRIu32 "\n"
                             "ALERT SID [%02d]:    %" PRIu32 "\n"
                             "ALERT REV [%02d]:    %" PRIu32 "\n"
                             "ALERT CLASS [%02d]:  %s\n"
                             "ALERT PRIO [%02d]:   %" PRIu32 "\n",
                             i, pa->s->msg,
                             i, pa->s->gid,
                             i, pa->s->id,
                             i, pa->s->rev,
                             i, pa->s->class_msg,
                             i, pa->s->prio);
    }

    MemBufferWriteString(aft->buffer,
                         "PACKET LEN:        %" PRIu32 "\n"
                         "PACKET:\n",
                         GET_PKT_LEN(p));
    PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
                         GET_PKT_DATA(p), GET_PKT_LEN(p));

    SCMutexLock(&aft->file_ctx->fp_mutex);
    (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp);
    fflush(aft->file_ctx->fp);
    aft->file_ctx->alerts += p->alerts.cnt;
    SCMutexUnlock(&aft->file_ctx->fp_mutex);

    return TM_ECODE_OK;
}