示例#1
0
/* get the bit with idx from the host */
static XBit *HostBitGet(Host *h, uint16_t idx)
{
    GenericVar *gv = HostGetStorageById(h, host_bit_id);
    for ( ; gv != NULL; gv = gv->next) {
        if (gv->type == DETECT_XBITS && gv->idx == idx) {
            return (XBit *)gv;
        }
    }

    return NULL;
}
static DetectThresholdEntry *ThresholdHostLookupEntry(Host *h, uint32_t sid, uint32_t gid)
{
    DetectThresholdEntry *e;

    for (e = HostGetStorageById(h, threshold_id); e != NULL; e = e->next) {
        if (e->sid == sid && e->gid == gid)
            break;
    }

    return e;
}
示例#3
0
/** \retval 1 host timed out wrt xbits
  * \retval 0 host still has active (non-expired) xbits */
int HostBitsTimedoutCheck(Host *h, struct timeval *ts)
{
    GenericVar *gv = HostGetStorageById(h, host_bit_id);
    for ( ; gv != NULL; gv = gv->next) {
        if (gv->type == DETECT_XBITS) {
            XBit *xb = (XBit *)gv;
            if (xb->expire > (uint32_t)ts->tv_sec)
                return 0;
        }
    }
    return 1;
}
示例#4
0
static void HostBitRemove(Host *h, uint16_t idx)
{
    XBit *fb = HostBitGet(h, idx);
    if (fb == NULL)
        return;

    GenericVar *gv = HostGetStorageById(h, host_bit_id);
    if (gv) {
        GenericVarRemove(&gv, (GenericVar *)fb);
        HostSetStorageById(h, host_bit_id, gv);
    }
}
示例#5
0
/**
 * \brief Removes the entries exceding the max timeout value
 *
 * \param tag_ctx Tag context
 * \param ts the current time
 *
 * \retval 1 no tags or tags removed -- host is free to go (from tag perspective)
 * \retval 0 still active tags
 */
int TagTimeoutCheck(Host *host, struct timeval *tv)
{
    DetectTagDataEntry *tde = NULL;
    DetectTagDataEntry *tmp = NULL;
    DetectTagDataEntry *prev = NULL;
    int retval = 1;

    tmp = HostGetStorageById(host, host_tag_id);
    if (tmp == NULL)
        return 1;

    prev = NULL;
    while (tmp != NULL) {
        if ((tv->tv_sec - tmp->last_ts) <= TAG_MAX_LAST_TIME_SEEN) {
            prev = tmp;
            tmp = tmp->next;
            retval = 0;
            continue;
        }

        /* timed out */

        if (prev != NULL) {
            prev->next = tmp->next;

            tde = tmp;
            tmp = tde->next;

            SCFree(tde);
            (void) SC_ATOMIC_SUB(num_tags, 1);
        } else {
            HostSetStorageById(host, host_tag_id, tmp->next);

            tde = tmp;
            tmp = tde->next;

            SCFree(tde);
            (void) SC_ATOMIC_SUB(num_tags, 1);
        }
    }
    return retval;
}
int ThresholdTimeoutCheck(Host *host, struct timeval *tv)
{
    DetectThresholdEntry *tde = NULL;
    DetectThresholdEntry *tmp = NULL;
    DetectThresholdEntry *prev = NULL;
    int retval = 1;

    tmp = HostGetStorageById(host, threshold_id);
    if (tmp == NULL)
         return 1;

    prev = NULL;
    while (tmp != NULL) {
        if ((tv->tv_sec - tmp->tv_sec1) <= tmp->seconds) {
            prev = tmp;
            tmp = tmp->next;
            retval = 0;
            continue;
        }

        /* timed out */

        if (prev != NULL) {
            prev->next = tmp->next;

            tde = tmp;
            tmp = tde->next;

            SCFree(tde);
        } else {
            HostSetStorageById(host, threshold_id, tmp->next);
            tde = tmp;
            tmp = tde->next;

            SCFree(tde);
        }
    }

    return retval;
}
示例#7
0
/* add a flowbit to the flow */
static void HostBitAdd(Host *h, uint16_t idx, uint32_t expire)
{
    XBit *fb = HostBitGet(h, idx);
    if (fb == NULL) {
        fb = SCMalloc(sizeof(XBit));
        if (unlikely(fb == NULL))
            return;

        fb->type = DETECT_XBITS;
        fb->idx = idx;
        fb->next = NULL;
        fb->expire = expire;

        GenericVar *gv = HostGetStorageById(h, host_bit_id);
        GenericVarAppend(&gv, (GenericVar *)fb);
        HostSetStorageById(h, host_bit_id, gv);

    // bit already set, lets update it's time
    } else {
        fb->expire = expire;
    }
}
示例#8
0
/* lock before using this */
int HostHasHostBits(Host *host)
{
    if (host == NULL)
        return 0;
    return HostGetStorageById(host, host_bit_id) ? 1 : 0;
}
示例#9
0
int TagHostHasTag(Host *host)
{
    return HostGetStorageById(host, host_tag_id) ? 1 : 0;
}
示例#10
0
void TagHandlePacketHost(Host *host, Packet *p)
{
    DetectTagDataEntry *tde = NULL;
    DetectTagDataEntry *prev = NULL;
    DetectTagDataEntry *iter;
    uint8_t flag_added = 0;

    iter = HostGetStorageById(host, host_tag_id);
    prev = NULL;
    while (iter != NULL) {
        /* update counters */
        iter->last_ts = p->ts.tv_sec;
        switch (iter->metric) {
            case DETECT_TAG_METRIC_PACKET:
                iter->packets++;
                break;
            case DETECT_TAG_METRIC_BYTES:
                iter->bytes += GET_PKT_LEN(p);
                break;
        }

        /* If this packet triggered the rule with tag, we dont need
         * to log it (the alert will log it) */
        if (!(iter->flags & TAG_ENTRY_FLAG_SKIPPED_FIRST)) {
            iter->flags |= TAG_ENTRY_FLAG_SKIPPED_FIRST;
        } else {
            /* Update metrics; remove if tag expired; and set alerts */
            switch (iter->metric) {
                case DETECT_TAG_METRIC_PACKET:
                    if (iter->packets > iter->count) {
                        /* tag expired */
                        if (prev != NULL) {
                            tde = iter;
                            prev->next = iter->next;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            continue;
                        } else {
                            tde = iter;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            HostSetStorageById(host, host_tag_id, iter);
                            continue;
                        }
                    } else if (flag_added == 0) {
                        /* It's matching the tag. Add it to be logged and
                         * update "flag_added" to add the packet once. */
                        p->flags |= PKT_HAS_TAG;
                        flag_added++;
                    }
                    break;
                case DETECT_TAG_METRIC_BYTES:
                    if (iter->bytes > iter->count) {
                        /* tag expired */
                        if (prev != NULL) {
                            tde = iter;
                            prev->next = iter->next;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            continue;
                        } else {
                            tde = iter;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            HostSetStorageById(host, host_tag_id, iter);
                            continue;
                        }
                    } else if (flag_added == 0) {
                        /* It's matching the tag. Add it to be logged and
                         * update "flag_added" to add the packet once. */
                        p->flags |= PKT_HAS_TAG;
                        flag_added++;
                    }
                    break;
                case DETECT_TAG_METRIC_SECONDS:
                    /* last_ts handles this metric, but also a generic time based
                     * expiration to prevent dead sessions/hosts */
                    if (iter->last_ts - iter->first_ts > iter->count) {
                        /* tag expired */
                        if (prev != NULL) {
                            tde = iter;
                            prev->next = iter->next;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            continue;
                        } else {
                            tde = iter;
                            iter = iter->next;
                            SCFree(tde);
                            (void) SC_ATOMIC_SUB(num_tags, 1);
                            HostSetStorageById(host, host_tag_id, iter);
                            continue;
                        }
                    } else if (flag_added == 0) {
                        /* It's matching the tag. Add it to be logged and
                         * update "flag_added" to add the packet once. */
                        p->flags |= PKT_HAS_TAG;
                        flag_added++;
                    }
                    break;
            }

        }

        prev = iter;
        iter = iter->next;
    }
}
示例#11
0
/**
 * \brief Add a tag entry for a host. If it already exist, update it.
 *
 * \param tag_ctx Tag context for hosts
 * \param tde Tag data
 * \param p packet
 *
 * \retval 0 if it was added, 1 if it was updated
 */
int TagHashAddTag(DetectTagDataEntry *tde, Packet *p)
{
    SCEnter();

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

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

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

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

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

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

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

    HostRelease(host);
    SCReturnInt(updated);
}
示例#12
0
int ThresholdHostHasThreshold(Host *host)
{
    return HostGetStorageById(host, threshold_id) ? 1 : 0;
}
示例#13
0
/**
 *  \retval 2 silent match (no alert but apply actions)
 *  \retval 1 normal match
 *  \retval 0 no match
 */
int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdData *td,
        uint32_t sid, uint32_t gid, PacketAlert *pa)
{
    int ret = 0;

    DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid);
    SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);

    switch(td->type)   {
        case TYPE_LIMIT:
        {
            SCLogDebug("limit");

            if (lookup_tsh != NULL)  {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    lookup_tsh->current_count++;

                    if (lookup_tsh->current_count <= td->count) {
                        ret = 1;
                    } else {
                        ret = 2;
                    }
                } else    {
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;

                    ret = 1;
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->tv_sec1 = p->ts.tv_sec;
                e->current_count = 1;

                ret = 1;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        case TYPE_THRESHOLD:
        {
            SCLogDebug("threshold");

            if (lookup_tsh != NULL)  {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    lookup_tsh->current_count++;

                    if (lookup_tsh->current_count >= td->count) {
                        ret = 1;
                        lookup_tsh->current_count = 0;
                    }
                } else {
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;
                }
            } else {
                if (td->count == 1)  {
                    ret = 1;
                } else {
                    DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                    if (e == NULL) {
                        break;
                    }

                    e->current_count = 1;
                    e->tv_sec1 = p->ts.tv_sec;

                    e->next = HostGetStorageById(h, threshold_id);
                    HostSetStorageById(h, threshold_id, e);
                }
            }
            break;
        }
        case TYPE_BOTH:
        {
            SCLogDebug("both");

            if (lookup_tsh != NULL) {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    /* within time limit */

                    lookup_tsh->current_count++;
                    if (lookup_tsh->current_count == td->count) {
                        ret = 1;
                    } else if (lookup_tsh->current_count > td->count) {
                        /* silent match */
                        ret = 2;
                    }
                } else {
                    /* expired, so reset */
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;

                    /* if we have a limit of 1, this is a match */
                    if (lookup_tsh->current_count == td->count) {
                        ret = 1;
                    }
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);

                /* for the first match we return 1 to
                 * indicate we should alert */
                if (td->count == 1)  {
                    ret = 1;
                }
            }
            break;
        }
        /* detection_filter */
        case TYPE_DETECTION:
        {
            SCLogDebug("detection_filter");

            if (lookup_tsh != NULL) {
                long double time_diff = ((p->ts.tv_sec + p->ts.tv_usec/1000000.0) -
                                         (lookup_tsh->tv_sec1 + lookup_tsh->tv_usec1/1000000.0));

                if (time_diff < td->seconds) {
                    /* within timeout */

                    lookup_tsh->current_count++;
                    if (lookup_tsh->current_count > td->count) {
                        ret = 1;
                    }
                } else {
                    /* expired, reset */

                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->tv_usec1 = p->ts.tv_usec;
                    lookup_tsh->current_count = 1;
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;
                e->tv_usec1 = p->ts.tv_usec;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        /* rate_filter */
        case TYPE_RATE:
        {
            SCLogDebug("rate_filter");

            ret = 1;

            if (lookup_tsh != NULL) {
                /* Check if we have a timeout enabled, if so,
                 * we still matching (and enabling the new_action) */
                if (lookup_tsh->tv_timeout != 0) {
                    if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) {
                        /* Ok, we are done, timeout reached */
                        lookup_tsh->tv_timeout = 0;
                    } else {
                        /* Already matching */
                        /* Take the action to perform */
                        RateFilterSetAction(p, pa, td->new_action);
                        ret = 1;
                    } /* else - if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) */

                } else {
                    /* Update the matching state with the timeout interval */
                    if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                        lookup_tsh->current_count++;
                        if (lookup_tsh->current_count > td->count) {
                            /* Then we must enable the new action by setting a
                             * timeout */
                            lookup_tsh->tv_timeout = p->ts.tv_sec;
                            /* Take the action to perform */
                            RateFilterSetAction(p, pa, td->new_action);
                            ret = 1;
                        }
                    } else {
                        lookup_tsh->tv_sec1 = p->ts.tv_sec;
                        lookup_tsh->current_count = 1;
                    }
                } /* else - if (lookup_tsh->tv_timeout != 0) */
            } else {
                if (td->count == 1) {
                    ret = 1;
                }

                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;
                e->tv_timeout = 0;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        /* case TYPE_SUPPRESS: is not handled here */
        default:
            SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
    }

    return ret;
}
/**
 *  \retval 2 silent match (no alert but apply actions)
 *  \retval 1 normal match
 *  \retval 0 no match
 */
int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint32_t sid, uint32_t gid) {
    int ret = 0;

    DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid);
    SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);

    switch(td->type)   {
        case TYPE_LIMIT:
        {
            SCLogDebug("limit");

            if (lookup_tsh != NULL)  {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    lookup_tsh->current_count++;

                    if (lookup_tsh->current_count <= td->count) {
                        ret = 1;
                    } else {
                        ret = 2;
                    }
                } else    {
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;

                    ret = 1;
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->tv_sec1 = p->ts.tv_sec;
                e->current_count = 1;

                ret = 1;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        case TYPE_THRESHOLD:
        {
            SCLogDebug("threshold");

            if (lookup_tsh != NULL)  {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    lookup_tsh->current_count++;

                    if (lookup_tsh->current_count >= td->count) {
                        ret = 1;
                        lookup_tsh->current_count = 0;
                    }
                } else {
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;
                }
            } else {
                if (td->count == 1)  {
                    ret = 1;
                } else {
                    DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                    if (e == NULL) {
                        break;
                    }

                    e->current_count = 1;
                    e->tv_sec1 = p->ts.tv_sec;

                    e->next = HostGetStorageById(h, threshold_id);
                    HostSetStorageById(h, threshold_id, e);
                }
            }
            break;
        }
        case TYPE_BOTH:
        {
            SCLogDebug("both");

            if (lookup_tsh != NULL) {
                if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                    /* within time limit */

                    lookup_tsh->current_count++;
                    if (lookup_tsh->current_count == td->count) {
                        ret = 1;
                    } else if (lookup_tsh->current_count > td->count) {
                        /* silent match */
                        ret = 2;
                    }
                } else {
                    /* expired, so reset */
                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->current_count = 1;

                    /* if we have a limit of 1, this is a match */
                    if (lookup_tsh->current_count == td->count) {
                        ret = 1;
                    }
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);

                /* for the first match we return 1 to
                 * indicate we should alert */
                if (td->count == 1)  {
                    ret = 1;
                }
            }
            break;
        }
        /* detection_filter */
        case TYPE_DETECTION:
        {
            SCLogDebug("detection_filter");

            if (lookup_tsh != NULL) {
                long double time_diff = ((p->ts.tv_sec + p->ts.tv_usec/1000000.0) -
                                         (lookup_tsh->tv_sec1 + lookup_tsh->tv_usec1/1000000.0));

                if (time_diff < td->seconds) {
                    /* within timeout */

                    lookup_tsh->current_count++;
                    if (lookup_tsh->current_count > td->count) {
                        ret = 1;
                    }
                } else {
                    /* expired, reset */

                    lookup_tsh->tv_sec1 = p->ts.tv_sec;
                    lookup_tsh->tv_usec1 = p->ts.tv_usec;
                    lookup_tsh->current_count = 1;
                }
            } else {
                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;
                e->tv_usec1 = p->ts.tv_usec;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        /* rate_filter */
        case TYPE_RATE:
        {
            SCLogDebug("rate_filter");

            ret = 1;

            if (lookup_tsh != NULL) {
                /* Check if we have a timeout enabled, if so,
                 * we still matching (and enabling the new_action) */
                if (lookup_tsh->tv_timeout != 0) {
                    if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) {
                        /* Ok, we are done, timeout reached */
                        lookup_tsh->tv_timeout = 0;
                    } else {
                        /* Already matching */
                        /* Take the action to perform */
                        switch (td->new_action) {
                            case TH_ACTION_ALERT:
                                PACKET_ALERT(p);
                                break;
                            case TH_ACTION_DROP:
                                PACKET_DROP(p);
                                break;
                            case TH_ACTION_REJECT:
                                PACKET_REJECT(p);
                                break;
                            case TH_ACTION_PASS:
                                PACKET_PASS(p);
                                break;
                            default:
                                /* Weird, leave the default action */
                                break;
                        }
                        ret = 1;
                    } /* else - if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) */

                } else {
                    /* Update the matching state with the timeout interval */
                    if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
                        lookup_tsh->current_count++;
                        if (lookup_tsh->current_count > td->count) {
                            /* Then we must enable the new action by setting a
                             * timeout */
                            lookup_tsh->tv_timeout = p->ts.tv_sec;
                            /* Take the action to perform */
                            switch (td->new_action) {
                                case TH_ACTION_ALERT:
                                    PACKET_ALERT(p);
                                    break;
                                case TH_ACTION_DROP:
                                    PACKET_DROP(p);
                                    break;
                                case TH_ACTION_REJECT:
                                    PACKET_REJECT(p);
                                    break;
                                case TH_ACTION_PASS:
                                    PACKET_PASS(p);
                                    break;
                                default:
                                    /* Weird, leave the default action */
                                    break;
                            }
                            ret = 1;
                        }
                    } else {
                        lookup_tsh->tv_sec1 = p->ts.tv_sec;
                        lookup_tsh->current_count = 1;
                    }
                } /* else - if (lookup_tsh->tv_timeout != 0) */
            } else {
                if (td->count == 1) {
                    ret = 1;
                }

                DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
                if (e == NULL) {
                    break;
                }

                e->current_count = 1;
                e->tv_sec1 = p->ts.tv_sec;
                e->tv_timeout = 0;

                e->next = HostGetStorageById(h, threshold_id);
                HostSetStorageById(h, threshold_id, e);
            }
            break;
        }
        case TYPE_SUPPRESS:
        {
            int res = 0;
            switch (td->track) {
                case TRACK_DST:
                    res = DetectAddressMatch(td->addr, &p->dst);
                    break;
                case TRACK_SRC:
                    res = DetectAddressMatch(td->addr, &p->src);
                    break;
                case TRACK_RULE:
                default:
                    SCLogError(SC_ERR_INVALID_VALUE,
                               "track mode %d is not supported", td->track);
                    break;
            }
            if (res == 0)
                ret = 1;
            else
                ret = 2; /* suppressed but still need actions */
            break;
        }
        default:
            SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
    }

    return ret;
}
示例#15
0
static int DetectThresholdTestSig3(void)
{
    Packet *p = NULL;
    Signature *s = NULL;
    ThreadVars th_v;
    DetectEngineThreadCtx *det_ctx;
    int result = 0;
    int alerts = 0;
    struct timeval ts;
    DetectThresholdEntry *lookup_tsh = NULL;

    HostInitConfig(HOST_QUIET);

    memset (&ts, 0, sizeof(struct timeval));
    TimeGet(&ts);

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

    p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);

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

    de_ctx->flags |= DE_QUIET;

    s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)");
    if (s == NULL) {
        goto end;
    }

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

    TimeGet(&p->ts);

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

    Host *host = HostLookupHostFromHash(&p->dst);
    if (host == NULL) {
        printf("host not found: ");
        goto cleanup;
    }

    if (!(ThresholdHostHasThreshold(host))) {
        HostRelease(host);
        printf("host has no threshold: ");
        goto cleanup;
    }
    HostRelease(host);

    TimeSetIncrementTime(200);
    TimeGet(&p->ts);

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

    host = HostLookupHostFromHash(&p->dst);
    if (host == NULL) {
        printf("host not found: ");
        goto cleanup;
    }
    HostRelease(host);

    lookup_tsh = HostGetStorageById(host, ThresholdHostStorageId());
    if (lookup_tsh == NULL) {
        HostRelease(host);
        printf("lookup_tsh is NULL: ");
        goto cleanup;
    }

    alerts = lookup_tsh->current_count;

    if (alerts == 3)
        result = 1;
    else {
        printf("alerts %u != 3: ", alerts);
        goto cleanup;
    }

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

    DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
    DetectEngineCtxFree(de_ctx);
end:
    UTHFreePackets(&p, 1);
    HostShutdown();
    return result;
}