Exemple #1
0
/**\test icmpv6 message type: echo reply, valid packet
 * \retval retval 0 = Error ; 1 = ok
 */
static int ICMPV6EchoRepTest01(void)
{
    int retval = 0;
    static uint8_t raw_ipv6[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 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, 0x81, 0x00,
        0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23
    };

    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
        return 0;
    IPV6Hdr ip6h;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip6h, 0, sizeof(IPV6Hdr));

    FlowInitConfig(FLOW_QUIET);
    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
    FlowShutdown();

    if (p->icmpv6h == NULL) {
        SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6");
        retval = 0;
        goto end;
    }

    SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p),
               ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));

    if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 ||
            ICMPV6_GET_ID(p) != 61477 || ICMPV6_GET_SEQ(p) != 29987) {
        SCLogDebug("ICMPv6 Echo reply decode failed");
        retval = 0;
        goto end;
    }

    retval = 1;
end:
    SCFree(p);
    return retval;
}
/**
 * \brief This function is used to match itype rule option set on a packet with those passed via itype:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectITypeData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectITypeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    int ret = 0;
    uint8_t pitype;
    DetectITypeData *itd = (DetectITypeData *)m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_ICMPV4(p)) {
        pitype = ICMPV4_GET_TYPE(p);
    } else if (PKT_IS_ICMPV6(p)) {
        pitype = ICMPV6_GET_TYPE(p);
    } else {
        /* Packet not ICMPv4 nor ICMPv6 */
        return ret;
    }

    switch(itd->mode) {
        case DETECT_ITYPE_EQ:
            ret = (pitype == itd->type1) ? 1 : 0;
            break;
        case DETECT_ITYPE_LT:
            ret = (pitype < itd->type1) ? 1 : 0;
            break;
        case DETECT_ITYPE_GT:
            ret = (pitype > itd->type1) ? 1 : 0;
            break;
        case DETECT_ITYPE_RN:
            ret = (pitype > itd->type1 && pitype < itd->type2) ? 1 : 0;
            break;
    }

    return ret;
}
Exemple #3
0
/** \test icmpv6 message type: parameter problem, invalid packet
 * \brief set the event ICMPV6_IPV6_UNKNOWN_VER properly when the embedded packet has an unknown version
 * \retval retval 0 = Error ; 1 = ok
 */
static int ICMPV6ParamProbTest02(void)
{
    int retval = 0;
    static uint8_t raw_ipv6[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 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,
        0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf,
        0x38, 0x70, 0x12, 0xb7, 0x00, 0x08, 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,
        0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40
    };

    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
        return 0;
    IPV6Hdr ip6h;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip6h, 0, sizeof(IPV6Hdr));

    FlowInitConfig(FLOW_QUIET);
    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
    FlowShutdown();

    if (p->icmpv6h == NULL) {
        SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6");
        retval = 0;
        goto end;
    }

    if (ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0) {
        SCLogDebug("ICMPv6 Not processed at all");
        retval = 0;
        goto end;
    }

    if (!DECODER_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER)) {
        SCLogDebug("ICMPv6 Error: Unknown embedded ipv6 version event not set");
        retval = 0;
        goto end;
    }

    retval = 1;
end:
    SCFree(p);
    return retval;
}
/**
 * \brief This function is used to match icmp_id rule option set on a packet
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectIcmpIdData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectIcmpIdMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    uint16_t pid;
    DetectIcmpIdData *iid = (DetectIcmpIdData *)m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_ICMPV4(p)) {
        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p),
                        ntohs(ICMPV4_GET_ID(p)));

                pid = ICMPV4_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return 0;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p),
                        ntohs(ICMPV6_GET_ID(p)));

                pid = ICMPV6_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return 0;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return 0;
    }

    if (pid == iid->id)
        return 1;

    return 0;
}
Exemple #5
0
static inline _Bool GetIcmpId(Packet *p, uint16_t *id)
{
    if (PKT_IS_PSEUDOPKT(p))
        return FALSE;

    uint16_t pid;
    if (PKT_IS_ICMPV4(p)) {
        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p),
                        ntohs(ICMPV4_GET_ID(p)));

                pid = ICMPV4_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return FALSE;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p),
                        ntohs(ICMPV6_GET_ID(p)));

                pid = ICMPV6_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return FALSE;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return FALSE;
    }

    *id = pid;
    return TRUE;
}
Exemple #6
0
/**
 * \brief This function is used to match icmp_seq rule option set on a packet
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectIcmpSeqData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectIcmpSeqMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {
    uint16_t seqn;
    DetectIcmpSeqData *iseq = (DetectIcmpSeqData *)m->ctx;

    if (PKT_IS_ICMPV4(p)) {
        SCLogDebug("ICMPV4_GET_SEQ(p) %"PRIu16" (network byte order), "
                "%"PRIu16" (host byte order)", ICMPV4_GET_SEQ(p),
                ntohs(ICMPV4_GET_SEQ(p)));

        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                seqn = ICMPV4_GET_SEQ(p);
                break;
            default:
                SCLogDebug("Packet has no seq field");
                return 0;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                seqn = ICMPV6_GET_SEQ(p);
                break;
            default:
                SCLogDebug("Packet has no seq field");
                return 0;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return 0;
    }

    if (seqn == iseq->seq)
        return 1;

    return 0;
}
Exemple #7
0
/**
 * \brief   Log the dropped packets in netfilter format when engine is running
 *          in inline mode
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is being logged
 * \param data  Pointer to the droplog struct
 *
 * \return return TM_EODE_OK on success
 */
static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data)
{
    LogDropLogThread *dlt = (LogDropLogThread *)data;
    uint16_t proto = 0;
    char timebuf[64];

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

    SCMutexLock(&dlt->file_ctx->fp_mutex);

    if (dlt->file_ctx->rotation_flag) {
        dlt->file_ctx->rotation_flag  = 0;
        if (SCConfLogReopen(dlt->file_ctx) != 0) {
            /* Rotation failed, error already logged. */
            SCMutexUnlock(&dlt->file_ctx->fp_mutex);
            return TM_ECODE_FAILED;
        }
    }

    char srcip[46] = "";
    char dstip[46] = "";

    if (PKT_IS_IPV4(p)) {
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, 16);
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, 16);
        fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16" "
                "TOS=0x%02"PRIu8" TTL=%"PRIu8" ID=%"PRIu16"", timebuf,
                srcip, dstip, IPV4_GET_IPLEN(p), IPV4_GET_IPTOS(p),
                IPV4_GET_IPTTL(p), IPV4_GET_IPID(p));
        proto = IPV4_GET_IPPROTO(p);
    } else if (PKT_IS_IPV6(p)) {
        PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
        fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16""
                " TC=%"PRIu32" HOPLIMIT=%"PRIu8" FLOWLBL=%"PRIu32"", timebuf,
                srcip, dstip, IPV6_GET_PLEN(p), IPV6_GET_CLASS(p),
                IPV6_GET_HLIM(p), IPV6_GET_FLOW(p));
        proto = IPV6_GET_L4PROTO(p);
    }

    if (SCProtoNameValid(proto) == TRUE) {
        fprintf(dlt->file_ctx->fp, " PROTO=%s",known_proto[proto]);
    } else {
        fprintf(dlt->file_ctx->fp, " PROTO=%03"PRIu16"",proto);
    }

    switch (proto) {
        case IPPROTO_TCP:
            if (PKT_IS_TCP(p)) {
                fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" "
                        "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"",
                        GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p),
                        TCP_GET_ACK(p), TCP_GET_WINDOW(p));
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : "");
                fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"",
                        TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p));
            }
            break;
        case IPPROTO_UDP:
            if (PKT_IS_UDP(p)) {
                fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16""
                        " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p),
                        UDP_GET_DST_PORT(p), UDP_GET_LEN(p));
            }
            break;
        case IPPROTO_ICMP:
            if (PKT_IS_ICMPV4(p)) {
                fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8""
                        " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p),
                        ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p));
            } else if (PKT_IS_ICMPV6(p)) {
                fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8""
                        " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p),
                        ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
            }
            break;
        default:
            fprintf(dlt->file_ctx->fp," Unknown protocol");
    }

    fprintf(dlt->file_ctx->fp,"\n");

    fflush(dlt->file_ctx->fp);

    dlt->drop_cnt++;
    SCMutexUnlock(&dlt->file_ctx->fp_mutex);

    return TM_ECODE_OK;

}
Exemple #8
0
/** \test icmpv6 message type: destination unreach, valid packet
 *
 * \retval retval 0 = Error ; 1 = ok
 */
static int ICMPV6DestUnreachTest01(void)
{
    int retval = 0;
    static uint8_t raw_ipv6[] = {
        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 (p == NULL)
        return 0;
    IPV6Hdr ip6h;
    ThreadVars tv;
    DecodeThreadVars dtv;
    uint32_t *ipv6src;
    uint32_t *ipv6dst;
    ipv6src = (uint32_t*) &raw_ipv6[8];
    ipv6dst = (uint32_t*) &raw_ipv6[24];


    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip6h, 0, sizeof(IPV6Hdr));

    FlowInitConfig(FLOW_QUIET);
    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
    FlowShutdown();

    if (p->icmpv6h == NULL) {
        SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6");
        retval = 0;
        goto end;
    }

    /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */
    if (ICMPV6_GET_TYPE(p) != 1 || ICMPV6_GET_CODE(p) != 0 ||
        ICMPV6_GET_EMB_IPV6(p) == NULL || ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE ) {
        SCLogDebug("ICMPv6 Not processed at all");
        retval = 0;
        goto end;
    }

    /* Let's check if we retrieved the embedded ipv6 addresses correctly */
    uint32_t i=0;
    for (i = 0; i < 4; i++) {
        if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
            p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) {
            SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set "
                       "the src and dest ip addresses correctly");
            retval = 0;
            goto end;
        }
    }

    retval = 1;
end:
    SCFree(p);
    return retval;
}
Exemple #9
0
/** \test icmpv6 message type: parameter problem, valid packet
 *
 * \retval retval 0 = Error ; 1 = ok
 */
static int ICMPV6ParamProbTest01(void)
{
    int retval = 0;
    static uint8_t raw_ipv6[] = {
        0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 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,
        0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf,
        0x69, 0x70, 0x12, 0xb7, 0x00, 0x08, 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,
        0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 };

    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
        return 0;
    IPV6Hdr ip6h;
    ThreadVars tv;
    DecodeThreadVars dtv;
    uint32_t *ipv6src;
    uint32_t *ipv6dst;
    ipv6src = (uint32_t*) &raw_ipv6[8];
    ipv6dst = (uint32_t*) &raw_ipv6[24];

    memset(&tv, 0, sizeof(ThreadVars));
    memset(p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&ip6h, 0, sizeof(IPV6Hdr));

    FlowInitConfig(FLOW_QUIET);
    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
    FlowShutdown();

    if (p->icmpv6h == NULL) {
        SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6");
        retval = 0;
        goto end;
    }

    if (ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 ||
        ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6) {
        SCLogDebug("ICMPv6 not processed at all");
        retval = 0;
        goto end;
    }

    /* Let's check if we retrieved the embedded ipv6 addresses correctly */
    uint32_t i=0;
    for (i = 0; i < 4; i++) {
        if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
            p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) {
            SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set "
                       "the src and dest ip addresses correctly");
            retval = 0;
            goto end;
        }
    }

    retval = 1;
end:
    SCFree(p);
    return retval;
}
Exemple #10
0
/**
 * \brief Decode ICMPV6 packets and fill the Packet with the decoded info
 *
 * \param tv Pointer to the thread variables
 * \param dtv Pointer to the decode thread variables
 * \param p Pointer to the packet we are filling
 * \param pkt Pointer to the raw packet buffer
 * \param len the len of the rest of the packet not processed yet
 * \param pq the packet queue were this packet go
 *
 * \retval void No return value
 */
void DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                  uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    int error_msg = 0;
    SCPerfCounterIncr(dtv->counter_icmpv6, tv->sc_perf_pca);

    if (len < ICMPV6_HEADER_LEN) {
        SCLogDebug("ICMPV6_PKT_TOO_SMALL");
        ENGINE_SET_EVENT(p, ICMPV6_PKT_TOO_SMALL);
        return;
    }

    p->icmpv6h = (ICMPV6Hdr *)pkt;
    p->proto = IPPROTO_ICMPV6;
    p->type = p->icmpv6h->type;
    p->code = p->icmpv6h->code;
    p->payload_len = len - ICMPV6_HEADER_LEN;
    p->payload = pkt + ICMPV6_HEADER_LEN;

    SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type,
               p->icmpv6h->code);

    switch (ICMPV6_GET_TYPE(p)) {
        case ICMP6_DST_UNREACH:
            SCLogDebug("ICMP6_DST_UNREACH");

            if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                  len - ICMPV6_HEADER_LEN );
            }

            error_msg = 1;
            break;
        case ICMP6_PACKET_TOO_BIG:
            SCLogDebug("ICMP6_PACKET_TOO_BIG");

            if (ICMPV6_GET_CODE(p) != 0) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                p->icmpv6vars.mtu = ICMPV6_GET_MTU(p);
                DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                  len - ICMPV6_HEADER_LEN );
            }

            error_msg = 1;
            break;
        case ICMP6_TIME_EXCEEDED:
            SCLogDebug("ICMP6_TIME_EXCEEDED");

            if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                  len - ICMPV6_HEADER_LEN );
            }

            error_msg = 1;
            break;
        case ICMP6_PARAM_PROB:
            SCLogDebug("ICMP6_PARAM_PROB");

            if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                p->icmpv6vars.error_ptr= ICMPV6_GET_ERROR_PTR(p);
                DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                  len - ICMPV6_HEADER_LEN );
            }

            error_msg = 1;
            break;
        case ICMP6_ECHO_REQUEST:
            SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u",
                       p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);

            if (ICMPV6_GET_CODE(p) != 0) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
                p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
            }

            break;
        case ICMP6_ECHO_REPLY:
            SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u",
                       p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);

            if (p->icmpv6h->code != 0) {
                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
            } else {
                p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
                p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
            }

            break;
        default:
            SCLogDebug("ICMPV6 Message type %" PRIu8 " not "
                       "implemented yet", ICMPV6_GET_TYPE(p));
            ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE);
    }

    /* for a info message the header is just 4 bytes */
    if (!error_msg) {
        if (p->payload_len >= 4) {
            p->payload_len -= 4;
            p->payload = pkt + 4;
        } else {
            p->payload_len = 0;
            p->payload = NULL;
        }
    }

#ifdef DEBUG
    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE))
        SCLogDebug("Unknown Code, ICMPV6_UNKNOWN_CODE");

    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_TYPE))
        SCLogDebug("Unknown Type, ICMPV6_UNKNOWN_TYPE");
#endif

    /* Flow is an integral part of us */
    FlowHandlePacket(tv, p);

    return;
}
Exemple #11
0
/**
 * \brief Convert IP packet to an IDMEF alert (RFC 4765).
 * This function stores the alert SID (description and reference),
 * the payload of the packet, and pre-processed data.
 *
 * \return 0 if ok
 */
static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx)
{
    SCEnter();

    if (unlikely(p == NULL))
        SCReturnInt(0);

    AddIntData(alert, "snort_rule_sid", pa->s->id);
    AddIntData(alert, "snort_rule_rev", pa->s->rev);

    if (ctx->log_packet_header) {
        if ( PKT_IS_IPV4(p) )
            PacketToDataV4(p, pa, alert);

        else if ( PKT_IS_IPV6(p) )
            PacketToDataV6(p, pa, alert);

        if ( PKT_IS_TCP(p) ) {
            AddIntData(alert, "tcp_seq", TCP_GET_SEQ(p));
            AddIntData(alert, "tcp_ack", TCP_GET_ACK(p));

            AddIntData(alert, "tcp_off", TCP_GET_OFFSET(p));
            AddIntData(alert, "tcp_res", TCP_GET_X2(p));
            AddIntData(alert, "tcp_flags", TCP_GET_FLAGS(p));

            AddIntData(alert, "tcp_win", TCP_GET_WINDOW(p));
            AddIntData(alert, "tcp_sum", TCP_GET_SUM(p));
            AddIntData(alert, "tcp_urp", TCP_GET_URG_POINTER(p));
            if (p->tcpvars.ts_val != 0) {
                AddIntData(alert, "tcp_tsval", TCP_GET_TSVAL(p));
            }
            if (p->tcpvars.ts_ecr != 0) {
                AddIntData(alert, "tcp_tsecr", TCP_GET_TSECR(p));
            }
            if (p->tcph != NULL) {
                AddIntData(alert, "tcp_wscale", TCP_GET_WSCALE(p));
            }
            if (TCP_HAS_SACKOK(p)) {
                AddIntData(alert, "tcp_sackok", TCP_GET_SACKOK(p));
            }
            if (TCP_HAS_SACK(p)) {
                AddIntData(alert, "tcp_sack_cnt", TCP_GET_SACK_CNT(p));
            }
            AddIntData(alert, "tcp_hlen", TCP_GET_HLEN(p));
        }

        else if ( PKT_IS_UDP(p) ) {
            AddIntData(alert, "udp_len", UDP_GET_LEN(p));
            AddIntData(alert, "udp_sum", UDP_GET_SUM(p));
        }

        else if ( PKT_IS_ICMPV4(p) ) {
            AddIntData(alert, "icmp_type", ICMPV4_GET_TYPE(p));
            AddIntData(alert, "icmp_code", ICMPV4_GET_CODE(p));
            AddIntData(alert, "icmp_sum", ICMPV4_GET_RAW_CSUM(p));

        }

        else if ( PKT_IS_ICMPV6(p) ) {
            AddIntData(alert, "icmp_type", ICMPV6_GET_TYPE(p));
            AddIntData(alert, "icmp_code", ICMPV6_GET_CODE(p));
            AddIntData(alert, "icmp_csum", ICMPV6_GET_RAW_CSUM(p));
        }
    }

    if (ctx->log_packet_content)
        AddByteData(alert, "payload", p->payload, p->payload_len);

    SCReturnInt(0);
}