extern const BaseApi* cd_icmp6_ip;
extern const BaseApi* cd_ipv6;
extern const BaseApi* cd_igmp;
+extern const BaseApi* cd_llc;
extern const BaseApi* cd_mobility;
extern const BaseApi* cd_mpls;
extern const BaseApi* cd_no_next;
cd_icmp6_ip,
cd_ipv6,
cd_igmp,
+ cd_llc,
cd_mobility,
cd_mpls,
cd_no_next,
#include "protocols/protocol_ids.h"
#include "codecs/sf_protocols.h"
#include "protocols/ipv6.h"
+#include "protocols/packet.h"
+#include "codecs/ip/ip_util.h"
namespace
{
void AuthCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
- v.push_back(IPPROTO_ID_AH);
+ v.push_back(IPPROTO_ID_AUTH);
}
bool AuthCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
}
next_prot_id = ah->ip6e_nxt;
+
+ if (p->ip_api.is_ip6())
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_AUTH, next_prot_id);
return true;
}
//-------------------------------------------------------------------------
static Module* mod_ctor()
-{
- return new AuthModule;
-}
+{ return new AuthModule; }
static void mod_dtor(Module* m)
-{
- delete m;
-}
+{ delete m; }
static Codec* ctor(Module*)
-{
- return new AuthCodec();
-}
+{ return new AuthCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi ah_api =
{
/* See if there are any ip_proto only rules that match */
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_DSTOPTS);
- ip_util::CheckIPv6ExtensionOrder(p);
-
if(raw_len < sizeof(IP6Dest))
{
}
- p->ip6_extensions[p->ip6_extension_count].type = IPPROTO_ID_DSTOPTS;
- p->ip6_extensions[p->ip6_extension_count].data = raw_pkt;
p->ip6_extension_count++;
next_prot_id = dsthdr->ip6dest_nxt;
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_DSTOPTS, next_prot_id);
if ( ip_util::CheckIPV6HopOptions(raw_pkt, raw_len, p))
return true;
return false;
//-------------------------------------------------------------------------
static Codec* ctor(Module*)
-{
- return new Ipv6DSTOptsCodec();
-}
+{ return new Ipv6DSTOptsCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi ipv6_dstopts_api =
{
#include "protocols/packet_manager.h"
#include "codecs/codec_events.h"
#include "protocols/protocol_ids.h"
+#include "codecs/ip/ip_util.h"
namespace
{
pad_length = *(esp_payload + guessed_len);
next_prot_id = *(esp_payload + guessed_len + 1);
+
+ if (p->ip_api.is_ip6())
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_ESP, next_prot_id);
+
+
+
// TODO: Leftover from Snort. Do we really want thsi?
const_cast<uint32_t&>(raw_len) -= (ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN);
const ip::IP6Frag* ip6frag_hdr = reinterpret_cast<const ip::IP6Frag*>(raw_pkt);
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_FRAGMENT);
- ip_util::CheckIPv6ExtensionOrder(p);
if(raw_len < ip::MIN_EXT_LEN )
{
}
/* If this is an IP Fragment, set some data... */
- p->ip6_frag_index = p->ip6_extension_count;
+ p->ip6_frag_index = p->num_layers;
p->ip_frag_start = raw_pkt + sizeof(ip::IP6Frag);
p->decode_flags &= ~DECODE__DF;
codec_events::decoder_event(p, DECODE_IPV6_UNORDERED_EXTENSIONS);
}
- // check header ordering up thru frag header
- ip_util::CheckIPv6ExtensionOrder(p);
lyr_len = sizeof(ip::IP6Frag);
+ next_prot_id = ip6frag_hdr->ip6f_nxt;
p->ip_frag_len = (uint16_t)(raw_len - lyr_len);
+ // check header ordering up thru frag header
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_FRAGMENT, next_prot_id);
+
if ( (p->decode_flags & DECODE__FRAG) && ((frag_offset > 0) ||
(ip6frag_hdr->ip6f_nxt != IPPROTO_UDP)) )
{
return false;
}
-
- p->ip6_extensions[p->ip6_extension_count].type = IPPROTO_ID_FRAGMENT;
- p->ip6_extensions[p->ip6_extension_count].data = raw_pkt;
p->ip6_extension_count++;
-
- next_prot_id = ip6frag_hdr->ip6f_nxt;
return true;
}
/* See if there are any ip_proto only rules that match */
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_HOPOPTS);
- ip_util::CheckIPv6ExtensionOrder(p);
lyr_len = sizeof(IP6HopByHop) + (hbh_hdr->ip6hbh_len << 3);
next_prot_id = (uint16_t) hbh_hdr->ip6hbh_nxt;
return false;
}
- p->ip6_extensions[p->ip6_extension_count].type = IPPROTO_ID_HOPOPTS;
- p->ip6_extensions[p->ip6_extension_count].data = raw_pkt;
p->ip6_extension_count++;
-
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_HOPOPTS, next_prot_id);
if ( ip_util::CheckIPV6HopOptions(raw_pkt, raw_len, p))
return true;
+
return false;
}
IPV6CheckIsatap(ip6h, p);
p->ip_api.set(ip6h);
+ p->curr_ip6_extension_order = 0;
+ p->decode_flags &= ~DECODE__ROUTING_SEEN;
IPV6MiscTests(p);
CheckIPV6Multicast(ip6h, p);
int i = lyr - c->layers;
if ( i + 1 == p->num_layers )
{
- uint8_t* b = (uint8_t*)p->ip6_extensions[p->ip6_frag_index].data;
+ const uint8_t* b = (uint8_t*)p->layers[p->ip6_frag_index].start;
if ( b ) lyr->length = b - p->layers[i].start;
}
}
#include "framework/codec.h"
#include "codecs/decode_module.h"
#include "codecs/codec_events.h"
-#include "codecs/ip/ip_util.h"
#include "protocols/protocol_ids.h"
#include "detection/fpdetect.h"
#include "main/snort.h"
{
/* See if there are any ip_proto only rules that match */
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_NONEXT);
- ip_util::CheckIPv6ExtensionOrder(p);
+
+ // No need ot check IPv6 extension order since this is automatically
+ // the last extension.
// I want the dsize to be zero, so set the raw_length the
// length to be zero.
if (data_left > header->nak.opt.len) {
/* checksum is expensive... do that only if the length is bad */
- if (header->checksum != 0) {
+ if (header->checksum != 0)
+ {
checksum = checksum::cksum_add((uint16_t*)data, (int)length);
if (checksum != 0)
return PGM_NAK_ERR;
const IP6Route *rte = reinterpret_cast<const IP6Route *>(raw_pkt);
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_ROUTING);
- ip_util::CheckIPv6ExtensionOrder(p);
+
if(raw_len < ip::MIN_EXT_LEN)
/* Routing type 0 extension headers are evil creatures. */
if (rte->ip6rte_type == 0)
- {
codec_events::decoder_event(p, DECODE_IPV6_ROUTE_ZERO);
- }
if (rte->ip6rte_nxt == IPPROTO_ID_HOPOPTS)
- {
codec_events::decoder_event(p, DECODE_IPV6_ROUTE_AND_HOPBYHOP);
- }
+
if (rte->ip6rte_nxt == IPPROTO_ID_ROUTING)
- {
codec_events::decoder_event(p, DECODE_IPV6_TWO_ROUTE_HEADERS);
- }
+
lyr_len = ip::MIN_EXT_LEN + (rte->ip6rte_len << 3);
if(lyr_len > raw_len)
}
- p->ip6_extensions[p->ip6_extension_count].type = IPPROTO_ID_ROUTING;
- p->ip6_extensions[p->ip6_extension_count].data = raw_pkt;
p->ip6_extension_count++;
next_prot_id = rte->ip6rte_nxt;
+ // check header ordering up thru frag header
+ ip_util::CheckIPv6ExtensionOrder(p, IPPROTO_ID_ROUTING, next_prot_id);
+ p->decode_flags &= DECODE__ROUTING_SEEN;
+
return true;
}
//-------------------------------------------------------------------------
static Codec* ctor(Module*)
-{
- return new Ipv6RoutingCodec();
-}
+{ return new Ipv6RoutingCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi ipv6_routing_api =
{
return false;
}
+
p->error_flags |= PKT_ERR_CKSUM_TCP;
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad TCP checksum\n",
"0x%x versus 0x%x\n", csum,
bool TcpCodec::update(Packet* p, Layer* lyr, uint32_t* len)
{
- tcp::TCPHdr* h = reinterpret_cast<tcp::TCPHdr*>(lyr->start);
+ tcp::TCPHdr* h = reinterpret_cast<tcp::TCPHdr*>(const_cast<uint8_t*>(lyr->start));
*len += h->hdr_len() + p->dsize;
uint16_t ip_len = ntohs(p->ip_api.len());
/* subtract the distance from udp header to 1st ip6 extension */
/* This gives the length of the UDP "payload", when fragmented */
- uhlen = ip_len - ((u_char *)udph - (u_char *)p->ip6_extensions[0].data);
+ uhlen = ip_len - ((u_char *)udph - (u_char *)p->ip_api.ip_data());
}
else
{
return true;
}
+/* Check for out-of-order IPv6 Extension Headers */
+void CheckIPv6ExtensionOrder(Packet* p, uint8_t proto, uint8_t next)
+{
+ const uint8_t current_order = IPV6ExtensionOrder(proto);
+ const uint8_t next_order = IPV6ExtensionOrder(next);
+
+ if (current_order <= p->curr_ip6_extension_order)
+ {
+ /* A second "Destination Options" header is allowed iff:
+ 1) A routing header was already seen, and
+ 2) The second destination header is the last one before the upper layer.
+ */
+ if (!((p->decode_flags & DECODE__ROUTING_SEEN) &&
+ (proto == IPPROTO_ID_DSTOPTS) &&
+ (next_order == IPV6_ORDER_MAX)))
+ {
+ codec_events::decoder_event(p, DECODE_IPV6_UNORDERED_EXTENSIONS);
+ }
+ }
+ else
+ {
+ p->curr_ip6_extension_order = current_order;
+ }
+
+ if (proto == IPPROTO_ID_ROUTING)
+ p->decode_flags &= DECODE__ROUTING_SEEN;
+}
+
+#if 0
+// FIXIT-M Delete after testing. Currently comment for reference
/* Check for out-of-order IPv6 Extension Headers */
void CheckIPv6ExtensionOrder(Packet *p)
{
current_type_order = next_type_order;
}
}
+#endif
} // namespace ipv6_util
#include "protocols/protocol_ids.h"
#include "protocols/packet.h"
#include "framework/codec.h"
+#include "main/snort_types.h"
namespace ip_util
{
-bool CheckIPV6HopOptions(const uint8_t *pkt, uint32_t len, Packet *p);
-void CheckIPv6ExtensionOrder(Packet *p);
+const int IPV6_ORDER_MAX = 7;
+
+SO_PUBLIC bool CheckIPV6HopOptions(const uint8_t *pkt, uint32_t len, Packet *p);
+SO_PUBLIC void CheckIPv6ExtensionOrder(Packet* p, uint8_t proto, uint8_t next);
+
static inline int IPV6ExtensionOrder(uint8_t type)
{
case IPPROTO_ID_DSTOPTS: return 2;
case IPPROTO_ID_ROUTING: return 3;
case IPPROTO_ID_FRAGMENT: return 4;
- case IPPROTO_ID_AH: return 5;
+ case IPPROTO_ID_AUTH: return 5;
case IPPROTO_ID_ESP: return 6;
- default: return 7;
+ default: return IPV6_ORDER_MAX;
}
}
#include "codecs/decode_module.h"
#include "codecs/codec_events.h"
#include "protocols/vlan.h"
+#include "protocols/eth.h"
#include "protocols/protocol_ids.h"
#include "codecs/sf_protocols.h"
+#include "protocols/packet_manager.h"
+#include "log/text_log.h"
namespace
{
virtual void get_protocol_ids(std::vector<uint16_t>& v);
virtual bool decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
-};
-
-struct EthLlc
-{
- uint8_t dsap;
- uint8_t ssap;
-} ;
-
-
-struct EthLlcOther
-{
- uint8_t ctrl;
- uint8_t org_code[3];
- uint16_t proto_id;
+ virtual void log(TextLog*, const uint8_t* /*raw_pkt*/, const Packet* const);
};
} // namespace
-
-static inline uint32_t len_vlan_llc_other()
-{
- return (sizeof(vlan::VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther));
-}
-
-
void VlanCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
v.push_back(ETHERTYPE_8021Q);
}
const vlan::VlanTagHdr *vh = reinterpret_cast<const vlan::VlanTagHdr *>(raw_pkt);
+ const uint16_t proto = ntohs(vh->vth_proto);
- DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Vlan traffic:\n");
- DebugMessage(DEBUG_DECODE, " Priority: %d(0x%X)\n",
- vlan::vth_priority(vh), vlan::vth_priority(vh));
- DebugMessage(DEBUG_DECODE, " CFI: %d\n", vlan::vth_cfi(vh));
- DebugMessage(DEBUG_DECODE, " Vlan ID: %d(0x%04X)\n",
- vlan::vth_vlan(vh), vlan::vth_vlan(vh));
- DebugMessage(DEBUG_DECODE, " Vlan Proto: 0x%04X\n",
- ntohs(vh->vth_proto));
- );
/* check to see if we've got an encapsulated LLC layer
* http://www.geocities.com/billalexander/ethernet.html
*/
- if(ntohs(vh->vth_proto) <= ETHERNET_MAX_LEN_ENCAP)
- {
- if(raw_len < sizeof(vlan::VlanTagHdr) + sizeof(EthLlc))
- {
- codec_events::decoder_event(p, DECODE_BAD_VLAN_ETHLLC);
- return false;
- }
-
- const EthLlc *ehllc = reinterpret_cast<const EthLlc *>(raw_pkt + sizeof(vlan::VlanTagHdr));
-
- DEBUG_WRAP(
- DebugMessage(DEBUG_DECODE, "LLC Header:\n");
- DebugMessage(DEBUG_DECODE, " DSAP: 0x%X\n", ehllc->dsap);
- DebugMessage(DEBUG_DECODE, " SSAP: 0x%X\n", ehllc->ssap);
- );
-
- if(ehllc->dsap == ETH_DSAP_IP && ehllc->ssap == ETH_SSAP_IP)
- {
- if (raw_len < len_vlan_llc_other())
- {
- codec_events::decoder_event(p, DECODE_BAD_VLAN_OTHER);
- return false;
- }
-
- const EthLlcOther *ehllcother = reinterpret_cast<const EthLlcOther *>(raw_pkt + sizeof(vlan::VlanTagHdr) + sizeof(EthLlc));
-
- DEBUG_WRAP(
- DebugMessage(DEBUG_DECODE, "LLC Other Header:\n");
- DebugMessage(DEBUG_DECODE, " CTRL: 0x%X\n",
- ehllcother->ctrl);
- DebugMessage(DEBUG_DECODE, " ORG: 0x%02X%02X%02X\n",
- ehllcother->org_code[0], ehllcother->org_code[1],
- ehllcother->org_code[2]);
- DebugMessage(DEBUG_DECODE, " PROTO: 0x%04X\n",
- ntohs(ehllcother->proto_id));
- );
-
- lyr_len = len_vlan_llc_other();
- next_prot_id = ntohs(ehllcother->proto_id);
- }
- }
+ if(proto <= ETHERNET_MAX_LEN_ENCAP)
+ next_prot_id = ETHERNET_LLC;
else
- {
- uint16_t vid = vlan::vth_vlan(vh);
+ next_prot_id = proto;
- // Vlan IDs 0 and 4095 are reserved.
- if (vid == 0 || vid == 4095)
- {
- codec_events::decoder_event(p, DECODE_BAD_VLAN);
- return false;
- }
+ // Vlan IDs 0 and 4095 are reserved.
+ const uint16_t vid = vlan::vth_vlan(vh);
+ if (vid == 0 || vid == 4095)
+ codec_events::decoder_event(p, DECODE_BAD_VLAN);
- lyr_len = sizeof(vlan::VlanTagHdr);
- next_prot_id = ntohs(vh->vth_proto);
- }
+ lyr_len = sizeof(vlan::VlanTagHdr);
p->proto_bits |= PROTO_BIT__VLAN;
return true;
}
+void VlanCodec::log(TextLog* text_log, const uint8_t* raw_pkt, const Packet* const)
+{
+ const vlan::VlanTagHdr *vh = reinterpret_cast<const vlan::VlanTagHdr *>(raw_pkt);
+ const uint16_t proto = ntohs(vh->vth_proto);
+ const uint16_t vid = vlan::vth_vlan(vh);
+ uint16_t proto_name;
+
+ if (proto <= ETHERNET_MAX_LEN_ENCAP)
+ proto_name = ETHERNET_LLC;
+ else
+ proto_name = proto;
+
+
+ TextLog_Print(text_log, "VLAN Priority:%d(0x%X) CFI:%d "
+ "Vlan_ID:%d(0x%04X) Next:%s(%04X)",
+ vlan::vth_priority(vh), vlan::vth_cfi(vh),
+ vid, vid, PacketManager::get_proto_name(proto_name),
+ proto);
+}
+
//-------------------------------------------------------------------------
// api
//-------------------------------------------------------------------------
static Module* mod_ctor()
-{
- return new VlanModule;
-}
+{ return new VlanModule; }
static void mod_dtor(Module* m)
-{
- delete m;
-}
+{ delete m; }
static Codec* ctor(Module*)
-{
- return new VlanCodec();
-}
+{ return new VlanCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi vlan_api =
{
if(STATIC_CODECS)
set(PLUGIN_LIST
+ cd_gtp.cc
cd_icmp4_ip.cc
cd_icmp6_ip.cc
- cd_gtp.cc
+ cd_llc.cc
cd_teredo.cc
)
add_shared_library(cd_teredo codecs cd_teredo.cc)
add_shared_library(cd_icmp4_ip codecs cd_icmp4_ip.cc)
add_shared_library(cd_icmp6_ip codecs cd_icmp6_ip.cc)
+ add_shared_library(cd_llc codecs cd_llc.cc)
endif(STATIC_CODECS)
plugin_list = \
cd_gtp.cc \
-cd_teredo.cc \
cd_icmp4_ip.cc \
-cd_icmp6_ip.cc
+cd_icmp6_ip.cc \
+cd_llc.cc \
+cd_teredo.cc
if STATIC_CODECS
libmisc_codecs_a_SOURCES += $(plugin_list)
else
ehlibdir = $(pkglibdir)/codecs
-ehlib_LTLIBRARIES = libcd_gtp.la
-libcd_gtp_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libcd_gtp_la_LDFLAGS = -export-dynamic -shared
-libcd_gtp_la_SOURCES = cd_gtp.cc
-ehlib_LTLIBRARIES += libcd_teredo.la
-libcd_teredo_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libcd_teredo_la_LDFLAGS = -export-dynamic -shared
-libcd_teredo_la_SOURCES = cd_teredo.cc
-
-ehlib_LTLIBRARIES += libcd_icmp4_ip.la
+ehlib_LTLIBRARIES = libcd_icmp4_ip.la
libcd_icmp4_ip_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
libcd_icmp4_ip_la_LDFLAGS = -export-dynamic -shared
libcd_icmp4_ip_la_SOURCES = cd_icmp4_ip.cc
libcd_icmp6_ip_la_LDFLAGS = -export-dynamic -shared
libcd_icmp6_ip_la_SOURCES = cd_icmp6_ip.cc
+ehlib_LTLIBRARIES += libcd_llc.la
+libcd_llc_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_llc_la_LDFLAGS = -export-dynamic -shared
+libcd_llc_la_SOURCES = libcd_llc.cc
+
+ehlib_LTLIBRARIES += libcd_gtp.la
+libcd_gtp_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_gtp_la_LDFLAGS = -export-dynamic -shared
+libcd_gtp_la_SOURCES = cd_gtp.cc
+
+ehlib_LTLIBRARIES += libcd_teredo.la
+libcd_teredo_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_teredo_la_LDFLAGS = -export-dynamic -shared
+libcd_teredo_la_SOURCES = cd_teredo.cc
+
endif
AM_CXXFLAGS = @AM_CXXFLAGS@
);
next_prot_id = ntohs(eh->ether_type);
+
if (next_prot_id > eth::MIN_ETHERTYPE )
- {
p->proto_bits |= PROTO_BIT__ETH;
- lyr_len = eth::ETH_HEADER_LEN;
- return true;
- }
+ else
+ next_prot_id = ETHERNET_LLC;
- return false;
+ lyr_len = eth::ETH_HEADER_LEN;
+ return true;
}
eh->ether_src[4], eh->ether_src[5]);
/* dest addr */
- TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X ", eh->ether_dst[0],
+ TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X", eh->ether_dst[0],
eh->ether_dst[1], eh->ether_dst[2], eh->ether_dst[3],
eh->ether_dst[4], eh->ether_dst[5]);
- /* protocol and pkt size */
- TextLog_Print(log, "type:0x%X", ntohs(eh->ether_type));
+ const uint16_t prot = ntohs(eh->ether_type);
- // FIXIT-L - J Log length in PacketManager
+ if (prot <= eth::MIN_ETHERTYPE)
+ TextLog_Print(log, " len:0x%04X", prot);
+ else
+ TextLog_Print(log, "type:0x%04X", prot);
}
//-------------------------------------------------------------------------
// reinterpret the raw data into this codec's data format
- DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
- DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n",
- (unsigned long)cap_len, (unsigned long)raw_len););
-
/* do a little validation */
if(cap_len < MINIMAL_IEEE80211_HEADER_LEN)
{
case WLAN_TYPE_DATA_DTACKPL:
case WLAN_TYPE_DATA_DATA:
{
-
+ lyr_len = IEEE802_11_DATA_HDR_LEN;
+ next_prot_id = ETHERNET_LLC;
+#if 0
if(cap_len < IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc))
{
codec_events::decoder_event(p, DECODE_BAD_80211_ETHLLC);
return false;
}
}
+#endif
break;
}
default:
//-------------------------------------------------------------------------
static Module* mod_ctor()
-{
- return new WlanCodecModule;
-}
+{ return new WlanCodecModule; }
static void mod_dtor(Module* m)
-{
- delete m;
-}
+{ delete m; }
static Codec* ctor(Module*)
-{
- return new WlanCodec();
-}
+{ return new WlanCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi wlan_api =
#include <string.h> // memcpy
#include "framework/codec.h"
-#include "codecs/template_module.h"
+#include "codecs/decode_module.h"
#include "protocols/packet.h"
-
+#include "framework/module.h"
namespace
{
//
// this macros is defined in the module to ensure identical names. However,
// if you don't want a module, define the name here.
-#ifndef CODEC_NAME
#define CODEC_NAME "name"
-#endif
+
+
+
+
+// inherit from DecodeModule rather than Module so the GID for
+// all codecs are identical. Additionally, all of the SIDS are
+// defined in DecodeModule. So, when creating new events, you
+// only need to look for codec SID collisions in one locations
+class NameModule : public DecodeModule
+{
+public:
+ NameModule();
+
+ bool set(const char*, Value&, SnortConfig*);
+ bool begin(const char*, int, SnortConfig*);
+ const RuleMap* get_rules() const;
+
+private:
+ // any structs or options which will be used when constructing
+ // the Codec
+ bool option1;
+
+};
+
+
+static const Parameter codec_params[] =
+{
+ { "parameter1", Parameter::PT_BOOL, nullptr, "false",
+ "This is a boolean parameter" },
+
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+
+// rules which will loaded into snort.
+// You can now reference these rules by calling a codec_event
+// in your main codec's functions
+const unsigned sid = 1;
+static const RuleMap codec_rules[] =
+{
+ { sid, "(" CODEC_NAME ") alert message" },
+ { 0, nullptr }
+};
+
+//-------------------------------------------------------------------------
+// template module
+//-------------------------------------------------------------------------
+
+NameModule::NameModule() : DecodeModule(CODEC_NAME, codec_params)
+{ }
+
+bool NameModule::set(const char*, Value& v, SnortConfig* sc)
+{
+ if ( v.is("parameter1") )
+ option1 = v.get_bool();
+
+ else
+ return false;
+
+ return true;
+}
+
+bool NameModule::begin(const char*, int, SnortConfig*)
+{
+ option1 = false;
+ return true;
+}
+
+const RuleMap* NameModule::get_rules() const
+{ return codec_rules; }
+
class NameCodec : public Codec
{
virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
- virtual void log(TextLog* /*log*/, const uint8_t* /*raw_in*/);
+ virtual void log(TextLog*, const uint8_t* /*raw_pkt*/, const Packet* const);
virtual void get_protocol_ids(std::vector<uint16_t>&);
virtual void get_data_link_type(std::vector<int>&);
virtual bool encode(EncState*, Buffer* out, const uint8_t* raw_in);
* details regarding Modules
*/
static Module* mod_ctor()
-{
- return new NameModule;
-}
+{ return new NameModule; }
static void mod_dtor(Module* m)
-{
- delete m;
-}
+{ delete m; }
+// initialize global variables
static void ginit()
-{
- // initialize global variables
-}
+{ }
+// cleanup any global variables
static void gterm()
-{
- // cleanup any global variables
-}
+{ }
+// initialize thread_local variables
static void tinit()
-{
- // initialize thread_local variables
-}
+{ }
+// cleanup any thread_local variables
static void tterm()
-{
- // cleanup any thread_local variables
-}
+{ }
static Codec* ctor(Module*)
-{
- return new NameCodec();
-}
+{ return new NameCodec(); }
static void dtor(Codec *cd)
-{
- delete cd;
-}
+{ delete cd; }
static const CodecApi name_api =
+++ /dev/null
-/*
-** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License Version 2 as
-** published by the Free Software Foundation. You may not use, modify or
-** distribute this program under any other version of the GNU General
-** Public License.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-// template_module.cc author Josh Rosenbaum <jrosenba@cisco.com>
-
-#include "codecs/template_module.h"
-
-
-static const Parameter codec_params[] =
-{
- { "parameter1", Parameter::PT_BOOL, nullptr, "false",
- "This is a boolean parameter" },
-
- { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-
-// rules which will loaded into snort.
-// You can now reference these rules by calling a codec_event
-// in your main codec's functions
-static const RuleMap codec_rules[] =
-{
- { SID, "(" CODEC_NAME ") alert message" },
- { 0, nullptr }
-};
-
-//-------------------------------------------------------------------------
-// rpc module
-//-------------------------------------------------------------------------
-
-NameCodec::NameCodec() : DecodeModule(CODEC_NAME, codec_params)
-{ }
-
-bool NameCodec::set(const char*, Value& v, SnortConfig* sc)
-{
- if ( v.is("parameter1") )
- option1 = v.get_bool();
-
- else
- return false;
-
- return true;
-}
-
-bool NameCodec::begin(const char*, int, SnortConfig*)
-{
- option1 = false;
- return true;
-}
-
-const NameCodec::RuleMap* get_rules() const
-{ return codec_rules; }
+++ /dev/null
-/*
-** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License Version 2 as
-** published by the Free Software Foundation. You may not use, modify or
-** distribute this program under any other version of the GNU General
-** Public License.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-// template_module.h author Josh Rosenbaum <jrosenba@cisco.com>
-
-#ifndef TEMPLATE_MODULE_H
-#define TEMPLATE_MODULE_H
-
-#include "codecs/decode_module.h"
-
-
-#define CODEC_NAME "name"
-
-// inherit from DecodeModule rather than Module so the GID for
-// all codecs are identical. Additionally, all of the SIDS are
-// defined in DecodeModule. So, when creating new events, you
-// only need to look for codec SID collisions in one locations
-class NameModule : public DecodeModule
-{
-public:
- NameModule();
-
- bool set(const char*, Value&, SnortConfig*);
- bool begin(const char*, int, SnortConfig*);
-
-private:
- // any structs or options which will be used when constructing
- // the Codec
- bool option1;
-
-};
-
-#endif
static int Norm_IP4 (
NormalizerConfig* c, Packet * p, uint8_t layer, int changes)
{
- IP4Hdr* h = (IP4Hdr*)(p->layers[layer].start);
+ IP4Hdr* h = (IP4Hdr*)const_cast<uint8_t*>(p->layers[layer].start);
uint16_t fragbits = ntohs(h->ip_off);
uint16_t origbits = fragbits;
}
if ( p->layers[layer].length > ip::IP4_HEADER_LEN )
{
- uint8_t* opts = p->layers[layer].start + ip::IP4_HEADER_LEN;
+ uint8_t* opts = const_cast<uint8_t*>(p->layers[layer].start) + ip::IP4_HEADER_LEN;
uint8_t len = p->layers[layer].length - ip::IP4_HEADER_LEN;
// expect len > 0 because IHL yields a multiple of 4
memset(opts, IPOPT_NOP, len);
static int Norm_IP6_Opts (
NormalizerConfig*, Packet * p, uint8_t layer, int changes)
{
- uint8_t* b = p->layers[layer].start;
+ uint8_t* b = const_cast<uint8_t*>(p->layers[layer].start);
ExtOpt* x = (ExtOpt*)b;
// whatever was here, turn it into one PADN option
uint8_t tcp_options_len = p->tcph->options_len();
if ( tcp_options_len > 0 )
{
- uint8_t* opts = p->layers[layer].start + tcp::TCP_HEADER_LEN;
+ uint8_t* opts = const_cast<uint8_t*>(p->layers[layer].start) + tcp::TCP_HEADER_LEN;
if ( Norm_IsEnabled(c, NORM_TCP_OPT) )
{
#define ETHERNET_HEADER_LEN 14
#define ETHERNET_MTU 1500
-#define ETH_DSAP_SNA 0x08 /* SNA */
-#define ETH_SSAP_SNA 0x00 /* SNA */
-#define ETH_DSAP_STP 0x42 /* Spanning Tree Protocol */
-#define ETH_SSAP_STP 0x42 /* Spanning Tree Protocol */
-#define ETH_DSAP_IP 0xaa /* IP */
-#define ETH_SSAP_IP 0xaa /* IP */
-
-#define ETH_ORG_CODE_ETHR 0x000000 /* Encapsulated Ethernet */
-#define ETH_ORG_CODE_CDP 0x00000c /* Cisco Discovery Proto */
namespace eth
{
return 0;
const IP6Frag* const frag_hdr = reinterpret_cast<const IP6Frag* const>(
- p->ip6_extensions[p->ip6_frag_index].data);
+ p->layers[p->ip6_frag_index].start);
return frag_hdr->get_id();
}
return 0;
const IP6Frag* const frag_hdr = reinterpret_cast<const IP6Frag* const>(
- p->ip6_extensions[p->ip6_frag_index].data);
+ p->layers[p->ip6_frag_index].start);
return frag_hdr->get_off();
}
{
case ETHERTYPE_IPV4:
case IPPROTO_ID_IPIP:
- return reinterpret_cast<IP4Hdr*>(layers[i].start)->get_proto();
+ return reinterpret_cast<const IP4Hdr*>(layers[i].start)->get_proto();
case ETHERTYPE_IPV6:
case IPPROTO_ID_IPV6:
- return reinterpret_cast<ip::IP6Hdr*>(layers[i].start)->get_next();
+ return reinterpret_cast<const ip::IP6Hdr*>(layers[i].start)->get_next();
default:
break;
}
uint16_t prot_id;
PROTO_ID proto;
uint16_t length;
- uint8_t* start;
+ const uint8_t* start;
};
uint16_t dsize; /* packet payload size */
ip::IpOptions ip_options[IP_OPTMAX]; /* ip options decode structure */
- ip::IP6Option ip6_extensions[IP6_EXTMAX]; /* IPv6 Extension References */
Options tcp_options[TCP_OPTLENMAX]; /* tcp options decode struct */
-
+ uint8_t curr_ip6_extension_order;
const uint8_t *ip_frag_start;
#define DECODE__TRUST_ON_FAIL 0x08 /* if decode fails, set the PKT_TRUST flag */
#define DECODE__UNSURE_ENCAP 0x10 /* packet may have incorrect encapsulation layer. */
/* don't alert if "next layer" is invalid. */
+#define DECODE__ROUTING_SEEN 0X20
#define DECODE__FREE 0xE0
#define IsIP(p) (p->ip_api.is_valid())
Layer& lyr = p->layers[p->num_layers++];
lyr.proto = cd->get_proto_id();
lyr.prot_id = prot_id;
- lyr.start = (uint8_t*)hdr_start;
+ lyr.start = hdr_start;
lyr.length = (uint16_t)len;
}
else
{
+ //FIXIT-M Alert when max layers maxed out.
LogMessage("(packet_manager) WARNING: decoder has too many layers;"
" next proto is something.\n");
}
p->packet_flags |= PKT_TRUST;
}
}
+ s_stats[mapped_prot + stat_offset]++;
if (ScMaxEncapsulations() != -1 &&
codec_events::decoder_event(p, DECODE_IP_MULTIPLE_ENCAPSULATION);
}
- if (p->ip6_extension_count > 0)
- ip_util::CheckIPv6ExtensionOrder(p);
-
- s_stats[mapped_prot + stat_offset]++;
-
/*
* NOTE: NEVER RETURN BEFORE SETTING THESE TWO VARIABLES!!
* they are no longer zeroed above, which means if they
for(int i = 0; CodecManager::s_protocols[i] != 0; i++)
pkt_names.push_back(CodecManager::s_protocols[i]->get_name());
- show_percent_stats((PegCount*) &g_stats, &pkt_names[0], (unsigned int) pkt_names.size(),
- "codec");
+ show_percent_stats((PegCount*) &g_stats, &pkt_names[0],
+ (unsigned int) pkt_names.size(), "codec");
}
void PacketManager::accumulate()
struct _daq_pkthdr;
+
/*
* PacketManager class
*/
constexpr uint16_t IPPROTO_ID_FRAGMENT = 44;
constexpr uint16_t IPPROTO_ID_GRE = 47;
constexpr uint16_t IPPROTO_ID_ESP = 50;
-constexpr uint16_t IPPROTO_ID_AH = 51; // RFC 4302
+constexpr uint16_t IPPROTO_ID_AUTH = 51; // RFC 4302
constexpr uint16_t IPPROTO_ID_ICMPV6 = 58;
constexpr uint16_t IPPROTO_ID_NONEXT = 59;
constexpr uint16_t IPPROTO_ID_DSTOPTS = 60;
constexpr uint16_t IP_EMBEDDED_IN_ICMP4 = 0x0103;
constexpr uint16_t IP_EMBEDDED_IN_ICMP6 = 0x0104;
constexpr uint16_t ETHERNET_802_3 = 0x0105; // CAPWAP sends data back to eth layer
+constexpr uint16_t ETHERNET_LLC = 0x0106;
{
// FIXIT-J use of last_extension works but is ugly
ip::IP6Extension *last_extension = (ip::IP6Extension *)
- (dpkt->pkt + (p->ip6_extensions[p->ip6_frag_index -1].data - p->pkt));
+ (dpkt->pkt + (p->layers[p->ip6_frag_index].start - p->pkt));
last_extension->ip6e_nxt = ft->protocol;
}
else
if (p->ip_api.is_ip6() && (p->frag_offset == 0))
{
- ip::IP6Frag *fragHdr = (ip::IP6Frag *)p->ip6_extensions[p->ip6_frag_index].data;
+ ip::IP6Frag *fragHdr = (ip::IP6Frag *)p->layers[p->ip6_frag_index].start;
if (ft->protocol != fragHdr->ip6f_nxt)
{
ft->protocol = fragHdr->ip6f_nxt;
{
if (p->frag_offset == 0)
{
- ip::IP6Frag *fragHdr = (ip::IP6Frag *)p->ip6_extensions[p->ip6_frag_index].data;
+ ip::IP6Frag *fragHdr = (ip::IP6Frag *)p->layers[p->ip6_frag_index].start;
ft->protocol = fragHdr->ip6f_nxt;
}
}