VLAN Support

remotes/origin/master-1.0.x
Breno Silva 16 years ago committed by Victor Julien
parent 29d51a6182
commit b02bb6b6b4

@ -14,6 +14,7 @@ source-pfring.c source-pfring.h \
source-ipfw.c source-ipfw.h \
decode.c decode.h \
decode-ethernet.c decode-ethernet.h \
decode-vlan.c decode-vlan.h \
decode-sll.c decode-sll.h \
decode-gre.c decode-gre.h \
decode-ppp.c decode-ppp.h \

@ -44,6 +44,10 @@ void DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *p
DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
len - ETHERNET_HEADER_LEN, pq);
break;
case ETHERNET_TYPE_VLAN:
DecodeVLAN(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));

@ -97,6 +97,10 @@ enum {
GRE_VERSION1_MALFORMED_SRE_HDR,
GRE_VERSION1_HDR_TOO_BIG,
/* VLAN EVENTS */
VLAN_HEADER_TOO_SMALL,
VLAN_UNKNOWN_TYPE,
/* RAW EVENTS */
IPRAW_INVALID_IPV,
};

@ -174,7 +174,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
if (pq != NULL) {
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, GRE_GET_PROTO(p->greh));
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, IPPROTO_IP);
DecodeTunnel(tv, dtv, tp, tp->pkt, tp->pktlen, pq);
PacketEnqueue(pq,tp);
@ -187,7 +187,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
if (pq != NULL) {
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, GRE_GET_PROTO(p->greh));
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, PPP_OVER_GRE);
DecodeTunnel(tv, dtv, tp, tp->pkt, tp->pktlen, pq);
PacketEnqueue(pq,tp);
@ -200,7 +200,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
if (pq != NULL) {
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, GRE_GET_PROTO(p->greh));
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, IPPROTO_IPV6);
DecodeTunnel(tv, dtv, tp, tp->pkt, tp->pktlen, pq);
PacketEnqueue(pq,tp);
@ -208,6 +208,20 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
}
break;
}
case ETHERNET_TYPE_VLAN:
{
if (pq != NULL) {
Packet *tp = TunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len, VLAN_OVER_GRE);
DecodeTunnel(tv, dtv, tp, tp->pkt, tp->pktlen, pq);
PacketEnqueue(pq,tp);
SET_TUNNEL_PKT(p);
}
break;
}
default:
return;
}

@ -21,12 +21,21 @@ void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol));
if (ntohs(sllh->sll_protocol) == ETHERNET_TYPE_IP) {
//printf("DecodeSll ip4\n");
DecodeIPV4(tv, dtv, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq);
} else if(ntohs(sllh->sll_protocol) == ETHERNET_TYPE_IPV6) {
//printf("DecodeSll ip6\n");
DecodeIPV6(tv, dtv, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq);
switch (ntohs(sllh->sll_protocol)) {
case ETHERNET_TYPE_IP:
DecodeIPV4(tv, dtv, p, pkt + SLL_HEADER_LEN,
len - SLL_HEADER_LEN, pq);
break;
case ETHERNET_TYPE_IPV6:
DecodeIPV6(tv, dtv, p, pkt + SLL_HEADER_LEN,
len - SLL_HEADER_LEN, pq);
break;
case ETHERNET_TYPE_VLAN:
DecodeVLAN(tv, dtv, p, pkt + SLL_HEADER_LEN,
len - SLL_HEADER_LEN, pq);
break;
default:
SCLogDebug("p %p pkt %p sll type %04x not supported", p,
pkt, ntohs(sllh->sll_protocol));
}
}

@ -0,0 +1,190 @@
/* Copyright (c) 2009 Open Information Security Foundation */
/** \file
* \author Breno Silva <breno.silva@gmail.com>
*/
#include "suricata-common.h"
#include "decode.h"
#include "decode-vlan.h"
#include "decode-events.h"
#include "flow.h"
#include "util-unittest.h"
#include "util-debug.h"
/**
* \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;
}
#ifdef UNITTESTS
/** \todo Must GRE+VLAN and Multi-Vlan packets to
* create more tests
*/
/**
* \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;
ThreadVars tv;
DecodeThreadVars dtv;
memset(&tv, 0, sizeof(ThreadVars));
memset(&p, 0, sizeof(Packet));
memset(&dtv, 0, sizeof(DecodeThreadVars));
DecodeVLAN(&tv, &dtv, &p, raw_vlan, sizeof(raw_vlan), NULL);
if(DECODER_ISSET_EVENT(&p,VLAN_HEADER_TOO_SMALL)) {
return 1;
}
return 0;
}
/**
* \test DecodeVLANTest02 test if vlan header has unknown type.
*
* \retval 1 on success
* \retval 0 on failure
*/
static int DecodeVLANtest02 (void) {
uint8_t raw_vlan[] = {
0x00, 0x20, 0x01, 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;
ThreadVars tv;
DecodeThreadVars dtv;
memset(&tv, 0, sizeof(ThreadVars));
memset(&p, 0, sizeof(Packet));
memset(&dtv, 0, sizeof(DecodeThreadVars));
DecodeVLAN(&tv, &dtv, &p, raw_vlan, sizeof(raw_vlan), NULL);
if(DECODER_ISSET_EVENT(&p,VLAN_UNKNOWN_TYPE)) {
return 1;
}
return 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;
ThreadVars tv;
DecodeThreadVars dtv;
memset(&tv, 0, sizeof(ThreadVars));
memset(&p, 0, sizeof(Packet));
memset(&dtv, 0, sizeof(DecodeThreadVars));
FlowInitConfig(FLOW_QUIET);
DecodeVLAN(&tv, &dtv, &p, raw_vlan, sizeof(raw_vlan), NULL);
FlowShutdown();
if(p.vlanh == NULL) {
return 0;
}
if(DECODER_ISSET_EVENT(&p,VLAN_HEADER_TOO_SMALL)) {
return 0;
}
if(DECODER_ISSET_EVENT(&p,VLAN_UNKNOWN_TYPE)) {
return 0;
}
return 1;
}
#endif /* UNITTESTS */
void DecodeVLANRegisterTests(void) {
#ifdef UNITTESTS
UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01, 1);
UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02, 1);
UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03, 1);
#endif /* UNITTESTS */
}

@ -0,0 +1,31 @@
/* Copyright (c) 2009 Open Information Security Foundation */
/** \file
* \author Breno Silva <breno.silva@gmail.com>
*/
#ifndef __DECODE_VLAN_H__
#define __DECODE_VLAN_H__
/** Vlan type */
#define ETHERNET_TYPE_VLAN 0x8100
/** Vlan macros to access Vlan priority, Vlan CFI and VID */
#define GET_VLAN_PRIORITY(vlanh) ((ntohs((vlanh)->vlan_cfi) & 0xe000) >> 13)
#define GET_VLAN_CFI(vlanh) ((ntohs((vlanh)->vlan_cfi) & 0x0100) >> 12)
#define GET_VLAN_ID(vlanh) ((unsigned short)(ntohs((vlanh)->vlan_cfi) & 0x0FFF))
#define GET_VLAN_PROTO(vlanh) ((ntohs((vlanh)->protocol)))
/** Vlan header struct */
typedef struct _VLANHdr {
uint16_t vlan_cfi;
uint16_t protocol; /** protocol field */
}VLANHdr;
/** VLAN header length */
#define VLAN_HEADER_LEN 4
void DecodeVLANRegisterTests(void);
#endif /* __DECODE_VLAN_H__ */

@ -11,11 +11,12 @@ void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
switch (p->tunnel_proto) {
case PPP_OVER_GRE:
return DecodePPP(tv, dtv, p, pkt, len, pq);
break;
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.", p->tunnel_proto);
break;
@ -82,6 +83,8 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
SC_PERF_TYPE_UINT64, "NULL");
dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv,
SC_PERF_TYPE_UINT64, "NULL");
dtv->counter_vlan = SCPerfTVRegisterCounter("decoder.vlan", tv,
SC_PERF_TYPE_UINT64, "NULL");
dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv,
SC_PERF_TYPE_DOUBLE, "NULL");
dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv,

@ -32,6 +32,7 @@
#include "decode-tcp.h"
#include "decode-udp.h"
#include "decode-raw.h"
#include "decode-vlan.h"
/* Address */
typedef struct Address_
@ -263,6 +264,7 @@ typedef struct Packet_
PPPOESessionHdr *pppoesh;
PPPOEDiscoveryHdr *pppoedh;
GREHdr *greh;
VLANHdr *vlanh;
IPV4Hdr *ip4h;
IPV4Vars ip4vars;
@ -348,6 +350,7 @@ typedef struct DecodeThreadVars_
uint16_t counter_icmpv6;
uint16_t counter_ppp;
uint16_t counter_gre;
uint16_t counter_vlan;
uint16_t counter_pppoe;
uint16_t counter_avg_pkt_size;
uint16_t counter_max_pkt_size;
@ -373,6 +376,7 @@ typedef struct DecodeThreadVars_
(p)->ethh = NULL; \
(p)->ppph = NULL; \
(p)->greh = NULL; \
(p)->vlanh = NULL; \
(p)->ip4h = NULL; \
(p)->ip6h = NULL; \
(p)->action = 0; \
@ -467,6 +471,7 @@ void DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_
void DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
Packet *SetupPkt (void);
Packet *TunnelPktSetup(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, uint8_t);
@ -507,6 +512,7 @@ inline void DecodeSetNoPacketInspectionFlag(Packet *);
#define LINKTYPE_PPP 9
#define LINKTYPE_RAW DLT_RAW
#define PPP_OVER_GRE 11
#define VLAN_OVER_GRE 13
/*Packet Flags*/
#define PKT_NOPACKET_INSPECTION 0x01 /**< Flag to indicate that packet header or contents should not be inspected*/

@ -81,6 +81,8 @@ struct DetectDecodeEvents_ {
{ "gre.version1_malformed_sre_hdr", GRE_VERSION1_MALFORMED_SRE_HDR, },
{ "gre.version1_hdr_too_big", GRE_VERSION1_HDR_TOO_BIG, },
{ "ipraw.wrong_ip_version",IPRAW_INVALID_IPV, },
{ "vlan.hlen_too_small",VLAN_HEADER_TOO_SMALL, },
{ "vlan.unknown_type",VLAN_UNKNOWN_TYPE, },
{ NULL, 0 },
};
#endif /* DETECT_EVENTS */

@ -683,6 +683,7 @@ int main(int argc, char **argv)
FlowAlertSidRegisterTests();
SCPerfRegisterTests();
DecodePPPRegisterTests();
DecodeVLANRegisterTests();
HTPParserRegisterTests();
TLSParserRegisterTests();
SMBParserRegisterTests();

Loading…
Cancel
Save