Esempio n. 1
0
/**
 * \brief Returns a cuda_device_pointer against the handle in the argument.
 *
 *        If a device pointer by the name \"name\"  is not registered for the
 *        handle, it is created and associated with this handle and cuda mem is
 *        alloted and the cuda_device_pointer is returned in the argument.
 *        If a device pointer by the name \"name\" is already registered with
 *        the handle, the cuda_device_pointer is returned in the argument.
 *
 * \param device_ptr Pointer to the device pointer instance which should be
 *                   with the cuda_device_pointer that has to be returned back.
 * \param name       Name of the device pointer by which we have to search
 *                   module for its existance.
 * \param size       Size of the cuda device memory to be alloted.
 * \param host_ptr   If any host memory has to be transferred to the cuda device
 *                   memory, it can sent using this argument.  host_ptr should
 *                   hold atleast size bytes in memory.
 * \param handle     A unique handle which identifies a module.  Obtained from
 *                   a call to SCCudaHlGetUniqueHandle().
 * \param cumodule_handle   A handle that identifies the CUmodule within the above module.
 *                   Obtained from a call to SCCudaHlGetCudaModule() or
 *                   SCCudaHlGetCudaModuleFromFile().
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlGetCudaDevicePtr(CUdeviceptr *device_ptr, const char *name,
                             size_t size, void *host_ptr, int handle,
                             int cumodule_handle)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleCUmodule *cumodule = NULL;
    SCCudaHlModuleDevicePointer *new_module_device_ptr = NULL;
    SCCudaHlModuleDevicePointer *module_device_ptr = NULL;

    if (device_ptr == NULL || name == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "device_ptr is NULL or name is NULL");
        goto error;
    }

    /* check if the particular module that wants to allocate device memory is
     * already registered or not.  If it is registered, check if a context has
     * been associated with the module.  If yes, then we can go ahead and
     * create the device memory or return the reference to the device memory if
     * we already have the device memory associated with the module.  If no, "
     * log warning and get out of here */
    if ( ((data = SCCudaHlGetModuleData(handle)) == NULL) ||
         (data->cuda_context == 0)) {
        SCLogDebug("Module not registered or no cuda context associated with "
                   "this module.  You can't create a CUDA module without"
                   "associating a context with a module first. To use this "
                   "registration facility, first register a module using "
                   "context using SCCudaHlRegisterModule(), and then register "
                   "a cuda context with that module using "
                   "SCCudaHlGetCudaContext(), after which you can call this "
                   "function ");
        goto error;
    }

    if ( (cumodule = SCCudaHlGetModuleCUmodule(data, cumodule_handle)) == NULL ) {
        SCLogDebug("CUmodule not registered with the module. Before you can request"
                   "a device pointer for a module you need to load the CUmodule into"
                   "the engine module using SCCudaHlGetCudaModule() or"
                   "SCCudaHlGetCudaModuleFromFile().");
        goto error;
    }

    /* if we already have a device pointer registered by this name return the
     * cuda device pointer instance */
    if ( (module_device_ptr = SCCudaHlCudaDevicePtrAvailable(cumodule, name)) != NULL) {
        device_ptr[0] = module_device_ptr->d_ptr;
        return 0;
    }

    new_module_device_ptr = SCMalloc(sizeof(SCCudaHlModuleDevicePointer));
    if (new_module_device_ptr == NULL)
        goto error;
    memset(new_module_device_ptr, 0, sizeof(SCCudaHlModuleDevicePointer));

    if ( (new_module_device_ptr->name = SCStrdup(name)) == NULL) {
        SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCCudaHlGetCudaDevicePtr. Exiting...");
        exit(EXIT_FAILURE);
    }

    /* allocate the cuda memory */
    if (SCCudaMemAlloc(&new_module_device_ptr->d_ptr, size) == -1)
        goto error;

    /* if the user has supplied a host buffer, copy contents to the device mem */
    if (host_ptr != NULL) {
        if (SCCudaMemcpyHtoD(new_module_device_ptr->d_ptr, host_ptr,
                             size) == -1) {
            goto error;
        }
    }

    /* send the newly assigned device pointer back to the caller */
    device_ptr[0] = new_module_device_ptr->d_ptr;

    /* insert it into the device_ptr list for the module instance */
    if (cumodule->device_ptrs == NULL) {
        cumodule->device_ptrs = new_module_device_ptr;
        return 0;
    }

    module_device_ptr = cumodule->device_ptrs;
    while (module_device_ptr->next != NULL)
        module_device_ptr = module_device_ptr->next;
    module_device_ptr->next = new_module_device_ptr;

    return 0;

 error:
    if (new_module_device_ptr != NULL)
        SCFree(new_module_device_ptr);
    return -1;
}
Esempio n. 2
0
/**
 * \brief This function is used to add the parsed isdataatdata into the current
 *        signature.
 * \param de_ctx pointer to the Detection Engine Context
 * \param s pointer to the Current Signature
 * \param isdataatstr pointer to the user provided isdataat options
 *
 * \retval 0 on Success
 * \retval -1 on Failure
 */
int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatstr)
{
    DetectIsdataatData *idad = NULL;
    SigMatch *sm = NULL;
    SigMatch *dm = NULL;
    SigMatch *pm = NULL;
    SigMatch *prev_pm = NULL;
    char *offset = NULL;

    idad = DetectIsdataatParse(isdataatstr, &offset);
    if (idad == NULL)
        goto error;

    sm = SigMatchAlloc();
    if (sm == NULL)
        goto error;

    sm->type = DETECT_ISDATAAT;
    sm->ctx = (void *)idad;

    if (s->alproto == ALPROTO_DCERPC &&
        idad->flags & ISDATAAT_RELATIVE) {

        pm = SigMatchGetLastSMFromLists(s, 6,
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
        dm = SigMatchGetLastSMFromLists(s, 6,
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);

        if (pm == NULL) {
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH);
        } else if (dm == NULL) {
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH);
        } else if (pm->idx > dm->idx) {
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH);
        } else {
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH);
        }
        prev_pm = SigMatchGetLastSMFromLists(s, 6,
                DETECT_CONTENT, sm->prev,
                DETECT_BYTEJUMP, sm->prev,
                DETECT_PCRE, sm->prev);
        if (prev_pm == NULL) {
            SCLogDebug("No preceding content or pcre keyword.  Possible "
                       "since this is a dce alproto sig.");
            if (offset != NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
                           "seen in isdataat - %s", offset);
                goto error;
            }
            return 0;
        }
    } else if (s->init_flags & SIG_FLAG_INIT_FILE_DATA) {
        if (idad->flags & ISDATAAT_RELATIVE) {
            pm = SigMatchGetLastSMFromLists(s, 10,
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                    DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                    DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                    DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                    DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH]);
            if (pm == NULL) {
                idad->flags &= ~ISDATAAT_RELATIVE;
            }

            s->flags |= SIG_FLAG_APPLAYER;
            AppLayerHtpEnableResponseBodyCallback();
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH);
        } else {
            s->flags |= SIG_FLAG_APPLAYER;
            AppLayerHtpEnableResponseBodyCallback();
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH);
        }

        if (pm == NULL) {
            SCLogDebug("No preceding content or pcre keyword.  Possible "
                       "since this is a file_data sig.");
            if (offset != NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
                           "seen in isdataat - %s", offset);
                goto error;
            }
            return 0;
        }

        prev_pm = pm;
    } else {
        if (!(idad->flags & ISDATAAT_RELATIVE)) {
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH);
            if (offset != NULL) {
                SigMatch *bed_sm =
                    DetectByteExtractRetrieveSMVar(offset, s,
                                                   SigMatchListSMBelongsTo(s, sm));
                if (bed_sm == NULL) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
                               "seen in isdataat - %s\n", offset);
                    goto error;
                }
                DetectIsdataatData *isdd = sm->ctx;
                isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
                isdd->flags |= ISDATAAT_OFFSET_BE;
                SCFree(offset);
            }
            return 0;
        }
        pm = SigMatchGetLastSMFromLists(s, 56,
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
                DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH],
                DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
                DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]);
        if (pm == NULL) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen "
                       "without a previous content uricontent, "
                       "http_client_body, http_header, http_raw_header, "
                       "http_method, http_cookie, http_raw_uri, "
                       "http_stat_msg, http_stat_code, byte_test, "
                       "byte_extract, byte_jump or http_user_agent keyword");
            goto error;
        } else {
            int list_type = SigMatchListSMBelongsTo(s, pm);
            if (list_type == -1) {
                goto error;
            }

            SigMatchAppendSMToList(s, sm, list_type);
        } /* else - if (pm == NULL) */

        prev_pm = pm;
    }

    if (offset != NULL) {
        SigMatch *bed_sm =
            DetectByteExtractRetrieveSMVar(offset, s,
                                           SigMatchListSMBelongsTo(s, sm));
        if (bed_sm == NULL) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
                       "seen in isdataat - %s\n", offset);
            goto error;
        }
        DetectIsdataatData *isdd = sm->ctx;
        isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
        isdd->flags |= ISDATAAT_OFFSET_BE;
        SCFree(offset);
    }

    DetectContentData *cd = NULL;
    DetectPcreData *pe = NULL;

    switch (prev_pm->type) {
        case DETECT_CONTENT:
            /* Set the relative next flag on the prev sigmatch */
            cd = (DetectContentData *)prev_pm->ctx;
            if (cd == NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                           "previous keyword!");
                return -1;
            }
            cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;

            break;

        case DETECT_PCRE:
            pe = (DetectPcreData *)prev_pm->ctx;
            if (pe == NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                           "previous keyword!");
                return -1;
            }
            pe->flags |= DETECT_PCRE_RELATIVE_NEXT;

            break;

        case DETECT_BYTEJUMP:
        case DETECT_BYTETEST:
        case DETECT_BYTE_EXTRACT:
            SCLogDebug("Do nothing for byte_jump, byte_test, byte_extract");
            break;

        default:
            /* this will never hit */
            SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                       "previous keyword!");
            return -1;
    } /* switch */

    return 0;

error:
    return -1;
}
Esempio n. 3
0
/**
 * \brief This function is used to add the parsed isdataatdata into the current
 *        signature.
 * \param de_ctx pointer to the Detection Engine Context
 * \param s pointer to the Current Signature
 * \param isdataatstr pointer to the user provided isdataat options
 *
 * \retval 0 on Success
 * \retval -1 on Failure
 */
int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatstr)
{
    DetectIsdataatData *idad = NULL;
    SigMatch *sm = NULL;
    SigMatch *dm = NULL;
    SigMatch *pm = NULL;
    SigMatch *prev_pm = NULL;

    idad = DetectIsdataatParse(isdataatstr);
    if (idad == NULL)
        goto error;

    sm = SigMatchAlloc();
    if (sm == NULL)
        goto error;

    sm->type = DETECT_ISDATAAT;
    sm->ctx = (void *)idad;

    if (s->alproto == ALPROTO_DCERPC &&
        idad->flags & ISDATAAT_RELATIVE) {

        pm = SigMatchGetLastSMFromLists(s, 6,
                                        DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                                        DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
        dm = SigMatchGetLastSMFromLists(s, 6,
                                        DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                                        DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);

        if (pm == NULL) {
            SigMatchAppendDcePayload(s, sm);
        } else if (dm == NULL) {
            SigMatchAppendDcePayload(s, sm);
        } else if (pm->idx > dm->idx) {
            SigMatchAppendPayload(s, sm);
        } else {
            SigMatchAppendDcePayload(s, sm);
        }
        prev_pm = SigMatchGetLastSMFromLists(s, 6,
                                             DETECT_CONTENT, sm->prev,
                                             DETECT_BYTEJUMP, sm->prev,
                                             DETECT_PCRE, sm->prev);
    } else {
        pm = SigMatchGetLastSMFromLists(s, 30,
                                        DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                                        DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
                                        DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
                                        DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
                                        DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
                                        DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
                                        DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
                                        DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
                                        DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
        if (pm == NULL) {
            if (idad->flags & ISDATAAT_RELATIVE) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen "
                           "without a previous content uricontent, "
                           "http_client_body, http_header, http_raw_header, "
                           "http_method or http_cookie keyword");
                goto error;
            } else {
                SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH);
            }
        } else {
            int list_type;
            if (pm->type == DETECT_PCRE || pm->type == DETECT_BYTEJUMP) {
                list_type = SigMatchListSMBelongsTo(s, pm);
                if (list_type == -1) {
                    goto error;
                }
            } else {
                switch (pm->type) {
                    case DETECT_CONTENT:
                        list_type = DETECT_SM_LIST_PMATCH;
                        break;
                    case DETECT_URICONTENT:
                        list_type = DETECT_SM_LIST_UMATCH;
                        break;
                    case DETECT_AL_HTTP_CLIENT_BODY:
                        list_type = DETECT_SM_LIST_HCBDMATCH;
                        break;
                    case DETECT_AL_HTTP_RAW_HEADER:
                        list_type = DETECT_SM_LIST_HRHDMATCH;
                        break;
                    case DETECT_AL_HTTP_HEADER:
                        list_type = DETECT_SM_LIST_HHDMATCH;
                        break;
                    case DETECT_AL_HTTP_METHOD:
                        list_type = DETECT_SM_LIST_HMDMATCH;
                        break;
                    case DETECT_AL_HTTP_COOKIE:
                        list_type = DETECT_SM_LIST_HCDMATCH;
                        break;
                } /* switch */
            } /* else */

            SigMatchAppendSMToList(s, sm, list_type);
        } /* else - if (pm == NULL) */

        prev_pm = pm;
    }

    if (!(idad->flags & ISDATAAT_RELATIVE)) {
        return 0;
    }

    if (prev_pm == NULL) {
        if (s->alproto == ALPROTO_DCERPC) {
            SCLogDebug("No preceding content or pcre keyword.  Possible "
                       "since this is a dce alproto sig.");
            return 0;
        } else {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, "
                       "uricontent, http_client_body, http_header, "
                       "http_raw_header, http_method or http_cookie keyword");
            goto error;
        }
    }

    DetectContentData *cd = NULL;
    DetectPcreData *pe = NULL;

    switch (prev_pm->type) {
        case DETECT_CONTENT:
        case DETECT_URICONTENT:
        case DETECT_AL_HTTP_CLIENT_BODY:
        case DETECT_AL_HTTP_HEADER:
        case DETECT_AL_HTTP_RAW_HEADER:
        case DETECT_AL_HTTP_METHOD:
        case DETECT_AL_HTTP_COOKIE:
            /* Set the relative next flag on the prev sigmatch */
            cd = (DetectContentData *)prev_pm->ctx;
            if (cd == NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                           "previous keyword!");
                return -1;
            }
            cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;

            break;

        case DETECT_PCRE:
            pe = (DetectPcreData *)prev_pm->ctx;
            if (pe == NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                           "previous keyword!");
                return -1;
            }
            pe->flags |= DETECT_PCRE_RELATIVE_NEXT;

            break;

        case DETECT_BYTEJUMP:
            SCLogDebug("Do nothing for bytejump");
            break;

        default:
            /* this will never hit */
            SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
                       "previous keyword!");
            return -1;
    } /* switch */

    return 0;

error:
    //if (idad != NULL)
    //    DetectIsdataatFree(idad);
    //if (sm != NULL)
    //    SCFree(sm);
    return -1;
}
Esempio n. 4
0
/** \test Send a get request in three chunks + more data. */
static int DetectSslVersionTestDetect01(void)
{
    int result = 0;
    Flow f;
    uint8_t sslbuf1[] = { 0x16 };
    uint32_t ssllen1 = sizeof(sslbuf1);
    uint8_t sslbuf2[] = { 0x03 };
    uint32_t ssllen2 = sizeof(sslbuf2);
    uint8_t sslbuf3[] = { 0x01 };
    uint32_t ssllen3 = sizeof(sslbuf3);
    uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 };
    uint32_t ssllen4 = sizeof(sslbuf4);
    TcpSession ssn;
    Packet *p = NULL;
    Signature *s = NULL;
    ThreadVars th_v;
    DetectEngineThreadCtx *det_ctx = NULL;
    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();

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

    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);

    FLOW_INITIALIZE(&f);
    f.protoctx = (void *)&ssn;
    f.proto = IPPROTO_TCP;
    p->flow = &f;
    p->flowflags |= FLOW_PKT_TOSERVER;
    p->flowflags |= FLOW_PKT_ESTABLISHED;
    p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
    f.alproto = ALPROTO_TLS;

    StreamTcpInitConfig(TRUE);

    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
    if (de_ctx == NULL) {
        goto end;
    }

    de_ctx->flags |= DE_QUIET;

    s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; sid:1;)");
    if (s == NULL) {
        goto end;
    }

    SigGroupBuild(de_ctx);
    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);

    SCMutexLock(&f.m);
    int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf1, ssllen1);
    if (r != 0) {
        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
        SCMutexUnlock(&f.m);
        goto end;
    }

    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf2, ssllen2);
    if (r != 0) {
        printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
        SCMutexUnlock(&f.m);
        goto end;
    }

    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf3, ssllen3);
    if (r != 0) {
        printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
        SCMutexUnlock(&f.m);
        goto end;
    }

    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf4, ssllen4);
    if (r != 0) {
        printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
        SCMutexUnlock(&f.m);
        goto end;
    }
    SCMutexUnlock(&f.m);

    SSLState *app_state = f.alstate;
    if (app_state == NULL) {
        printf("no ssl state: ");
        goto end;
    }

    if (app_state->client_connp.content_type != 0x16) {
        printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type);
        goto end;
    }

    if (app_state->client_connp.version != TLS_VERSION_10) {
        printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version);
        goto end;
    }

    SCLogDebug("app_state is at %p, app_state->server_connp.version 0x%02X app_state->client_connp.version 0x%02X",
        app_state, app_state->server_connp.version, app_state->client_connp.version);

    /* do detect */
    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);

    if (!(PacketAlertCheck(p, 1))) {
        goto end;
    }

    result = 1;

end:
    if (alp_tctx != NULL)
        AppLayerParserThreadCtxFree(alp_tctx);
    SigGroupCleanup(de_ctx);
    SigCleanSignatures(de_ctx);

    DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
    DetectEngineCtxFree(de_ctx);

    StreamTcpFreeConfig(TRUE);
    FLOW_DESTROY(&f);

    UTHFreePackets(&p, 1);
    return result;
}
/**
 * \brief Parses a line from the classification file and adds it to Classtype
 *        hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht.
 *
 * \param rawstr Pointer to the string to be parsed.
 * \param index  Relative index of the string to be parsed.
 * \param de_ctx Pointer to the Detection Engine Context.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCClassConfAddClasstype(char *rawstr, uint8_t index, DetectEngineCtx *de_ctx)
{
    const char *ct_name = NULL;
    const char *ct_desc = NULL;
    const char *ct_priority_str = NULL;
    int ct_priority = 0;
    uint8_t ct_id = index;

    SCClassConfClasstype *ct_new = NULL;
    SCClassConfClasstype *ct_lookup = NULL;

#define MAX_SUBSTRINGS 30
    int ret = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30);
    if (ret < 0) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in "
                   "classification.config file");
        goto error;
    }

    /* retrieve the classtype name */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &ct_name);
    if (ret < 0) {
        SCLogInfo("pcre_get_substring() failed");
        goto error;
    }

    /* retrieve the classtype description */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &ct_desc);
    if (ret < 0) {
        SCLogInfo("pcre_get_substring() failed");
        goto error;
    }

    /* retrieve the classtype priority */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 3, &ct_priority_str);
    if (ret < 0) {
        SCLogInfo("pcre_get_substring() failed");
        goto error;
    }
    if (ct_priority_str == NULL) {
        goto error;
    }

    ct_priority = atoi(ct_priority_str);

    /* Create a new instance of the parsed Classtype string */
    ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority);
    if (ct_new == NULL)
        goto error;

    /* Check if the Classtype is present in the HashTable.  In case it's present
     * ignore it, as it is a duplicate.  If not present, add it to the table */
    ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0);
    if (ct_lookup == NULL) {
        if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0)
            SCLogDebug("HashTable Add failed");
    } else {
        SCLogDebug("Duplicate classtype found inside classification.config");
        if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc);
        if (ct_new->classtype) SCFree(ct_new->classtype);
        SCFree(ct_new);
    }

    if (ct_name) SCFree((char *)ct_name);
    if (ct_desc) SCFree((char *)ct_desc);
    if (ct_priority_str) SCFree((char *)ct_priority_str);
    return 0;

 error:
    if (ct_name) SCFree((char *)ct_name);
    if (ct_desc) SCFree((char *)ct_desc);
    if (ct_priority_str) SCFree((char *)ct_priority_str);

    return -1;
}
Esempio n. 6
0
/**
 * \brief Free request body chunks that are already fully parsed.
 *
 * \param state htp_state, with reference to our config
 * \param body the body to prune
 * \param direction STREAM_TOSERVER (request), STREAM_TOCLIENT (response)
 *
 * \retval none
 */
void HtpBodyPrune(HtpState *state, HtpBody *body, int direction)
{
    SCEnter();

    if (body == NULL || body->first == NULL) {
        SCReturn;
    }

    if (body->body_parsed == 0) {
        SCReturn;
    }

    /* get the configured inspect sizes. Default to response values */
    uint32_t min_size = state->cfg->response.inspect_min_size;
    uint32_t window = state->cfg->response.inspect_window;

    if (direction == STREAM_TOSERVER) {
        min_size = state->cfg->request.inspect_min_size;
        window = state->cfg->request.inspect_window;
    }

    uint64_t max_window = ((min_size > window) ? min_size : window);
    uint64_t in_flight = body->content_len_so_far - body->body_inspected;

    /* Special case. If body_inspected is not being updated, we make sure that
     * we prune the body. We allow for some extra size/room as we may be called
     * multiple times on uninspected body chunk additions if a large block of
     * data was ack'd at once. Want to avoid pruning before inspection. */
    if (in_flight > (max_window * 3)) {
        body->body_inspected = body->content_len_so_far - max_window;
    } else if (body->body_inspected < max_window) {
        SCReturn;
    }

    uint64_t left_edge = body->body_inspected;
    if (left_edge <= min_size || left_edge <= window)
        left_edge = 0;
    if (left_edge)
        left_edge -= window;

    if (left_edge) {
        SCLogDebug("sliding body to offset %"PRIu64, left_edge);
        StreamingBufferSlideToOffset(body->sb, left_edge);
    }

    SCLogDebug("pruning chunks of body %p", body);

    HtpBodyChunk *cur = body->first;
    while (cur != NULL) {
        HtpBodyChunk *next = cur->next;
        SCLogDebug("cur %p", cur);

        if (!StreamingBufferSegmentIsBeforeWindow(body->sb, &cur->sbseg)) {
            SCLogDebug("not removed");
            break;
        }

        body->first = next;
        if (body->last == cur) {
            body->last = next;
        }

        HTPFree(cur, sizeof(HtpBodyChunk));

        cur = next;
        SCLogDebug("removed");
    }

    SCReturn;
}
Esempio n. 7
0
/**
 * \brief Function to parse the TLS field in packet received from the server
 *
 *  \param  tls_state   Pointer the state in which the value to be stored
 *  \param  pstate      Application layer tarser state for this session
 *  \param  input       Pointer the received input data
 *  \param  input_len   Length in bytes of the received data
 *  \param  output      Pointer to the list of parsed output elements
 */
static int TLSParseServerRecord(Flow *f, void *tls_state, AppLayerParserState *pstate,
                                uint8_t *input, uint32_t input_len,
                                AppLayerParserResult *output)
{
    SCEnter();

    if (input_len >= 7) {
        if (SSLParseServerRecord(f, tls_state, pstate, input, input_len, output)
                == 1)
        {
            SCLogDebug("it seems the ssl version 2 is detected");
            SCReturnInt(1);
        }
    }

    SCLogDebug("tls_state %p, pstate %p, input %p,input_len %" PRIu32 "",
               tls_state, pstate, input, input_len);
    //PrintRawDataFp(stdout, input,input_len);

    uint16_t max_fields = 3;
    int16_t u = 0;
    uint32_t offset = 0;

    if (pstate == NULL)
        SCReturnInt(-1);

    for (u = pstate->parse_field; u < max_fields; u++) {
        SCLogDebug("u %" PRIu32 "", u);

        switch(u % 3) {
        case 0: /* TLS CONTENT TYPE */
        {
            uint8_t *data = input + offset;
            uint32_t data_len = input_len - offset;

            int r = AlpParseFieldBySize(output, pstate,
                                        TLS_FIELD_SERVER_CONTENT_TYPE,
                                        /* single byte field */1, data,
                                        data_len, &offset);
            SCLogDebug("r = %" PRId32 "", r);

            if (r == 0) {
                pstate->parse_field = 0;
                SCReturnInt(0);
            } else if (r == -1) {
                SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, "
                           "r %d", r);
                SCReturnInt(-1);
            }
            break;
        }
        case 1: /* TLS VERSION */
        {
            uint8_t *data = input + offset;
            uint32_t data_len = input_len - offset;

            int r = AlpParseFieldBySize(output, pstate,
                                        TLS_FIELD_SERVER_VERSION,/* 2 byte
                                       *field */2, data, data_len, &offset);
            if (r == 0) {
                pstate->parse_field = 1;
                SCReturnInt(0);
            } else if (r == -1) {
                SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, "
                           "r %d", r);
                SCReturnInt(-1);
            }
            break;
        }
        case 2: /* TLS Record Message Length */
        {
            uint8_t *data = input + offset;
            uint32_t data_len = input_len - offset;

            int r = AlpParseFieldBySize(output, pstate, TLS_FIELD_LENGTH,
                                        /* 2 byte field */2, data, data_len,
                                        &offset);

            if (r == 0) {
                pstate->parse_field = 2;
                SCReturnInt(0);
            } else if (r == -1) {
                SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, "
                           "r %d", r);
                SCReturnInt(-1);
            }

            /* Parsing of the record is done. Since we may have more than
             * one record, we check here if we still have data left *after*
             * this record. In that case setup the parser to parse that
             * record as well. */
            uint16_t record_len;
            int ret = ByteExtractUint16(&record_len, BYTE_BIG_ENDIAN,
                                        output->tail->data_len, output->tail->data_ptr);
            if (ret != 2) {
                SCReturnInt(-1);
            }

            /* calulate the point up to where the current record
             * is in the data */
            uint32_t record_offset = (offset + record_len);

            SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len"
                       " %"PRIu16")", record_offset, offset, record_len);

            /* if our input buffer is bigger than the data up to and
             * including the current record, we instruct the parser to
             * expect another record of 3 fields */
            if (input_len <= record_offset)
                break;

            max_fields += 3;
            offset += record_len;
            break;
        }
        }

    }

    pstate->parse_field = 0;
    SCReturnInt(1);
}
Esempio n. 8
0
void *TmThreadsSlot1NoInOut(void *td) {
    ThreadVars *tv = (ThreadVars *)td;
    Tm1Slot *s = (Tm1Slot *)tv->tm_slots;
    char run = 1;
    TmEcode r = TM_ECODE_OK;

    /* Set the thread name */
    SCSetThreadName(tv->name);

    /* Drop the capabilities for this thread */
    SCDropCaps(tv);

    if (tv->thread_setup_flags != 0)
        TmThreadSetupOptions(tv);

    SCLogDebug("%s starting", tv->name);

    if (s->s.SlotThreadInit != NULL) {
        r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data);
        if (r != TM_ECODE_OK) {
            EngineKill();

            TmThreadsSetFlag(tv, THV_CLOSED);
            pthread_exit((void *) -1);
        }
    }
    memset(&s->s.slot_pre_pq, 0, sizeof(PacketQueue));
    memset(&s->s.slot_post_pq, 0, sizeof(PacketQueue));

    TmThreadsSetFlag(tv, THV_INIT_DONE);

    while(run) {
        TmThreadTestThreadUnPaused(tv);

        r = s->s.SlotFunc(tv, NULL, s->s.slot_data, /* no outqh, no pq */NULL, NULL);
        //printf("%s: TmThreadsSlot1NoInNoOut: r %" PRId32 "\n", tv->name, r);

        /* handle error */
        if (r == TM_ECODE_FAILED) {
            TmThreadsSetFlag(tv, THV_FAILED);
            break;
        }

        if (TmThreadsCheckFlag(tv, THV_KILL)) {
            //printf("%s: TmThreadsSlot1NoInOut: KILL is set\n", tv->name);
            SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0);
            run = 0;
        }
    }

    if (s->s.SlotThreadExitPrintStats != NULL) {
        s->s.SlotThreadExitPrintStats(tv, s->s.slot_data);
    }

    if (s->s.SlotThreadDeinit != NULL) {
        r = s->s.SlotThreadDeinit(tv, s->s.slot_data);
        if (r != TM_ECODE_OK) {
            TmThreadsSetFlag(tv, THV_CLOSED);
            pthread_exit((void *) -1);
        }
    }

    //printf("TmThreadsSlot1NoInOut: %s ending\n", tv->name);
    TmThreadsSetFlag(tv, THV_CLOSED);
    pthread_exit((void *) 0);
}
Esempio n. 9
0
void *TmThreadsSlot1(void *td) {
    ThreadVars *tv = (ThreadVars *)td;
    Tm1Slot *s = (Tm1Slot *)tv->tm_slots;
    Packet *p = NULL;
    char run = 1;
    TmEcode r = TM_ECODE_OK;

    /* Set the thread name */
    SCSetThreadName(tv->name);

    /* Drop the capabilities for this thread */
    SCDropCaps(tv);

    if (tv->thread_setup_flags != 0)
        TmThreadSetupOptions(tv);

    SCLogDebug("%s starting", tv->name);

    if (s->s.SlotThreadInit != NULL) {
        r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data);
        if (r != TM_ECODE_OK) {
            EngineKill();

            TmThreadsSetFlag(tv, THV_CLOSED);
            pthread_exit((void *) -1);
        }
    }
    memset(&s->s.slot_pre_pq, 0, sizeof(PacketQueue));
    memset(&s->s.slot_post_pq, 0, sizeof(PacketQueue));

    TmThreadsSetFlag(tv, THV_INIT_DONE);
    while(run) {
        TmThreadTestThreadUnPaused(tv);

        /* input a packet */
        p = tv->tmqh_in(tv);

        if (p == NULL) {
            //printf("%s: TmThreadsSlot1: p == NULL\n", tv->name);
        } else {
            r = s->s.SlotFunc(tv, p, s->s.slot_data, &s->s.slot_pre_pq, &s->s.slot_post_pq);
            /* handle error */
            if (r == TM_ECODE_FAILED) {
                TmqhReleasePacketsToPacketPool(&s->s.slot_pre_pq);
                TmqhReleasePacketsToPacketPool(&s->s.slot_post_pq);
                TmqhOutputPacketpool(tv, p);
                TmThreadsSetFlag(tv, THV_FAILED);
                break;
            }

            while (s->s.slot_pre_pq.top != NULL) {
                /* handle new packets from this func */
                Packet *extra_p = PacketDequeue(&s->s.slot_pre_pq);
                if (extra_p != NULL) {
                    tv->tmqh_out(tv, extra_p);
                }
            }

            /* output the packet */
            tv->tmqh_out(tv, p);

            while (s->s.slot_post_pq.top != NULL) {
                /* handle new packets from this func */
                Packet *extra_p = PacketDequeue(&s->s.slot_post_pq);
                if (extra_p != NULL) {
                    tv->tmqh_out(tv, extra_p);
                }
            }
        }

        if (TmThreadsCheckFlag(tv, THV_KILL)) {
            //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name);
            SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0);
            run = 0;
        }
    }

    if (s->s.SlotThreadExitPrintStats != NULL) {
        s->s.SlotThreadExitPrintStats(tv, s->s.slot_data);
    }

    if (s->s.SlotThreadDeinit != NULL) {
        r = s->s.SlotThreadDeinit(tv, s->s.slot_data);
        if (r != TM_ECODE_OK) {
            TmThreadsSetFlag(tv, THV_CLOSED);
            pthread_exit((void *) -1);
        }
    }

    SCLogDebug("%s ending", tv->name);
    TmThreadsSetFlag(tv, THV_CLOSED);
    pthread_exit((void *) 0);
}
Esempio n. 10
0
/**
 * \internal
 * \brief this function is used to decode IEEE802.1q packets
 *
 * \param tv pointer to the thread vars
 * \param dtv pointer code thread vars
 * \param p pointer to the packet struct
 * \param pkt pointer to the raw packet
 * \param len packet len
 * \param pq pointer to the packet queue
 *
 */
int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    uint32_t proto;

    if (p->vlan_idx == 0)
        SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca);
    else if (p->vlan_idx == 1)
        SCPerfCounterIncr(dtv->counter_vlan_qinq, tv->sc_perf_pca);

    if(len < VLAN_HEADER_LEN)    {
        ENGINE_SET_INVALID_EVENT(p, VLAN_HEADER_TOO_SMALL);
        return TM_ECODE_FAILED;
    }
    if (p->vlan_idx >= 2) {
        ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
        return TM_ECODE_FAILED;
    }

    p->vlanh[p->vlan_idx] = (VLANHdr *)pkt;
    if(p->vlanh[p->vlan_idx] == NULL)
        return TM_ECODE_FAILED;

    proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]);

    SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "",
            p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]),
            GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len);

    /* only store the id for flow hashing if it's not disabled. */
    if (dtv->vlan_disabled == 0)
        p->vlan_id[p->vlan_idx] = (uint16_t)GET_VLAN_ID(p->vlanh[p->vlan_idx]);

    p->vlan_idx++;

    switch (proto)   {
        case ETHERNET_TYPE_IP:
            DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                       len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_IPV6:
            DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                       len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_SESS:
            DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                               len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_DISC:
            DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                                 len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_VLAN:
        case ETHERNET_TYPE_8021AD:
            if (p->vlan_idx >= 2) {
                ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
                return TM_ECODE_OK;
            } else {
                DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                        len - VLAN_HEADER_LEN, pq);
            }
            break;
        default:
            SCLogDebug("unknown VLAN type: %" PRIx32 "", proto);
            ENGINE_SET_INVALID_EVENT(p, VLAN_UNKNOWN_TYPE);
            return TM_ECODE_OK;
    }

    return TM_ECODE_OK;
}
Esempio n. 11
0
void TmThreadKillThreads(void) {
    ThreadVars *tv = NULL;
    int i = 0;

    for (i = 0; i < TVT_MAX; i++) {
        tv = tv_root[i];


        while (tv) {
            TmThreadsSetFlag(tv, THV_KILL);
            SCLogDebug("told thread %s to stop", tv->name);

            if (tv->inq != NULL) {
                int i;

                //printf("TmThreadKillThreads: (t->inq->reader_cnt + t->inq->writer_cnt) %" PRIu32 "\n", (t->inq->reader_cnt + t->inq->writer_cnt));

                /* make sure our packet pending counter doesn't block */
                //SCCondSignal(&cond_pending);

                /* signal the queue for the number of users */

                if (tv->InShutdownHandler != NULL) {
                    tv->InShutdownHandler(tv);
                }
                for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) {
                    if (tv->inq->q_type == 0)
                        SCCondSignal(&trans_q[tv->inq->id].cond_q);
                    else
                        SCCondSignal(&data_queues[tv->inq->id].cond_q);
                }

                /* to be sure, signal more */
                int cnt = 0;
                while (1) {
                    if (TmThreadsCheckFlag(tv, THV_CLOSED)) {
                        SCLogDebug("signalled the thread %" PRId32 " times", cnt);
                        break;
                    }

                    cnt++;

                    if (tv->InShutdownHandler != NULL) {
                        tv->InShutdownHandler(tv);
                    }

                    for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) {
                        if (tv->inq->q_type == 0)
                            SCCondSignal(&trans_q[tv->inq->id].cond_q);
                        else
                            SCCondSignal(&data_queues[tv->inq->id].cond_q);
                    }
                    usleep(100);
                }

                SCLogDebug("signalled tv->inq->id %" PRIu32 "", tv->inq->id);
            }

            if (tv->cond != NULL ) {
                int cnt = 0;
                while (1) {
                    if (TmThreadsCheckFlag(tv, THV_CLOSED)) {
                        SCLogDebug("signalled the thread %" PRId32 " times", cnt);
                        break;
                    }

                    cnt++;

                    pthread_cond_broadcast(tv->cond);

                    usleep(100);
                }
            }

            /* join it */
            pthread_join(tv->t, NULL);
            SCLogDebug("thread %s stopped", tv->name);

            tv = tv->next;
        }
    }
}
Esempio n. 12
0
static int DetectSslVersionTestDetect03(void)
{
    DetectEngineCtx *de_ctx = NULL;
    int result = 0;
    Flow f;
    uint8_t sslbuf1[] = { 0x16 };
    uint32_t ssllen1 = sizeof(sslbuf1);
    uint8_t sslbuf2[] = { 0x03 };
    uint32_t ssllen2 = sizeof(sslbuf2);
    uint8_t sslbuf3[] = { 0x01 };
    uint32_t ssllen3 = sizeof(sslbuf3);
    uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 };
    uint32_t ssllen4 = sizeof(sslbuf4);
    TcpSession ssn;
    Packet *p = NULL;
    Signature *s = NULL;
    ThreadVars th_v;
    DetectEngineThreadCtx *det_ctx = NULL;

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

    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
    p->tcph->th_seq = htonl(1000);

    FLOW_INITIALIZE(&f);
    f.protoctx = (void *)&ssn;
    p->flow = &f;
    p->flowflags |= FLOW_PKT_TOSERVER;
    p->flowflags |= FLOW_PKT_ESTABLISHED;
    p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
    f.alproto = ALPROTO_TLS;
    f.proto = p->proto;

    StreamTcpInitConfig(TRUE);
    FlowL7DataPtrInit(&f);

    StreamMsg *stream_msg = StreamMsgGetFromPool();
    if (stream_msg == NULL) {
        printf("no stream_msg: ");
        goto end;
    }

    memcpy(stream_msg->data.data, sslbuf4, ssllen4);
    stream_msg->data.data_len = ssllen4;

    ssn.toserver_smsg_head = stream_msg;
    ssn.toserver_smsg_tail = stream_msg;

    de_ctx = DetectEngineCtxInit();
    if (de_ctx == NULL) {
        goto end;
    }

    de_ctx->flags |= DE_QUIET;

    s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; content:\"|01 00 00 AD|\"; sid:1;)");
    if (s == NULL) {
        goto end;
    }

    if (s->flags & SIG_FLAG_PACKET) {
        SCLogDebug("SIG_FLAG_PACKET flags");
    }

    SigGroupBuild(de_ctx);
    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);

    int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf1, ssllen1);
    if (r != 0) {
        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
        goto end;
    }

    r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf2, ssllen2);
    if (r != 0) {
        printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
        goto end;
    }

    r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf3, ssllen3);
    if (r != 0) {
        printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
        goto end;
    }

    r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf4, ssllen4);
    if (r != 0) {
        printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
        goto end;
    }

    TlsState *app_state = f.aldata[AlpGetStateIdx(ALPROTO_TLS)];
    if (app_state == NULL) {
        printf("no ssl state: ");
        goto end;
    }

    if (app_state->client_content_type != 0x16) {
        printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_content_type);
        goto end;
    }

    if (app_state->client_version != TLS_VERSION_10) {
        printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_version);
        goto end;
    }

    /* do detect */
    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);

    if (!(PacketAlertCheck(p, 1))) {
        printf("signature 1 didn't match while it should have: ");
        goto end;
    }

    result = 1;

end:
    if (de_ctx != NULL) {
        SigGroupCleanup(de_ctx);
        SigCleanSignatures(de_ctx);
        DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
        DetectEngineCtxFree(de_ctx);
    }

    FlowL7DataPtrFree(&f);
    StreamTcpFreeConfig(TRUE);
    FLOW_DESTROY(&f);
    UTHFreePackets(&p, 1);
    return result;
}
Esempio n. 13
0
/**
 * \brief Parses a line from the reference config file and adds it to Reference
 *        Config hash table DetectEngineCtx->reference_conf_ht.
 *
 * \param rawstr Pointer to the string to be parsed.
 * \param de_ctx Pointer to the Detection Engine Context.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
static int SCRConfAddReference(char *rawstr, DetectEngineCtx *de_ctx)
{
    const char *system = NULL;
    const char *url = NULL;

    SCRConfReference *ref_new = NULL;
    SCRConfReference *ref_lookup = NULL;

#define MAX_SUBSTRINGS 30
    int ret = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30);
    if (ret < 0) {
        SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in "
                   "reference.config file");
        goto error;
    }

    /* retrieve the reference system */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &system);
    if (ret < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring() failed");
        goto error;
    }

    /* retrieve the reference url */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &url);
    if (ret < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring() failed");
        goto error;
    }

    /* Create a new instance of the parsed Reference string */
    ref_new = SCRConfAllocSCRConfReference(system, url);

    /* Check if the Reference is present in the HashTable.  In case it's present
     * ignore it, as it's a duplicate.  If not present, add it to the table */
    ref_lookup = HashTableLookup(de_ctx->reference_conf_ht, ref_new, 0);
    if (ref_lookup == NULL) {
        if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) {
            SCLogDebug("HashTable Add failed");
        }
    } else {
        SCLogDebug("Duplicate reference found inside reference.config");
        SCRConfDeAllocSCRConfReference(ref_new);
    }

    /* free the substrings */
    pcre_free_substring(system);
    pcre_free_substring(url);
    return 0;

 error:
    if (system)
        pcre_free_substring(system);
    if (url)
        pcre_free_substring(url);

    return -1;
}
Esempio n. 14
0
/**
 * \brief Frees a Cuda Device Pointer.
 *
 *        If a device pointer by the name \"name\"  is registered for this
 *        handle, it is freed.
 *
 * \param name       Name of the device pointer by which we have to search
 *                   module for its existance.
 * \param handle     A unique handle which identifies a module.  Obtained from
 *                   a call to SCCudaHlGetUniqueHandle().
 * \param cumodule   A handle that identifies the CUmodule within the above module.
 *                   Obtained from a call to SCCudaHlGetCudaModule() or
 *                   SCCudaHlGetCudaModuleFromFile().
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlFreeCudaDevicePtr(const char *name, int handle, int cumodule_handle)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleCUmodule *cumodule = NULL;
    SCCudaHlModuleDevicePointer *module_device_ptr = NULL;
    SCCudaHlModuleDevicePointer *temp_module_device_ptr = NULL;

    if (name == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "device_ptr is NULL or name is NULL");
        goto error;
    }

    /* check if the particular module that wants to free device memory is
     * already registered or not.  If it is registered, check if a context has
     * been associated with the module.  If yes, then we can go ahead and
     * free the device memory.
     */
    if ( ((data = SCCudaHlGetModuleData(handle)) == NULL) ||
         (data->cuda_context == 0)) {
        SCLogDebug("Module not registered or no cuda context associated with "
                   "this module.  You can't create a CUDA module without"
                   "associating a context with a module first. To use this "
                   "registration facility, first register a module using "
                   "context using SCCudaHlRegisterModule(), and then register "
                   "a cuda context with that module using "
                   "SCCudaHlGetCudaContext(), after which you can call this "
                   "function ");
        goto error;
    }

    if ( (cumodule = SCCudaHlGetModuleCUmodule(data, cumodule_handle)) == NULL ) {
        SCLogDebug("CUmodule not registered with the module. Before you can request"
                   "a device pointer for a module you need to load the CUmodule into"
                   "the engine module using SCCudaHlGetCudaModule() or"
                   "SCCudaHlGetCudaModuleFromFile().");
        goto error;
    }

    /* if we do not have a device pointer registered by this name get out */
    if ( (module_device_ptr = SCCudaHlCudaDevicePtrAvailable(cumodule, name)) == NULL) {
        goto error;
    }

    SCCudaMemFree(module_device_ptr->d_ptr);
    module_device_ptr->d_ptr = 0;
    if (module_device_ptr == cumodule->device_ptrs) {
        cumodule->device_ptrs = cumodule->device_ptrs->next;
    } else {
        temp_module_device_ptr = cumodule->device_ptrs;
        while (strcmp(temp_module_device_ptr->next->name, name) != 0) {
            temp_module_device_ptr = temp_module_device_ptr->next;
        }
        temp_module_device_ptr->next = temp_module_device_ptr->next->next;
    }
    SCFree(module_device_ptr->name);
    SCFree(module_device_ptr);

    return 0;

 error:
    return -1;
}
Esempio n. 15
0
static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
{
    BUG_ON(thread_data == NULL);
    if (list == NULL) {
        /* No child loggers registered. */
        return TM_ECODE_OK;
    }

    OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
    if (p->flow == NULL)
        return TM_ECODE_OK;

    Flow * const f = p->flow;
    const uint8_t ipproto = f->proto;
    const AppProto alproto = f->alproto;

    if (AppLayerParserProtocolIsTxAware(p->proto, alproto) == 0)
        goto end;
    if (AppLayerParserProtocolHasLogger(p->proto, alproto) == 0)
        goto end;
    const LoggerId logger_expectation = AppLayerParserProtocolGetLoggerBits(p->proto, alproto);
    if (logger_expectation == 0)
        goto end;

    void *alstate = f->alstate;
    if (alstate == NULL) {
        SCLogDebug("no alstate");
        goto end;
    }

    const uint8_t ts_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOSERVER);
    const uint8_t tc_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOCLIENT);
    const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
    uint64_t tx_id = AppLayerParserGetTransactionLogId(f->alparser);
    uint64_t max_id = tx_id;
    int logged = 0;
    int gap = 0;

    AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
    AppLayerGetTxIterState state;
    memset(&state, 0, sizeof(state));

    while (1) {
        AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, tx_id, total_txs, &state);
        if (ires.tx_ptr == NULL)
            break;
        void * const tx = ires.tx_ptr;
        tx_id = ires.tx_id;

        LoggerId tx_logged = AppLayerParserGetTxLogged(f, alstate, tx);
        const LoggerId tx_logged_old = tx_logged;
        SCLogDebug("logger: expect %08x, have %08x", logger_expectation, tx_logged);
        if (tx_logged == logger_expectation) {
            /* tx already fully logged */
            goto next_tx;
        }

        int tx_progress_ts = AppLayerParserGetStateProgress(p->proto, alproto,
                tx, ts_disrupt_flags);
        int tx_progress_tc = AppLayerParserGetStateProgress(p->proto, alproto,
                tx, tc_disrupt_flags);
        SCLogDebug("tx_progress_ts %d tx_progress_tc %d",
                tx_progress_ts, tx_progress_tc);

        const OutputTxLogger *logger = list;
        const OutputLoggerThreadStore *store = op_thread_data->store;
#ifdef DEBUG_VALIDATION
        BUG_ON(logger == NULL && store != NULL);
        BUG_ON(logger != NULL && store == NULL);
        BUG_ON(logger == NULL && store == NULL);
#endif
        while (logger && store) {
            BUG_ON(logger->LogFunc == NULL);

            SCLogDebug("logger %p, LogCondition %p, ts_log_progress %d "
                    "tc_log_progress %d", logger, logger->LogCondition,
                    logger->ts_log_progress, logger->tc_log_progress);
            if (logger->alproto == alproto &&
                (tx_logged_old & (1<<logger->logger_id)) == 0)
            {
                SCLogDebug("alproto match, logging tx_id %"PRIu64, tx_id);

                if (!(AppLayerParserStateIssetFlag(f->alparser,
                                                   APP_LAYER_PARSER_EOF))) {
                    if (logger->LogCondition) {
                        int r = logger->LogCondition(tv, p, alstate, tx, tx_id);
                        if (r == FALSE) {
                            SCLogDebug("conditions not met, not logging");
                            goto next_logger;
                        }
                    } else {
                        if (tx_progress_tc < logger->tc_log_progress) {
                            SCLogDebug("progress not far enough, not logging");
                            goto next_logger;
                        }

                        if (tx_progress_ts < logger->ts_log_progress) {
                            SCLogDebug("progress not far enough, not logging");
                            goto next_logger;
                        }
                    }
                }

                SCLogDebug("Logging tx_id %"PRIu64" to logger %d", tx_id,
                    logger->logger_id);
                PACKET_PROFILING_LOGGER_START(p, logger->logger_id);
                logger->LogFunc(tv, store->thread_data, p, f, alstate, tx, tx_id);
                PACKET_PROFILING_LOGGER_END(p, logger->logger_id);

                tx_logged |= (1<<logger->logger_id);
            }

next_logger:
            logger = logger->next;
            store = store->next;
#ifdef DEBUG_VALIDATION
            BUG_ON(logger == NULL && store != NULL);
            BUG_ON(logger != NULL && store == NULL);
#endif
        }

        if (tx_logged != tx_logged_old) {
            SCLogDebug("logger: storing %08x (was %08x)",
                tx_logged, tx_logged_old);
            AppLayerParserSetTxLogged(p->proto, alproto, alstate, tx,
                    tx_logged);
        }

        /* If all loggers logged set a flag and update the last tx_id
         * that was logged.
         *
         * If not all loggers were logged we flag that there was a gap
         * so any subsequent transactions in this loop don't increase
         * the maximum ID that was logged. */
        if (!gap && tx_logged == logger_expectation) {
            logged = 1;
            max_id = tx_id;
        } else {
            gap = 1;
        }
next_tx:
        if (!ires.has_next)
            break;
        tx_id++;
    }

    /* Update the the last ID that has been logged with all
     * transactions before it. */
    if (logged) {
        SCLogDebug("updating log tx_id %"PRIu64, max_id);
        AppLayerParserSetTransactionLogId(f->alparser, max_id + 1);
    }

end:
    return TM_ECODE_OK;
}
Esempio n. 16
0
/**
 *  \todo only the first "slot" currently makes the "post_pq" available
 *        to the thread module.
 */
void *TmThreadsSlotVar(void *td) {
    ThreadVars *tv = (ThreadVars *)td;
    TmVarSlot *s = (TmVarSlot *)tv->tm_slots;
    Packet *p = NULL;
    char run = 1;
    TmEcode r = TM_ECODE_OK;
    TmSlot *slot = NULL;

    /* Set the thread name */
    SCSetThreadName(tv->name);

    /* Drop the capabilities for this thread */
    SCDropCaps(tv);

    if (tv->thread_setup_flags != 0)
        TmThreadSetupOptions(tv);

    /* check if we are setup properly */
    if (s == NULL || s->s == NULL || tv->tmqh_in == NULL || tv->tmqh_out == NULL) {
        EngineKill();

        TmThreadsSetFlag(tv, THV_CLOSED);
        pthread_exit((void *) -1);
    }

    for (slot = s->s; slot != NULL; slot = slot->slot_next) {
        if (slot->SlotThreadInit != NULL) {
            r = slot->SlotThreadInit(tv, slot->slot_initdata, &slot->slot_data);
            if (r != TM_ECODE_OK) {
                EngineKill();

                TmThreadsSetFlag(tv, THV_CLOSED);
                pthread_exit((void *) -1);
            }
        }
        memset(&slot->slot_pre_pq, 0, sizeof(PacketQueue));
        memset(&slot->slot_post_pq, 0, sizeof(PacketQueue));
    }

    TmThreadsSetFlag(tv, THV_INIT_DONE);

    while(run) {
        TmThreadTestThreadUnPaused(tv);

        /* input a packet */
        p = tv->tmqh_in(tv);

        if (p != NULL) {
            /* run the thread module(s) */
            r = TmThreadsSlotVarRun(tv, p, s->s);
            if (r == TM_ECODE_FAILED) {
                TmqhOutputPacketpool(tv, p);
                TmThreadsSetFlag(tv, THV_FAILED);
                break;
            }

            /* output the packet */
            tv->tmqh_out(tv, p);

            /* now handle the post_pq packets */
            while (s->s->slot_post_pq.top != NULL) {
                Packet *extra_p = PacketDequeue(&s->s->slot_post_pq);
                if (extra_p == NULL)
                    continue;

                if (s->s->slot_next != NULL) {
                    r = TmThreadsSlotVarRun(tv, extra_p, s->s->slot_next);
                    if (r == TM_ECODE_FAILED) {
                        TmqhOutputPacketpool(tv, extra_p);
                        TmThreadsSetFlag(tv, THV_FAILED);
                        break;
                    }
                }

                /* output the packet */
                tv->tmqh_out(tv, extra_p);
            }
        }

        if (TmThreadsCheckFlag(tv, THV_KILL)) {
            run = 0;
        }
    }
    SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0);

    for (slot = s->s; slot != NULL; slot = slot->slot_next) {
        if (slot->SlotThreadExitPrintStats != NULL) {
            slot->SlotThreadExitPrintStats(tv, slot->slot_data);
        }

        if (slot->SlotThreadDeinit != NULL) {
            r = slot->SlotThreadDeinit(tv, slot->slot_data);
            if (r != TM_ECODE_OK) {
                TmThreadsSetFlag(tv, THV_CLOSED);
                pthread_exit((void *) -1);
            }
        }
    }

    SCLogDebug("%s ending", tv->name);
    TmThreadsSetFlag(tv, THV_CLOSED);
    pthread_exit((void *) 0);
}
Esempio n. 17
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;
}
Esempio n. 18
0
/**
 * \brief Creates and returns the TV instance for a new thread.
 *
 * \param name       Name of this TV instance
 * \param inq_name   Incoming queue name
 * \param inqh_name  Incoming queue handler name as set by TmqhSetup()
 * \param outq_name  Outgoing queue name
 * \param outqh_name Outgoing queue handler as set by TmqhSetup()
 * \param slots      String representation for the slot function to be used
 * \param fn_p       Pointer to function when \"slots\" is of type \"custom\"
 * \param mucond     Flag to indicate whether to initialize the condition
 *                   and the mutex variables for this newly created TV.
 *
 * \retval the newly created TV instance, or NULL on error
 */
ThreadVars *TmThreadCreate(char *name, char *inq_name, char *inqh_name,
                           char *outq_name, char *outqh_name, char *slots,
                           void * (*fn_p)(void *), int mucond)
{
    ThreadVars *tv = NULL;
    Tmq *tmq = NULL;
    Tmqh *tmqh = NULL;

    SCLogDebug("creating thread \"%s\"...", name);

    /* XXX create separate function for this: allocate a thread container */
    tv = SCMalloc(sizeof(ThreadVars));
    if (tv == NULL)
        goto error;
    memset(tv, 0, sizeof(ThreadVars));

    SC_ATOMIC_INIT(tv->flags);
    SCMutexInit(&tv->sc_perf_pctx.m, NULL);

    tv->name = name;
    /* default state for every newly created thread */
    TmThreadsSetFlag(tv, THV_PAUSE);
    TmThreadsSetFlag(tv, THV_USE);
    /* default aof for every newly created thread */
    tv->aof = THV_RESTART_THREAD;

    /* set the incoming queue */
    if (inq_name != NULL && strcmp(inq_name,"packetpool") != 0) {
        SCLogDebug("inq_name \"%s\"", inq_name);

        tmq = TmqGetQueueByName(inq_name);
        if (tmq == NULL) {
            tmq = TmqCreateQueue(inq_name);
            if (tmq == NULL) goto error;
        }
        SCLogDebug("tmq %p", tmq);

        tv->inq = tmq;
        tv->inq->reader_cnt++;
        SCLogDebug("tv->inq %p", tv->inq);
    }
    if (inqh_name != NULL) {
        SCLogDebug("inqh_name \"%s\"", inqh_name);

        tmqh = TmqhGetQueueHandlerByName(inqh_name);
        if (tmqh == NULL) goto error;

        tv->tmqh_in = tmqh->InHandler;
        tv->InShutdownHandler = tmqh->InShutdownHandler;
        SCLogDebug("tv->tmqh_in %p", tv->tmqh_in);
    }

    /* set the outgoing queue */
    if (outqh_name != NULL) {
        SCLogDebug("outqh_name \"%s\"", outqh_name);

        tmqh = TmqhGetQueueHandlerByName(outqh_name);
        if (tmqh == NULL) goto error;

        tv->tmqh_out = tmqh->OutHandler;

        if (outq_name != NULL && strcmp(outq_name,"packetpool") != 0) {
            SCLogDebug("outq_name \"%s\"", outq_name);

            if (tmqh->OutHandlerCtxSetup != NULL) {
                tv->outctx = tmqh->OutHandlerCtxSetup(outq_name);
                tv->outq = NULL;
            } else {
                tmq = TmqGetQueueByName(outq_name);
                if (tmq == NULL) {
                    tmq = TmqCreateQueue(outq_name);
                    if (tmq == NULL) goto error;
                }
                SCLogDebug("tmq %p", tmq);

                tv->outq = tmq;
                tv->outctx = NULL;
                tv->outq->writer_cnt++;
            }
        }
    }

    if (TmThreadSetSlots(tv, slots, fn_p) != TM_ECODE_OK) {
        goto error;
    }

    if (mucond != 0)
        TmThreadInitMC(tv);

    return tv;
error:
    printf("ERROR: failed to setup a thread.\n");
    return NULL;
}
Esempio n. 19
0
/**
 * \brief Decode the nodes/frames located at certain position/level
 *
 * \param ac pointer to the ASN1 ctx
 * \param node_id node index at the asn1 stack of the ctx
 *
 * \retval byte of parser status
 */
uint8_t SCAsn1Decode(Asn1Ctx *ac, uint16_t node_id) {
    Asn1Node *node = NULL;
    uint8_t ret = 0;

    /* while remaining data, and no fatal error, or end, or max stack frames */
    while (ac->iter < ac->end
           && !(ac->parser_status & ASN1_STATUS_DONE)
           && ac->cur_frame < asn1_max_frames_config)
    {
        /* Prepare a new frame */
        if (SCAsn1CtxNewFrame(ac, node_id) == NULL)
            break;

        ac->cur_frame = node_id;
        node = ASN1CTX_GET_NODE(ac, node_id);

        SCLogDebug("ASN1 Getting ID, cur:%x remaining %"PRIu32, (uint8_t)*ac->iter, (uint32_t)(ac->end - ac->iter));

        /* Get identifier/tag */
        ret = SCAsn1DecodeIdentifier(ac);
        if (ret == ASN1_PARSER_ERR) {
            SCLogDebug("Error parsing identifier");

            node->flags |= ASN1_BER_EVENT_INVALID_ID;
            ac->ctx_flags |= node->flags;

            break;
        }

        SCLogDebug("ASN1 Getting LEN");

        /* Get length of content */
        ret = SCAsn1DecodeLength(ac);
        if (ret == ASN1_PARSER_ERR) {
            SCLogDebug("Error parsing length");

            node->flags |= ASN1_BER_EVENT_INVALID_LEN;
            ac->ctx_flags |= node->flags;

            break;
        }

        if ( !(node->flags & ASN1_NODE_IS_EOC)) {
            SCLogDebug("ASN1 Getting CONTENT");

            /* Inspect content */
            ret = SCAsn1DecodeContent(ac);
            if (ret == ASN1_PARSER_ERR) {
                SCLogDebug("Error parsing content");

                break;
            }

            /* Skip to the next record (if any) */
            if (node->id.tag_type != ASN1_TAG_TYPE_CONSTRUCTED)
                /* Is primitive, skip it all (no need to decode it)*/
                ac->iter += node->data.len;
        }

        /* Check if we are done with data */
        ret = SCAsn1CheckBounds(ac);
        if (ret == ASN1_PARSER_ERR) {

            ac->parser_status |= ASN1_STATUS_DONE;
            /* There's no more data available */
            ret = ASN1_PARSER_OK;

            break;
        }
#if 0
        printf("Tag Num: %"PRIu32", Tag Type: %"PRIu8", Class:%"PRIu8", Length: %"PRIu32"\n", node->id.tag_num, node->id.tag_type, node->id.class_tag, node->len.len);
        printf("Data: \n");
        PrintRawDataFp(stdout, node->data.ptr, node->len.len);
        printf(" -- EOD --\n");
#endif

        /* Stack flags/events here, so we have the resume at the ctx flags */
        ac->ctx_flags |= node->flags;

        /* Check if it's not a primitive type,
         * then we need to decode contents */
        if (node->id.tag_type == ASN1_TAG_TYPE_CONSTRUCTED) {
            ret = SCAsn1Decode(ac, node_id + 1);
        } /* Else we have reached a primitive type and stop the recursion,
           * look if we have other branches at the same level */

        /* But first check if it's a constructed node, and the sum of child
         * lengths was more than the length of this frame
         * this would mean that we have an overflow at the attributes */
        if (ac->iter > node->data.ptr + node->data.len + 1) {
            /* We decoded more length on this frame */
        }

        node_id = ac->cur_frame + 1;
    }

    return ret;
}
Esempio n. 20
0
static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq)
{
    BUG_ON(thread_data == NULL);
    BUG_ON(list == NULL);

    OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
    OutputTxLogger *logger = list;
    OutputLoggerThreadStore *store = op_thread_data->store;

    BUG_ON(logger == NULL && store != NULL);
    BUG_ON(logger != NULL && store == NULL);
    BUG_ON(logger == NULL && store == NULL);

    if (p->flow == NULL)
        return TM_ECODE_OK;

    Flow * const f = p->flow;

    FLOWLOCK_WRLOCK(f); /* WRITE lock before we updated flow logged id */
    AppProto alproto = f->alproto;

    if (AppLayerParserProtocolIsTxAware(p->proto, alproto) == 0)
        goto end;
    if (AppLayerParserProtocolHasLogger(p->proto, alproto) == 0)
        goto end;

    void *alstate = f->alstate;
    if (alstate == NULL) {
        SCLogDebug("no alstate");
        goto end;
    }

    uint64_t total_txs = AppLayerParserGetTxCnt(p->proto, alproto, alstate);
    uint64_t tx_id = AppLayerParserGetTransactionLogId(f->alparser);
    int tx_progress_done_value_ts =
        AppLayerParserGetStateProgressCompletionStatus(p->proto, alproto,
                                                       STREAM_TOSERVER);
    int tx_progress_done_value_tc =
        AppLayerParserGetStateProgressCompletionStatus(p->proto, alproto,
                                                       STREAM_TOCLIENT);
    int proto_logged = 0;

    for (; tx_id < total_txs; tx_id++)
    {
        void *tx = AppLayerParserGetTx(p->proto, alproto, alstate, tx_id);
        if (tx == NULL) {
            SCLogDebug("tx is NULL not logging");
            continue;
        }

        if (!(AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF)))
        {
            int tx_progress = AppLayerParserGetStateProgress(p->proto, alproto,
                                                             tx, FlowGetDisruptionFlags(f, STREAM_TOSERVER));
            if (tx_progress < tx_progress_done_value_ts) {
                SCLogDebug("progress not far enough, not logging");
                break;
            }

            tx_progress = AppLayerParserGetStateProgress(p->proto, alproto,
                                                         tx, FlowGetDisruptionFlags(f, STREAM_TOCLIENT));
            if (tx_progress < tx_progress_done_value_tc) {
                SCLogDebug("progress not far enough, not logging");
                break;
            }
        }

        // call each logger here (pseudo code)
        logger = list;
        store = op_thread_data->store;
        while (logger && store) {
            BUG_ON(logger->LogFunc == NULL);

            SCLogDebug("logger %p", logger);
            if (logger->alproto == alproto) {
                SCLogDebug("alproto match, logging tx_id %ju", tx_id);
                PACKET_PROFILING_TMM_START(p, logger->module_id);
                logger->LogFunc(tv, store->thread_data, p, f, alstate, tx, tx_id);
                PACKET_PROFILING_TMM_END(p, logger->module_id);
                proto_logged = 1;
            }

            logger = logger->next;
            store = store->next;

            BUG_ON(logger == NULL && store != NULL);
            BUG_ON(logger != NULL && store == NULL);
        }

        if (proto_logged) {
            SCLogDebug("updating log tx_id %ju", tx_id);
            AppLayerParserSetTransactionLogId(f->alparser);
        }
    }

end:
    FLOWLOCK_UNLOCK(f);
    return TM_ECODE_OK;
}
Esempio n. 21
0
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
}
Esempio n. 22
0
int AppLayerParserParse(AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto,
                        uint8_t flags, uint8_t *input, uint32_t input_len)
{
    SCEnter();
#ifdef DEBUG_VALIDATION
    BUG_ON(f->protomap != FlowGetProtoMapping(f->proto));
#endif
    AppLayerParserState *pstate = NULL;
    AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto];
    void *alstate = NULL;

    /* we don't have the parser registered for this protocol */
    if (p->StateAlloc == NULL)
        goto end;

    /* Do this check before calling AppLayerParse */
    if (flags & STREAM_GAP) {
        SCLogDebug("stream gap detected (missing packets), "
                   "this is not yet supported.");

        if (f->alstate != NULL)
            AppLayerParserStreamTruncated(f->proto, alproto, f->alstate, flags);
        goto error;
    }

    /* Get the parser state (if any) */
    pstate = f->alparser;
    if (pstate == NULL) {
        f->alparser = pstate = AppLayerParserStateAlloc();
        if (pstate == NULL)
            goto error;
    }
    pstate->version++;
    SCLogDebug("app layer parser state version incremented to %"PRIu16,
               pstate->version);

    if (flags & STREAM_EOF)
        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);

    alstate = f->alstate;
    if (alstate == NULL) {
        f->alstate = alstate = p->StateAlloc();
        if (alstate == NULL)
            goto error;
        SCLogDebug("alloced new app layer state %p (name %s)",
                   alstate, AppLayerGetProtoName(f->alproto));
    } else {
        SCLogDebug("using existing app layer state %p (name %s))",
                   alstate, AppLayerGetProtoName(f->alproto));
    }

    /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
    if (input_len > 0) {
        /* invoke the parser */
        if (p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate,
                input, input_len,
                alp_tctx->alproto_local_storage[f->protomap][alproto]) < 0)
        {
            goto error;
        }
    }

    /* set the packets to no inspection and reassembly if required */
    if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) {
        AppLayerParserSetEOF(pstate);
        FlowSetNoPayloadInspectionFlag(f);
        FlowSetSessionNoApplayerInspectionFlag(f);

        /* Set the no reassembly flag for both the stream in this TcpSession */
        if (f->proto == IPPROTO_TCP && pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
            /* Used only if it's TCP */
            TcpSession *ssn = f->protoctx;
            if (ssn != NULL) {
                StreamTcpSetSessionNoReassemblyFlag(ssn,
                                                    flags & STREAM_TOCLIENT ? 1 : 0);
                StreamTcpSetSessionNoReassemblyFlag(ssn,
                                                    flags & STREAM_TOSERVER ? 1 : 0);
            }
        }
    }

    /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */
    if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) {
        FlowSetNoPayloadInspectionFlag(f);
        /* Set the no reassembly flag for both the stream in this TcpSession */
        if (f->proto == IPPROTO_TCP) {
            /* Used only if it's TCP */
            TcpSession *ssn = f->protoctx;
            if (ssn != NULL) {
                StreamTcpSetDisableRawReassemblyFlag(ssn, 0);
                StreamTcpSetDisableRawReassemblyFlag(ssn, 1);
            }
        }
    }

    /* next, see if we can get rid of transactions now */
    AppLayerParserTransactionsCleanup(f);

    /* stream truncated, inform app layer */
    if (flags & STREAM_DEPTH)
        AppLayerParserStreamTruncated(f->proto, alproto, alstate, flags);

 end:
    SCReturnInt(0);
 error:
    /* Set the no app layer inspection flag for both
     * the stream in this Flow */
    FlowSetSessionNoApplayerInspectionFlag(f);
    AppLayerParserSetEOF(pstate);
    SCReturnInt(-1);
}
Esempio n. 23
0
/**
 * \brief Add a tag entry for a host. If it already exist, update it.
 *
 * \param tag_ctx Tag context for hosts
 * \param tde Tag data
 * \param p packet
 *
 * \retval 0 if it was added, 1 if it was updated
 */
int TagHashAddTag(DetectTagDataEntry *tde, Packet *p)
{
    SCEnter();

    uint8_t updated = 0;
    uint16_t num_tags = 0;
    Host *host = NULL;

    /* Lookup host in the hash. If it doesn't exist yet it's
     * created. */
    if (tde->flags & TAG_ENTRY_FLAG_DIR_SRC) {
        host = HostGetHostFromHash(&p->src);
    } else if (tde->flags & TAG_ENTRY_FLAG_DIR_DST) {
        host = HostGetHostFromHash(&p->dst);
    }
    /* no host for us */
    if (host == NULL) {
        return -1;
    }

    void *tag = HostGetStorageById(host, host_tag_id);
    if (tag == NULL) {
        /* get a new tde as the one we have is on the stack */
        DetectTagDataEntry *new_tde = DetectTagDataCopy(tde);
        if (new_tde != NULL) {
            HostSetStorageById(host, host_tag_id, new_tde);
            (void) SC_ATOMIC_ADD(num_tags, 1);
        }
    } else {
        /* Append the tag to the list of this host */

        /* First iterate installed entries searching a duplicated sid/gid */
        DetectTagDataEntry *iter = NULL;

        for (iter = tag; iter != NULL; iter = iter->next) {
            num_tags++;
            if (iter->sid == tde->sid && iter->gid == tde->gid) {
                iter->cnt_match++;
                /* If so, update data, unless the maximum MATCH limit is
                 * reached. This prevents possible DOS attacks */
                if (iter->cnt_match < DETECT_TAG_MATCH_LIMIT) {
                    /* Reset time and counters */
                    iter->first_ts = iter->last_ts = tde->first_ts;
                    iter->packets = 0;
                    iter->bytes = 0;
                }
                updated = 1;
                break;
            }
        }

        /* If there was no entry of this rule, append the new tde */
        if (updated == 0 && num_tags < DETECT_TAG_MAX_TAGS) {
            /* get a new tde as the one we have is on the stack */
            DetectTagDataEntry *new_tde = DetectTagDataCopy(tde);
            if (new_tde != NULL) {
                (void) SC_ATOMIC_ADD(num_tags, 1);

                new_tde->next = tag;
                HostSetStorageById(host, host_tag_id, new_tde);
            }
        } else if (num_tags == DETECT_TAG_MAX_TAGS) {
            SCLogDebug("Max tags for sessions reached (%"PRIu16")", num_tags);
        }
    }

    HostRelease(host);
    SCReturnInt(updated);
}
Esempio n. 24
0
static void DetectHttpStatMsgSetupCallback(Signature *s)
{
    SCLogDebug("callback invoked by %u", s->id);
    s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
}
/**
 * \brief Inits the context to be used by the Classification Config parsing API.
 *
 *        This function initializes the hash table to be used by the Detection
 *        Engine Context to hold the data from the classification.config file,
 *        obtains the file desc to parse the classification.config file, and
 *        inits the regex used to parse the lines from classification.config
 *        file.
 *
 * \param de_ctx Pointer to the Detection Engine Context.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCClassConfInitContextAndLocalResources(DetectEngineCtx *de_ctx)
{
    char *filename = NULL;
    const char *eb = NULL;
    int eo;
    int opts = 0;

    /* init the hash table to be used by the classification config Classtypes */
    de_ctx->class_conf_ht = HashTableInit(4096, SCClassConfClasstypeHashFunc,
                                          SCClassConfClasstypeHashCompareFunc,
                                          SCClassConfClasstypeHashFree);
    if (de_ctx->class_conf_ht == NULL) {
        SCLogError(SC_ERR_HASH_TABLE_INIT, "Error initializing the hash "
                   "table");
        goto error;
    }

    /* if it is not NULL, use the file descriptor.  The hack so that we can
     * avoid using a dummy classification file for testing purposes and
     * instead use an input stream against a buffer containing the
     * classification strings */
    if (fd == NULL) {
        filename = SCClassConfGetConfFilename();
        if ( (fd = fopen(filename, "r")) == NULL) {
            SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno));
            goto error;
        }
    }

    regex = pcre_compile(DETECT_CLASSCONFIG_REGEX, opts, &eb, &eo, NULL);
    if (regex == NULL) {
        SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s",
                   DETECT_CLASSCONFIG_REGEX, eo, eb);
        goto error;
    }

    regex_study = pcre_study(regex, 0, &eb);
    if (eb != NULL) {
        SCLogDebug("pcre study failed: %s", eb);
        goto error;
    }

    return 0;

 error:
    if (de_ctx->class_conf_ht != NULL) {
        HashTableFree(de_ctx->class_conf_ht);
        de_ctx->class_conf_ht = NULL;
    }
    if (fd != NULL) {
        fclose(fd);
        fd = NULL;
    }

    if (regex != NULL) {
        pcre_free(regex);
        regex = NULL;
    }
    if (regex_study != NULL) {
        pcre_free(regex_study);
        regex_study = NULL;
    }

    return -1;
}
Esempio n. 26
0
void TimeModeSetLive(void)
{
    live = TRUE;
    SCLogDebug("live time mode enabled");
}
Esempio n. 27
0
/**
 * \internal
 * \brief Forces reassembly for flows that need it.
 *
 * When this function is called we're running in virtually dead engine,
 * so locking the flows is not strictly required. The reasons it is still
 * done are:
 * - code consistency
 * - silence complaining profilers
 * - allow us to aggressively check using debug valdation assertions
 * - be robust in case of future changes
 * - locking overhead if neglectable when no other thread fights us
 *
 * \param q The queue to process flows from.
 */
static inline void FlowForceReassemblyForHash(void)
{
    Flow *f;
    TcpSession *ssn;
    int client_ok;
    int server_ok;
    int tcp_needs_inspection;

    uint32_t idx = 0;

    /* We use this packet just for reassembly purpose */
    Packet *reassemble_p = PacketGetFromAlloc();
    if (reassemble_p == NULL)
        return;

    for (idx = 0; idx < flow_config.hash_size; idx++) {
        FlowBucket *fb = &flow_hash[idx];

        FBLOCK_LOCK(fb);

        /* get the topmost flow from the QUEUE */
        f = fb->head;

        /* we need to loop through all the flows in the queue */
        while (f != NULL) {
            PACKET_RECYCLE(reassemble_p);

            FLOWLOCK_WRLOCK(f);

            /* Get the tcp session for the flow */
            ssn = (TcpSession *)f->protoctx;

            /* \todo Also skip flows that shouldn't be inspected */
            if (ssn == NULL) {
                FLOWLOCK_UNLOCK(f);
                f = f->hnext;
                continue;
            }

            /* ah ah!  We have some unattended toserver segments */
            if ((client_ok = StreamHasUnprocessedSegments(ssn, 0)) == 1) {
                StreamTcpThread *stt = SC_ATOMIC_GET(stream_pseudo_pkt_stream_tm_slot->slot_data);

                ssn->client.last_ack = (ssn->client.seg_list_tail->seq +
                        ssn->client.seg_list_tail->payload_len);

                FlowForceReassemblyPseudoPacketSetup(reassemble_p, 1, f, ssn, 1);
                StreamTcpReassembleHandleSegment(stream_pseudo_pkt_stream_TV,
                        stt->ra_ctx, ssn, &ssn->server,
                        reassemble_p, NULL);
                FlowDeReference(&reassemble_p->flow);
                if (StreamTcpReassembleProcessAppLayer(stt->ra_ctx) < 0) {
                    SCLogDebug("shutdown flow timeout "
                               "StreamTcpReassembleProcessAppLayer() erroring "
                               "over something");
                }
            }
            /* oh oh!  We have some unattended toclient segments */
            if ((server_ok = StreamHasUnprocessedSegments(ssn, 1)) == 1) {
                StreamTcpThread *stt = SC_ATOMIC_GET(stream_pseudo_pkt_stream_tm_slot->slot_data);

                ssn->server.last_ack = (ssn->server.seg_list_tail->seq +
                        ssn->server.seg_list_tail->payload_len);

                FlowForceReassemblyPseudoPacketSetup(reassemble_p, 0, f, ssn, 1);
                StreamTcpReassembleHandleSegment(stream_pseudo_pkt_stream_TV,
                        stt->ra_ctx, ssn, &ssn->client,
                        reassemble_p, NULL);
                FlowDeReference(&reassemble_p->flow);
                if (StreamTcpReassembleProcessAppLayer(stt->ra_ctx) < 0) {
                    SCLogDebug("shutdown flow timeout "
                               "StreamTcpReassembleProcessAppLayer() erroring "
                               "over something");
                }
            }

            if (ssn->state >= TCP_ESTABLISHED && ssn->state != TCP_CLOSED)
                tcp_needs_inspection = 1;
            else
                tcp_needs_inspection = 0;

            FLOWLOCK_UNLOCK(f);

            /* insert a pseudo packet in the toserver direction */
            if (client_ok || tcp_needs_inspection)
            {
                FLOWLOCK_WRLOCK(f);
                Packet *p = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 1);
                FLOWLOCK_UNLOCK(f);

                if (p == NULL) {
                    TmqhOutputPacketpool(NULL, reassemble_p);
                    FBLOCK_UNLOCK(fb);
                    return;
                }
                PKT_SET_SRC(p, PKT_SRC_FFR_SHUTDOWN);

                if (stream_pseudo_pkt_detect_prev_TV != NULL) {
                    stream_pseudo_pkt_detect_prev_TV->
                        tmqh_out(stream_pseudo_pkt_detect_prev_TV, p);
                } else {
                    TmSlot *s = stream_pseudo_pkt_detect_tm_slot;
                    while (s != NULL) {
                        TmSlotFunc SlotFunc = SC_ATOMIC_GET(s->SlotFunc);
                        SlotFunc(NULL, p, SC_ATOMIC_GET(s->slot_data), &s->slot_pre_pq,
                                    &s->slot_post_pq);
                        s = s->slot_next;
                    }

                    if (stream_pseudo_pkt_detect_TV != NULL) {
                        stream_pseudo_pkt_detect_TV->
                            tmqh_out(stream_pseudo_pkt_detect_TV, p);
                    } else {
                        TmqhOutputPacketpool(NULL, p);
                    }
                }
            } /* if (ssn->client.seg_list != NULL) */
            if (server_ok || tcp_needs_inspection)
            {
                FLOWLOCK_WRLOCK(f);
                Packet *p = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1);
                FLOWLOCK_UNLOCK(f);

                if (p == NULL) {
                    TmqhOutputPacketpool(NULL, reassemble_p);
                    FBLOCK_UNLOCK(fb);
                    return;
                }
                PKT_SET_SRC(p, PKT_SRC_FFR_SHUTDOWN);

                if (stream_pseudo_pkt_detect_prev_TV != NULL) {
                    stream_pseudo_pkt_detect_prev_TV->
                        tmqh_out(stream_pseudo_pkt_detect_prev_TV, p);
                } else {
                    TmSlot *s = stream_pseudo_pkt_detect_tm_slot;
                    while (s != NULL) {
                        TmSlotFunc SlotFunc = SC_ATOMIC_GET(s->SlotFunc);
                        SlotFunc(NULL, p, SC_ATOMIC_GET(s->slot_data), &s->slot_pre_pq,
                                    &s->slot_post_pq);
                        s = s->slot_next;
                    }

                    if (stream_pseudo_pkt_detect_TV != NULL) {
                        stream_pseudo_pkt_detect_TV->
                            tmqh_out(stream_pseudo_pkt_detect_TV, p);
                    } else {
                        TmqhOutputPacketpool(NULL, p);
                    }
                }
            } /* if (ssn->server.seg_list != NULL) */

            /* next flow in the queue */
            f = f->hnext;
        } /* while (f != NULL) */
        FBLOCK_UNLOCK(fb);
    }

    PKT_SET_SRC(reassemble_p, PKT_SRC_FFR_SHUTDOWN);
    TmqhOutputPacketpool(NULL, reassemble_p);
    return;
}
Esempio n. 28
0
void TimeModeSetOffline (void)
{
    live = FALSE;
    SCLogDebug("offline time mode enabled");
}
Esempio n. 29
0
void RegisterAppLayerGetActiveTxIdFunc(GetActiveTxIdFunc FuncPtr)
{
    //BUG_ON(AppLayerGetActiveTxIdFuncPtr != NULL);
    AppLayerGetActiveTxIdFuncPtr = FuncPtr;
    SCLogDebug("AppLayerGetActiveTxIdFuncPtr is now %p", AppLayerGetActiveTxIdFuncPtr);
}
Esempio n. 30
0
/**
 * \brief Returns a cuda_module against the handle in the argument.
 *
 *        If a cuda_module is not present for a handle, it is created
 *        and associated with this handle and the cuda_module is returned
 *        in the argument.
 *
 * \param p_module The loaded CUmodule that is returned.
 * \param ptx_image Name of the module source file, w/o the .cu extension
 * \param handle    A unique handle which identifies a module.  Obtained from
 *                  a call to SCCudaHlGetUniqueHandle().
 *
 * \retval  A unique handle within the module that is associated with the
 *          loaded CUmodule. Needed for future API calls.
 * \retval  -1 on failure.
 */
int SCCudaHlGetCudaModule(CUmodule *p_module, const char *ptx_image, int handle)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleCUmodule *new_module_cumodule = NULL;
    SCCudaHlModuleCUmodule *module_cumodules = NULL;

    if (p_module == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "p_module NULL");
        return -1;
    }

    /* check if the particular module that wants a CUDA module is already
     * registered or not.  If it is registered, check if a context has
     * been associated with the module.  If yes, then we can go ahead and
     * create a cuda module and associate it with the module referenced by
     * the handle in the functions arguments. If no, log warning and get
     * out of here */
    if ( ((data = SCCudaHlGetModuleData(handle)) == NULL) ||
         (data->cuda_context == 0)) {
        SCLogDebug("Module not registered or no cuda context associated with "
                   "this module.  You can't create a CUDA module without"
                   "associating a context with a module first. To use this "
                   "registration facility, first register a module using "
                   "context using SCCudaHlRegisterModule(), and then register "
                   "a cuda context with that module using "
                   "SCCudaHlGetCudaContext(), after which you can call this "
                   "function ");
        return -1;
    }

    /* Register new CUmodule in the module */
    new_module_cumodule = SCMalloc(sizeof(SCCudaHlModuleCUmodule));
    if (new_module_cumodule == NULL) {
        exit(EXIT_FAILURE);
    }
    memset(new_module_cumodule, 0, sizeof(SCCudaHlModuleCUmodule));

    /* select the ptx image based on the compute capability supported by all
     * devices (i.e. the lowest) */
    char* image = SCMalloc(strlen(ptx_image)+15);
    memset(image, 0x0, sizeof(image));

    int major = INT_MAX;
    int minor = INT_MAX;
    SCCudaDevices *devices = SCCudaGetDeviceList();
    int i=0;
    for (; i<devices->count; i++){
        if (devices->devices[i]->major_rev < major){
            major = devices->devices[i]->major_rev;
            minor = devices->devices[i]->minor_rev;
        }
        if (devices->devices[i]->major_rev == major &&
            devices->devices[i]->minor_rev < minor){
            minor = devices->devices[i]->minor_rev;
        }
    }
    snprintf(image, strlen(ptx_image) + 15, "%s_sm_%u%u",
             ptx_image, major, minor);

    /* we don't have a cuda module associated with this module.  Create a
     * cuda module, update the module with this cuda module reference and
     * then return the module refernce back to the calling function using
     * the argument */
    SCLogDebug("Loading kernel module: %s\n",image);
    if (SCCudaModuleLoadData(p_module, (void *)SCCudaPtxDumpGetModule(image)) == -1)
        goto error;
    SCFree(image);

    new_module_cumodule->cuda_module = p_module[0];
    new_module_cumodule->cuda_module_handle = SCCudaHlGetUniqueHandle();

    /* insert it into the cuda_modules list for the module instance */
    if (data->cuda_modules == NULL) {
        data->cuda_modules = new_module_cumodule;
        return new_module_cumodule->cuda_module_handle;
    }

    module_cumodules = data->cuda_modules;
    while (module_cumodules->next != NULL)
        module_cumodules = module_cumodules->next;
    module_cumodules->next = new_module_cumodule;

    return new_module_cumodule->cuda_module_handle;

 error:
    SCFree(image);
    return -1;
}