alert pkthdr any any -> any any (msg:"SURICATA VLAN unknown type"; decode-event:vlan.unknown_type; classtype:protocol-command-decode; sid:2200067; rev:2;)
# more than 2 vlan layers in the packet
alert pkthdr any any -> any any (msg:"SURICATA VLAN too many layers"; decode-event:vlan.too_many_layers; classtype:protocol-command-decode; sid:2200091; rev:2;)
+alert pkthdr any any -> any any (msg:"SURICATA IEEE802.1AH header too small"; decode-event:ieee8021ah.header_too_small; classtype:protocol-command-decode; sid:2200112; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA IP raw invalid IP version "; decode-event:ipraw.invalid_ip_version; classtype:protocol-command-decode; sid:2200068; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Packet size too large"; decode-event:ipv4.frag_pkt_too_large; classtype:protocol-command-decode; sid:2200069; rev:3;)
# Cisco Fabric Path/DCE
alert pkthdr any any -> any any (msg:"SURICATA DCE packet too small"; decode-event:dce.pkt_too_small; classtype:protocol-command-decode; sid:2200110; rev:2;)
-# next sid is 2200112
+# next sid is 2200113
#define ETHERNET_TYPE_PPPOE_DISC 0x8863 /* discovery stage */
#define ETHERNET_TYPE_PPPOE_SESS 0x8864 /* session stage */
#define ETHERNET_TYPE_8021AD 0x88a8
+#define ETHERNET_TYPE_8021AH 0x88e7
#define ETHERNET_TYPE_8021Q 0x8100
#define ETHERNET_TYPE_LOOP 0x9000
#define ETHERNET_TYPE_8021QINQ 0x9100
{ "decoder.vlan.header_too_small",VLAN_HEADER_TOO_SMALL, },
{ "decoder.vlan.unknown_type",VLAN_UNKNOWN_TYPE, },
{ "decoder.vlan.too_many_layers", VLAN_HEADER_TOO_MANY_LAYERS, },
+ { "decoder.ieee8021ah.header_too_small", IEEE8021AH_HEADER_TOO_SMALL, },
/* RAW EVENTS */
{ "decoder.ipraw.invalid_ip_version",IPRAW_INVALID_IPV, },
VLAN_UNKNOWN_TYPE, /**< vlan unknown type */
VLAN_HEADER_TOO_MANY_LAYERS,
+ IEEE8021AH_HEADER_TOO_SMALL,
+
/* RAW EVENTS */
IPRAW_INVALID_IPV, /**< invalid ip version in ip raw */
#include "util-profiling.h"
#include "host.h"
+static int DecodeIEEE8021ah(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
+ uint8_t *pkt, uint16_t len, PacketQueue *pq);
+
/**
* \internal
* \brief this function is used to decode IEEE802.1q packets
len - VLAN_HEADER_LEN, pq);
}
break;
+ case ETHERNET_TYPE_8021AH:
+ DecodeIEEE8021ah(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 0;
}
+typedef struct IEEE8021ahHdr_ {
+ uint32_t flags;
+ uint8_t c_destination[6];
+ uint8_t c_source[6];
+ uint16_t type; /**< next protocol */
+} __attribute__((__packed__)) IEEE8021ahHdr;
+
+#define IEEE8021AH_HEADER_LEN sizeof(IEEE8021ahHdr)
+
+static int DecodeIEEE8021ah(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+{
+ StatsIncr(tv, dtv->counter_ieee8021ah);
+
+ if (len < IEEE8021AH_HEADER_LEN) {
+ ENGINE_SET_INVALID_EVENT(p, IEEE8021AH_HEADER_TOO_SMALL);
+ return TM_ECODE_FAILED;
+ }
+
+ IEEE8021ahHdr *hdr = (IEEE8021ahHdr *)pkt;
+ uint16_t next_proto = ntohs(hdr->type);
+
+ switch (next_proto) {
+ case ETHERNET_TYPE_VLAN:
+ case ETHERNET_TYPE_8021QINQ: {
+ DecodeVLAN(tv, dtv, p, pkt + IEEE8021AH_HEADER_LEN,
+ len - IEEE8021AH_HEADER_LEN, pq);
+ break;
+ }
+ }
+ return TM_ECODE_OK;
+}
+
#ifdef UNITTESTS
/** \todo Must GRE+VLAN and Multi-Vlan packets to
* create more tests
dtv->counter_gre = StatsRegisterCounter("decoder.gre", tv);
dtv->counter_vlan = StatsRegisterCounter("decoder.vlan", tv);
dtv->counter_vlan_qinq = StatsRegisterCounter("decoder.vlan_qinq", tv);
+ dtv->counter_ieee8021ah = StatsRegisterCounter("decoder.ieee8021ah", tv);
dtv->counter_teredo = StatsRegisterCounter("decoder.teredo", tv);
dtv->counter_ipv4inipv6 = StatsRegisterCounter("decoder.ipv4_in_ipv6", tv);
dtv->counter_ipv6inipv6 = StatsRegisterCounter("decoder.ipv6_in_ipv6", tv);
uint16_t counter_gre;
uint16_t counter_vlan;
uint16_t counter_vlan_qinq;
+ uint16_t counter_ieee8021ah;
uint16_t counter_pppoe;
uint16_t counter_teredo;
uint16_t counter_mpls;