Esempio n. 1
0
/**
 * \brief Write a pid file (used at the startup)
 *        This commonly needed by the init scripts
 *
 * \param pointer to the name of the pid file to write (optarg)
 *
 * \retval 0 if succes
 * \retval -1 on failure
 */
int SCPidfileCreate(const char *pidfile)
{
    SCEnter();

    int pidfd = 0;
    char val[16];

    size_t len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
    if (len <= 0) {
        SCLogError(SC_ERR_PIDFILE_SNPRINTF, "Pid error (%s)", strerror(errno));
        SCReturnInt(-1);
    }

    pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
    if (pidfd < 0) {
        SCLogError(SC_ERR_PIDFILE_OPEN, "unable to set pidfile '%s': %s",
                   pidfile,
                   strerror(errno));
        SCReturnInt(-1);
    }

    ssize_t r = write(pidfd, val, (unsigned int)len);
    if (r == -1) {
        SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: %s", strerror(errno));
        close(pidfd);
        SCReturnInt(-1);
    } else if ((size_t)r != len) {
        SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: wrote"
                " %"PRIdMAX" of %"PRIuMAX" bytes.", (intmax_t)r, (uintmax_t)len);
        close(pidfd);
        SCReturnInt(-1);
    }

    close(pidfd);
    SCReturnInt(0);
}
Esempio n. 2
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);
}
Esempio n. 3
0
TmEcode LogFilestoreLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();
    int r = TM_ECODE_OK;

    /* no flow, no htp state */
    if (p->flow == NULL) {
        SCReturnInt(TM_ECODE_OK);
    }

    if (!(PKT_IS_TCP(p))) {
        SCReturnInt(TM_ECODE_OK);
    }

    SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt);

    if (PKT_IS_IPV4(p)) {
        r = LogFilestoreLogIPv4(tv, p, data, pq, postpq);
    } else if (PKT_IS_IPV6(p)) {
        r = LogFilestoreLogIPv6(tv, p, data, pq, postpq);
    }

    SCReturnInt(r);
}
Esempio n. 4
0
/**
 * \brief Check if a SigGroupHead contains a Signature, whose sid is sent as an
 *        argument.
 *
 * \param de_ctx Pointer to the detection engine context.
 * \param sgh    Pointer to the SigGroupHead that has to be checked for the
 *               presence of a Signature.
 * \param sid    The Signature id(sid) that has to be checked in the SigGroupHead.
 *
 * \retval 1 On successfully finding the sid in the SigGroupHead.
 * \retval 0 If the sid is not found in the SigGroupHead
 */
int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
                              uint32_t sid)
{
    SCEnter();

    uint32_t sig = 0;
    Signature *s = NULL;
    uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx);

    if (sgh == NULL) {
        SCReturnInt(0);
    }

    for (sig = 0; sig < max_sid; sig++) {
        if (sgh->init->sig_array == NULL) {
            SCReturnInt(0);
        }

        /* Check if the SigGroupHead has an entry for the sid */
        if ( !(sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) )
            continue;

        /* If we have reached here, we have an entry for sid in the SigGrouHead.
         * Retrieve the Signature from the detection engine context */
        s = de_ctx->sig_array[sig];
        if (s == NULL)
            continue;

        /* If the retrieved Signature matches the sid arg, we have a match */
        if (s->id == sid) {
            SCReturnInt(1);
        }
    }

    SCReturnInt(0);
}
Esempio n. 5
0
/**
 * \brief this function is used to parse urilen data into the current signature
 *
 * \param de_ctx pointer to the Detection Engine Context
 * \param s pointer to the Current Signature
 * \param urilenstr pointer to the user provided urilen options
 *
 * \retval 0 on Success
 * \retval -1 on Failure
 */
static int DetectUrilenSetup (DetectEngineCtx *de_ctx, Signature *s, char *urilenstr)
{
    SCEnter();
    DetectUrilenData *urilend = NULL;
    SigMatch *sm = NULL;

    if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
        SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
                   "alproto set");
        goto error;
    }

    urilend = DetectUrilenParse(urilenstr);
    if (urilend == NULL)
        goto error;
    sm = SigMatchAlloc();
    if (sm == NULL)
        goto error;
    sm->type = DETECT_AL_URILEN;
    sm->ctx = (void *)urilend;

    if (urilend->raw_buffer)
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH);
    else
        SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_UMATCH);

    /* Flagged the signature as to inspect the app layer data */
    s->flags |= SIG_FLAG_APPLAYER;
    s->alproto = ALPROTO_HTTP;

    SCReturnInt(0);

error:
    DetectUrilenFree(urilend);
    SCReturnInt(-1);
}
Esempio n. 6
0
/** \brief  Function to return the default bloomfilter size for the mpm algorithm,
 *          which has been defined by the user in the config file
 *
 *  \param  conf_val    pointer to the string value of bloom filter size
 *  \retval bloom_value returns the bloom filter value as defined by user,
 *                      otherwise default medium size value
 */
uint32_t MpmGetBloomSize(const char *conf_val)
{
    SCEnter();
    uint32_t bloom_value = BLOOMSIZE_MEDIUM;

    if(strncmp(conf_val, "low", 3) == 0) {
        bloom_value = BLOOMSIZE_LOW;
    } else if(strncmp(conf_val, "medium", 6) == 0) {
        bloom_value = BLOOMSIZE_MEDIUM;
    } else if(strncmp(conf_val, "high", 4) == 0) {
        bloom_value = BLOOMSIZE_HIGH;
    }

    SCReturnInt(bloom_value);
}
Esempio n. 7
0
/**
 * \brief This function passes off to link type decoders.
 *
 * DecodePcap reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param t pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into PcapThreadVars for ptv
 * \param pq pointer to the current PacketQueue
 */
TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

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

    /* update counters */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
//    SCPerfCounterIncr(dtv->counter_pkts_per_sec, tv->sc_perf_pca);

    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
#if 0
    SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca,
                           (GET_PKT_LEN(p) * 8)/1000000.0);
#endif

    SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));

    /* call the decoder */
    switch(p->datalink) {
        case LINKTYPE_LINUX_SLL:
            DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_ETHERNET:
            DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_PPP:
            DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_RAW:
            DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        default:
            SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodePcap", p->datalink);
            break;
    }

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 8
0
/**
 *  \internal
 *  \brief Apply the prefilter keyword to the last match
 *  \param det_ctx detection engine ctx
 *  \param s signature
 *  \param nullstr should be null
 *  \retval 0 ok
 *  \retval -1 failure
 */
static int DetectPrefilterSetup (DetectEngineCtx *de_ctx, Signature *s, char *nullstr)
{
    SCEnter();

    SigMatch *sm = NULL;
    int ret = -1;

    if (nullstr != NULL) {
        SCLogError(SC_ERR_INVALID_VALUE, "prefilter has value");
        goto end;
    }

    if (s->flags & SIG_FLAG_PREFILTER) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "prefilter already set");
        goto end;
    }

    sm = SigMatchGetLastSM(s);
    if (sm == NULL) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "prefilter needs preceding match");
        goto end;
    }

    s->prefilter_sm = sm;
    s->flags |= SIG_FLAG_PREFILTER;

    /* if the sig match is content, prefilter should act like
     * 'fast_pattern' w/o options. */
    if (sm->type == DETECT_CONTENT) {
        DetectContentData *cd = (DetectContentData *)sm->ctx;
        if ((cd->flags & DETECT_CONTENT_NEGATED) &&
                ((cd->flags & DETECT_CONTENT_DISTANCE) ||
                 (cd->flags & DETECT_CONTENT_WITHIN) ||
                 (cd->flags & DETECT_CONTENT_OFFSET) ||
                 (cd->flags & DETECT_CONTENT_DEPTH)))
        {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "prefilter; cannot be "
                    "used with negated content, along with relative modifiers");
            goto end;
        }
        cd->flags |= DETECT_CONTENT_FAST_PATTERN;
    }

    ret = 0;
 end:
    SCReturnInt(ret);
}
Esempio n. 9
0
/**
 * \brief This function is used to match flow flags set on a packet with those passed via flow:
 *
 * \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 DetectFlowData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectFlowMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    SCEnter();

    SCLogDebug("pkt %p", p);

    if (p->flowflags & FLOW_PKT_TOSERVER) {
        SCLogDebug("FLOW_PKT_TOSERVER");
    } else if (p->flowflags & FLOW_PKT_TOCLIENT) {
        SCLogDebug("FLOW_PKT_TOCLIENT");
    }

    if (p->flowflags & FLOW_PKT_ESTABLISHED) {
        SCLogDebug("FLOW_PKT_ESTABLISHED");
    } else if (p->flowflags & FLOW_PKT_STATELESS) {
        SCLogDebug("FLOW_PKT_STATELESS");
    }

    uint8_t cnt = 0;
    DetectFlowData *fd = (DetectFlowData *)m->ctx;

    if (fd->flags & FLOW_PKT_TOSERVER && p->flowflags & FLOW_PKT_TOSERVER) {
        cnt++;
    } else if (fd->flags & FLOW_PKT_TOCLIENT && p->flowflags & FLOW_PKT_TOCLIENT) {
        cnt++;
    }

    if (fd->flags & FLOW_PKT_ESTABLISHED && p->flowflags & FLOW_PKT_ESTABLISHED) {
        cnt++;
    } else if (fd->flags & FLOW_PKT_STATELESS) {
        cnt++;
    }

    if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH) {
        if (fd->flags & FLOW_PKT_ONLYSTREAM)
            cnt++;
    } else {
        if (fd->flags & FLOW_PKT_NOSTREAM)
            cnt++;
    }

    int ret = (fd->match_cnt == cnt) ? 1 : 0;
    SCLogDebug("returning %" PRId32 " cnt %" PRIu8 " fd->match_cnt %" PRId32 " fd->flags 0x%02X p->flowflags 0x%02X",
        ret, cnt, fd->match_cnt, fd->flags, p->flowflags);
    SCReturnInt(ret);
}
Esempio n. 10
0
static int StreamTcpSackTest12 (void) {
    TcpStream stream;
    int retval = 0;

    memset(&stream, 0, sizeof(stream));
    stream.window = 2000;

    StreamTcpSackInsertRange(&stream, 800, 1000);
    StreamTcpSackInsertRange(&stream, 700, 900);
    StreamTcpSackInsertRange(&stream, 600, 800);
    StreamTcpSackInsertRange(&stream, 500, 700);
    StreamTcpSackInsertRange(&stream, 100, 600);
#ifdef DEBUG
    StreamTcpSackPrintList(&stream);
#endif /* DEBUG */

    if (stream.sack_head->le != 100) {
        goto end;
    }

    if (StreamTcpSackedSize(&stream) != 900) {
        printf("size should be 900, is %u: ", StreamTcpSackedSize(&stream));
        goto end;
    }

    StreamTcpSackInsertRange(&stream, 0, 1000);

    if (StreamTcpSackedSize(&stream) != 1000) {
        printf("size should be 1000, is %u: ", StreamTcpSackedSize(&stream));
        goto end;
    }

    stream.last_ack = 500;

    StreamTcpSackPruneList(&stream);

    if (StreamTcpSackedSize(&stream) != 500) {
        printf("size should be 500, is %u: ", StreamTcpSackedSize(&stream));
        goto end;
    }

    retval = 1;
end:
    SCReturnInt(retval);
}
Esempio n. 11
0
/**
 *  \brief Main NFQ reading Loop function
 */
TmEcode ReceiveNFQLoop(ThreadVars *tv, void *data, void *slot)
{
    SCEnter();
    NFQThreadVars *ntv = (NFQThreadVars *)data;
    NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index);

    ntv->slot = ((TmSlot *) slot)->slot_next;

    while(1) {
        if (suricata_ctl_flags != 0) {
            break;
        }
        NFQRecvPkt(nq, ntv);

        SCPerfSyncCountersIfSignalled(tv, 0);
    }
    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 12
0
TmEcode DecodePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

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

    /* update counters */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
//    SCPerfCounterIncr(dtv->counter_pkts_per_sec, tv->sc_perf_pca);

    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
#if 0
    SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca,
                           (GET_PKT_LEN(p) * 8)/1000000.0 );
#endif
    SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));

    double curr_ts = p->ts.tv_sec + p->ts.tv_usec / 1000.0;
    if (curr_ts < prev_signaled_ts || (curr_ts - prev_signaled_ts) > 60.0) {
        prev_signaled_ts = curr_ts;
        FlowWakeupFlowManagerThread();
    }

    /* update the engine time representation based on the timestamp
     * of the packet. */
    TimeSet(&p->ts);

    /* call the decoder */
    pcap_g.Decoder(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

#ifdef DEBUG
    BUG_ON(p->pkt_src != PKT_SRC_WIRE && p->pkt_src != PKT_SRC_FFR_V2);
#endif

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 13
0
static int LogTcpDataLoggerDir(ThreadVars *tv, void *thread_data, const Flow *f,
        const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags)
{
    SCEnter();
    LogTcpDataLogThread *aft = thread_data;
    LogTcpDataFileCtx *td = aft->tcpdatalog_ctx;
    const char *mode = "a";

    if (flags & OUTPUT_STREAMING_FLAG_OPEN)
        mode = "w";

    if (data && data_len) {
        char srcip[46] = "", dstip[46] = "";
        if (FLOW_IS_IPV4(f)) {
            PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip));
            PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip));
        } else if (FLOW_IS_IPV6(f)) {
            PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip));
            PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip));
        }

        char name[PATH_MAX];

        char tx[64] = { 0 };
        if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) {
            snprintf(tx, sizeof(tx), "%"PRIu64, tx_id);
        }

        snprintf(name, sizeof(name), "%s/%s/%s_%u-%s_%u-%s-%s.data",
                td->log_dir,
                td->type == STREAMING_HTTP_BODIES ? "http" : "tcp",
                srcip, f->sp, dstip, f->dp, tx,
                flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc");

        FILE *fp = fopen(name, mode);
        BUG_ON(fp == NULL);

        // PrintRawDataFp(stdout, (uint8_t *)data, data_len);
        fwrite(data, data_len, 1, fp);

        fclose(fp);
    }
    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 14
0
int RunModeIdsAFPAutoFp(DetectEngineCtx *de_ctx)
{
    SCEnter();

/* We include only if AF_PACKET is enabled */
#ifdef HAVE_AF_PACKET
    int ret;
    char *live_dev = NULL;

    RunModeInitialize();

    TimeModeSetLive();

    (void)ConfGet("af-packet.live-interface", &live_dev);

    SCLogDebug("live_dev %s", live_dev);

    if (AFPPeersListInit() != TM_ECODE_OK) {
        SCLogError(SC_ERR_RUNMODE, "Unable to init peers list.");
        exit(EXIT_FAILURE);
    }

    ret = RunModeSetLiveCaptureAutoFp(de_ctx,
                              ParseAFPConfig,
                              AFPConfigGeThreadsCount,
                              "ReceiveAFP",
                              "DecodeAFP", "RxAFP",
                              live_dev);
    if (ret != 0) {
        SCLogError(SC_ERR_RUNMODE, "Unable to start runmode");
        exit(EXIT_FAILURE);
    }

    /* In IPS mode each threads must have a peer */
    if (AFPPeersListCheck() != TM_ECODE_OK) {
        SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer.");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("RunModeIdsAFPAutoFp initialised");
#endif /* HAVE_AF_PACKET */

    SCReturnInt(0);
}
static int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                                Flow *f, uint8_t flags, void *state, Signature *s,
                                SigMatch *m)
{
    SCEnter();
    AppLayerDecoderEvents *decoder_events = NULL;
    int r = 0;
    DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;

    if (r == 0) {
        decoder_events = AppLayerParserGetDecoderEvents(f->alparser);
        if (decoder_events != NULL &&
                AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
            r = 1;
        }
    }

    SCReturnInt(r);
}
Esempio n. 16
0
/**
 * \brief Add IPv4 header data, to be stored in the Additional Data
 * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765).
 *
 * \return 0 if ok
 */
static int PacketToDataV4(Packet *p, PacketAlert *pa, idmef_alert_t *alert)
{
    SCEnter();

    AddIntData(alert, "ip_ver", IPV4_GET_RAW_VER(p->ip4h));
    AddIntData(alert, "ip_hlen", IPV4_GET_RAW_HLEN(p->ip4h));
    AddIntData(alert, "ip_tos", IPV4_GET_RAW_IPTOS(p->ip4h));
    AddIntData(alert, "ip_len", ntohs(IPV4_GET_RAW_IPLEN(p->ip4h)));

    AddIntData(alert, "ip_id", ntohs(IPV4_GET_RAW_IPID(p->ip4h)));

    AddIntData(alert, "ip_off", ntohs(IPV4_GET_RAW_IPOFFSET(p->ip4h)));

    AddIntData(alert, "ip_ttl", IPV4_GET_RAW_IPTTL(p->ip4h));
    AddIntData(alert, "ip_proto", IPV4_GET_RAW_IPPROTO(p->ip4h));

    AddIntData(alert, "ip_sum", ntohs(p->ip4h->ip_csum));

    SCReturnInt(0);
}
Esempio n. 17
0
int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
                             Flow *f, uint8_t flags, void *state, Signature *s,
                             SigMatch *m)
{
    SCEnter();
    int r = 0;

    DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;

    FLOWLOCK_RDLOCK(f);

    AppLayerDecoderEvents *decoder_events = AppLayerGetDecoderEventsForFlow(f);
    if (decoder_events != NULL &&
            AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
        r = 1;
    }

    FLOWLOCK_UNLOCK(f);
    SCReturnInt(r);
}
Esempio n. 18
0
/**
 * \brief Create the hash for threshold tables
 *
 * \param ht Hash Table
 * \param data Data that will be used to create the hash
 * \param datalen Data length
 *
 * \retval hash the hash
 */
uint32_t ThresholdHashFunc(HashListTable *ht, void *data, uint16_t datalen)
{
    SCEnter();

    DetectThresholdEntry *dt = (DetectThresholdEntry *)data;
    uint32_t hash = 0;

    if (dt->ipv == 4)
        hash = (dt->sid + dt->gid + dt->addr.addr_data32[0]);
    else if (dt->ipv == 6)
        hash = (dt->sid + dt->gid + dt->addr.addr_data32[0] +
                dt->addr.addr_data32[1] +
                dt->addr.addr_data32[2] +
                dt->addr.addr_data32[3]);
    else {
        SCLogDebug("no dt->ipv");
    }

    SCReturnInt(hash % THRESHOLD_HASH_SIZE);
}
Esempio n. 19
0
/** \brief Verify and store a match
 *
 *   used at search runtime
 *
 *  \param thread_ctx mpm thread ctx
 *  \param pmq storage for match results
 *  \param list end match to check against (entire list will be checked)
 *  \param offset match offset in the buffer
 *  \param patlen length of the pattern we're checking
 *
 *  \retval 0 no match after all
 *  \retval 1 (new) match
 */
int
MpmVerifyMatch(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, uint32_t patid)
{
    SCEnter();

    /* Handle pattern id storage */
    if (pmq != NULL && pmq->pattern_id_bitarray != NULL) {
        SCLogDebug("using pattern id arrays, storing %"PRIu32, patid);

        if (!(pmq->pattern_id_bitarray[(patid / 8)] & (1<<(patid % 8)))) {
            /* flag this pattern id as being added now */
            pmq->pattern_id_bitarray[(patid / 8)] |= (1<<(patid % 8));
            /* append the pattern_id to the array with matches */
            pmq->pattern_id_array[pmq->pattern_id_array_cnt] = patid;
            pmq->pattern_id_array_cnt++;
            SCLogDebug("pattern_id_array_cnt %u", pmq->pattern_id_array_cnt);
        }
    }

    SCReturnInt(1);
}
Esempio n. 20
0
static int StreamTcpSackTest09 (void) {
    TcpStream stream;
    int retval = 0;

    memset(&stream, 0, sizeof(stream));
    stream.window = 100;

    StreamTcpSackInsertRange(&stream, 0,  9);
    StreamTcpSackInsertRange(&stream, 11, 19);
    StreamTcpSackInsertRange(&stream, 21, 29);
    StreamTcpSackInsertRange(&stream, 31, 39);
    StreamTcpSackInsertRange(&stream, 0, 40);

#ifdef DEBUG
    StreamTcpSackPrintList(&stream);
#endif /* DEBUG */

    if (stream.sack_head->le != 0) {
        goto end;
    }

    if (StreamTcpSackedSize(&stream) != 40) {
        printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream));
        goto end;
    }

    stream.last_ack = 39;

    StreamTcpSackPruneList(&stream);

    if (StreamTcpSackedSize(&stream) != 1) {
        printf("size should be 1, is %u: ", StreamTcpSackedSize(&stream));
        goto end;
    }

    retval = 1;
end:
    SCReturnInt(retval);
}
Esempio n. 21
0
/**
 * \brief This function passes off to link type decoders.
 *
 * DecodePcap reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param t pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into PcapThreadVars for ptv
 * \param pq pointer to the current PacketQueue
 */
TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

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

    /* update counters */
    DecodeUpdatePacketCounters(tv, dtv, p);

    /* call the decoder */
    switch(p->datalink) {
        case LINKTYPE_LINUX_SLL:
            DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_ETHERNET:
            DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_PPP:
            DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_RAW:
            DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        case LINKTYPE_NULL:
            DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
            break;
        default:
            SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodePcap", p->datalink);
            break;
    }

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 22
0
static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f)
{
    SCEnter();
    JsonFlowLogThread *jhl = (JsonFlowLogThread *)thread_data;

    /* reset */
    MemBufferReset(jhl->buffer);

    json_t *js = CreateJSONHeaderFromFlow(f, "flow");
    if (unlikely(js == NULL))
        return TM_ECODE_OK;

    JsonFlowLogJSON(jhl, js, f);

    OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, &jhl->buffer);
    json_object_del(js, "http");

    json_object_clear(js);
    json_decref(js);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 23
0
/**
 *  \brief Inspect the file inspecting keywords against the SMTP transactions.
 *
 *  \param tv thread vars
 *  \param det_ctx detection engine thread ctx
 *  \param f flow
 *  \param s signature to inspect
 *  \param alstate state
 *  \param flags direction flag
 *
 *  \retval 0 no match
 *  \retval 1 match
 *  \retval 2 can't match
 *  \retval 3 can't match filestore signature
 *
 *  \note flow is not locked at this time
 */
int DetectFileInspectSmtp(ThreadVars *tv,
                          DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
                          Signature *s, Flow *f, uint8_t flags, void *alstate,
                          void *tx, uint64_t tx_id)
{
    SCEnter();
    int r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
    SMTPState *smtp_state = NULL;
    FileContainer *ffc;

    smtp_state = (SMTPState *)alstate;
    if (smtp_state == NULL) {
        SCLogDebug("no SMTP state");
        goto end;
    }

    if (flags & STREAM_TOSERVER)
        ffc = smtp_state->files_ts;
    else
        goto end;

    int match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc);
    if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) {
        r = DETECT_ENGINE_INSPECT_SIG_MATCH;
    } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH) {
        SCLogDebug("sid %u can't match on this transaction", s->id);
        r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
    } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE) {
        SCLogDebug("sid %u can't match on this transaction (filestore sig)", s->id);
        r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE;
    } else if (match == DETECT_ENGINE_INSPECT_SIG_MATCH_MORE_FILES) {
        SCLogDebug("match with more files ahead");
        r = match;
    }

end:
    SCReturnInt(r);
}
Esempio n. 24
0
/**
 * \brief This function is used to match flow flags set on a packet with those passed via flow:
 *
 * \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 DetectFlowData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectFlowMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx)
{
    SCEnter();

    SCLogDebug("pkt %p", p);

    if (p->flowflags & FLOW_PKT_TOSERVER) {
        SCLogDebug("FLOW_PKT_TOSERVER");
    } else if (p->flowflags & FLOW_PKT_TOCLIENT) {
        SCLogDebug("FLOW_PKT_TOCLIENT");
    }

    if (p->flowflags & FLOW_PKT_ESTABLISHED) {
        SCLogDebug("FLOW_PKT_ESTABLISHED");
    }

    const DetectFlowData *fd = (const DetectFlowData *)ctx;

    int ret = FlowMatch(p->flags, p->flowflags, det_ctx->flags, fd->flags, fd->match_cnt);;
    SCLogDebug("returning %" PRId32 " fd->match_cnt %" PRId32 " fd->flags 0x%02X p->flowflags 0x%02X",
        ret, fd->match_cnt, fd->flags, p->flowflags);
    SCReturnInt(ret);
}
Esempio n. 25
0
/**
 * \brief   This function is used to match filesize rule option.
 *
 * \param t thread local vars
 * \param det_ctx pattern matcher thread local data
 * \param f *LOCKED* flow
 * \param flags direction flags
 * \param file file being inspected
 * \param s signature being inspected
 * \param m sigmatch that we will cast into DetectFilesizeData
 *
 * \retval 0 no match
 * \retval 1 match
 */
static int DetectFilesizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
                       uint8_t flags, File *file, Signature *s, SigMatch *m)
{
    SCEnter();

    DetectFilesizeData *fsd = (DetectFilesizeData *)m->ctx;
    int ret = 0;
    uint64_t file_size = FileSize(file);

    SCLogDebug("file size %"PRIu64", check %"PRIu64, file_size, fsd->size1);

    if (file->state == FILE_STATE_CLOSED) {
        switch (fsd->mode) {
            case DETECT_FILESIZE_EQ:
                if (file_size == fsd->size1)
                    ret = 1;
                break;
            case DETECT_FILESIZE_LT:
                if (file_size < fsd->size1)
                    ret = 1;
                break;
            case DETECT_FILESIZE_GT:
                if (file_size > fsd->size1)
                    ret = 1;
                break;
            case DETECT_FILESIZE_RA:
                if (file_size > fsd->size1 && file_size < fsd->size2)
                    ret = 1;
                break;
        }
    /* truncated, error: only see if what we have meets the GT condition */
    } else if (file->state > FILE_STATE_CLOSED) {
        if (fsd->mode == DETECT_FILESIZE_GT && file_size > fsd->size1)
            ret = 1;
    }
    SCReturnInt(ret);
}
Esempio n. 26
0
/**
 * \brief   This function passes off to link type decoders.
 *
 * DecodeErfDag reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param t pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into PcapThreadVars for ptv
 * \param pq pointer to the current PacketQueue
 */
TmEcode DecodeErfDag(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
                     PacketQueue *postpq)
{
    SCEnter();
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    /* update counters */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
//    SCPerfCounterIncr(dtv->counter_pkts_per_sec, tv->sc_perf_pca);

    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
#if 0
    SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca,
                           (GET_PKT_LEN(p) * 8)/1000000.0);
#endif

    SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));

    /* call the decoder */
    switch(p->datalink) {
    case LINKTYPE_ETHERNET:
        DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
        break;
    default:
        SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED,
                   "Error: datalink type %" PRId32 " not yet supported in module DecodeErfDag",
                   p->datalink);
        break;
    }

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 27
0
/**
 * \brief Decode the ERF file.
 *
 * This function ups the decoder counters and then passes the packet
 * off to the ethernet decoder.
 */
TmEcode
DecodeErfFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    /* Update counters. */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
//    SCPerfCounterIncr(dtv->counter_pkts_per_sec, tv->sc_perf_pca);

    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
#if 0
    SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca,
                           (GET_PKT_LEN(p) * 8)/1000000.0 );
#endif

    SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
    SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));

    DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 28
0
static int LogTcpDataLoggerFile(ThreadVars *tv, void *thread_data, const Flow *f,
        const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags)
{
    SCEnter();
    LogTcpDataLogThread *aft = thread_data;
    LogTcpDataFileCtx *td = aft->tcpdatalog_ctx;

    if (data && data_len) {
        MemBufferReset(aft->buffer);

        char srcip[46] = "", dstip[46] = "";
        if (FLOW_IS_IPV4(f)) {
            PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip));
            PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip));
        } else if (FLOW_IS_IPV6(f)) {
            PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip));
            PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip));
        }

        char name[PATH_MAX];
        snprintf(name, sizeof(name), "%s_%u-%s_%u-%s:",
                srcip, f->sp, dstip, f->dp,
                flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc");

        PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
                aft->buffer->size, (uint8_t *)name,strlen(name));
        MemBufferWriteString(aft->buffer, "\n");

        PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset,
                aft->buffer->size, (uint8_t *)data,data_len);

        td->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer),
                MEMBUFFER_OFFSET(aft->buffer), td->file_ctx);
    }
    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 29
0
/**
 *  \brief Main NFQ reading Loop function
 */
TmEcode ReceiveNFQLoop(ThreadVars *tv, void *data, void *slot)
{
    SCEnter();
    NFQThreadVars *ntv = (NFQThreadVars *)data;
    NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index);

    ntv->slot = ((TmSlot *) slot)->slot_next;

    while(1) {
        if (suricata_ctl_flags != 0) {
            NFQMutexLock(nq);
            if (nq->qh) {
                nfq_destroy_queue(nq->qh);
                nq->qh = NULL;
            }
            NFQMutexUnlock(nq);
            break;
        }
        NFQRecvPkt(nq, ntv);

        StatsSyncCountersIfSignalled(tv);
    }
    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 30
0
int AppLayerParserSetup(void)
{
    SCEnter();

    AppProto alproto = 0;
    int flow_proto = 0;

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

    /* set the default tx handler if none was set explicitly */
    if (AppLayerGetActiveTxIdFuncPtr == NULL) {
        RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveDetectLog);
    }

    /* lets set a default value for stream_depth */
    for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
        for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
            alp_ctx.ctxs[flow_proto][alproto].stream_depth =
                stream_config.reassembly_depth;
        }
    }

    SCReturnInt(0);
}