From: Josh Date: Fri, 18 Apr 2014 14:10:17 +0000 (-0400) Subject: Adding GRE and ARP codecs X-Git-Tag: 3.0.0-233~1559^2~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6fa06749e71634c832a39d136533f270a148ae98;p=thirdparty%2Fsnort3.git Adding GRE and ARP codecs --- diff --git a/src/codecs/plugins/CMakeLists.txt b/src/codecs/plugins/CMakeLists.txt index 0697d2213..3e048512c 100644 --- a/src/codecs/plugins/CMakeLists.txt +++ b/src/codecs/plugins/CMakeLists.txt @@ -7,6 +7,7 @@ add_library( codec_plugins STATIC cd_ah.cc cd_arp.cc cd_ethloopback.cc + cd_gre.cc ) diff --git a/src/codecs/tmp/prot_gre.cc b/src/codecs/plugins/cd_gre.cc similarity index 61% rename from src/codecs/tmp/prot_gre.cc rename to src/codecs/plugins/cd_gre.cc index ceda9df36..61d609ea0 100644 --- a/src/codecs/tmp/prot_gre.cc +++ b/src/codecs/plugins/cd_gre.cc @@ -21,21 +21,61 @@ */ +#include "framework/codec.h" +#include "codecs/codec_events.h" +#include "codecs/decode_module.h" +#include "protocols/packet.h" + +namespace +{ + +class GreCodec : public Codec +{ +public: + GreCodec() : Codec("GRE"){}; + ~GreCodec(); -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "generators.h" -#include "decode.h" -#include "static_include.h" -#include "prot_gre.h" + virtual bool decode(const uint8_t *raw_pkt, const uint32_t len, + Packet *, uint16_t &p_hdr_len, int &next_prot_id); -// other decoders -#include "decoder_includes.h" -#include "prot_arp.h" -#include "prot_ethloopback.h" -#include "prot_pppencap.h" + virtual void get_protocol_ids(std::vector&); + virtual void get_data_link_type(std::vector&){}; + +}; + +static const uint16_t GRE_PROT_ID = 47; +static const uint32_t GRE_HEADER_LEN = 4; +static const uint32_t GRE_CHKSUM_LEN = 2; +static const uint32_t GRE_OFFSET_LEN = 2; +static const uint32_t GRE_KEY_LEN = 4; +static const uint32_t GRE_SEQ_LEN = 4; +static const uint32_t GRE_SRE_HEADER_LEN = 4; + +/* GRE version 1 used with PPTP */ +static const uint32_t GRE_V1_HEADER_LEN =8; +static const uint32_t GRE_V1_ACK_LEN = 4; + +#define GRE_V1_FLAGS(x) (x->version & 0x78) +#define GRE_V1_ACK(x) (x->version & 0x80) +#define GRE_CHKSUM(x) (x->flags & 0x80) +#define GRE_ROUTE(x) (x->flags & 0x40) +#define GRE_KEY(x) (x->flags & 0x20) +#define GRE_SEQ(x) (x->flags & 0x10) +#define GRE_SSR(x) (x->flags & 0x08) +#define GRE_RECUR(x) (x->flags & 0x07) +#define GRE_FLAGS(x) (x->version & 0xF8) + +#if 0 +#define GRE_HEADER_LEN 4 +#define GRE_CHKSUM_LEN 2 +#define GRE_OFFSET_LEN 2 +#define GRE_KEY_LEN 4 +#define GRE_SEQ_LEN 4 +#define GRE_SRE_HEADER_LEN 4 +#endif + +} // anonymous namespace @@ -57,17 +97,14 @@ * * Notes: see RFCs 1701, 2784 and 2637 */ -bool GRE::Decode(const uint8_t *pkt, const uint32_t len, - Packet *p, uint16_t &p_hdr_len, uint16_t &next_prot_id) +bool GreCodec::decode(const uint8_t *raw_pkt, const uint32_t len, + Packet *p, uint16_t &p_hdr_len, int &next_prot_id) { - uint32_t hlen; /* GRE header length */ - uint32_t payload_len; - if (len < GRE_HEADER_LEN) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_DGRAM_LT_GREHDR, - pkt, len); - return; + raw_pkt, len); + return false; } if (p->encapsulated) @@ -75,8 +112,8 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, /* discard packet - multiple GRE encapsulation */ /* not sure if this is ever used but I am assuming it is not */ CodecEvents::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, - pkt, len); - return; + raw_pkt, len); + return false; } /* Note: Since GRE doesn't have a field to indicate header length and @@ -84,8 +121,8 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, * figure out the length */ - p->greh = (GREHdr *)pkt; - hlen = GRE_HEADER_LEN; + p->greh = (GREHdr *)raw_pkt; + p_hdr_len = GRE_HEADER_LEN; switch (GRE_VERSION(p->greh)) { @@ -94,18 +131,18 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, if (GRE_RECUR(p->greh) || GRE_FLAGS(p->greh)) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_INVALID_HEADER, - pkt, len); - return; + raw_pkt, len); + return false; } if (GRE_CHKSUM(p->greh) || GRE_ROUTE(p->greh)) - hlen += GRE_CHKSUM_LEN + GRE_OFFSET_LEN; + p_hdr_len += GRE_CHKSUM_LEN + GRE_OFFSET_LEN; if (GRE_KEY(p->greh)) - hlen += GRE_KEY_LEN; + p_hdr_len += GRE_KEY_LEN; if (GRE_SEQ(p->greh)) - hlen += GRE_SEQ_LEN; + p_hdr_len += GRE_SEQ_LEN; /* if this flag is set, we need to walk through all of the * Source Route Entries */ @@ -116,12 +153,12 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, uint8_t sre_length; const uint8_t *sre_ptr; - sre_ptr = pkt + hlen; + sre_ptr = raw_pkt + p_hdr_len; while (1) { - hlen += GRE_SRE_HEADER_LEN; - if (hlen > len) + p_hdr_len += GRE_SRE_HEADER_LEN; + if (p_hdr_len > len) break; sre_addrfamily = ntohs(*((uint16_t *)sre_ptr)); @@ -136,7 +173,7 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, if ((sre_addrfamily == 0) && (sre_length == 0)) break; - hlen += sre_length; + p_hdr_len += sre_length; sre_ptr += sre_length; } } @@ -150,57 +187,54 @@ bool GRE::Decode(const uint8_t *pkt, const uint32_t len, GRE_RECUR(p->greh) || GRE_V1_FLAGS(p->greh)) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_V1_INVALID_HEADER, - pkt, len); - return; + raw_pkt, len); + return false; } /* protocol must be 0x880B - PPP */ if (GRE_PROTO(p->greh) != GRE_TYPE_PPP) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_V1_INVALID_HEADER, - pkt, len); - return; + raw_pkt, len); + return false; } /* this flag should always be present */ if (!(GRE_KEY(p->greh))) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_V1_INVALID_HEADER, - pkt, len); - return; + raw_pkt, len); + return false; } - hlen += GRE_KEY_LEN; + p_hdr_len += GRE_KEY_LEN; if (GRE_SEQ(p->greh)) - hlen += GRE_SEQ_LEN; + p_hdr_len += GRE_SEQ_LEN; if (GRE_V1_ACK(p->greh)) - hlen += GRE_V1_ACK_LEN; + p_hdr_len += GRE_V1_ACK_LEN; break; default: CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_INVALID_VERSION, - pkt, len); - return; + raw_pkt, len); + return false; } - if (hlen > len) + if (p_hdr_len > len) { CodecEvents::decoder_alert_encapsulated(p, DECODE_GRE_DGRAM_LT_GREHDR, - pkt, len); - return; + raw_pkt, len); + return false; } - PushLayer(PROTO_GRE, p, pkt, hlen); - payload_len = len - hlen; - - p_hdr_len = hlen; next_prot_id = GRE_PROTO(p->greh); return true; } +#if 0 /* * ENCODER */ @@ -208,14 +242,13 @@ void GRE_Format (EncodeFlags, const Packet*, Packet* c, Layer* lyr) { c->greh = (GREHdr*)lyr->start; } - - +#endif void GreCodec::get_protocol_ids(std::vector& v) { - v.push_back(IPPROTO_GRE); + v.push_back(GRE_PROT_ID); } static Codec* ctor() @@ -228,12 +261,23 @@ static void dtor(Codec *cd) delete cd; } +static void sum() +{ +// sum_stats((PegCount*)&gdc, (PegCount*)&dc, array_size(dc_pegs)); +// memset(&dc, 0, sizeof(dc)); +} + +static void stats() +{ +// show_percent_stats((PegCount*)&gdc, dc_pegs, array_size(dc_pegs), +// "decoder"); +} -static const char* name = "gre_decode"; +static const char* name = "gre_codec"; -static const CodecApi udp_api = +static const CodecApi codec_api = { { PT_CODEC, name, CDAPI_PLUGIN_V0, 0 }, NULL, // pinit @@ -242,7 +286,8 @@ static const CodecApi udp_api = NULL, // tterm ctor, // ctor dtor, // dtor - NULL, - NULL + sum, // sum + stats // stats }; + diff --git a/src/protocols/CMakeLists.txt b/src/protocols/CMakeLists.txt index 79977d1ef..e6dad368d 100644 --- a/src/protocols/CMakeLists.txt +++ b/src/protocols/CMakeLists.txt @@ -9,5 +9,10 @@ add_library (protocols eth.h icmp4.h icmp6.h + gre.h + gtp.h + arp.h + wlan.h + teredo.h ) diff --git a/src/protocols/arp.h b/src/protocols/arp.h index d86cf95c2..8dd60cc3b 100644 --- a/src/protocols/arp.h +++ b/src/protocols/arp.h @@ -26,7 +26,7 @@ namespace arp{ namespace detail{ -} // namespace detial +} // namespace detail diff --git a/src/codecs/tmp/prot_gre.h b/src/protocols/gre.h similarity index 68% rename from src/codecs/tmp/prot_gre.h rename to src/protocols/gre.h index d0e1a9998..254d2f3b8 100644 --- a/src/codecs/tmp/prot_gre.h +++ b/src/protocols/gre.h @@ -19,8 +19,35 @@ */ -#ifndef PROT_GRE_H -#define PROT_GRE_H +#ifndef GRE_H +#define GRE_H +namespace gre{ + +namespace detail{ + +} // namespace detail + +/* GRE related stuff */ +struct GREHdr +{ + uint8_t flags; + uint8_t version; + uint16_t ether_type; + +}; + + +} // namespace gre + +typedef gre::GREHdr GREHdr; + + +#define GRE_TYPE_TRANS_BRIDGING 0x6558 +#define GRE_TYPE_PPP 0x880B + + +#define GRE_VERSION(x) (x->version & 0x07) +#define GRE_PROTO(x) ntohs(x->ether_type) #endif diff --git a/src/protocols/packet.h b/src/protocols/packet.h index d5ed85a2f..ccaa6bc6e 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -60,6 +60,7 @@ extern "C" { #include "protocols/icmp4.h" #include "protocols/icmp6.h" #include "protocols/arp.h" +#include "protocols/gre.h" /* D E F I N E S ************************************************************/ @@ -515,45 +516,6 @@ typedef struct _WifiHdr #endif -/* GRE related stuff */ -typedef struct _GREHdr -{ - uint8_t flags; - uint8_t version; - uint16_t ether_type; - -} GREHdr; - -#ifndef IPPROTO_GRE -#define IPPROTO_GRE 47 -#endif - -#define GRE_TYPE_TRANS_BRIDGING 0x6558 -#define GRE_TYPE_PPP 0x880B - -#define GRE_HEADER_LEN 4 -#define GRE_CHKSUM_LEN 2 -#define GRE_OFFSET_LEN 2 -#define GRE_KEY_LEN 4 -#define GRE_SEQ_LEN 4 -#define GRE_SRE_HEADER_LEN 4 - -#define GRE_CHKSUM(x) (x->flags & 0x80) -#define GRE_ROUTE(x) (x->flags & 0x40) -#define GRE_KEY(x) (x->flags & 0x20) -#define GRE_SEQ(x) (x->flags & 0x10) -#define GRE_SSR(x) (x->flags & 0x08) -#define GRE_RECUR(x) (x->flags & 0x07) -#define GRE_VERSION(x) (x->version & 0x07) -#define GRE_FLAGS(x) (x->version & 0xF8) -#define GRE_PROTO(x) ntohs(x->ether_type) - -/* GRE version 1 used with PPTP */ -#define GRE_V1_HEADER_LEN 8 -#define GRE_V1_ACK_LEN 4 -#define GRE_V1_FLAGS(x) (x->version & 0x78) -#define GRE_V1_ACK(x) (x->version & 0x80) - typedef struct _ERSpanType2Hdr { uint16_t ver_vlan;