예제 #1
0
/**
 * \brief Search for a threshold data into threshold hash table
 *
 * \param de_ctx Dectection Context
 * \param tsh_ptr Threshold element
 * \param p Packet structure
 *
 * \retval lookup_tsh Return the threshold element
 */
DetectThresholdEntry *ThresholdHashSearch(DetectEngineCtx *de_ctx, DetectThresholdEntry *tsh_ptr, Packet *p)
{
    SCEnter();

    DetectThresholdEntry *lookup_tsh = NULL;

    SCLogDebug("tsh_ptr->track %u", tsh_ptr->track);

    if (tsh_ptr->track == TRACK_DST) {
        if (PKT_IS_IPV4(p)) {
            SCLogDebug("ipv4 dst");
            lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_dst, tsh_ptr, sizeof(DetectThresholdEntry));
        } else if (PKT_IS_IPV6(p)) {
            lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_dst_ipv6, tsh_ptr, sizeof(DetectThresholdEntry));
        }
    } else if (tsh_ptr->track == TRACK_SRC) {
        if (PKT_IS_IPV4(p)) {
            SCLogDebug("ipv4 src");
            lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_src, tsh_ptr, sizeof(DetectThresholdEntry));
        } else if (PKT_IS_IPV6(p))
            lookup_tsh = HashListTableLookup(de_ctx->ths_ctx.threshold_hash_table_src_ipv6, tsh_ptr, sizeof(DetectThresholdEntry));
    } else {
        SCLogDebug("no track, weird");
    }

    SCReturnPtr(lookup_tsh, "DetectThresholdEntry");
}
예제 #2
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;
}
예제 #3
0
int ReCalculateChecksum(Packet *p)
{
    if (PKT_IS_IPV4(p)) {
        if (PKT_IS_TCP(p)) {
            /* TCP */
            p->tcph->th_sum = 0;
            p->tcph->th_sum = TCPChecksum(p->ip4h->s_ip_addrs,
                    (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0);
        } else if (PKT_IS_UDP(p)) {
            p->udph->uh_sum = 0;
            p->udph->uh_sum = UDPV4Checksum(p->ip4h->s_ip_addrs,
                    (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0);
        }
        /* IPV4 */
        p->ip4h->ip_csum = 0;
        p->ip4h->ip_csum = IPV4Checksum((uint16_t *)p->ip4h,
                IPV4_GET_RAW_HLEN(p->ip4h), 0);
    } else if (PKT_IS_IPV6(p)) {
        /* just TCP for IPV6 */
        if (PKT_IS_TCP(p)) {
            p->tcph->th_sum = 0;
            p->tcph->th_sum = TCPV6Checksum(p->ip6h->s_ip6_addrs,
                    (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0);
        } else if (PKT_IS_UDP(p)) {
            p->udph->uh_sum = 0;
            p->udph->uh_sum = UDPV6Checksum(p->ip6h->s_ip6_addrs,
                    (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0);
        }
    }

    return 0;
}
예제 #4
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;
}
예제 #5
0
static inline DetectThresholdEntry *DetectThresholdEntryAlloc(DetectThresholdData *td, Packet *p, Signature *s) {
    SCEnter();

    DetectThresholdEntry *ste = SCMalloc(sizeof(DetectThresholdEntry));
    if (ste == NULL) {
        SCReturnPtr(NULL, "DetectThresholdEntry");
    }

    if (PKT_IS_IPV4(p))
        ste->ipv = 4;
    else if (PKT_IS_IPV6(p))
        ste->ipv = 6;

    ste->sid = s->id;
    ste->gid = s->gid;

    if (td->track == TRACK_DST) {
        COPY_ADDRESS(&p->dst, &ste->addr);
    } else if (td->track == TRACK_SRC) {
        COPY_ADDRESS(&p->src, &ste->addr);
    }

    ste->track = td->track;
    ste->seconds = td->seconds;
    ste->tv_timeout = 0;

    SCReturnPtr(ste, "DetectThresholdEntry");
}
예제 #6
0
static int LogFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff, const FileData *ffd, uint8_t flags)
{
    SCEnter();
    LogFilestoreLogThread *aft = (LogFilestoreLogThread *)thread_data;
    char filename[PATH_MAX] = "";
    int file_fd = -1;
    int ipver = -1;

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

    if (PKT_IS_IPV4(p)) {
        ipver = AF_INET;
    } else if (PKT_IS_IPV6(p)) {
        ipver = AF_INET6;
    } else {
        return 0;
    }

    SCLogDebug("ff %p, ffd %p", ff, ffd);

    snprintf(filename, sizeof(filename), "%s/file.%u",
            g_logfile_base_dir, ff->file_id);

    if (flags & OUTPUT_FILEDATA_FLAG_OPEN) {
        aft->file_cnt++;

        /* create a .meta file that contains time, src/dst/sp/dp/proto */
        LogFilestoreLogCreateMetaFile(p, ff, filename, ipver);

        file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
        if (file_fd == -1) {
            SCLogDebug("failed to create file");
            return -1;
        }
    /* we can get called with a NULL ffd when we need to close */
    } else if (ffd != NULL) {
        file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY);
        if (file_fd == -1) {
            SCLogDebug("failed to open file %s: %s", filename, strerror(errno));
            return -1;
        }
    }

    if (file_fd != -1) {
        ssize_t r = write(file_fd, (const void *)ffd->data, (size_t)ffd->len);
        if (r == -1) {
            SCLogDebug("write failed: %s", strerror(errno));
        }
        close(file_fd);
    }

    if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) {
        LogFilestoreLogCloseMetaFile(ff);
    }

    return 0;
}
예제 #7
0
/**
 *  \brief Recalculate the csum for a modified packet
 *
 *  \param p packet to inspect
 */
void StreamTcpInlineRecalcCsum(Packet *p) {
    if (!(p->flags & PKT_STREAM_MODIFIED)) {
        SCReturn;
    }

    if (!(PKT_IS_TCP(p))) {
        SCReturn;
    }

    if (PKT_IS_IPV4(p)) {
        /* TCP */
        p->tcph->th_sum = 0;
        p->tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p->ip4h->ip_src),
                (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen));
        /* IPV4 */
        p->ip4h->ip_csum = 0;
        p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h,
                IPV4_GET_RAW_HLEN(p->ip4h));
    } else if (PKT_IS_IPV6(p)) {
        /* just TCP for IPV6 */
        p->tcph->th_sum = 0;
        p->tcph->th_sum = TCPV6CalculateChecksum((uint16_t *)&(p->ip6h->ip6_src),
                (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen));
    }

    SCReturn;
}
예제 #8
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);
    }
}
예제 #9
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_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;
}
예제 #10
0
/**
 * \brief Handle a packet and check if needs a threshold logic
 *
 * \param de_ctx Detection Context
 * \param sig Signature pointer
 * \param p Packet structure
 *
 * \retval 1 alert is not suppressed
 * \retval 0 alert is suppressed
 */
static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
                       Signature *s, Packet *p, uint16_t pos)
{
    SCEnter();
    int ret = 1;
    DetectThresholdData *td = NULL;
    SigMatch *sm = NULL;

    if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) {
        SCReturnInt(1);
    }

    do {
        td = SigGetThresholdTypeIter(s, p, &sm);
        if (td != NULL) {
            SCLogDebug("td %p", td);
            ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s);
            if (ret == 0) {
                /* It doesn't match threshold, remove it */
                PacketAlertRemove(p, pos);
                break;
            }
        }
    } while (sm != NULL);

    SCReturnInt(ret);
}
예제 #11
0
/**
 * \brief Handle a packet and check if needs a threshold logic
 *        Also apply rule action if necessary.
 *
 * \param de_ctx Detection Context
 * \param sig Signature pointer
 * \param p Packet structure
 *
 * \retval 1 alert is not suppressed
 * \retval 0 alert is suppressed
 */
static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
                       Signature *s, Packet *p, uint16_t pos)
{
    SCEnter();
    int ret = 1;
    DetectThresholdData *td = NULL;
    SigMatch *sm = NULL;

    if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) {
        SCReturnInt(1);
    }

    do {
        td = SigGetThresholdTypeIter(s, p, &sm);
        if (td != NULL) {
            SCLogDebug("td %p", td);

            /* PacketAlertThreshold returns 2 if the alert is suppressed but
             * we do need to apply rule actions to the packet. */
            ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s);
            if (ret == 0 || ret == 2) {
                /* It doesn't match threshold, remove it */
                SCReturnInt(ret);
            }
        }
    } while (sm != NULL);

    SCReturnInt(1);
}
예제 #12
0
파일: detect-ttl.c 프로젝트: thus/suricata
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);
    }
}
예제 #13
0
static int AlertDebugLogLogger(ThreadVars *tv, void *thread_data, const Packet *p)
{
    if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) {
        return AlertDebugLogger(tv, p, thread_data);
    } else if (p->events.cnt > 0) {
        return AlertDebugLogDecoderEvent(tv, p, thread_data);
    }
    return TM_ECODE_OK;
}
예제 #14
0
void SCProfilingPrintPacketProfile(Packet *p)
{
    if (profiling_packets_csv_enabled == 0 || p == NULL || packet_profile_csv_fp == NULL || p->profile == NULL) {
        return;
    }

    uint64_t delta = p->profile->ticks_end - p->profile->ticks_start;

    fprintf(packet_profile_csv_fp, "%"PRIu64",%c,%"PRIu8",%"PRIu64",",
            p->pcap_cnt, PKT_IS_IPV4(p) ? '4' : (PKT_IS_IPV6(p) ? '6' : '?'), p->proto,
            delta);

    int i;
    uint64_t tmm_total = 0;
    uint64_t tmm_streamtcp_tcp = 0;

    for (i = 0; i < TMM_SIZE; i++) {
        PktProfilingTmmData *pdt = &p->profile->tmm[i];

        uint64_t tmm_delta = pdt->ticks_end - pdt->ticks_start;
        fprintf(packet_profile_csv_fp, "%"PRIu64",", tmm_delta);
        tmm_total += tmm_delta;

        if (p->proto == IPPROTO_TCP && i == TMM_STREAMTCP) {
            tmm_streamtcp_tcp = tmm_delta;
        }
    }

    fprintf(packet_profile_csv_fp, "%"PRIu64",", delta - tmm_total);

    uint64_t app_total = 0;
    for (i = 0; i < ALPROTO_MAX; i++) {
        PktProfilingAppData *pdt = &p->profile->app[i];

        fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent);

        if (p->proto == IPPROTO_TCP) {
            app_total += pdt->ticks_spent;
        }
    }

    uint64_t real_tcp = 0;
    if (tmm_streamtcp_tcp > app_total)
        real_tcp = tmm_streamtcp_tcp - app_total;
    fprintf(packet_profile_csv_fp, "%"PRIu64",", real_tcp);

    fprintf(packet_profile_csv_fp, "%"PRIu64",", p->profile->proto_detect);

    for (i = 0; i < PROF_DETECT_SIZE; i++) {
        PktProfilingDetectData *pdt = &p->profile->detect[i];

        fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent);
    }
    fprintf(packet_profile_csv_fp,"\n");
}
예제 #15
0
static int JsonAlertLogger(ThreadVars *tv, void *thread_data, const Packet *p)
{
    JsonAlertLogThread *aft = thread_data;

    if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) {
        return AlertJson(tv, aft, p);
    } else if (p->alerts.cnt > 0) {
        return AlertJsonDecoderEvent(tv, aft, p);
    }
    return 0;
}
예제 #16
0
TmEcode AlertFastLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    if (PKT_IS_IPV4(p)) {
        return AlertFastLogIPv4(tv, p, data, pq, postpq);
    } else if (PKT_IS_IPV6(p)) {
        return AlertFastLogIPv6(tv, p, data, pq, postpq);
    } else if (p->events.cnt > 0) {
        return AlertFastLogDecoderEvent(tv, p, data, pq, postpq);
    }

    return TM_ECODE_OK;
}
예제 #17
0
/* initialize the flow from the first packet
 * we see from it. */
void FlowInit(Flow *f, const Packet *p)
{
    SCEnter();
    SCLogDebug("flow %p", f);

    f->proto = p->proto;
    f->recursion_level = p->recursion_level;
    f->vlan_id[0] = p->vlan_id[0];
    f->vlan_id[1] = p->vlan_id[1];

    if (PKT_IS_IPV4(p)) {
        FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, &f->src);
        FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, &f->dst);
        f->flags |= FLOW_IPV4;
    } else if (PKT_IS_IPV6(p)) {
        FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, &f->src);
        FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, &f->dst);
        f->flags |= FLOW_IPV6;
    }
#ifdef DEBUG
    /* XXX handle default */
    else {
        printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
    }
#endif

    if (p->tcph != NULL) { /* XXX MACRO */
        SET_TCP_SRC_PORT(p,&f->sp);
        SET_TCP_DST_PORT(p,&f->dp);
    } else if (p->udph != NULL) { /* XXX MACRO */
        SET_UDP_SRC_PORT(p,&f->sp);
        SET_UDP_DST_PORT(p,&f->dp);
    } else if (p->icmpv4h != NULL) {
        f->type = p->type;
        f->code = p->code;
    } else if (p->icmpv6h != NULL) {
        f->type = p->type;
        f->code = p->code;
    } else if (p->sctph != NULL) { /* XXX MACRO */
        SET_SCTP_SRC_PORT(p,&f->sp);
        SET_SCTP_DST_PORT(p,&f->dp);
    } /* XXX handle default */
#ifdef DEBUG
    else {
        printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
    }
#endif
    COPY_TIMESTAMP(&p->ts, &f->startts);

    f->protomap = FlowGetProtoMapping(f->proto);

    SCReturn;
}
예제 #18
0
/** \internal
 *  \brief fill lua stack with header info
 *  \param luastate the lua state
 *  \param p packet
 *  \retval cnt number of data items placed on the stack
 *
 *  Places: ipver (number), src ip (string), dst ip (string), protocol (number),
 *          sp or icmp type (number), dp or icmp code (number).
 */
static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p)
{
    int ipver = 0;
    if (PKT_IS_IPV4(p)) {
        ipver = 4;
    } else if (PKT_IS_IPV6(p)) {
        ipver = 6;
    }
    lua_pushnumber (luastate, ipver);
    if (ipver == 0)
        return 1;

    char srcip[46] = "", dstip[46] = "";
    if (PKT_IS_IPV4(p)) {
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
    } else if (PKT_IS_IPV6(p)) {
        PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
    }

    lua_pushstring (luastate, srcip);
    lua_pushstring (luastate, dstip);

    /* proto and ports (or type/code) */
    lua_pushnumber (luastate, p->proto);
    if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) {
        lua_pushnumber (luastate, p->sp);
        lua_pushnumber (luastate, p->dp);

    } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
        lua_pushnumber (luastate, p->type);
        lua_pushnumber (luastate, p->code);
    } else {
        lua_pushnumber (luastate, 0);
        lua_pushnumber (luastate, 0);
    }

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

    if ( ! p )
        SCReturnInt(0);

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

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

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

        if ( PKT_IS_TCP(p) ) {
            AddIntData(alert, "tcp_seq", ntohl(p->tcph->th_seq));
            AddIntData(alert, "tcp_ack", ntohl(p->tcph->th_ack));

            AddIntData(alert, "tcp_off", TCP_GET_RAW_OFFSET(p->tcph));
            AddIntData(alert, "tcp_res", TCP_GET_RAW_X2(p->tcph));
            AddIntData(alert, "tcp_flags", p->tcph->th_flags);

            AddIntData(alert, "tcp_win", ntohs(p->tcph->th_win));
            AddIntData(alert, "tcp_sum", ntohs(p->tcph->th_sum));
            AddIntData(alert, "tcp_urp", ntohs(p->tcph->th_urp));

        }

        else if ( PKT_IS_UDP(p) ) {
            AddIntData(alert, "udp_len", ntohs(p->udph->uh_len));
            AddIntData(alert, "udp_sum", ntohs(p->udph->uh_sum));
        }

        else if ( PKT_IS_ICMPV4(p) ) {
            AddIntData(alert, "icmp_type", p->icmpv4h->type);
            AddIntData(alert, "icmp_code", p->icmpv4h->code);
            AddIntData(alert, "icmp_sum", ntohs(p->icmpv4h->checksum));

        }
    }

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

    SCReturnInt(0);
}
예제 #20
0
int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
{
    SCEnter();

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

    int r = 0;
    if (PKT_IS_IPV4(p)) {
        r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET);
    } else if (PKT_IS_IPV6(p)) {
        r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET6);
    }

    SCReturnInt(r);
}
예제 #21
0
파일: detect-ttl.c 프로젝트: thus/suricata
/**
 * \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);
}
예제 #22
0
/**
 *  \brief Unified2 main entry function
 *
 *  \retval TM_ECODE_OK all is good
 *  \retval TM_ECODE_FAILED serious error
 */
TmEcode Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    int ret = 0;

    if (PKT_IS_IPV4(p)) {
        ret = Unified2IPv4TypeAlert (t, p, data, pq);
    } else if(PKT_IS_IPV6(p)) {
        ret = Unified2IPv6TypeAlert (t, p, data, pq);
    } else {
        /* we're only supporting IPv4 and IPv6 */
        return TM_ECODE_OK;
    }

    if (ret != 0) {
        return TM_ECODE_FAILED;
    }

    return TM_ECODE_OK;
}
예제 #23
0
TmEcode LogHttpLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    SCEnter();

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

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

    if (PKT_IS_IPV4(p)) {
        SCReturnInt(LogHttpLogIPv4(tv, p, data, pq, postpq));
    } else if (PKT_IS_IPV6(p)) {
        SCReturnInt(LogHttpLogIPv6(tv, p, data, pq, postpq));
    }

    SCReturnInt(TM_ECODE_OK);
}
예제 #24
0
static int LogFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff)
{
    SCEnter();
    LogFileLogThread *aft = (LogFileLogThread *)thread_data;
    int ipver = -1;

    if (PKT_IS_IPV4(p)) {
        ipver = AF_INET;
    } else if (PKT_IS_IPV6(p)) {
        ipver = AF_INET6;
    } else {
        return 0;
    }

    BUG_ON(ff->flags & FILE_LOGGED);

    SCLogDebug("ff %p", ff);

    LogFileWriteJsonRecord(aft, p, ff, ipver);

    aft->file_cnt++;
    return 0;
}
예제 #25
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);;
}
예제 #26
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);
}
예제 #27
0
TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {
    int ret = 0;

    /* ACTION_REJECT defaults to rejecting the SRC */
    if (!(p->action & ACTION_REJECT) &&
        !(p->action & ACTION_REJECT_DST) &&
        !(p->action & ACTION_REJECT_BOTH)) {
        return TM_ECODE_OK;
    }

    if (PKT_IS_IPV4(p)) {
        if (PKT_IS_TCP(p)) {
            ret = RejectSendIPv4TCP(tv, p, data);
        } else if(PKT_IS_UDP(p)) {
            ret = RejectSendIPv4ICMP(tv, p, data);
        } else {
            return TM_ECODE_OK;
        }
    } else if (PKT_IS_IPV6(p)) {
        if (PKT_IS_TCP(p)) {
            ret = RejectSendIPv6TCP(tv, p, data);
        } else if(PKT_IS_UDP(p)){
            ret = RejectSendIPv6ICMP(tv, p, data);
        } else {
            return TM_ECODE_OK;
        }
    } else {
        /* we're only supporting IPv4 and IPv6 */
        return TM_ECODE_OK;
    }

    if (ret)
        return TM_ECODE_FAILED;
    else
        return TM_ECODE_OK;
}
예제 #28
0
json_t *CreateJSONHeader(Packet *p, int direction_sensitive, char *event_type)
{
    char timebuf[64];
    char srcip[46], dstip[46];
    Port sp, dp;

    json_t *js = json_object();
    if (unlikely(js == NULL))
        return NULL;

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

    srcip[0] = '\0';
    dstip[0] = '\0';
    if (direction_sensitive) {
        if ((PKT_IS_TOCLIENT(p))) {
            if (PKT_IS_IPV4(p)) {
                PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
                PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
            } else if (PKT_IS_IPV6(p)) {
                PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
                PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
            }
            sp = p->sp;
            dp = p->dp;
        } else {
            if (PKT_IS_IPV4(p)) {
                PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip));
                PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip));
            } else if (PKT_IS_IPV6(p)) {
                PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip));
                PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip));
            }
            sp = p->dp;
            dp = p->sp;
        }
    } else {
        if (PKT_IS_IPV4(p)) {
            PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
            PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
        } else if (PKT_IS_IPV6(p)) {
            PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
            PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
        }
        sp = p->sp;
        dp = p->dp;
    }

    char proto[16];
    if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) {
        strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto));
    } else {
        snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p));
    }

    /* time & tx */
    json_object_set_new(js, "time", json_string(timebuf));

    /* sensor id */
    if (sensor_id >= 0)
        json_object_set_new(js, "sensor_id", json_integer(sensor_id));

    /* pcap_cnt */
    if (p->pcap_cnt != 0) {
        json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt));
    }

    if (event_type) {
        json_object_set_new(js, "event_type", json_string(event_type));
    }

    /* vlan */
    if (p->vlan_idx > 0) {
        json_t *js_vlan;
        switch (p->vlan_idx) {
            case 1:
                json_object_set_new(js, "vlan",
                                    json_integer(ntohs(GET_VLAN_ID(p->vlanh[0]))));
                break;
            case 2:
                js_vlan = json_array();
                if (unlikely(js != NULL)) {
                    json_array_append_new(js_vlan,
                                    json_integer(ntohs(GET_VLAN_ID(p->vlanh[0]))));
                    json_array_append_new(js_vlan,
                                    json_integer(ntohs(GET_VLAN_ID(p->vlanh[1]))));
                    json_object_set_new(js, "vlan", js_vlan);
                }
                break;
            default:
                /* shouldn't get here */
                break;
        }
    }

    /* tuple */
    json_object_set_new(js, "src_ip", json_string(srcip));
    switch(p->proto) {
        case IPPROTO_ICMP:
            break;
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
            json_object_set_new(js, "src_port", json_integer(sp));
            break;
    }
    json_object_set_new(js, "dest_ip", json_string(dstip));
    switch(p->proto) {
        case IPPROTO_ICMP:
            break;
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
            json_object_set_new(js, "dest_port", json_integer(dp));
            break;
    }
    json_object_set_new(js, "proto", json_string(proto));
    switch (p->proto) {
        case IPPROTO_ICMP:
            if (p->icmpv4h) {
                json_object_set_new(js, "icmp_type",
                                    json_integer(p->icmpv4h->type));
                json_object_set_new(js, "icmp_code",
                                    json_integer(p->icmpv4h->code));
            }
            break;
        case IPPROTO_ICMPV6:
            if (p->icmpv6h) {
                json_object_set_new(js, "icmp_type",
                                    json_integer(p->icmpv6h->type));
                json_object_set_new(js, "icmp_code",
                                    json_integer(p->icmpv6h->code));
            }
            break;
    }

    return js;
}
예제 #29
0
void SCProfilingAddPacket(Packet *p)
{
    if (p == NULL || p->profile == NULL ||
        p->profile->ticks_start == 0 || p->profile->ticks_end == 0 ||
        p->profile->ticks_start > p->profile->ticks_end)
        return;

    pthread_mutex_lock(&packet_profile_lock);
    {

        if (profiling_packets_csv_enabled)
            SCProfilingPrintPacketProfile(p);

        if (PKT_IS_IPV4(p)) {
            SCProfilePacketData *pd = &packet_profile_data4[p->proto];

            uint64_t delta = p->profile->ticks_end - p->profile->ticks_start;
            if (pd->min == 0 || delta < pd->min) {
                pd->min = delta;
            }
            if (pd->max < delta) {
                pd->max = delta;
            }

            pd->tot += delta;
            pd->cnt ++;

            if (IS_TUNNEL_PKT(p)) {
                pd = &packet_profile_data4[256];

                if (pd->min == 0 || delta < pd->min) {
                    pd->min = delta;
                }
                if (pd->max < delta) {
                    pd->max = delta;
                }

                pd->tot += delta;
                pd->cnt ++;
            }

            SCProfilingUpdatePacketGenericRecords(p, p->profile->flowworker,
                packet_profile_flowworker_data, PROFILE_FLOWWORKER_SIZE);

            SCProfilingUpdatePacketTmmRecords(p);
            SCProfilingUpdatePacketAppRecords(p);
            SCProfilingUpdatePacketDetectRecords(p);
            SCProfilingUpdatePacketLogRecords(p);

        } else if (PKT_IS_IPV6(p)) {
            SCProfilePacketData *pd = &packet_profile_data6[p->proto];

            uint64_t delta = p->profile->ticks_end - p->profile->ticks_start;
            if (pd->min == 0 || delta < pd->min) {
                pd->min = delta;
            }
            if (pd->max < delta) {
                pd->max = delta;
            }

            pd->tot += delta;
            pd->cnt ++;

            if (IS_TUNNEL_PKT(p)) {
                pd = &packet_profile_data6[256];

                if (pd->min == 0 || delta < pd->min) {
                    pd->min = delta;
                }
                if (pd->max < delta) {
                    pd->max = delta;
                }

                pd->tot += delta;
                pd->cnt ++;
            }

            SCProfilingUpdatePacketGenericRecords(p, p->profile->flowworker,
                packet_profile_flowworker_data, PROFILE_FLOWWORKER_SIZE);

            SCProfilingUpdatePacketTmmRecords(p);
            SCProfilingUpdatePacketAppRecords(p);
            SCProfilingUpdatePacketDetectRecords(p);
            SCProfilingUpdatePacketLogRecords(p);
        }
    }
    pthread_mutex_unlock(&packet_profile_lock);
}
예제 #30
0
static TmEcode AlertDebugLogger(ThreadVars *tv, const Packet *p, void *thread_data)
{
    AlertDebugLogThread *aft = (AlertDebugLogThread *)thread_data;
    int i;
    char timebuf[64];
    const char *pkt_src_str = NULL;

    if (p->alerts.cnt == 0)
        return TM_ECODE_OK;

    MemBufferReset(aft->buffer);

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

    MemBufferWriteString(aft->buffer, "+================\n"
                         "TIME:              %s\n", timebuf);
    if (p->pcap_cnt > 0) {
        MemBufferWriteString(aft->buffer, "PCAP PKT NUM:      %"PRIu64"\n", p->pcap_cnt);
    }
    pkt_src_str = PktSrcToString(p->pkt_src);
    MemBufferWriteString(aft->buffer, "PKT SRC:           %s\n", pkt_src_str);

    char srcip[46], dstip[46];
    if (PKT_IS_IPV4(p)) {
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
    } else if (PKT_IS_IPV6(p)) {
        PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
    }

    MemBufferWriteString(aft->buffer, "SRC IP:            %s\n"
                         "DST IP:            %s\n"
                         "PROTO:             %" PRIu32 "\n",
                         srcip, dstip, p->proto);
    if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) {
        MemBufferWriteString(aft->buffer, "SRC PORT:          %" PRIu32 "\n"
                             "DST PORT:          %" PRIu32 "\n",
                             p->sp, p->dp);
        if (PKT_IS_TCP(p)) {
            MemBufferWriteString(aft->buffer, "TCP SEQ:           %"PRIu32"\n"
                                 "TCP ACK:           %"PRIu32"\n",
                                 TCP_GET_SEQ(p), TCP_GET_ACK(p));
        }
    }

    /* flow stuff */
    MemBufferWriteString(aft->buffer, "FLOW:              to_server: %s, "
                         "to_client: %s\n",
                         p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE",
                         p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE");

    if (p->flow != NULL) {
        int applayer = 0;
        applayer = StreamTcpAppLayerIsDisabled(p->flow);
        CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf));
        MemBufferWriteString(aft->buffer, "FLOW Start TS:     %s\n", timebuf);
        MemBufferWriteString(aft->buffer, "FLOW PKTS TODST:   %"PRIu32"\n"
                             "FLOW PKTS TOSRC:   %"PRIu32"\n"
                             "FLOW Total Bytes:  %"PRIu64"\n",
                             p->flow->todstpktcnt, p->flow->tosrcpktcnt,
                             p->flow->todstbytecnt + p->flow->tosrcbytecnt);
        MemBufferWriteString(aft->buffer,
                             "FLOW IPONLY SET:   TOSERVER: %s, TOCLIENT: %s\n"
                             "FLOW ACTION:       DROP: %s\n"
                             "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n"
                             "FLOW APP_LAYER:    DETECTED: %s, PROTO %"PRIu16"\n",
                             p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE",
                             p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE",
                             p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE",
                             p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE",
                             p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE",
                             applayer ? "TRUE" : "FALSE",
                             (p->flow->alproto != ALPROTO_UNKNOWN) ? "TRUE" : "FALSE", p->flow->alproto);
        AlertDebugLogFlowVars(aft, p);
    }

    AlertDebugLogPktVars(aft, p);

/* any stuff */
/* Sig details? */

    MemBufferWriteString(aft->buffer,
                         "PACKET LEN:        %" PRIu32 "\n"
                         "PACKET:\n",
                         GET_PKT_LEN(p));
    PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
                         GET_PKT_DATA(p), GET_PKT_LEN(p));

    MemBufferWriteString(aft->buffer, "ALERT CNT:           %" PRIu32 "\n",
                         p->alerts.cnt);

    for (i = 0; i < p->alerts.cnt; i++) {
        const PacketAlert *pa = &p->alerts.alerts[i];
        if (unlikely(pa->s == NULL)) {
            continue;
        }

        MemBufferWriteString(aft->buffer,
                             "ALERT MSG [%02d]:      %s\n"
                             "ALERT GID [%02d]:      %" PRIu32 "\n"
                             "ALERT SID [%02d]:      %" PRIu32 "\n"
                             "ALERT REV [%02d]:      %" PRIu32 "\n"
                             "ALERT CLASS [%02d]:    %s\n"
                             "ALERT PRIO [%02d]:     %" PRIu32 "\n"
                             "ALERT FOUND IN [%02d]: %s\n",
                             i, pa->s->msg,
                             i, pa->s->gid,
                             i, pa->s->id,
                             i, pa->s->rev,
                             i, pa->s->class_msg ? pa->s->class_msg : "<none>",
                             i, pa->s->prio,
                             i,
                             pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH  ? "STREAM" :
                             (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET"));
        if (pa->flags & PACKET_ALERT_FLAG_TX) {
            MemBufferWriteString(aft->buffer,
                    "ALERT IN TX [%02d]:    %"PRIu64"\n", i, pa->tx_id);
        } else {
            MemBufferWriteString(aft->buffer,
                    "ALERT IN TX [%02d]:    N/A\n", i);
        }
        if (p->payload_len > 0) {
            MemBufferWriteString(aft->buffer,
                                 "PAYLOAD LEN:         %" PRIu32 "\n"
                                 "PAYLOAD:\n",
                                 p->payload_len);
            PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
                                 p->payload, p->payload_len);
        }
        if ((pa->flags & PACKET_ALERT_FLAG_STATE_MATCH) ||
            (pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH)) {
            /* This is an app layer or stream alert */
            int ret;
            uint8_t flag;
            if (!(PKT_IS_TCP(p)) || p->flow == NULL ||
                    p->flow->protoctx == NULL) {
                return TM_ECODE_OK;
            }
            /* IDS mode reverse the data */
            /** \todo improve the order selection policy */
            if (p->flowflags & FLOW_PKT_TOSERVER) {
                flag = FLOW_PKT_TOCLIENT;
            } else {
                flag = FLOW_PKT_TOSERVER;
            }
            ret = StreamSegmentForEach((const Packet *)p, flag,
                                 AlertDebugPrintStreamSegmentCallback,
                                 (void *)aft);
            if (ret < 0) {
                return TM_ECODE_FAILED;
            }
        }
    }

    aft->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer),
        MEMBUFFER_OFFSET(aft->buffer), aft->file_ctx);

    return TM_ECODE_OK;
}