Example #1
0
/**
 * \brief Checks if the packet sent as the argument, has a valid or invalid
 *        icmpv6 checksum, based on whether icmpv6-csum option for this rule
 *        has been supplied with "valid" or "invalid" argument
 *
 * \param t       Pointer to the tv for this detection module instance
 * \param det_ctx Pointer to the detection engine thread context
 * \param p       Pointer to the Packet currently being matched
 * \param s       Pointer to the Signature, the packet is being currently
 *                matched with
 * \param m       Pointer to the keyword_structure(SigMatch) from the above
 *                Signature, the Packet is being currently matched with
 *
 * \retval 1 if the Packet contents match the keyword option; 0 otherwise
 */
static int DetectICMPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
        Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
    const DetectCsumData *cd = (const DetectCsumData *)ctx;

    if (p->ip6h == NULL || p->icmpv6h == NULL || p->proto != IPPROTO_ICMPV6 || PKT_IS_PSEUDOPKT(p) ||
        (GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))) <= 0) {
        return 0;
    }

    if (p->flags & PKT_IGNORE_CHECKSUM) {
        return cd->valid;
    }

    if (p->level4_comp_csum == -1) {
        uint16_t len = IPV6_GET_RAW_PLEN(p->ip6h) -
            ((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN);
        p->level4_comp_csum = ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs,
                                                      (uint16_t *)p->icmpv6h,
                                                      len);
    }

    if (p->level4_comp_csum == p->icmpv6h->csum && cd->valid == 1)
        return 1;
    else if (p->level4_comp_csum != p->icmpv6h->csum && cd->valid == 0)
        return 1;
    else
        return 0;
}
Example #2
0
/**
 * \brief This function is used to match TTL rule option on a packet with those passed via ttl:
 *
 * \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 DetectTtlData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {

    int ret = 0;
    uint8_t pttl;
    DetectTtlData *ttld = (DetectTtlData *) m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_IPV4(p)) {
        pttl = IPV4_GET_IPTTL(p);
    } else if (PKT_IS_IPV6(p)) {
        pttl = IPV6_GET_HLIM(p);
    } else {
        SCLogDebug("Packet is of not IPv4 or IPv6");
        return ret;
    }

    if (ttld->mode == DETECT_TTL_EQ && pttl == ttld->ttl1)
        ret = 1;
    else if (ttld->mode == DETECT_TTL_LT && pttl < ttld->ttl1)
        ret = 1;
    else if (ttld->mode == DETECT_TTL_GT && pttl > ttld->ttl1)
        ret = 1;
    else if (ttld->mode == DETECT_TTL_RA && (pttl > ttld->ttl1 && pttl < ttld->ttl2))
        ret = 1;

    return ret;
}
/**
 * \brief This function is used to match fragoffset 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 DetectFragOffsetData
 *
 * \retval 0 no match or frag is not set
 * \retval 1 match
 *
 */
int DetectFragOffsetMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx)
{
    uint16_t frag = 0;
    const DetectFragOffsetData *fragoff = (const DetectFragOffsetData *)ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_IPV4(p)) {
        frag = IPV4_GET_IPOFFSET(p);
    } else if (PKT_IS_IPV6(p)) {
        if(IPV6_EXTHDR_FH(p)) {
            frag = IPV6_EXTHDR_GET_FH_OFFSET(p);
        } else {
            return 0;
        }
    } else {
        SCLogDebug("No IPv4 or IPv6 packet");
        return 0;
    }

    switch (fragoff->mode)  {
        case FRAG_LESS:
            if (frag < fragoff->frag_off) return 1;
            break;
        case FRAG_MORE:
            if (frag > fragoff->frag_off) return 1;
            break;
        default:
            if (frag == fragoff->frag_off) return 1;
    }

    return 0;
}
Example #4
0
/**
 * \brief Checks if the packet sent as the argument, has a valid or invalid
 *        udpv6 checksum, based on whether udpv6-csum option for this rule
 *        has been supplied with "valid" or "invalid" argument
 *
 * \param t       Pointer to the tv for this detection module instance
 * \param det_ctx Pointer to the detection engine thread context
 * \param p       Pointer to the Packet currently being matched
 * \param s       Pointer to the Signature, the packet is being currently
 *                matched with
 * \param m       Pointer to the keyword_structure(SigMatch) from the above
 *                Signature, the Packet is being currently matched with
 *
 * \retval 1 if the Packet contents match the keyword option; 0 otherwise
 */
static int DetectUDPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
        Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
    const DetectCsumData *cd = (const DetectCsumData *)ctx;

    if (p->ip6h == NULL || p->udph == NULL || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p))
        return 0;

    if (p->flags & PKT_IGNORE_CHECKSUM) {
        return cd->valid;
    }

    if (p->level4_comp_csum == -1)
        p->level4_comp_csum = UDPV6Checksum(p->ip6h->s_ip6_addrs,
                                            (uint16_t *)p->udph,
                                            (p->payload_len +
                                                UDP_HEADER_LEN),
                                            p->udph->uh_sum);

    if (p->level4_comp_csum == 0 && cd->valid == 1)
        return 1;
    else if (p->level4_comp_csum != 0 && cd->valid == 0)
        return 1;
    else
        return 0;
}
Example #5
0
/**
 * \brief Checks if the packet sent as the argument, has a valid or invalid
 *        tcpv4 checksum, based on whether tcpv4-csum option for this rule
 *        has been supplied with "valid" or "invalid" argument
 *
 * \param t       Pointer to the tv for this detection module instance
 * \param det_ctx Pointer to the detection engine thread context
 * \param p       Pointer to the Packet currently being matched
 * \param s       Pointer to the Signature, the packet is being currently
 *                matched with
 * \param m       Pointer to the keyword_structure(SigMatch) from the above
 *                Signature, the Packet is being currently matched with
 *
 * \retval 1 if the Packet contents match the keyword option; 0 otherwise
 */
static int DetectTCPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
        Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
    const DetectCsumData *cd = (const DetectCsumData *)ctx;

    if (p->ip4h == NULL || p->tcph == NULL || p->proto != IPPROTO_TCP || PKT_IS_PSEUDOPKT(p))
        return 0;

    if (p->flags & PKT_IGNORE_CHECKSUM) {
        return cd->valid;
    }

    if (p->level4_comp_csum == -1)
        p->level4_comp_csum = TCPChecksum(p->ip4h->s_ip_addrs,
                                          (uint16_t *)p->tcph,
                                          (p->payload_len +
                                              TCP_GET_HLEN(p)),
                                          p->tcph->th_sum);

    if (p->level4_comp_csum == 0 && cd->valid == 1)
        return 1;
    else if (p->level4_comp_csum != 0 && cd->valid == 0)
        return 1;
    else
        return 0;
}
Example #6
0
/**
 * \brief This function is used to match TEMPLATE rule option 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 with context that we will cast into DetectTemplateData
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectTemplateMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
                                Signature *s, const SigMatchCtx *ctx)
{
    int ret = 0;
    const DetectTemplateData *templated = (const DetectTemplateData *) ctx;
#if 0
    if (PKT_IS_PSEUDOPKT(p)) {
        /* fake pkt */
    }

    if (PKT_IS_IPV4(p)) {
        /* ipv4 pkt */
    } else if (PKT_IS_IPV6(p)) {
        /* ipv6 pkt */
    } else {
        SCLogDebug("packet is of not IPv4 or IPv6");
        return ret;
    }
#endif
    /* packet payload access */
    if (p->payload != NULL && p->payload_len > 0) {
        if (templated->arg1 == p->payload[0] &&
            templated->arg2 == p->payload[p->payload_len - 1])
        {
            ret = 1;
        }
    }

    return ret;
}
Example #7
0
static void
PrefilterPacketTtlMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
{
    if (PKT_IS_PSEUDOPKT(p)) {
        SCReturn;
    }

    uint8_t pttl;
    if (PKT_IS_IPV4(p)) {
        pttl = IPV4_GET_IPTTL(p);
    } else if (PKT_IS_IPV6(p)) {
        pttl = IPV6_GET_HLIM(p);
    } else {
        SCLogDebug("Packet is of not IPv4 or IPv6");
        return;
    }

    const PrefilterPacketHeaderCtx *ctx = pectx;
    if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
        return;

    if (TtlMatch(pttl, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
    {
        SCLogDebug("packet matches ttl/hl %u", pttl);
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
    }
}
Example #8
0
/**
 * \brief This function is used to match icode rule option set on a packet with those passed via icode:
 *
 * \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 DetectICodeData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectICodeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {
    int ret = 0;
    uint8_t picode;
    DetectICodeData *icd = (DetectICodeData *)m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_ICMPV4(p)) {
        picode = ICMPV4_GET_CODE(p);
    } else if (PKT_IS_ICMPV6(p)) {
        picode = ICMPV6_GET_CODE(p);
    } else {
        /* Packet not ICMPv4 nor ICMPv6 */
        return ret;
    }

    switch(icd->mode) {
        case DETECT_ICODE_EQ:
            ret = (picode == icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_LT:
            ret = (picode < icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_GT:
            ret = (picode > icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_RN:
            ret = (picode >= icd->code1 && picode <= icd->code2) ? 1 : 0;
            break;
    }

    return ret;
}
Example #9
0
/**
 * \brief Check if we need to drop-log this packet
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is tested
 *
 * \retval bool TRUE or FALSE
 */
static int LogDropCondition(ThreadVars *tv, const Packet *p)
{
    if (!EngineModeIsIPS()) {
        SCLogDebug("engine is not running in inline mode, so returning");
        return FALSE;
    }
    if (PKT_IS_PSEUDOPKT(p)) {
        SCLogDebug("drop log doesn't log pseudo packets");
        return FALSE;
    }

    if (p->flow != NULL) {
        int ret = FALSE;
        FLOWLOCK_RDLOCK(p->flow);
        if (p->flow->flags & FLOW_ACTION_DROP) {
            if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED))
                ret = TRUE;
            else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED))
                ret = TRUE;
        }
        FLOWLOCK_UNLOCK(p->flow);
        return ret;
    } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
        return TRUE;
    }

    return FALSE;
}
Example #10
0
/**
 * \brief Decode a packet coming from NFQ
 */
TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{

    IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    /* XXX HACK: flow timeout can call us for injected pseudo packets
     *           see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
    if (PKT_IS_PSEUDOPKT(p))
        return TM_ECODE_OK;

    DecodeUpdatePacketCounters(tv, dtv, p);

    if (IPV4_GET_RAW_VER(ip4h) == 4) {
        SCLogDebug("IPv4 packet");
        DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
    } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
        SCLogDebug("IPv6 packet");
        DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
    } else {
        SCLogDebug("packet unsupported by NFQ, first byte: %02x", *GET_PKT_DATA(p));
    }

    PacketDecodeFinalize(tv, dtv, p);

    return TM_ECODE_OK;
}
Example #11
0
static void
PrefilterPacketFragOffsetMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
{
    if (PKT_IS_PSEUDOPKT(p))
        return;

    uint16_t frag;

    if (PKT_IS_IPV4(p)) {
        frag = IPV4_GET_IPOFFSET(p);
    } else if (PKT_IS_IPV6(p)) {
        if (IPV6_EXTHDR_ISSET_FH(p)) {
            frag = IPV6_EXTHDR_GET_FH_OFFSET(p);
        } else {
            return;
        }
    } else {
        SCLogDebug("No IPv4 or IPv6 packet");
        return;
    }

    const PrefilterPacketHeaderCtx *ctx = pectx;
    if (FragOffsetMatch(frag, ctx->v1.u8[0], ctx->v1.u16[1]))
    {
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
    }
}
Example #12
0
/**
 * \brief Check if we need to drop-log this packet
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is tested
 *
 * \retval bool TRUE or FALSE
 */
static int JsonDropLogCondition(ThreadVars *tv, const Packet *p)
{
    if (!EngineModeIsIPS()) {
        SCLogDebug("engine is not running in inline mode, so returning");
        return FALSE;
    }
    if (PKT_IS_PSEUDOPKT(p)) {
        SCLogDebug("drop log doesn't log pseudo packets");
        return FALSE;
    }

    if (g_droplog_flows_start && p->flow != NULL) {
        int ret = FALSE;

        /* for a flow that will be dropped fully, log just once per direction */
        if (p->flow->flags & FLOW_ACTION_DROP) {
            if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED))
                ret = TRUE;
            else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED))
                ret = TRUE;
        }

        /* if drop is caused by signature, log anyway */
        if (p->alerts.drop.action != 0)
            ret = TRUE;

        return ret;
    } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
        return TRUE;
    }

    return FALSE;
}
Example #13
0
/**
 * \internal
 * \brief This function is used to match packets with a given Ack number
 *
 * \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 DetectAckData
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectAckMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                          Packet *p, Signature *s, const SigMatchCtx *ctx)
{
    const DetectAckData *data = (const DetectAckData *)ctx;

    /* This is only needed on TCP packets */
    if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
        return 0;
    }

    return (data->ack == TCP_GET_ACK(p)) ? 1 : 0;
}
Example #14
0
/**
 * \internal
 * \brief This function is used to match packets with a given Seq number
 *
 * \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 DetectSeqData
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectSeqMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                          Packet *p, Signature *s, SigMatch *m)
{
    DetectSeqData *data = (DetectSeqData *)m->ctx;

    /* This is only needed on TCP packets */
    if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
        return 0;
    }

    return (data->seq == TCP_GET_SEQ(p)) ? 1 : 0;
}
Example #15
0
/**
 * \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;
}
Example #16
0
/**
 * \internal
 * \brief This function is used to match flags on a packet with those passed via flags:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param s pointer to the Signature
 * \param m pointer to the sigmatch
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
        const Signature *s, const SigMatchCtx *ctx)
{
    SCEnter();

    if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
        SCReturnInt(0);
    }

    const DetectFlagsData *de = (const DetectFlagsData *)ctx;
    const uint8_t flags = p->tcph->th_flags;

    return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags);
}
Example #17
0
static void
PrefilterPacketAckMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
{
    const PrefilterPacketHeaderCtx *ctx = pectx;

    if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
        return;

    if ((p->proto) == IPPROTO_TCP && !(PKT_IS_PSEUDOPKT(p)) &&
        (p->tcph != NULL) && (TCP_GET_ACK(p) == ctx->v1.u32[0]))
    {
        SCLogDebug("packet matches TCP ack %u", ctx->v1.u32[0]);
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
    }
}
Example #18
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;
}
Example #19
0
/**
 * \internal
 * \brief This function is used to match flags on a packet with those passed via dsize:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param s pointer to the Signature
 * \param m pointer to the sigmatch
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectDsizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx)
{
    SCEnter();
    int ret = 0;

    if (PKT_IS_PSEUDOPKT(p)) {
        SCReturnInt(0);
    }

    const DetectDsizeData *dd = (const DetectDsizeData *)ctx;

    SCLogDebug("p->payload_len %"PRIu16"", p->payload_len);

    ret = DsizeMatch(p->payload_len, dd->mode, dd->dsize, dd->dsize2);

    SCReturnInt(ret);
}
Example #20
0
/**
 * \brief Match function for tos keyword.
 *
 * \param tv ThreadVars instance.
 * \param det_ctx Pointer to the detection thread ctx.
 * \param p Pointer to the packet.
 * \param m Pointer to the SigMatch containing the tos data.
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectTosMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p,
                   const Signature *s, const SigMatchCtx *ctx)
{
    const DetectTosData *tosd = (const DetectTosData *)ctx;
    int result = 0;

    if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p)) {
        return 0;
    }

    if (tosd->tos == IPV4_GET_IPTOS(p)) {
        SCLogDebug("tos match found for %d\n", tosd->tos);
        result = 1;
    }

    return (tosd->negated ^ result);
}
Example #21
0
int DetectPayloadLenFieldMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                        Packet *p, Signature *s, SigMatch *m) {
	DetectPayloadLenFieldData *ed = m->ctx;

	if (p->ip4h == NULL || PKT_IS_PSEUDOPKT(p) || p->payload_len == 0 || p->payload_len < ed->len + ed->offset)
		return 0;

	uint32_t read_len = 0;

	// This works just for little endian systems and streams
	memcpy(((char*)&read_len), p->payload + ed->offset, ed->len);

	//printf("Found len: %d\n", read_len);


	return read_len == p->payload_len;
}
Example #22
0
static void
PrefilterPacketDsizeMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
{
    if (PKT_IS_PSEUDOPKT(p)) {
        SCReturn;
    }

    const PrefilterPacketHeaderCtx *ctx = pectx;
    if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
        return;

    const uint16_t dsize = p->payload_len;
    if (DsizeMatch(dsize, ctx->v1.u8[0], ctx->v1.u16[1], ctx->v1.u16[2]))
    {
        SCLogDebug("packet matches dsize %u", dsize);
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
    }
}
Example #23
0
static void
PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
{
    if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
        SCReturn;
    }

    const PrefilterPacketHeaderCtx *ctx = pectx;
    if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
        return;

    const uint8_t flags = p->tcph->th_flags;
    if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
    {
        SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]);
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
    }
}
Example #24
0
/**
 * \brief This function is used to match TTL rule option on a packet with those passed via ttl:
 *
 * \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 DetectTtlData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx)
{

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    uint8_t pttl;
    if (PKT_IS_IPV4(p)) {
        pttl = IPV4_GET_IPTTL(p);
    } else if (PKT_IS_IPV6(p)) {
        pttl = IPV6_GET_HLIM(p);
    } else {
        SCLogDebug("Packet is of not IPv4 or IPv6");
        return 0;
    }

    const DetectTtlData *ttld = (const DetectTtlData *)ctx;
    return TtlMatch(pttl, ttld->mode, ttld->ttl1, ttld->ttl2);
}
Example #25
0
/**
 * \brief This function is used to match the specified id 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 DetectIdData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectIdMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
                        Signature *s, SigMatch *m)
{
    DetectIdData *id_d = (DetectIdData *)m->ctx;

    /**
     * To match a ipv4 packet with a "id" rule
     */
    if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p)) {
        return 0;
    }

    if (id_d->id == IPV4_GET_IPID(p)) {
        SCLogDebug("IPV4 Proto and matched with ip_id: %u.\n",
                    id_d->id);
        return 1;
    }

    return 0;
}
Example #26
0
/**
 * \internal
 * \brief This function is used to match packets with a IPs in an specified country
 *
 * \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 DetectGeoipData
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectGeoipMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                             Packet *p, Signature *s, SigMatch *m)
{
    DetectGeoipData *geoipdata = (DetectGeoipData *)m->ctx;
    int matches = 0;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_IPV4(p))
    {
        if (geoipdata->flags & ( GEOIP_MATCH_SRC_FLAG | GEOIP_MATCH_BOTH_FLAG ))
        {
            if (CheckGeoMatchIPv4(geoipdata, GET_IPV4_SRC_ADDR_U32(p)))
            {
                if (geoipdata->flags & GEOIP_MATCH_BOTH_FLAG)
                    matches++;
                else
                    return 1;
            }
        }
        if (geoipdata->flags & ( GEOIP_MATCH_DST_FLAG | GEOIP_MATCH_BOTH_FLAG ))
        {
            if (CheckGeoMatchIPv4(geoipdata, GET_IPV4_DST_ADDR_U32(p)))
            {
                if (geoipdata->flags & GEOIP_MATCH_BOTH_FLAG)
                    matches++;
                else
                    return 1;
            }
        }
        /* if matches == 2 is because match-on is "both" */
        if (matches == 2)
            return 1;
    }

    return 0;
}
Example #27
0
/**
 * \brief This function is used to match fragoffset 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 DetectFragOffsetData
 *
 * \retval 0 no match or frag is not set
 * \retval 1 match
 *
 */
int DetectFragOffsetMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx)
{
    uint16_t frag = 0;
    const DetectFragOffsetData *fragoff = (const DetectFragOffsetData *)ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_IPV4(p)) {
        frag = IPV4_GET_IPOFFSET(p);
    } else if (PKT_IS_IPV6(p)) {
        if (IPV6_EXTHDR_ISSET_FH(p)) {
            frag = IPV6_EXTHDR_GET_FH_OFFSET(p);
        } else {
            return 0;
        }
    } else {
        SCLogDebug("No IPv4 or IPv6 packet");
        return 0;
    }

    return FragOffsetMatch(frag, fragoff->mode, fragoff->frag_off);;
}
Example #28
0
/**
 * \internal
 * \brief This function is used to match fragbits on a packet with those passed via fragbits:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param s pointer to the Signature
 * \param m pointer to the sigmatch
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectFragBitsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    int ret = 0;
    uint16_t fragbits = 0;
    DetectFragBitsData *de = (DetectFragBitsData *)m->ctx;

    if (!de || !PKT_IS_IPV4(p) || !p || PKT_IS_PSEUDOPKT(p))
        return ret;

    if(IPV4_GET_MF(p))
        fragbits |= FRAGBITS_HAVE_MF;
    if(IPV4_GET_DF(p))
        fragbits |= FRAGBITS_HAVE_DF;
    if(IPV4_GET_RF(p))
        fragbits |= FRAGBITS_HAVE_RF;

    switch(de->modifier)    {
    case MODIFIER_ANY:
        if((fragbits & de->fragbits) > 0)
            return 1;
        return ret;
    case MODIFIER_PLUS:
        if(((fragbits & de->fragbits) == de->fragbits) && (((fragbits - de->fragbits) > 0)))
            return 1;
        return ret;
    case MODIFIER_NOT:
        if((fragbits & de->fragbits) != de->fragbits)
            return 1;
        return ret;
    default:
        if(fragbits == de->fragbits)
            return 1;
    }

    return ret;
}
Example #29
0
/**
 * \brief Checks if the packet sent as the argument, has a valid or invalid
 *        icmpv4 checksum, based on whether icmpv4-csum option for this rule
 *        has been supplied with "valid" or "invalid" argument
 *
 * \param t       Pointer to the tv for this detection module instance
 * \param det_ctx Pointer to the detection engine thread context
 * \param p       Pointer to the Packet currently being matched
 * \param s       Pointer to the Signature, the packet is being currently
 *                matched with
 * \param m       Pointer to the keyword_structure(SigMatch) from the above
 *                Signature, the Packet is being currently matched with
 *
 * \retval 1 if the Packet contents match the keyword option; 0 otherwise
 */
static int DetectICMPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
        Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
    const DetectCsumData *cd = (const DetectCsumData *)ctx;

    if (p->ip4h == NULL || p->icmpv4h == NULL || p->proto != IPPROTO_ICMP || PKT_IS_PSEUDOPKT(p))
        return 0;

    if (p->flags & PKT_IGNORE_CHECKSUM) {
        return cd->valid;
    }

    if (p->level4_comp_csum == -1)
        p->level4_comp_csum = ICMPV4CalculateChecksum((uint16_t *)p->icmpv4h,
                                                      ntohs(IPV4_GET_RAW_IPLEN(p->ip4h)) -
                                                      IPV4_GET_RAW_HLEN(p->ip4h) * 4);

    if (p->level4_comp_csum == p->icmpv4h->checksum && cd->valid == 1)
        return 1;
    else if (p->level4_comp_csum != p->icmpv4h->checksum && cd->valid == 0)
        return 1;
    else
        return 0;
}
Example #30
0
/**
 * \internal
 * \brief This function is used to match flags on a packet with those passed via dsize:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param s pointer to the Signature
 * \param m pointer to the sigmatch
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectDsizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    SCEnter();
    int ret = 0;

    if (PKT_IS_PSEUDOPKT(p)) {
        SCReturnInt(0);
    }

    DetectDsizeData *dd = (DetectDsizeData *)m->ctx;

    SCLogDebug("p->payload_len %"PRIu16"", p->payload_len);

    if (dd->mode == DETECTDSIZE_EQ && dd->dsize == p->payload_len)
        ret = 1;
    else if (dd->mode == DETECTDSIZE_LT && p->payload_len < dd->dsize)
        ret = 1;
    else if (dd->mode == DETECTDSIZE_GT && p->payload_len > dd->dsize)
        ret = 1;
    else if (dd->mode == DETECTDSIZE_RA && p->payload_len > dd->dsize && p->payload_len < dd->dsize2)
        ret = 1;

    SCReturnInt(ret);
}