Exemple #1
0
/**
 * \brief Decode a packet coming from NFQ
 */
TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{

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

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

    DecodeUpdatePacketCounters(tv, dtv, p);

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

    PacketDecodeFinalize(tv, dtv, p);

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

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

    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
    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));
#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

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

    return TM_ECODE_OK;
}
Exemple #3
0
/**
 * \brief This function passes off to link type decoders.
 * \todo Unit tests are needed for this module.
 *
 * DecodeIPFW reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param tv pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into IPFWThreadVars for ptv
 * \param pq pointer to the PacketQueue
 */
TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    SCEnter();

    /* update counters */
    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
    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));

    /* Process IP packets */
    if (IPV4_GET_RAW_VER(ip4h) == 4) {
        SCLogDebug("DecodeIPFW ip4 processing");
        DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
        SCLogDebug("DecodeIPFW ip6 processing");
        DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else {
        /* We don't support anything besides IP packets for now, bridged packets? */
        SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p));
       SCReturnInt(TM_ECODE_FAILED);
    }

    SCReturnInt(TM_ECODE_OK);
}
Exemple #4
0
/**
 * \brief This function passes off to link type decoders.
 * \todo Unit tests are needed for this module.
 *
 * DecodeIPFW reads packets from the PacketQueue and passes
 * them off to the proper link type decoder.
 *
 * \param tv pointer to ThreadVars
 * \param p pointer to the current packet
 * \param data pointer that gets cast into IPFWThreadVars for ptv
 * \param pq pointer to the PacketQueue
 */
TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p);
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;

    SCEnter();

    /* 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);

    /* Process IP packets */
    if (IPV4_GET_RAW_VER(ip4h) == 4) {
        SCLogDebug("DecodeIPFW ip4 processing");
        DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
        SCLogDebug("DecodeIPFW ip6 processing");
        DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);

    } else {
        /* We don't support anything besides IP packets for now, bridged packets? */
        SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p));
       SCReturnInt(TM_ECODE_FAILED);
    }

    PacketDecodeFinalize(tv, dtv, p);

    SCReturnInt(TM_ECODE_OK);
}
Exemple #5
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);
}
Exemple #6
0
/**
 * \brief Decode a packet coming from NFQ
 */
TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{

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

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

    SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
    SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
    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));
#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

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

    PacketDecodeFinalize(tv, dtv, p);

    return TM_ECODE_OK;
}
Exemple #7
0
/**
 * Note, this is the IP header, plus a bit of the original packet, not the whole thing!
 */
int DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
{
    /** Check the sizes, the header must fit at least */
    if (len < IPV4_HEADER_LEN) {
        SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT");
        ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT);
        return -1;
    }

    IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet;

    /** Check the embedded version */
    if (IPV4_GET_RAW_VER(icmp4_ip4h) != 4) {
        /** Check the embedded version */
        SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version "
                   "ICMPV4_IPV4_UNKNOWN_VER");
        ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER);
        return -1;
    }

    /** We need to fill icmpv4vars */
    p->icmpv4vars.emb_ipv4h = icmp4_ip4h;

    /** Get the IP address from the contained packet */
    p->icmpv4vars.emb_ip4_src = IPV4_GET_RAW_IPSRC(icmp4_ip4h);
    p->icmpv4vars.emb_ip4_dst = IPV4_GET_RAW_IPDST(icmp4_ip4h);

    p->icmpv4vars.emb_ip4_hlen=IPV4_GET_RAW_HLEN(icmp4_ip4h) << 2;

    switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) {
        case IPPROTO_TCP:
            if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) {
                p->icmpv4vars.emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_tcph->th_sport);
                p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_tcph->th_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else if (len >= IPV4_HEADER_LEN + 4) {
                /* only access th_sport and th_dport */
                TCPHdr *emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN);

                p->icmpv4vars.emb_tcph = NULL;
                p->icmpv4vars.emb_sport = ntohs(emb_tcph->th_sport);
                p->icmpv4vars.emb_dport = ntohs(emb_tcph->th_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;
                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else {
                SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP "
                           "header Didn't fit in the packet!");
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
            }

            break;
        case IPPROTO_UDP:
            if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) {
                p->icmpv4vars.emb_udph = (UDPHdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_udph->uh_sport);
                p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_udph->uh_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else {
                SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP "
                           "header Didn't fit in the packet!");
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
            }

            break;
        case IPPROTO_ICMP:
            if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN ) {
                p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
                p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header");
            }

            break;
    }

    /* debug print */
#ifdef DEBUG
    char s[16], d[16];
    PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s));
    PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d));
    SCLogDebug("ICMPv4 embedding IPV4 %s->%s - PROTO: %" PRIu32 " ID: %" PRIu32 "", s,d,
            IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h));
#endif

    return 0;
}
/**
 * \brief Main decoding function for PPPOE Session packets
 */
int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca);

    if (len < PPPOE_SESSION_HEADER_LEN) {
        ENGINE_SET_INVALID_EVENT(p, PPPOE_PKT_TOO_SMALL);
        return TM_ECODE_FAILED;
    }

    p->pppoesh = (PPPOESessionHdr *)pkt;
    if (p->pppoesh == NULL)
        return TM_ECODE_FAILED;

    SCLogDebug("PPPOE VERSION %" PRIu32 " TYPE %" PRIu32 " CODE %" PRIu32 " SESSIONID %" PRIu32 " LENGTH %" PRIu32 "",
           PPPOE_SESSION_GET_VERSION(p->pppoesh),  PPPOE_SESSION_GET_TYPE(p->pppoesh),  p->pppoesh->pppoe_code,  ntohs(p->pppoesh->session_id),  ntohs(p->pppoesh->pppoe_length));

    /* can't use DecodePPP() here because we only get a single 2-byte word to indicate protocol instead of the full PPP header */

    if (ntohs(p->pppoesh->pppoe_length) > 0) {
        /* decode contained PPP packet */

        switch (ntohs(p->pppoesh->protocol))
        {
            case PPP_VJ_COMP:
            case PPP_IPX:
            case PPP_OSI:
            case PPP_NS:
            case PPP_DECNET:
            case PPP_APPLE:
            case PPP_BRPDU:
            case PPP_STII:
            case PPP_VINES:
            case PPP_HELLO:
            case PPP_LUXCOM:
            case PPP_SNS:
            case PPP_MPLS_UCAST:
            case PPP_MPLS_MCAST:
            case PPP_IPCP:
            case PPP_OSICP:
            case PPP_NSCP:
            case PPP_DECNETCP:
            case PPP_APPLECP:
            case PPP_IPXCP:
            case PPP_STIICP:
            case PPP_VINESCP:
            case PPP_IPV6CP:
            case PPP_MPLSCP:
            case PPP_LCP:
            case PPP_PAP:
            case PPP_LQM:
            case PPP_CHAP:
                ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO);
                break;

            case PPP_VJ_UCOMP:

                if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN))    {
                    ENGINE_SET_INVALID_EVENT(p, PPPVJU_PKT_TOO_SMALL);
                    return TM_ECODE_OK;
                }

                if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) {
                    DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
                }
                break;

            case PPP_IP:
                if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN))    {
                    ENGINE_SET_INVALID_EVENT(p, PPPIPV4_PKT_TOO_SMALL);
                    return TM_ECODE_OK;
                }

                DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
                break;

            /* PPP IPv6 was not tested */
            case PPP_IPV6:
                if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN))    {
                    ENGINE_SET_INVALID_EVENT(p, PPPIPV6_PKT_TOO_SMALL);
                    return TM_ECODE_OK;
                }

                DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
                break;

            default:
                SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
                ENGINE_SET_INVALID_EVENT(p, PPP_WRONG_TYPE);
                return TM_ECODE_OK;
        }
    }
    return TM_ECODE_OK;
}
Exemple #9
0
int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    StatsIncr(tv, dtv->counter_ppp);

    if (unlikely(len < PPP_HEADER_LEN)) {
        ENGINE_SET_INVALID_EVENT(p, PPP_PKT_TOO_SMALL);
        return TM_ECODE_FAILED;
    }

    p->ppph = (PPPHdr *)pkt;
    if (unlikely(p->ppph == NULL))
        return TM_ECODE_FAILED;

    SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "",
        p, pkt, ntohs(p->ppph->protocol), len);

    switch (ntohs(p->ppph->protocol))
    {
        case PPP_VJ_UCOMP:
            if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
                ENGINE_SET_INVALID_EVENT(p,PPPVJU_PKT_TOO_SMALL);
                p->ppph = NULL;
                return TM_ECODE_FAILED;
            }

            if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
                return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
            } else
                return TM_ECODE_FAILED;
            break;

        case PPP_IP:
            if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
                ENGINE_SET_INVALID_EVENT(p,PPPIPV4_PKT_TOO_SMALL);
                p->ppph = NULL;
                return TM_ECODE_FAILED;
            }

            return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);

            /* PPP IPv6 was not tested */
        case PPP_IPV6:
            if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
                ENGINE_SET_INVALID_EVENT(p,PPPIPV6_PKT_TOO_SMALL);
                p->ppph = NULL;
                return TM_ECODE_FAILED;
            }

            return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);

        case PPP_VJ_COMP:
        case PPP_IPX:
        case PPP_OSI:
        case PPP_NS:
        case PPP_DECNET:
        case PPP_APPLE:
        case PPP_BRPDU:
        case PPP_STII:
        case PPP_VINES:
        case PPP_HELLO:
        case PPP_LUXCOM:
        case PPP_SNS:
        case PPP_MPLS_UCAST:
        case PPP_MPLS_MCAST:
        case PPP_IPCP:
        case PPP_OSICP:
        case PPP_NSCP:
        case PPP_DECNETCP:
        case PPP_APPLECP:
        case PPP_IPXCP:
        case PPP_STIICP:
        case PPP_VINESCP:
        case PPP_IPV6CP:
        case PPP_MPLSCP:
        case PPP_LCP:
        case PPP_PAP:
        case PPP_LQM:
        case PPP_CHAP:
            ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO);
            return TM_ECODE_OK;

        default:
            SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
            ENGINE_SET_INVALID_EVENT(p, PPP_WRONG_TYPE);
            return TM_ECODE_OK;
    }

}