int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                   uint8_t *pkt, uint16_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;
    }

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

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

    switch (ntohs(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;
        default:
            SCLogDebug("p %p pkt %p ether type %04x not supported", p,
                       pkt, ntohs(p->ethh->eth_type));
    }

    return TM_ECODE_OK;
}
示例#2
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;
}
示例#3
0
/** DecodePPPOEtest02
 *  \brief Valid PPPOE packet - check the invalid ICMP type encapsulated is flagged
 *  \retval 0 Expected test value
 */
static int DecodePPPOEtest02 (void)   {

    uint8_t raw_pppoe[] = {
        0x11, 0x00, 0x00, 0x01, 0x00, 0x40, 0x00, 0x21,
        0x45, 0x00, 0x00, 0x3c, 0x05, 0x5c, 0x00, 0x00,
        0x20, 0x01, 0xff, 0x30, 0xc0, 0xa8, 0x0a, 0x7f,
        0xc0, 0xa8, 0x0a, 0x65, 0xab, 0xcd, 0x16, 0x5e,
        0x02, 0x00, 0x37, 0x00, 0x41, 0x42, 0x43, 0x44,
        0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
        0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
        0x55, 0x56, 0x57, 0x41, 0x42, 0x43, 0x44, 0x45,
        0x46, 0x47, 0x48, 0x49 };

    Packet *p = SCMalloc(SIZE_OF_PACKET);
    if (p == NULL)
    return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;
    int ret = 0;

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

    DecodePPPOESession(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL);

    if(DECODER_ISSET_EVENT(p,PPPOE_PKT_TOO_SMALL))  {
        goto end;
    }

    // and we insist that the invalid ICMP encapsulated (type 0xab, code 0xcd) is flagged

    if(! DECODER_ISSET_EVENT(p,ICMPV4_UNKNOWN_TYPE))  {
        goto end;
    }

    ret = 1;
end:
    FlowShutdown();
    SCFree(p);
    return ret;
}
示例#4
0
/** DecodePPPOEtest01
 *  \brief Decode malformed PPPOE packet (too short)
 *  \retval 1 Expected test value
 */
static int DecodePPPOEtest01 (void)
{

    uint8_t raw_pppoe[] = { 0x11, 0x00, 0x00, 0x00, 0x00 };
    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return 0;
    ThreadVars tv;
    DecodeThreadVars dtv;

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

    DecodePPPOESession(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL);

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

    SCFree(p);
    return 0;
}
示例#5
0
/** DecodePPPOEtest01
 *  \brief Decode malformed PPPOE packet (too short)
 *  \retval 1 Expected test value
 */
static int DecodePPPOEtest01 (void)   {

    uint8_t raw_pppoe[] = { 0x11, 0x00, 0x00, 0x00, 0x00 };
    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));

    DecodePPPOESession(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL);

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

    SCFree(p);
    return 0;
}
示例#6
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;
}