int DetectAppLayerEventTest01(void)
{
    AppLayerParserBackupParserTable();
    AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP,
                            DetectAppLayerEventTestGetEventInfo);

    AppLayerEventType event_type;
    int result = 0;
    uint8_t ipproto_bitarray[256 / 8];
    memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray));
    ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);

    DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
                                                             &event_type);
    if (aled == NULL)
        goto end;
    if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) {
        printf("failure 1\n");
        goto end;
    }
    if (aled->alproto != ALPROTO_SMTP ||
        aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) {
        printf("test failure.  Holding wrong state\n");
        goto end;
    }

    result = 1;

 end:
    AppLayerParserRestoreParserTable();
    if (aled != NULL)
        DetectAppLayerEventFree(aled);
    return result;
}
int DetectAppLayerEventTest01(void)
{
    AppLayerParserBackupAlprotoTable();
    AppLayerRegisterGetEventInfo(ALPROTO_SMTP,
                                 DetectAppLayerEventTestGetEventInfo);

    AppLayerEventType event_type;
    int result = 0;

    DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
                                                             &event_type);
    if (aled == NULL)
        goto end;
    if (aled->alproto != ALPROTO_SMTP ||
        aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) {
        printf("test failure.  Holding wrong state\n");
        goto end;
    }

    result = 1;

 end:
    AppLayerParserRestoreAlprotoTable();
    if (aled != NULL)
        DetectAppLayerEventFree(aled);
    return result;
}
int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
    DetectAppLayerEventData *data = NULL;
    SigMatch *sm = NULL;

    data = DetectAppLayerEventParse(arg);
    if (data == NULL)
        goto error;

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

    sm->type = DETECT_AL_APP_LAYER_EVENT;
    sm->ctx = (void *)data;

    if (s->alproto != ALPROTO_UNKNOWN) {
        if (s->alproto != ((DetectAppLayerEventData *)sm->ctx)->alproto) {
            SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains "
                       "conflicting keywords needing different alprotos");
            goto error;
        }
    } else {
        s->alproto = ((DetectAppLayerEventData *)sm->ctx)->alproto;
    }

    SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
    s->flags |= SIG_FLAG_APPLAYER;

    return 0;

 error:
    return -1;
}
int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
    DetectAppLayerEventData *data = NULL;
    SigMatch *sm = NULL;
    AppLayerEventType event_type;

    data = DetectAppLayerEventParse(arg, &event_type);
    if (data == NULL)
        goto error;

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

    sm->type = DETECT_AL_APP_LAYER_EVENT;
    sm->ctx = (void *)data;

    if (s->alproto != ALPROTO_UNKNOWN) {
        if (s->alproto == ALPROTO_DNS &&
                (data->alproto == ALPROTO_DNS_UDP || data->alproto == ALPROTO_DNS_TCP))
        {
            SCLogDebug("DNS app layer event");
        } else if (s->alproto != data->alproto) {
            SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains "
                       "conflicting keywords needing different alprotos");
            goto error;
        }
    } else {
        s->alproto = data->alproto;
    }

    if (event_type == APP_LAYER_EVENT_TYPE_PACKET) {
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
    } else if (event_type == APP_LAYER_EVENT_TYPE_GENERAL) {
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
        s->flags |= SIG_FLAG_APPLAYER;
    } else {
        /* implied APP_LAYER_EVENT_TYPE_TRANSACTION */
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_APP_EVENT);
        s->flags |= SIG_FLAG_APPLAYER;
    }

    return 0;

error:
    if (data)
        SCFree(data);
    if (sm) {
        sm->ctx = NULL;
        SigMatchFree(sm);
    }
    return -1;
}
static int DetectAppLayerEventSetupP1(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
    DetectAppLayerEventData *data = NULL;
    SigMatch *sm = NULL;
    AppLayerEventType event_type;

    data = DetectAppLayerEventParse(arg, &event_type);
    if (data == NULL)
        goto error;

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

    sm->type = DETECT_AL_APP_LAYER_EVENT;
    sm->ctx = (void *)data;

    if (s->alproto != ALPROTO_UNKNOWN) {
        if (s->alproto != data->alproto) {
            SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains "
                       "conflicting keywords needing different alprotos");
            goto error;
        }
    } else {
        s->alproto = data->alproto;
    }

    if (event_type == APP_LAYER_EVENT_TYPE_PACKET) {
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
    } else {
        /* We push it to this list temporarily.  We deal with
         * these in DetectAppLayerEventPrepare(). */
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_APP_EVENT);
        s->flags |= SIG_FLAG_APPLAYER;
    }

    return 0;

error:
    if (data)
        SCFree(data);
    if (sm) {
        sm->ctx = NULL;
        SigMatchFree(sm);
    }
    return -1;
}
int DetectAppLayerEventTest01(void)
{
    AppLayerDecoderEventsModuleCreateBackup();
    AppLayerDecoderEventsModuleRegister(ALPROTO_SMTP, app_layer_event_test_map);

    int result = 0;

    DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1");
    if (aled == NULL)
        goto end;
    if (aled->alproto != ALPROTO_SMTP ||
        aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) {
        printf("test failure.  Holding wrong state\n");
        goto end;
    }

    result = 1;

 end:
    AppLayerDecoderEventsModuleRestoreBackup();
    if (aled != NULL)
        DetectAppLayerEventFree(aled);
    return result;
}