コード例 #1
0
ファイル: decode.c プロジェクト: coanor/suricata
/**
 *  \brief Copy data to Packet payload at given offset
 *
 * This function copies data/payload to a Packet. It uses the
 * space allocated at Packet creation (pointed by Packet::pkt)
 * or allocate some memory (pointed by Packet::ext_pkt) if the
 * data size is too big to fit in initial space (of size
 * default_packet_size).
 *
 *  \param Pointer to the Packet to modify
 *  \param Offset of the copy relatively to payload of Packet
 *  \param Pointer to the data to copy
 *  \param Length of the data to copy
 */
inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen)
{
    if (unlikely(offset + datalen > MAX_PAYLOAD_SIZE)) {
        /* too big */
        return -1;
    }

    /* Do we have already an packet with allocated data */
    if (! p->ext_pkt) {
        if (offset + datalen <= (int)default_packet_size) {
            /* data will fit in memory allocated with packet */
            memcpy(GET_PKT_DIRECT_DATA(p) + offset, data, datalen);
        } else {
            /* here we need a dynamic allocation */
            p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE);
            if (unlikely(p->ext_pkt == NULL)) {
                SET_PKT_LEN(p, 0);
                return -1;
            }
            /* copy initial data */
            memcpy(p->ext_pkt, GET_PKT_DIRECT_DATA(p), GET_PKT_DIRECT_MAX_SIZE(p));
            /* copy data as asked */
            memcpy(p->ext_pkt + offset, data, datalen);
        }
    } else {
        memcpy(p->ext_pkt + offset, data, datalen);
    }
    return 0;
}
コード例 #2
0
ファイル: source-pfring.c プロジェクト: AmesianX/suricata
/**
 * \brief Pfring Packet Process function.
 *
 * This function fills in our packet structure from libpfring.
 * From here the packets are picked up by the  DecodePfring thread.
 *
 * \param user pointer to PfringThreadVars
 * \param h pointer to pfring packet header
 * \param p pointer to the current packet
 */
static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p)
{

    PfringThreadVars *ptv = (PfringThreadVars *)user;

    ptv->bytes += h->caplen;
    ptv->pkts++;
    p->livedev = ptv->livedev;

    /* PF_RING may fail to set timestamp */
    if (h->ts.tv_sec == 0) {
        gettimeofday((struct timeval *)&h->ts, NULL);
    }

    p->ts.tv_sec = h->ts.tv_sec;
    p->ts.tv_usec = h->ts.tv_usec;

    /* PF_RING all packets are marked as a link type of ethernet
     * so that is what we do here. */
    p->datalink = LINKTYPE_ETHERNET;

    /* get vlan id from header. Check on vlan_id not null even if comment in
     * header announce NO_VLAN is used when there is no VLAN. But NO_VLAN
     * is not defined nor used in PF_RING code. And vlan_id is set to 0
     * in PF_RING kernel code when there is no VLAN. */
    if ((!ptv->vlan_disabled) && h->extended_hdr.parsed_pkt.vlan_id) {
        p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff;
        p->vlan_idx = 1;
        p->vlanh[0] = NULL;
    }

    switch (ptv->checksum_mode) {
        case CHECKSUM_VALIDATION_RXONLY:
            if (h->extended_hdr.rx_direction == 0) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        case CHECKSUM_VALIDATION_DISABLE:
            p->flags |= PKT_IGNORE_CHECKSUM;
            break;
        case CHECKSUM_VALIDATION_AUTO:
            if (ptv->livedev->ignore_checksum) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            } else if (ChecksumAutoModeCheck(ptv->pkts,
                        SC_ATOMIC_GET(ptv->livedev->pkts),
                        SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
                ptv->livedev->ignore_checksum = 1;
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        default:
            break;
    }

    SET_PKT_LEN(p, h->caplen);
}
コード例 #3
0
ファイル: decode.c プロジェクト: coanor/suricata
/**
 * \brief Set data for Packet and set length when zeo copy is used
 *
 *  \param Pointer to the Packet to modify
 *  \param Pointer to the data
 *  \param Length of the data
 */
inline int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen)
{
    SET_PKT_LEN(p, (size_t)pktlen);
    if (unlikely(!pktdata)) {
        return -1;
    }
    p->ext_pkt = pktdata;
    p->flags |= PKT_ZERO_COPY;

    return 0;
}
コード例 #4
0
ファイル: decode.c プロジェクト: atonkyra/suricata
inline int PacketCallocExtPkt(Packet *p, int datalen)
{
    if (! p->ext_pkt) {
        p->ext_pkt = SCCalloc(1, datalen);
        if (unlikely(p->ext_pkt == NULL)) {
            SET_PKT_LEN(p, 0);
            return -1;
        }
    }
    return 0;
}
コード例 #5
0
ファイル: source-erf-dag.c プロジェクト: 58698301/suricata
/**
 * \brief   Process a DAG record into a TM packet buffer.
 * \param   prec pointer to a DAG record.
 * \param
 */
TmEcode ProcessErfDagRecord(ErfDagThreadVars *ewtn, char *prec, Packet *p)
{
    SCEnter();

    int wlen = 0;
    dag_record_t  *dr = (dag_record_t*)prec;
    erf_payload_t *pload;

    assert(prec);
    assert(p);

    if (p == NULL) SCReturnInt(TM_ECODE_OK);

    /* Only support ethernet at this time. */
    if (dr->type != TYPE_ETH &&
	    dr->type != TYPE_DSM_COLOR_ETH &&
	    dr->type != TYPE_COLOR_ETH &&
	    dr->type != TYPE_COLOR_HASH_ETH) {
        SCLogError(SC_ERR_UNIMPLEMENTED,
                   "Processing of DAG record type: %d not implemented.", dr->type);
        SCReturnInt(TM_ECODE_FAILED);
    }

    wlen = ntohs(dr->wlen);

    pload = &(dr->rec);

    SET_PKT_LEN(p, wlen - 4);   /* Trim the FCS... */
    p->datalink = LINKTYPE_ETHERNET;

    /* Take into account for link type Ethernet ETH frame starts
     * after ther ERF header + pad.
     */
    PacketCopyData(p, pload->eth.dst, GET_PKT_LEN(p));

    SCLogDebug("pktlen: %" PRIu32 " (pkt %02x, pkt data %02x)",
               GET_PKT_LEN(p), *p, *GET_PKT_DATA(p));

    /* Convert ERF time to timeval - from libpcap. */
    uint64_t ts = dr->ts;
    p->ts.tv_sec = ts >> 32;
    ts = (ts & 0xffffffffULL) * 1000000;
    ts += 0x80000000; /* rounding */
    p->ts.tv_usec = ts >> 32;
    if (p->ts.tv_usec >= 1000000) {
        p->ts.tv_usec -= 1000000;
        p->ts.tv_sec++;
    }

    ewtn->pkts++;
    ewtn->bytes += wlen;

    SCReturnInt(TM_ECODE_OK);
}
コード例 #6
0
ファイル: source-pfring.c プロジェクト: song-liu/suricata
/**
 * \brief Pfring Packet Process function.
 *
 * This function fills in our packet structure from libpfring.
 * From here the packets are picked up by the  DecodePfring thread.
 *
 * \param user pointer to PfringThreadVars
 * \param h pointer to pfring packet header
 * \param p pointer to the current packet
 */
static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) {

    PfringThreadVars *ptv = (PfringThreadVars *)user;

    ptv->bytes += h->caplen;
    ptv->pkts++;
    p->livedev = ptv->livedev;

    /* PF_RING may fail to set timestamp */
    if (h->ts.tv_sec == 0) {
        gettimeofday((struct timeval *)&h->ts, NULL);
    }

    p->ts.tv_sec = h->ts.tv_sec;
    p->ts.tv_usec = h->ts.tv_usec;

    /* PF_RING all packets are marked as a link type of ethernet
     * so that is what we do here. */
    p->datalink = LINKTYPE_ETHERNET;

    switch (ptv->checksum_mode) {
        case CHECKSUM_VALIDATION_RXONLY:
            if (h->extended_hdr.rx_direction == 0) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        case CHECKSUM_VALIDATION_DISABLE:
            p->flags |= PKT_IGNORE_CHECKSUM;
            break;
        case CHECKSUM_VALIDATION_AUTO:
            if (ptv->livedev->ignore_checksum) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            } else if (ChecksumAutoModeCheck(ptv->pkts,
                        SC_ATOMIC_GET(ptv->livedev->pkts),
                        SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
                ptv->livedev->ignore_checksum = 1;
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        default:
            break;
    }

    SET_PKT_LEN(p, h->caplen);
}
コード例 #7
0
static int Unified2Test05 (void)   {
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;
    void *data = NULL;
    OutputCtx *oc;
    LogFileCtx *lf;
    Signature s;

    uint8_t raw_ipv4_tcp[] = {
        0x00, 0x14, 0xbf, 0xe8, 0xcb, 0x26, 0xaa, 0x00,
        0x04, 0x00, 0x0a, 0x04, 0x08, 0x00, 0x45, 0x00,
        0x00, 0x3c, 0x8c, 0x55, 0x40, 0x00, 0x40, 0x06,
        0x69, 0x86, 0xc0, 0xa8, 0x0a, 0x68, 0x4a, 0x7d,
        0x2f, 0x53, 0xc2, 0x40, 0x00, 0x50, 0x1f, 0x00,
        0xa4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
        0x16, 0xd0, 0x3d, 0x4e, 0x00, 0x00, 0x02, 0x04,
        0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x00, 0x1c,
        0x28, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03,
        0x03, 0x06};
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    int ret;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&pq, 0, sizeof(PacketQueue));
    p->pkt = (uint8_t *)(p + 1);
    memset(&s, 0, sizeof(Signature));

    p->alerts.cnt++;
    p->alerts.alerts[p->alerts.cnt-1].s = &s;
    p->alerts.alerts[p->alerts.cnt-1].s->id = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->gid = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->rev = 1;
    SET_PKT_LEN(p, sizeof(raw_ipv4_tcp));

    FlowInitConfig(FLOW_QUIET);

    DecodeEthernet(&tv, &dtv, p, raw_ipv4_tcp, sizeof(raw_ipv4_tcp), &pq);

    FlowShutdown();

    p->action = ACTION_DROP;

    oc = Unified2AlertInitCtx(NULL);
    if (oc == NULL) {
        SCFree(p);
        return 0;
    }
    lf = (LogFileCtx *)oc->data;
    if(lf == NULL) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadInit(&tv, oc, &data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }
    ret = Unified2Alert(&tv, p, data, &pq, NULL);
    if(ret == TM_ECODE_FAILED) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadDeinit(&tv, data);
    if(ret == TM_ECODE_FAILED) {
        SCFree(p);
        return 0;
    }

    Unified2AlertDeInitCtx(oc);

    PACKET_CLEANUP(p);
    SCFree(p);
    return 1;
}
コード例 #8
0
static int Unified2Test04 (void)   {
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;
    void *data = NULL;
    OutputCtx *oc;
    LogFileCtx *lf;
    Signature s;

    uint8_t raw_ppp[] = {
        0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c,
        0x4d, 0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17,
        0xbf, 0x01, 0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03,
        0xea, 0x37, 0x00, 0x17, 0x6d, 0x0b, 0xba, 0xc3,
        0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x10, 0x20,
        0xdd, 0xe1, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4};
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    int ret;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&pq, 0, sizeof(PacketQueue));
    p->pkt = (uint8_t *)(p + 1);
    memset(&s, 0, sizeof(Signature));

    p->alerts.cnt++;
    p->alerts.alerts[p->alerts.cnt-1].s = &s;
    p->alerts.alerts[p->alerts.cnt-1].s->id = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->gid = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->rev = 1;
    SET_PKT_LEN(p, sizeof(raw_ppp));

    FlowInitConfig(FLOW_QUIET);

    DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), &pq);

    FlowShutdown();

    oc = Unified2AlertInitCtx(NULL);
    if (oc == NULL) {
        SCFree(p);
        return 0;
    }
    lf = (LogFileCtx *)oc->data;
    if(lf == NULL) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadInit(&tv, oc, &data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }
    ret = Unified2Alert(&tv, p, data, &pq, NULL);
    if(ret == TM_ECODE_FAILED) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadDeinit(&tv, data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }

    Unified2AlertDeInitCtx(oc);

    PACKET_CLEANUP(p);
    SCFree(p);
    return 1;
}
コード例 #9
0
static int Unified2Test03 (void) {
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;
    void *data = NULL;
    OutputCtx *oc;
    LogFileCtx *lf;
    Signature s;

    uint8_t raw_gre[] = {
        0x00, 0x0e, 0x50, 0x06, 0x42, 0x96, 0xaa, 0x00,
        0x04, 0x00, 0x0a, 0x04, 0x08, 0x00, 0x45, 0x00,
        0x00, 0x74, 0x35, 0xa2, 0x40, 0x00, 0x40, 0x2f,
        0xef, 0xcb, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00,
        0x00, 0x8a, 0x30, 0x01, 0x88, 0x0b, 0x00, 0x54,
        0x00, 0x00, 0x00, 0x18, 0x29, 0x5f, 0xff, 0x03,
        0x00, 0x21, 0x45, 0x00, 0x00, 0x50, 0xf4, 0x05,
        0x40, 0x00, 0x3f, 0x06, 0x20, 0xb8, 0x50, 0x7e,
        0x2b, 0x2d, 0xd4, 0xcc, 0xd6, 0x72, 0x0a, 0x92,
        0x1a, 0x0b, 0xc9, 0xaf, 0x24, 0x02, 0x8c, 0xdd,
        0x45, 0xf6, 0x80, 0x18, 0x21, 0xfc, 0x10, 0x7c,
        0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x08, 0x19,
        0x1a, 0xda, 0x84, 0xd6, 0xda, 0x3e, 0x50, 0x49,
        0x4e, 0x47, 0x20, 0x73, 0x74, 0x65, 0x72, 0x6c,
        0x69, 0x6e, 0x67, 0x2e, 0x66, 0x72, 0x65, 0x65,
        0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74,
        0x0d, 0x0a};
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    int ret;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&pq, 0, sizeof(PacketQueue));
    p->pkt = (uint8_t *)(p + 1);
    memset(&s, 0, sizeof(Signature));

    p->alerts.cnt++;
    p->alerts.alerts[p->alerts.cnt-1].s = &s;
    p->alerts.alerts[p->alerts.cnt-1].s->id = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->gid = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->rev = 1;
    SET_PKT_LEN(p, sizeof(raw_gre));

    FlowInitConfig(FLOW_QUIET);

    DecodeEthernet(&tv, &dtv, p, raw_gre, sizeof(raw_gre), &pq);

    FlowShutdown();

    oc = Unified2AlertInitCtx(NULL);
    if (oc == NULL) {
        SCFree(p);
        return 0;
    }
    lf = (LogFileCtx *)oc->data;
    if(lf == NULL) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadInit(&tv, oc, &data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }
    ret = Unified2Alert(&tv, p, data, &pq, NULL);
    if(ret == TM_ECODE_FAILED) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadDeinit(&tv, data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }

    Unified2AlertDeInitCtx(oc);

    Packet *pkt = PacketDequeue(&pq);
    while (pkt != NULL) {
        SCFree(pkt);
        pkt = PacketDequeue(&pq);
    }

    PACKET_CLEANUP(p);
    SCFree(p);
    return 1;
}
コード例 #10
0
/**
 * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests
 * specifying ip and port sources and destinations (IPV6)
 *
 * \param payload pointer to the payloadd buffer
 * \param payload_len pointer to the length of the payload
 * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP
 * \param src pointer to a string containing the ip source
 * \param dst pointer to a string containing the ip destination
 * \param sport pointer to a string containing the port source
 * \param dport pointer to a string containing the port destination
 *
 * \retval Packet pointer to the built in packet
 */
Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len,
                           uint8_t ipproto, char *src, char *dst,
                           uint16_t sport, uint16_t dport)
{
    uint32_t in[4];

    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return NULL;

    TimeSet(&p->ts);

    p->src.family = AF_INET6;
    p->dst.family = AF_INET6;
    p->payload = payload;
    p->payload_len = payload_len;
    p->proto = ipproto;

    p->ip6h = SCMalloc(sizeof(IPV6Hdr));
    if (p->ip6h == NULL)
        goto error;
    memset(p->ip6h, 0, sizeof(IPV6Hdr));
    p->ip6h->s_ip6_nxt = ipproto;
    p->ip6h->s_ip6_plen = htons(payload_len + sizeof(TCPHdr));

    if (inet_pton(AF_INET6, src, &in) != 1)
        goto error;
    p->src.addr_data32[0] = in[0];
    p->src.addr_data32[1] = in[1];
    p->src.addr_data32[2] = in[2];
    p->src.addr_data32[3] = in[3];
    p->sp = sport;
    p->ip6h->s_ip6_src[0] = in[0];
    p->ip6h->s_ip6_src[1] = in[1];
    p->ip6h->s_ip6_src[2] = in[2];
    p->ip6h->s_ip6_src[3] = in[3];

    if (inet_pton(AF_INET6, dst, &in) != 1)
        goto error;
    p->dst.addr_data32[0] = in[0];
    p->dst.addr_data32[1] = in[1];
    p->dst.addr_data32[2] = in[2];
    p->dst.addr_data32[3] = in[3];
    p->dp = dport;
    p->ip6h->s_ip6_dst[0] = in[0];
    p->ip6h->s_ip6_dst[1] = in[1];
    p->ip6h->s_ip6_dst[2] = in[2];
    p->ip6h->s_ip6_dst[3] = in[3];

    p->tcph = SCMalloc(sizeof(TCPHdr));
    if (p->tcph == NULL)
        goto error;
    memset(p->tcph, 0, sizeof(TCPHdr));
    p->tcph->th_sport = htons(sport);
    p->tcph->th_dport = htons(dport);

    SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(TCPHdr) + payload_len);
    return p;

error:
    if (p != NULL) {
        if (p->ip6h != NULL) {
            SCFree(p->ip6h);
        }
        if (p->tcph != NULL) {
            SCFree(p->tcph);
        }
        SCFree(p);
    }
    return NULL;
}
コード例 #11
0
ファイル: source-pfring.c プロジェクト: bmeeks8/suricata
/**
 * \brief Pfring Packet Process function.
 *
 * This function fills in our packet structure from libpfring.
 * From here the packets are picked up by the  DecodePfring thread.
 *
 * \param user pointer to PfringThreadVars
 * \param h pointer to pfring packet header
 * \param p pointer to the current packet
 */
static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p)
{
    PfringThreadVars *ptv = (PfringThreadVars *)user;

    ptv->bytes += h->caplen;
    ptv->pkts++;
    p->livedev = ptv->livedev;

    /* PF_RING may fail to set timestamp */
    if (h->ts.tv_sec == 0) {
        gettimeofday((struct timeval *)&h->ts, NULL);
    }

    p->ts.tv_sec = h->ts.tv_sec;
    p->ts.tv_usec = h->ts.tv_usec;

    /* PF_RING all packets are marked as a link type of ethernet
     * so that is what we do here. */
    p->datalink = LINKTYPE_ETHERNET;

    /* In the past, we needed this vlan handling in cases
     * where the vlan header was stripped from the raw packet.
     * With modern (at least >= 6) versions of PF_RING, the
     * 'copy_data_to_ring' function (kernel/pf_ring.c) makes
     * sure that if the hardware stripped the vlan header,
     * it is put back by PF_RING.
     *
     * PF_RING should put it back in all cases, but as a extra
     * precaution keep the check here. If the vlan header is
     * part of the raw packet, the vlan_offset will be set.
     * So is it is not set, use the parsed info from PF_RING's
     * extended header.
     */
    if ((!ptv->vlan_disabled) &&
        h->extended_hdr.parsed_pkt.offset.vlan_offset == 0 &&
        h->extended_hdr.parsed_pkt.vlan_id)
    {
        p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff;
        p->vlan_idx = 1;
        p->vlanh[0] = NULL;

        if (!ptv->vlan_hdr_warned) {
            SCLogWarning(SC_ERR_PF_RING_VLAN, "no VLAN header in the raw "
                    "packet. See #2355.");
            ptv->vlan_hdr_warned = true;
        }
    }

    switch (ptv->checksum_mode) {
        case CHECKSUM_VALIDATION_RXONLY:
            if (h->extended_hdr.rx_direction == 0) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        case CHECKSUM_VALIDATION_DISABLE:
            p->flags |= PKT_IGNORE_CHECKSUM;
            break;
        case CHECKSUM_VALIDATION_AUTO:
            if (ptv->livedev->ignore_checksum) {
                p->flags |= PKT_IGNORE_CHECKSUM;
            } else if (ChecksumAutoModeCheck(ptv->pkts,
                        SC_ATOMIC_GET(ptv->livedev->pkts),
                        SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
                ptv->livedev->ignore_checksum = 1;
                p->flags |= PKT_IGNORE_CHECKSUM;
            }
            break;
        default:
            break;
    }

    SET_PKT_LEN(p, h->caplen);
}
コード例 #12
0
ファイル: decode.c プロジェクト: coanor/suricata
/**
 *  \brief Copy data to Packet payload and set packet length
 *
 *  \param Pointer to the Packet to modify
 *  \param Pointer to the data to copy
 *  \param Length of the data to copy
 */
inline int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen)
{
    SET_PKT_LEN(p, (size_t)pktlen);
    return PacketCopyDataOffset(p, 0, pktdata, pktlen);
}
コード例 #13
0
ファイル: flow-timeout.c プロジェクト: codercold/suricata
/**
 * \internal
 * \brief Pseudo packet setup for flow forced reassembly.
 *
 * \param direction Direction of the packet.  0 indicates toserver and 1
 *                  indicates toclient.
 * \param f         Pointer to the flow.
 * \param ssn       Pointer to the tcp session.
 * \param dummy     Indicates to create a dummy pseudo packet.  Not all pseudo
 *                  packets need to force reassembly, in which case we just
 *                  set dummy ack/seq values.
 */
static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p,
                                                           int direction,
                                                           Flow *f,
                                                           TcpSession *ssn,
                                                           int dummy)
{
    p->datalink = DLT_RAW;
    p->proto = IPPROTO_TCP;
    FlowReference(&p->flow, f);
    p->flags |= PKT_STREAM_EST;
    p->flags |= PKT_STREAM_EOF;
    p->flags |= PKT_HAS_FLOW;
    p->flags |= PKT_PSEUDO_STREAM_END;
    if (direction == 0)
        p->flowflags |= FLOW_PKT_TOSERVER;
    else
        p->flowflags |= FLOW_PKT_TOCLIENT;
    p->flowflags |= FLOW_PKT_ESTABLISHED;
    p->payload = NULL;
    p->payload_len = 0;

    if (FLOW_IS_IPV4(f)) {
        if (direction == 0) {
            FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->src);
            FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->dst);
            p->sp = f->sp;
            p->dp = f->dp;
        } else {
            FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->dst);
            FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->src);
            p->sp = f->dp;
            p->dp = f->sp;
        }

        /* set the ip header */
        p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
        /* version 4 and length 20 bytes for the tcp header */
        p->ip4h->ip_verhl = 0x45;
        p->ip4h->ip_tos = 0;
        p->ip4h->ip_len = htons(40);
        p->ip4h->ip_id = 0;
        p->ip4h->ip_off = 0;
        p->ip4h->ip_ttl = 64;
        p->ip4h->ip_proto = IPPROTO_TCP;
        //p->ip4h->ip_csum =
        if (direction == 0) {
            p->ip4h->s_ip_src.s_addr = f->src.addr_data32[0];
            p->ip4h->s_ip_dst.s_addr = f->dst.addr_data32[0];
        } else {
            p->ip4h->s_ip_src.s_addr = f->dst.addr_data32[0];
            p->ip4h->s_ip_dst.s_addr = f->src.addr_data32[0];
        }

        /* set the tcp header */
        p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 20);

        SET_PKT_LEN(p, 40); /* ipv4 hdr + tcp hdr */

    } else if (FLOW_IS_IPV6(f)) {
        if (direction == 0) {
            FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->src);
            FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->dst);
            p->sp = f->sp;
            p->dp = f->dp;
        } else {
            FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->dst);
            FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->src);
            p->sp = f->dp;
            p->dp = f->sp;
        }

        /* set the ip header */
        p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
        /* version 6 */
        p->ip6h->s_ip6_vfc = 0x60;
        p->ip6h->s_ip6_flow = 0;
        p->ip6h->s_ip6_nxt = IPPROTO_TCP;
        p->ip6h->s_ip6_plen = htons(20);
        p->ip6h->s_ip6_hlim = 64;
        if (direction == 0) {
            p->ip6h->s_ip6_src[0] = f->src.addr_data32[0];
            p->ip6h->s_ip6_src[1] = f->src.addr_data32[1];
            p->ip6h->s_ip6_src[2] = f->src.addr_data32[2];
            p->ip6h->s_ip6_src[3] = f->src.addr_data32[3];
            p->ip6h->s_ip6_dst[0] = f->dst.addr_data32[0];
            p->ip6h->s_ip6_dst[1] = f->dst.addr_data32[1];
            p->ip6h->s_ip6_dst[2] = f->dst.addr_data32[2];
            p->ip6h->s_ip6_dst[3] = f->dst.addr_data32[3];
        } else {
            p->ip6h->s_ip6_src[0] = f->dst.addr_data32[0];
            p->ip6h->s_ip6_src[1] = f->dst.addr_data32[1];
            p->ip6h->s_ip6_src[2] = f->dst.addr_data32[2];
            p->ip6h->s_ip6_src[3] = f->dst.addr_data32[3];
            p->ip6h->s_ip6_dst[0] = f->src.addr_data32[0];
            p->ip6h->s_ip6_dst[1] = f->src.addr_data32[1];
            p->ip6h->s_ip6_dst[2] = f->src.addr_data32[2];
            p->ip6h->s_ip6_dst[3] = f->src.addr_data32[3];
        }

        /* set the tcp header */
        p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 40);

        SET_PKT_LEN(p, 60); /* ipv6 hdr + tcp hdr */
    }

    p->tcph->th_offx2 = 0x50;
    p->tcph->th_flags |= TH_ACK;
    p->tcph->th_win = 10;
    p->tcph->th_urp = 0;

    /* to server */
    if (direction == 0) {
        p->tcph->th_sport = htons(f->sp);
        p->tcph->th_dport = htons(f->dp);

        if (dummy) {
            p->tcph->th_seq = htonl(ssn->client.next_seq);
            p->tcph->th_ack = htonl(ssn->server.last_ack);
        } else {
            p->tcph->th_seq = htonl(ssn->client.next_seq);
            p->tcph->th_ack = htonl(ssn->server.seg_list_tail->seq +
                                    ssn->server.seg_list_tail->payload_len);
        }

        /* to client */
    } else {
        p->tcph->th_sport = htons(f->dp);
        p->tcph->th_dport = htons(f->sp);

        if (dummy) {
            p->tcph->th_seq = htonl(ssn->server.next_seq);
            p->tcph->th_ack = htonl(ssn->client.last_ack);
        } else {
            p->tcph->th_seq = htonl(ssn->server.next_seq);
            p->tcph->th_ack = htonl(ssn->client.seg_list_tail->seq +
                                    ssn->client.seg_list_tail->payload_len);
        }
    }

    if (FLOW_IS_IPV4(f)) {
        p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs,
                                               (uint16_t *)p->tcph, 20);
        /* calc ipv4 csum as we may log it and barnyard might reject
         * a wrong checksum */
        p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h,
                IPV4_GET_RAW_HLEN(p->ip4h));
    } else if (FLOW_IS_IPV6(f)) {
        p->tcph->th_sum = TCPCalculateChecksum(p->ip6h->s_ip6_addrs,
                                               (uint16_t *)p->tcph, 20);
    }

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

    AppLayerSetEOF(f);

    return p;
}
コード例 #14
0
static int Unified2Test02 (void)   {
    ThreadVars tv;
    DecodeThreadVars dtv;
    PacketQueue pq;
    void *data = NULL;
    OutputCtx *oc;
    LogFileCtx *lf;
    Signature s;

    uint8_t raw_ipv6_tcp[] = {
        0x00, 0x11, 0x25, 0x82, 0x95, 0xb5, 0x00, 0xd0,
        0x09, 0xe3, 0xe8, 0xde, 0x86, 0xdd, 0x60, 0x00,
        0x00, 0x00, 0x00, 0x28, 0x06, 0x40, 0x20, 0x01,
        0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00, 0x02, 0xd0,
        0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01,
        0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41,
        0x00, 0x50, 0xab, 0xdc, 0xd6, 0x60, 0x00, 0x00,
        0x00, 0x00, 0xa0, 0x02, 0x16, 0x80, 0x41, 0xa2,
        0x00, 0x00, 0x02, 0x04, 0x05, 0xa0, 0x04, 0x02,
        0x08, 0x0a, 0x00, 0x0a, 0x22, 0xa8, 0x00, 0x00,
        0x00, 0x00, 0x01, 0x03, 0x03, 0x05 };
    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (unlikely(p == NULL))
        return 0;
    int ret;

    memset(&dtv, 0, sizeof(DecodeThreadVars));
    memset(&tv, 0, sizeof(ThreadVars));
    memset(&pq, 0, sizeof(PacketQueue));
    memset(p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    memset(&s, 0, sizeof(Signature));

    PACKET_INITIALIZE(p);

    p->alerts.cnt++;
    p->alerts.alerts[p->alerts.cnt-1].s = &s;
    p->alerts.alerts[p->alerts.cnt-1].s->id = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->gid = 1;
    p->alerts.alerts[p->alerts.cnt-1].s->rev = 1;
    SET_PKT_LEN(p, sizeof(raw_ipv6_tcp));

    FlowInitConfig(FLOW_QUIET);

    DecodeEthernet(&tv, &dtv, p, raw_ipv6_tcp, sizeof(raw_ipv6_tcp), &pq);

    FlowShutdown();

    oc = Unified2AlertInitCtx(NULL);
    if (oc == NULL) {
        SCFree(p);
        return 0;
    }
    lf = (LogFileCtx *)oc->data;
    if(lf == NULL) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadInit(&tv, oc, &data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }
    ret = Unified2Alert(&tv, p, data, &pq, NULL);
    if(ret == TM_ECODE_FAILED) {
        SCFree(p);
        return 0;
    }
    ret = Unified2AlertThreadDeinit(&tv, data);
    if(ret == -1) {
        SCFree(p);
        return 0;
    }

    Unified2AlertDeInitCtx(oc);

    PACKET_CLEANUP(p);
    SCFree(p);
    return 1;
}
コード例 #15
0
ファイル: source-nfq.c プロジェクト: gcordrey/suricata
int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
{
    struct nfq_data *tb = (struct nfq_data *)data;
    int ret;
    char *pktdata;
    struct nfqnl_msg_packet_hdr *ph;

    ph = nfq_get_msg_packet_hdr(tb);
    if (ph != NULL) {
        p->nfq_v.id = ntohl(ph->packet_id);
        //p->nfq_v.hw_protocol = ntohs(p->nfq_v.ph->hw_protocol);
        p->nfq_v.hw_protocol = ph->hw_protocol;
    }
    p->nfq_v.mark = nfq_get_nfmark(tb);
    if (nfq_config.mode == NFQ_REPEAT_MODE) {
        if ((nfq_config.mark & nfq_config.mask) ==
                (p->nfq_v.mark & nfq_config.mask)) {
            int iter = 0;
            if (already_seen_warning < MAX_ALREADY_TREATED)
                SCLogInfo("Packet seems already treated by suricata");
            already_seen_warning++;
            do {
                ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL);
            } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME));
            if (ret < 0) {
                SCLogWarning(SC_ERR_NFQ_SET_VERDICT,
                             "nfq_set_verdict of %p failed %" PRId32 "",
                             p, ret);
            }
            return -1 ;
        }
    }
    p->nfq_v.ifi  = nfq_get_indev(tb);
    p->nfq_v.ifo  = nfq_get_outdev(tb);

#ifdef NFQ_GET_PAYLOAD_SIGNED
    ret = nfq_get_payload(tb, &pktdata);
#else
    ret = nfq_get_payload(tb, (unsigned char **) &pktdata);
#endif /* NFQ_GET_PAYLOAD_SIGNED */
    if (ret > 0) {
        /* nfq_get_payload returns a pointer to a part of memory
         * that is not preserved over the lifetime of our packet.
         * So we need to copy it. */
        if (ret > 65536) {
            /* Will not be able to copy data ! Set length to 0
             * to trigger an error in packet decoding.
             * This is unlikely to happen */
            SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "NFQ sent too big packet");
            SET_PKT_LEN(p, 0);
        } else {
            PacketCopyData(p, (uint8_t *)pktdata, ret);
        }
    } else if (ret ==  -1) {
        /* unable to get pointer to data, ensure packet length is zero.
         * This will trigger an error in packet decoding */
        SET_PKT_LEN(p, 0);
    }

    ret = nfq_get_timestamp(tb, &p->ts);
    if (ret != 0) {
        memset (&p->ts, 0, sizeof(struct timeval));
        gettimeofday(&p->ts, NULL);
    }

    p->datalink = DLT_RAW;
    return 0;
}
コード例 #16
0
/**
 * \brief   Process a DAG record into a TM packet buffer.
 * \param   prec pointer to a DAG record.
 * \param
 */
static inline TmEcode ProcessErfDagRecord(ErfDagThreadVars *ewtn, char *prec)
{
    SCEnter();

    int wlen = 0;
    int rlen = 0;
    int hdr_num = 0;
    char hdr_type = 0;
    dag_record_t  *dr = (dag_record_t*)prec;
    erf_payload_t *pload;
    Packet *p;

    hdr_type = dr->type;
    wlen = ntohs(dr->wlen);
    rlen = ntohs(dr->rlen);

    /* count extension headers */
    while (hdr_type & 0x80) {
        if (rlen < (dag_record_size + (hdr_num * 8))) {
            SCLogError(SC_ERR_UNIMPLEMENTED,
                       "Insufficient captured packet length.");
            SCReturnInt(TM_ECODE_FAILED);
        }
        hdr_type = prec[(dag_record_size + (hdr_num * 8))];
        hdr_num++;
    }

    /* Check that the whole frame was captured */
    if (rlen < (dag_record_size + (8 * hdr_num) + 2 + wlen)) {
        SCLogInfo("Incomplete frame captured.");
        SCReturnInt(TM_ECODE_OK);
    }

    /* skip over extension headers */
    pload = (erf_payload_t *)(prec + dag_record_size + (8 * hdr_num));

    p = PacketGetFromQueueOrAlloc();
    if (p == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC,
                   "Failed to allocate a Packet on stream: %d, DAG: %s",
                   ewtn->dagstream, ewtn->dagname);
        SCReturnInt(TM_ECODE_FAILED);
    }
    PKT_SET_SRC(p, PKT_SRC_WIRE);

    SET_PKT_LEN(p, wlen);
    p->datalink = LINKTYPE_ETHERNET;

    /* Take into account for link type Ethernet ETH frame starts
     * after ther ERF header + pad.
     */
    if (unlikely(PacketCopyData(p, pload->eth.dst, GET_PKT_LEN(p)))) {
        TmqhOutputPacketpool(ewtn->tv, p);
        SCReturnInt(TM_ECODE_FAILED);
    }

    /* Convert ERF time to timeval - from libpcap. */
    uint64_t ts = dr->ts;
    p->ts.tv_sec = ts >> 32;
    ts = (ts & 0xffffffffULL) * 1000000;
    ts += 0x80000000; /* rounding */
    p->ts.tv_usec = ts >> 32;
    if (p->ts.tv_usec >= 1000000) {
        p->ts.tv_usec -= 1000000;
        p->ts.tv_sec++;
    }

    SCPerfCounterIncr(ewtn->packets, ewtn->tv->sc_perf_pca);
    ewtn->bytes += wlen;

    if (TmThreadsSlotProcessPkt(ewtn->tv, ewtn->slot, p) != TM_ECODE_OK) {
        TmqhOutputPacketpool(ewtn->tv, p);
        SCReturnInt(TM_ECODE_FAILED);
    }

    SCReturnInt(TM_ECODE_OK);
}
コード例 #17
0
/**
 * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests
 * specifying ip and port sources and destinations
 *
 * \param payload pointer to the payloadd buffer
 * \param payload_len pointer to the length of the payload
 * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP
 * \param src pointer to a string containing the ip source
 * \param dst pointer to a string containing the ip destination
 * \param sport pointer to a string containing the port source
 * \param dport pointer to a string containing the port destination
 *
 * \retval Packet pointer to the built in packet
 */
Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len,
                           uint8_t ipproto, char *src, char *dst,
                           uint16_t sport, uint16_t dport)
{
    struct in_addr in;

    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return NULL;

    struct timeval tv;
    TimeGet(&tv);
    COPY_TIMESTAMP(&tv, &p->ts);

    p->src.family = AF_INET;
    p->dst.family = AF_INET;
    p->payload = payload;
    p->payload_len = payload_len;
    p->proto = ipproto;

    if (inet_pton(AF_INET, src, &in) != 1)
        goto error;
    p->src.addr_data32[0] = in.s_addr;
    p->sp = sport;

    if (inet_pton(AF_INET, dst, &in) != 1)
        goto error;
    p->dst.addr_data32[0] = in.s_addr;
    p->dp = dport;

    p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    if (p->ip4h == NULL)
        goto error;

    p->ip4h->s_ip_src.s_addr = p->src.addr_data32[0];
    p->ip4h->s_ip_dst.s_addr = p->dst.addr_data32[0];
    p->ip4h->ip_proto = ipproto;
    p->ip4h->ip_verhl = sizeof(IPV4Hdr);
    p->proto = ipproto;

    int hdr_offset = sizeof(IPV4Hdr);
    switch (ipproto) {
        case IPPROTO_UDP:
            p->udph = (UDPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->udph == NULL)
                goto error;

            p->udph->uh_sport = sport;
            p->udph->uh_dport = dport;
            hdr_offset += sizeof(UDPHdr);
            break;
        case IPPROTO_TCP:
            p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->tcph == NULL)
                goto error;

            p->tcph->th_sport = htons(sport);
            p->tcph->th_dport = htons(dport);
            hdr_offset += sizeof(TCPHdr);
            break;
        case IPPROTO_ICMP:
            p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->icmpv4h == NULL)
                goto error;

            hdr_offset += sizeof(ICMPV4Hdr);
            break;
        default:
            break;
        /* TODO: Add more protocols */
    }

    PacketCopyDataOffset(p, hdr_offset, payload, payload_len);
    SET_PKT_LEN(p, hdr_offset + payload_len);
    p->payload = GET_PKT_DATA(p)+hdr_offset;

    return p;

error:
    SCFree(p);
    return NULL;
}