Beispiel #1
0
void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
        uint8_t *pkt, uint16_t len, PacketQueue *pq, uint8_t proto)
{
    switch (proto) {
        case PPP_OVER_GRE:
            return DecodePPP(tv, dtv, p, pkt, len, pq);
        case IPPROTO_IP:
            return DecodeIPV4(tv, dtv, p, pkt, len, pq);
        case IPPROTO_IPV6:
            return DecodeIPV6(tv, dtv, p, pkt, len, pq);
       case VLAN_OVER_GRE:
            return DecodeVLAN(tv, dtv, p, pkt, len, pq);
        default:
            SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
            break;
    }
}
Beispiel #2
0
/**
 * \test DecodeVLANTest02 test a good vlan header.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int DecodeVLANtest03 (void)   {
    uint8_t raw_vlan[] = {
        0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
        0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
        0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
        0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
        0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
        0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
        0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    FlowInitConfig(FLOW_QUIET);

    DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL);


    if(p->vlanh == NULL) {
        goto error;
    }

    if(ENGINE_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL))  {
        goto error;
    }

    if(ENGINE_ISSET_EVENT(p,VLAN_UNKNOWN_TYPE))  {
        goto error;
    }

    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 1;

error:
    PACKET_RECYCLE(p);
    FlowShutdown();
    SCFree(p);
    return 0;
}
Beispiel #3
0
/**
 * \internal
 * \brief this function is used to decode IEEE802.1q packets
 *
 * \param tv pointer to the thread vars
 * \param dtv pointer code thread vars
 * \param p pointer to the packet struct
 * \param pkt pointer to the raw packet
 * \param len packet len
 * \param pq pointer to the packet queue
 *
 */
void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca);

    if(len < VLAN_HEADER_LEN)    {
        DECODER_SET_EVENT(p,VLAN_HEADER_TOO_SMALL);
        return;
    }

    p->vlanh = (VLANHdr *)pkt;
    if(p->vlanh == NULL)
        return;

    SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "",
        p, pkt, GET_VLAN_PROTO(p->vlanh), GET_VLAN_PRIORITY(p->vlanh), GET_VLAN_CFI(p->vlanh), GET_VLAN_ID(p->vlanh), len);

    switch (GET_VLAN_PROTO(p->vlanh))   {
        case ETHERNET_TYPE_IP:
            DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                       len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_IPV6:
            DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                       len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_SESS:
            DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                               len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_DISC:
            DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                                 len - VLAN_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_VLAN:
            DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                                 len - VLAN_HEADER_LEN, pq);
            break;
        default:
            SCLogDebug("unknown VLAN type: %" PRIx32 "",GET_VLAN_PROTO(p->vlanh));
            DECODER_SET_EVENT(p,VLAN_UNKNOWN_TYPE);
            return;
    }

    return;
}
Beispiel #4
0
/**
 * \test DecodeVLANTest02 test a good vlan header.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int DecodeVLANtest03 (void)   {
    uint8_t raw_vlan[] = {
        0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
        0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
        0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
        0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
        0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
        0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
        0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

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

    FlowInitConfig(FLOW_QUIET);

    DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL);

    FlowShutdown();

    if(p->vlanh == NULL) {
        SCFree(p);
        return 0;
    }

    if(DECODER_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL))  {
        SCFree(p);
        return 0;
    }

    if(DECODER_ISSET_EVENT(p,VLAN_UNKNOWN_TYPE))  {
        SCFree(p);
        return 0;
    }

    SCFree(p);
    return 1;
}
Beispiel #5
0
/**
 * \test DecodeVLANTest01 test if vlan header is too small.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int DecodeVLANtest01 (void)   {
    uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

    memset(&tv, 0, sizeof(ThreadVars));
    memset(&dtv, 0, sizeof(DecodeThreadVars));

    DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL);

    if(ENGINE_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL))  {
        SCFree(p);
        return 1;
    }

    SCFree(p);
    return 0;
}
Beispiel #6
0
int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
        uint8_t *pkt, uint16_t len, PacketQueue *pq, enum DecodeTunnelProto proto)
{
    switch (proto) {
        case DECODE_TUNNEL_PPP:
            return DecodePPP(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_IPV4:
            return DecodeIPV4(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_IPV6:
            return DecodeIPV6(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_VLAN:
            return DecodeVLAN(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_ETHERNET:
            return DecodeEthernet(tv, dtv, p, pkt, len, pq);
        case DECODE_TUNNEL_ERSPAN:
            return DecodeERSPAN(tv, dtv, p, pkt, len, pq);
        default:
            SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
            break;
    }
    return TM_ECODE_OK;
}
Beispiel #7
0
/**
 * \test DecodeVLANTest01 test if vlan header is too small.
 *
 *  \retval 1 on success
 *  \retval 0 on failure
 */
static int DecodeVLANtest01 (void)   {
    uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

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

    DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL);

    if(DECODER_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL))  {
        SCFree(p);
        return 1;
    }

    SCFree(p);
    return 0;
}
Beispiel #8
0
/**
 * \internal
 * \brief this function is used to decode IEEE802.1q packets
 *
 * \param tv pointer to the thread vars
 * \param dtv pointer code thread vars
 * \param p pointer to the packet struct
 * \param pkt pointer to the raw packet
 * \param len packet len
 * \param pq pointer to the packet queue
 *
 */
int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
    uint32_t proto;

    SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca);

    if(len < VLAN_HEADER_LEN)    {
        ENGINE_SET_INVALID_EVENT(p, VLAN_HEADER_TOO_SMALL);
        return TM_ECODE_FAILED;
    }
    if (p->vlan_idx >= 2) {
        ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
        return TM_ECODE_FAILED;
    }

    p->vlanh[p->vlan_idx] = (VLANHdr *)pkt;
    if(p->vlanh[p->vlan_idx] == NULL)
        return TM_ECODE_FAILED;

    proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]);

    SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "",
               p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]),
               GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len);

    /* only store the id for flow hashing if it's not disabled. */
    if (dtv->vlan_disabled == 0)
        p->vlan_id[p->vlan_idx] = (uint16_t)GET_VLAN_ID(p->vlanh[p->vlan_idx]);

    p->vlan_idx++;

    switch (proto)   {
    case ETHERNET_TYPE_IP:
        DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                   len - VLAN_HEADER_LEN, pq);
        break;
    case ETHERNET_TYPE_IPV6:
        DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                   len - VLAN_HEADER_LEN, pq);
        break;
    case ETHERNET_TYPE_PPPOE_SESS:
        DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                           len - VLAN_HEADER_LEN, pq);
        break;
    case ETHERNET_TYPE_PPPOE_DISC:
        DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                             len - VLAN_HEADER_LEN, pq);
        break;
    case ETHERNET_TYPE_VLAN:
        if (p->vlan_idx >= 2) {
            ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
            return TM_ECODE_OK;
        } else {
            DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                       len - VLAN_HEADER_LEN, pq);
        }
        break;
    default:
        SCLogDebug("unknown VLAN type: %" PRIx32 "", proto);
        ENGINE_SET_INVALID_EVENT(p, VLAN_UNKNOWN_TYPE);
        return TM_ECODE_OK;
    }

    return TM_ECODE_OK;
}
/*
  *   @mbuf:
  *   @pkt:    start of l2 header
  *   @len:    len of l2 packet
  */
int DecodeEthernet(mbuf_t *mbuf, uint8_t *pkt, uint16_t len)
{
    EthernetHdr *pethh;

    LOGDBG(SEC_ETHERNET_DBG_BIT, "==============>enter DecodeEthernet\n");

    if (unlikely(len < ETHERNET_HEADER_LEN))
    {
        STAT_L2_HEADER_ERR;
        DP_Log_Func(mbuf);
        return DECODE_DROP;
    }

    pethh = (EthernetHdr *)(pkt);

    if((0 == pethh->eth_dst[0]
        && 0 == pethh->eth_dst[1]
        && 0 == pethh->eth_dst[2]
        && 0 == pethh->eth_dst[3]
        && 0 == pethh->eth_dst[4]
        && 0 == pethh->eth_dst[5]) ||
        (0 == pethh->eth_src[0]
        && 0 == pethh->eth_src[1]
        && 0 == pethh->eth_src[2]
        && 0 == pethh->eth_src[3]
        && 0 == pethh->eth_src[4]
        && 0 == pethh->eth_src[5]))
    {
        STAT_L2_HEADER_ERR;
        DP_Log_Func(mbuf);
        return DECODE_DROP;
    }


    mbuf->ethh = (void *)pethh;

    LOGDBG(SEC_ETHERNET_DBG_BIT, "dst mac is %x:%x:%x:%x:%x:%x\n",
        pethh->eth_dst[0],pethh->eth_dst[1],
        pethh->eth_dst[2],pethh->eth_dst[3],
        pethh->eth_dst[4],pethh->eth_dst[5]);

    LOGDBG(SEC_ETHERNET_DBG_BIT, "src mac is %x:%x:%x:%x:%x:%x\n",
        pethh->eth_src[0],pethh->eth_src[1],
        pethh->eth_src[2],pethh->eth_src[3],
        pethh->eth_src[4],pethh->eth_src[5]);

    LOGDBG(SEC_ETHERNET_DBG_BIT, "eth type is 0x%x\n", pethh->eth_type);

    memcpy(mbuf->eth_dst, pethh->eth_dst, 6);
    memcpy(mbuf->eth_src, pethh->eth_src, 6);

    switch (pethh->eth_type) {
        case ETHERNET_TYPE_IP:
        {
            STAT_L2_RECV_OK;
            return DecodeIPV4(mbuf, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN);
        }
    #ifdef ROUTE_PROC_ENABLE
        case ETHERNET_TYPE_ARP:
        {
            if(SEC_OK != oct_pow_se2linux(mbuf))
            {
                STAT_L2_ARP_SE2LINUX_FAIL;
                return DECODE_DROP;
            }
            else
            {
                STAT_L2_ARP_SE2LINUX_OK;
                STAT_L2_RECV_OK;
                return DECODE_OK;
            }
        }
    #endif
        case ETHERNET_TYPE_VLAN:
        case ETHERNET_TYPE_8021QINQ:
        {
            STAT_L2_RECV_OK;
            return DecodeVLAN(mbuf, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN);
        }
        default:
        {
            LOGDBG(SEC_ETHERNET_DBG_BIT, "ether type %04x not supported", pethh->eth_type);
            STAT_L2_UNSUPPORT;
        #if 0
            output_fw_proc(mbuf);
        #endif
            Decode_unsupport_proto_handle(mbuf);
            return DECODE_OK;
        }
    }

    return DECODE_OK;
}
Beispiel #10
0
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                   uint8_t *pkt, uint32_t len, PacketQueue *pq)
{
    StatsIncr(tv, dtv->counter_eth);

    if (unlikely(len < ETHERNET_HEADER_LEN)) {
        ENGINE_SET_INVALID_EVENT(p, ETHERNET_PKT_TOO_SMALL);
        return TM_ECODE_FAILED;
    }

    if (unlikely(len > ETHERNET_HEADER_LEN + USHRT_MAX)) {
        return TM_ECODE_FAILED;
    }

    p->ethh = (EthernetHdr *)pkt;
    if (unlikely(p->ethh == NULL))
        return TM_ECODE_FAILED;

    SCLogDebug("p %p pkt %p ether type %04x", p, pkt, SCNtohs(p->ethh->eth_type));

    switch (SCNtohs(p->ethh->eth_type)) {
        case ETHERNET_TYPE_IP:
            //printf("DecodeEthernet ip4\n");
            DecodeIPV4(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                       len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_IPV6:
            //printf("DecodeEthernet ip6\n");
            DecodeIPV6(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                       len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_SESS:
            //printf("DecodeEthernet PPPOE Session\n");
            DecodePPPOESession(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                               len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_PPPOE_DISC:
            //printf("DecodeEthernet PPPOE Discovery\n");
            DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                                 len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_VLAN:
        case ETHERNET_TYPE_8021QINQ:
            DecodeVLAN(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                                 len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_MPLS_UNICAST:
        case ETHERNET_TYPE_MPLS_MULTICAST:
            DecodeMPLS(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                       len - ETHERNET_HEADER_LEN, pq);
            break;
        case ETHERNET_TYPE_DCE:
            if (unlikely(len < ETHERNET_DCE_HEADER_LEN)) {
                ENGINE_SET_INVALID_EVENT(p, DCE_PKT_TOO_SMALL);
            } else {
                DecodeEthernet(tv, dtv, p, pkt + ETHERNET_DCE_HEADER_LEN,
                    len - ETHERNET_DCE_HEADER_LEN, pq);
            }
            break;
        default:
            SCLogDebug("p %p pkt %p ether type %04x not supported", p,
                       pkt, SCNtohs(p->ethh->eth_type));
    }

    return TM_ECODE_OK;
}