Ejemplo n.º 1
0
/**
 * \test HOP header decode
 */
static int DecodeIPV6HopTest01 (void)
{
    uint8_t raw_pkt1[] = {
        0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
        0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0xff, /* 0xff is a nonsene opt */
        0x02,0x00,0x00,0x00,0x00,
        0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    };
    Packet *p1 = PacketGetFromAlloc();
    FAIL_IF(unlikely(p1 == NULL));
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;

    FlowInitConfig(FLOW_QUIET);

    memset(&pq, 0, sizeof(PacketQueue));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));

    DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);

    FAIL_IF (!(ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)));

    PACKET_RECYCLE(p1);
    SCFree(p1);
    FlowShutdown();
    PASS;
}
Ejemplo n.º 2
0
/**
 * \test DecodeVLANTest02 test a good vlan header.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int DecodeVLANtest03 (void)   {
    uint8_t raw_vlan[] = {
        0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
        0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
        0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
        0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
        0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
        0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
        0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3
    };
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    FlowInitConfig(FLOW_QUIET);

    DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL);


    if(p->vlanh == NULL) {
        goto error;
    }

    if(ENGINE_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL))  {
        goto error;
    }

    if(ENGINE_ISSET_EVENT(p,VLAN_UNKNOWN_TYPE))  {
        goto error;
    }

    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 1;

error:
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 0;
}
Ejemplo n.º 3
0
/** DecodeRawtest02
 *  \brief Valid Raw packet
 *  \retval 0 Expected test value
 */
static int DecodeRawTest02 (void)
{

    /* IPV4/TCP/no eth header */
    uint8_t raw_ip[] = {
        0x45, 0x00, 0x00, 0x30, 0x00, 0xad, 0x40, 0x00,
        0x7f, 0x06, 0xac, 0xc5, 0xc0, 0xa8, 0x67, 0x02,
        0xc0, 0xa8, 0x66, 0x02, 0x0b, 0xc7, 0x00, 0x50,
        0x1d, 0xb3, 0x12, 0x37, 0x00, 0x00, 0x00, 0x00,
        0x70, 0x02, 0x40, 0x00, 0xb8, 0xc8, 0x00, 0x00,
        0x02, 0x04, 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 };

    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv,  0, sizeof(ThreadVars));

    if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) {
    SCFree(p);
    return 0;
    }

    FlowInitConfig(FLOW_QUIET);

    DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL);
    if (p->ip4h == NULL) {
        printf("expected a valid ipv4 header but it was NULL: ");
        PACKET_RECYCLE(p);
        FlowShutdown();
        SCFree(p);
        return 0;
    }

    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 1;
}
Ejemplo n.º 4
0
/**
 * \test routing header decode
 */
static int DecodeIPV6RouteTest01 (void)
{

    uint8_t raw_pkt1[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
        0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
        0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

        0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf,
        0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00,
        0xfa, 0x87, 0x00, 0x00,
    };
    Packet *p1 = PacketGetFromAlloc();
    if (unlikely(p1 == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;
    int result = 0;
    PacketQueue pq;

    FlowInitConfig(FLOW_QUIET);

    memset(&pq, 0, sizeof(PacketQueue));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));

    DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);

    if (!(IPV6_EXTHDR_ISSET_RH(p1))) {
        printf("ipv6 routing header not detected: ");
        goto end;
    }

    if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
        printf("ipv6 routing length incorrect: ");
        goto end;
    }

    result = 1;
end:
    PACKET_RECYCLE(p1);
    SCFree(p1);
    FlowShutdown();
    return result;
}
Ejemplo n.º 5
0
/**
 * \test HOP header decode
 */
static int DecodeIPV6HopTest01 (void)
{
    uint8_t raw_pkt1[] = {
        0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
        0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0x05,0x02,0x00,0x00,0x00,0x00,
        0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    };
    Packet *p1 = PacketGetFromAlloc();
    if (unlikely(p1 == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;
    int result = 0;
    PacketQueue pq;

    FlowInitConfig(FLOW_QUIET);

    memset(&pq, 0, sizeof(PacketQueue));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));

    DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);

    if (!(IPV6_EXTHDR_ISSET_HH(p1))) {
        printf("ipv6 routing header not detected: ");
        goto end;
    }

    if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
        printf("ipv6 routing length incorrect: ");
        goto end;
    }

    if (ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)) {
        printf("engine event IPV6_HOPOPTS_UNKNOWN_OPT set: ");
        goto end;
    }

    result = 1;
end:
    PACKET_RECYCLE(p1);
    SCFree(p1);
    FlowShutdown();
    return result;
}
Ejemplo n.º 6
0
/** \test Get the wscale of 2 */
static int TCPGetWscaleTest01(void)
{
    int retval = 0;
    static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
                                0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
                                0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
                                0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
                                0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    IPV4Hdr ip4h;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip4h, 0, sizeof(IPV4Hdr));

    p->src.family = AF_INET;
    p->dst.family = AF_INET;
    p->ip4h = &ip4h;


    FlowInitConfig(FLOW_QUIET);
    DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);

    if (p->tcph == NULL) {
        printf("tcp packet decode failed: ");
        goto end;
    }

    uint8_t wscale = TCP_GET_WSCALE(p);
    if (wscale != 2) {
        printf("wscale %"PRIu8", expected 2: ", wscale);
        goto end;
    }

    retval = 1;
end:
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return retval;
}
Ejemplo n.º 7
0
/** DecodeRawtest01
 *  \brief Valid Raw packet
 *  \retval 0 Expected test value
 */
static int DecodeRawTest01 (void)
{

    /* IPV6/TCP/no eth header */
    uint8_t raw_ip[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40,
        0x20, 0x01, 0x06, 0x18, 0x04, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x51, 0x99, 0xcc, 0x70,
        0x20, 0x01, 0x06, 0x18, 0x00, 0x01, 0x80, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
        0x8c, 0x9b, 0x00, 0x50, 0x6a, 0xe7, 0x07, 0x36,
        0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x30,
        0x29, 0x9c, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8c,
        0x04, 0x02, 0x08, 0x0a, 0x00, 0xdd, 0x1a, 0x39,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02 };
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv,  0, sizeof(ThreadVars));

    if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) {
    SCFree(p);
    return 0;
    }

    FlowInitConfig(FLOW_QUIET);

    DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL);
    if (p->ip6h == NULL) {
        printf("expected a valid ipv6 header but it was NULL: ");
        FlowShutdown();
        SCFree(p);
        return 0;
    }

    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 1;

}
Ejemplo n.º 8
0
/** DecodeRawtest03
 *  \brief Valid Raw packet
 *  \retval 0 Expected test value
 */
static int DecodeRawTest03 (void)   {

    /* IPV13 */
    uint8_t raw_ip[] = {
        0xdf, 0x00, 0x00, 0x3d, 0x49, 0x42, 0x40, 0x00,
        0x40, 0x06, 0xcf, 0x8a, 0x0a, 0x1f, 0x03, 0xaf,
        0x0a, 0x1f, 0x0a, 0x02, 0xa5, 0xe7, 0xde, 0xad,
        0x00, 0x0c, 0xe2, 0x0e, 0x8b, 0xfe, 0x0c, 0xe7,
        0x80, 0x18, 0x00, 0xb7, 0xaf, 0xeb, 0x00, 0x00,
        0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xab, 0x4f,
        0x34, 0x40, 0x67, 0x31, 0x3b, 0x63, 0x61, 0x74,
        0x20, 0x6b, 0x65, 0x79, 0x3b };

    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv,  0, sizeof(ThreadVars));

    if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) {
        SCFree(p);
        return 1;
    }

    FlowInitConfig(FLOW_QUIET);

    DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL);
    if (ENGINE_ISSET_EVENT(p,IPRAW_INVALID_IPV)) {
        FlowShutdown();
        SCFree(p);
        return 0;
    } else {
        printf("expected IPRAW_INVALID_IPV to be set but it wasn't: ");
    }
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 1;
}
Ejemplo n.º 9
0
/**
 * \test routing header decode
 */
static int DecodeIPV6RouteTest01 (void)
{
    uint8_t raw_pkt1[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
        0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
        0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

        0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf,
        0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00,
        0xfa, 0x87, 0x00, 0x00,
    };
    Packet *p1 = PacketGetFromAlloc();
    FAIL_IF(unlikely(p1 == NULL));
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;

    FlowInitConfig(FLOW_QUIET);

    memset(&pq, 0, sizeof(PacketQueue));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));

    DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);

    FAIL_IF (!(IPV6_EXTHDR_ISSET_RH(p1)));
    FAIL_IF (p1->ip6eh.rh_type != 0);
    PACKET_RECYCLE(p1);
    SCFree(p1);
    FlowShutdown();
    PASS;
}
Ejemplo n.º 10
0
/**
 * \test Test packet Matches
 * \param raw_eth_pkt pointer to the ethernet packet
 * \param pktsize size of the packet
 * \param sig pointer to the signature to test
 * \param sid sid number of the signature
 * \retval return 1 if match
 * \retval return 0 if not
 */
static
int DetectReplaceLongPatternMatchTest(uint8_t *raw_eth_pkt, uint16_t pktsize,
                                      char *sig, uint32_t sid, uint8_t *pp,
                                      uint16_t *len)
{
    int result = 0;

    Packet *p = NULL;
    p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;

    DecodeThreadVars dtv;

    ThreadVars th_v;
    DetectEngineThreadCtx *det_ctx = NULL;

    if (pp == NULL) {
        SCLogDebug("replace: looks like a second run");
    }

    PacketCopyData(p, raw_eth_pkt, pktsize);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&th_v, 0, sizeof(th_v));
    dtv.app_tctx = AppLayerGetCtxThread(&th_v);

    FlowInitConfig(FLOW_QUIET);
    DecodeEthernet(&th_v, &dtv, p, GET_PKT_DATA(p), pktsize, NULL);

    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
    if (de_ctx == NULL) {
        goto end;
    }
    de_ctx->flags |= DE_QUIET;

    de_ctx->sig_list = SigInit(de_ctx, sig);
    if (de_ctx->sig_list == NULL) {
        goto end;
    }
    de_ctx->sig_list->next = NULL;

    if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_CONTENT) {
        DetectContentData *co = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
        if (co->flags & DETECT_CONTENT_RELATIVE_NEXT) {
            printf("relative next flag set on final match which is content: ");
            goto end;
        }
    }

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

    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
    DetectEngineMoveToFreeList(de_ctx);

    if (PacketAlertCheck(p, sid) != 1) {
        SCLogDebug("replace: no alert on sig %d", sid);
        goto end;
    }

    if (pp) {
        memcpy(pp, GET_PKT_DATA(p), GET_PKT_LEN(p));
        *len = pktsize;
        SCLogDebug("replace: copying %d on %p", *len, pp);
    }


    result = 1;
end:
    if (dtv.app_tctx != NULL)
        AppLayerDestroyCtxThread(dtv.app_tctx);
    if (det_ctx != NULL)
        DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
    DetectEnginePruneFreeList();
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);


    return result;
}
Ejemplo n.º 11
0
/**
 * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int FragBitsTestParse04 (void) {
    uint8_t raw_eth[] = {
        0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
        0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
        0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
        0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
        0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
        0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
        0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
        0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
        0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
        0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
        0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
        0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
        0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
        0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
        0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
        0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
        0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
        0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
        0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
        0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
        0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
        0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
        0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
        0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
        0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
        0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
        0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
        0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
        0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
        0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
        0x51
    };
    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;
    IPV4Hdr ipv4h;
    int ret = 0;
    DetectFragBitsData *de = NULL;
    SigMatch *sm = NULL;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ipv4h, 0, sizeof(IPV4Hdr));
    dtv.app_tctx = AppLayerGetCtxThread(&tv);

    p->ip4h = &ipv4h;

    FlowInitConfig(FLOW_QUIET);

    DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL);


    de = DetectFragBitsParse("!D");

    if (de == NULL || (de->fragbits != FRAGBITS_HAVE_DF) || (de->modifier != MODIFIER_NOT))
        goto error;

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

    sm->type = DETECT_FRAGBITS;
    sm->ctx = (void *)de;

    ret = DetectFragBitsMatch(&tv,NULL,p,NULL,sm);

    if(ret) {
        if (de) SCFree(de);
        if (sm) SCFree(sm);
        PACKET_RECYCLE(p);
        FlowShutdown();
        SCFree(p);
        return 1;
    }

error:
    if (de) SCFree(de);
    if (sm) SCFree(sm);
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 0;
}
Ejemplo n.º 12
0
/** \brief Return packet to Packet pool
 *
 */
void PacketPoolReturnPacket(Packet *p)
{
    PACKET_RECYCLE(p);
    RingBufferMrMwPut(ringbuffer, (void *)p);
}
Ejemplo n.º 13
0
static int TCPGetSackTest01(void)
{
    int retval = 0;
    static uint8_t raw_tcp[] = {
        0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
        0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
        0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
        0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
        0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
    static uint8_t raw_tcp_sack[] = {
        0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
        0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    IPV4Hdr ip4h;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip4h, 0, sizeof(IPV4Hdr));

    p->src.family = AF_INET;
    p->dst.family = AF_INET;
    p->ip4h = &ip4h;

    FlowInitConfig(FLOW_QUIET);
    DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);

    if (p->tcph == NULL) {
        printf("tcp packet decode failed: ");
        goto end;
    }

    if (!TCP_HAS_SACK(p)) {
        printf("tcp packet sack not decoded: ");
        goto end;
    }

    int sack = TCP_GET_SACK_CNT(p);
    if (sack != 2) {
        printf("expected 2 sack records, got %u: ", TCP_GET_SACK_CNT(p));
        goto end;
    }

    uint8_t *sackptr = TCP_GET_SACK_PTR(p);
    if (sackptr == NULL) {
        printf("no sack data: ");
        goto end;
    }

    if (memcmp(sackptr, raw_tcp_sack, 16) != 0) {
        printf("malformed sack data: ");
        goto end;
    }

    retval = 1;
end:
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return retval;
}
Ejemplo n.º 14
0
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
{
    int proot = 0;

    SCEnter();
    SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false");

    /** \todo make this a callback
     *  Release tcp segments. Done here after alerting can use them. */
    if (p->flow != NULL && p->proto == IPPROTO_TCP) {
        SCMutexLock(&p->flow->m);
        StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ?
                STREAM_TOSERVER : STREAM_TOCLIENT);
        SCMutexUnlock(&p->flow->m);
    }

    if (IS_TUNNEL_PKT(p)) {
        SCLogDebug("Packet %p is a tunnel packet: %s",
            p,p->root ? "upper layer" : "tunnel root");

        /* get a lock to access root packet fields */
        SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex;
        SCMutexLock(m);

        if (IS_TUNNEL_ROOT_PKT(p)) {
            SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE");
            if (TUNNEL_PKT_TPR(p) == 0) {
                SCLogDebug("TUNNEL_PKT_TPR(p) == 0, no more tunnel packet "
                        "depending on this root");
                /* if this packet is the root and there are no
                 * more tunnel packets, return it to the pool */

                /* fall through */
            } else {
                SCLogDebug("tunnel root Packet %p: TUNNEL_PKT_TPR(p) > 0, so "
                        "packets are still depending on this root, setting "
                        "p->tunnel_verdicted == 1", p);
                /* if this is the root and there are more tunnel
                 * packets, return this to the pool. It's still referenced
                 * by the tunnel packets, and we will return it
                 * when we handle them */
                SET_TUNNEL_PKT_VERDICTED(p);

                SCMutexUnlock(m);

                PACKET_PROFILING_END(p);
                SCReturn;
            }
        } else {
            SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt");

            /* the p->root != NULL here seems unnecessary: IS_TUNNEL_PKT checks
             * that p->tunnel_pkt == 1, IS_TUNNEL_ROOT_PKT checks that +
             * p->root == NULL. So when we are here p->root can only be
             * non-NULL, right? CLANG thinks differently. May be a FP, but
             * better safe than sorry. VJ */
            if (p->root != NULL && IS_TUNNEL_PKT_VERDICTED(p->root) &&
                    TUNNEL_PKT_TPR(p) == 1)
            {
                SCLogDebug("p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1");
                /* the root is ready and we are the last tunnel packet,
                 * lets enqueue them both. */
                TUNNEL_DECR_PKT_TPR_NOLOCK(p);

                /* handle the root */
                SCLogDebug("setting proot = 1 for root pkt, p->root %p "
                        "(tunnel packet %p)", p->root, p);
                proot = 1;

                /* fall through */
            } else {
                /* root not ready yet, so get rid of the tunnel pkt only */

                SCLogDebug("NOT p->root->tunnel_verdicted == 1 && "
                        "TUNNEL_PKT_TPR(p) == 1 (%" PRIu32 ")", TUNNEL_PKT_TPR(p));

                TUNNEL_DECR_PKT_TPR_NOLOCK(p);

                 /* fall through */
            }
        }
        SCMutexUnlock(m);

        SCLogDebug("tunnel stuff done, move on (proot %d)", proot);
    }

    FlowDecrUsecnt(p->flow);

    /* we're done with the tunnel root now as well */
    if (proot == 1) {
        SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false");

        FlowDecrUsecnt(p->root->flow);
        /* if p->root uses extended data, free them */
        if (p->root->ReleaseData) {
            if (p->root->ReleaseData(t, p->root) == TM_ECODE_FAILED) {
                SCLogWarning(SC_ERR_INVALID_ACTION,
                        "Unable to release packet data");
            }
        }
        if (p->root->ext_pkt) {
            if (!(p->root->flags & PKT_ZERO_COPY)) {
                SCFree(p->root->ext_pkt);
            }
            p->root->ext_pkt = NULL;
        }
        if (p->root->flags & PKT_ALLOC) {
            PACKET_CLEANUP(p->root);
            SCFree(p->root);
            p->root = NULL;
        } else {
            PACKET_RECYCLE(p->root);
            RingBufferMrMwPut(ringbuffer, (void *)p->root);
        }

    }

    if (p->ReleaseData) {
        if (p->ReleaseData(t, p) == TM_ECODE_FAILED) {
            SCLogWarning(SC_ERR_INVALID_ACTION, "Unable to release packet data");
        }
    }

    /* if p uses extended data, free them */
    if (p->ext_pkt) {
        if (!(p->flags & PKT_ZERO_COPY)) {
            SCFree(p->ext_pkt);
        }
        p->ext_pkt = NULL;
    }

    PACKET_PROFILING_END(p);

    SCLogDebug("getting rid of tunnel pkt... alloc'd %s (root %p)", p->flags & PKT_ALLOC ? "true" : "false", p->root);
    if (p->flags & PKT_ALLOC) {
        PACKET_CLEANUP(p);
        SCFree(p);
    } else {
        PACKET_RECYCLE(p);
        RingBufferMrMwPut(ringbuffer, (void *)p);
    }

    SCReturn;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;

    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;
            }

            (void)FlowForceReassemblyNeedReassembly(f, &server_ok, &client_ok);

            /* ah ah!  We have some unattended toserver segments */
            if (client_ok == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
                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);
            }
            /* oh oh!  We have some unattended toclient segments */
            if (server_ok == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) {
                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);
            }

            FLOWLOCK_UNLOCK(f);

            /* insert a pseudo packet in the toserver direction */
            if (client_ok) {
                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 (server_ok) {
                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);
                    }
                }
            }

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

    PKT_SET_SRC(reassemble_p, PKT_SRC_FFR_SHUTDOWN);
    TmqhOutputPacketpool(NULL, reassemble_p);
    return;
}
Ejemplo n.º 17
0
/**
 * \test DetectDsizeIcmpv6Test01 is a test for checking the working of
 *       dsize keyword by creating 2 rules and matching a crafted packet
 *       against them. Only the first one shall trigger.
 */
int DetectDsizeIcmpv6Test01 (void) {
    int result = 0;

    static uint8_t raw_icmpv6[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00,
        0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };

    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (unlikely(p == NULL))
        return 0;
    IPV6Hdr ip6h;
    ThreadVars tv;
    DecodeThreadVars dtv;
    Signature *s = NULL;
    ThreadVars th_v;
    DetectEngineThreadCtx *det_ctx = NULL;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip6h, 0, sizeof(IPV6Hdr));
    memset(&th_v, 0, sizeof(ThreadVars));

    FlowInitConfig(FLOW_QUIET);
    p->src.family = AF_INET6;
    p->dst.family = AF_INET6;
    p->ip6h = &ip6h;

    DecodeIPV6(&tv, &dtv, p, raw_icmpv6, sizeof(raw_icmpv6), NULL);

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

    de_ctx->flags |= DE_QUIET;

    s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
            "(msg:\"ICMP Large ICMP Packet\"; dsize:>8; sid:1; rev:4;)");
    if (s == NULL) {
        goto end;
    }

    s = s->next = SigInit(de_ctx, "alert icmp any any -> any any "
            "(msg:\"ICMP Large ICMP Packet\"; dsize:>800; sid:2; rev:4;)");
    if (s == NULL) {
        goto end;
    }

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

    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
    if (PacketAlertCheck(p, 1) == 0) {
        printf("sid 1 did not alert, but should have: ");
        goto cleanup;
    } else if (PacketAlertCheck(p, 2)) {
        printf("sid 2 alerted, but should not have: ");
        goto cleanup;
    }

    result = 1;

cleanup:
    SigGroupCleanup(de_ctx);
    SigCleanSignatures(de_ctx);

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

    PACKET_RECYCLE(p);
    FlowShutdown();
end:
    SCFree(p);
    return result;

}
Ejemplo n.º 18
0
/**
 * \test fragment decoding
 */
static int DecodeIPV6FragTest01 (void)
{

    uint8_t raw_frag1[] = {
        0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
        0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7,
        0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13,
        0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a,
        0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
        0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44,
        0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37,
        0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
        0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74,
        0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50,
        0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d,
        0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30,
        0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
        0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
        0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b,
        0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f,
        0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f,
        0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41,
        0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
        0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
        0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73,
        0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a,
        0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39,
        0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33,
        0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22,
        0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75,
        0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a,
        0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    };
    uint8_t raw_frag2[] = {
        0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
        0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20,
    };
    Packet *pkt;
    Packet *p1 = PacketGetFromAlloc();
    if (unlikely(p1 == NULL))
        return 0;
    Packet *p2 = PacketGetFromAlloc();
    if (unlikely(p2 == NULL)) {
        SCFree(p1);
        return 0;
    }
    ThreadVars tv;
    DecodeThreadVars dtv;
    int result = 0;
    PacketQueue pq;

    FlowInitConfig(FLOW_QUIET);
    DefragInit();

    memset(&pq, 0, sizeof(PacketQueue));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    PacketCopyData(p1, raw_frag1, sizeof(raw_frag1));
    PacketCopyData(p2, raw_frag2, sizeof(raw_frag2));

    DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);

    if (!(IPV6_EXTHDR_ISSET_FH(p1))) {
        printf("ipv6 frag header not detected: ");
        goto end;
    }

    DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2), &pq);

    if (!(IPV6_EXTHDR_ISSET_FH(p2))) {
        printf("ipv6 frag header not detected: ");
        goto end;
    }

    if (pq.len != 1) {
        printf("no reassembled packet: ");
        goto end;
    }

    result = 1;
end:
    PACKET_RECYCLE(p1);
    PACKET_RECYCLE(p2);
    SCFree(p1);
    SCFree(p2);
    pkt = PacketDequeue(&pq);
    while (pkt != NULL) {
        PACKET_RECYCLE(pkt);
        SCFree(pkt);
        pkt = PacketDequeue(&pq);
    }
    DefragDestroy();
    FlowShutdown();
    return result;
}
Ejemplo n.º 19
0
static int DetectCsumICMPV6Test01(void)
{
    DetectEngineCtx *de_ctx = NULL;
    Signature *s = NULL;
    ThreadVars tv;
    DetectEngineThreadCtx *det_ctx = NULL;
    DecodeThreadVars dtv;

    Packet *p = PacketGetFromAlloc();
    FAIL_IF_NULL(p);

    uint8_t pkt[] = {
        0x00, 0x30, 0x18, 0xa8, 0x7c, 0x23, 0x2c, 0x41,
        0x38, 0xa7, 0xea, 0xeb, 0x86, 0xdd, 0x60, 0x00,
        0x00, 0x00, 0x00, 0x40, 0x3c, 0x40, 0xad, 0xa1,
        0x09, 0x80, 0x00, 0x01, 0xd6, 0xf3, 0x20, 0x01,
        0xf4, 0xbe, 0xea, 0x3c, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x32, 0xb2, 0x00, 0x01, 0x32, 0xb2,
        0x09, 0x80, 0x20, 0x01, 0x00, 0x00, 0x3c, 0x00,
        0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
        0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
        0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
        0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
        0x63, 0xc2, 0x00, 0x00, 0x00, 0x00 };

    PacketCopyData(p, pkt, sizeof(pkt));

    memset(&tv, 0, sizeof(tv));
    memset(&dtv, 0, sizeof(dtv));

    StreamTcpInitConfig(TRUE);
    FlowInitConfig(FLOW_QUIET);

    de_ctx = DetectEngineCtxInit();
    FAIL_IF_NULL(de_ctx);
    de_ctx->mpm_matcher = mpm_default_matcher;
    de_ctx->flags |= DE_QUIET;

    s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any "
                                   "(icmpv6-csum:valid; sid:1;)");
    FAIL_IF_NULL(s);
    SigGroupBuild(de_ctx);

    DecodeEthernet(&tv, &dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), NULL);

    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);

    SigMatchSignatures(&tv, de_ctx, det_ctx, p);

    FAIL_IF(!PacketAlertCheck(p, 1));

    DetectEngineThreadCtxDeinit(&tv, det_ctx);
    DetectEngineCtxFree(de_ctx);

    StreamTcpFreeConfig(TRUE);
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    PASS;
}