#ifndef CODEC_EVENTS_H
#define CODEC_EVENTS_H
+#include "framework/codec.h"
#include "codecs/decode_module.h"
#include "events/event_queue.h"
namespace codec_events
{
-inline void decoder_event(CodecSid const sid)
+inline void decoder_event(const CodecData& codec, CodecSid const sid)
{
-#if 0
- // FIXIT-H -J Remove this function if PacketManager::decode() - assert never occurs
- /* Can this return statement ever be true? */
- /* Remove function if so */
- if ( p->packet_flags & PKT_REBUILT_STREAM )
+ if ( codec.codec_flags & CODEC_STREAM_REBUILT )
return;
-#endif
SnortEventqAdd(GID_DECODE, sid);
}
if (raw.len < MIN_AUTH_LEN)
{
- codec_events::decoder_event(DECODE_AUTH_HDR_TRUNC);
+ codec_events::decoder_event(codec, DECODE_AUTH_HDR_TRUNC);
return false;
}
if (codec.lyr_len > raw.len)
{
- codec_events::decoder_event(DECODE_AUTH_HDR_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_AUTH_HDR_BAD_LEN);
return false;
}
// must be called AFTER setting next_prot_id
if (snort.ip_api.is_ip6())
+ {
ip_util::CheckIPv6ExtensionOrder(codec, IPPROTO_ID_AUTH);
+ codec.proto_bits |= PROTO_BIT__IP6_EXT;
+ codec.ip6_csum_proto = ah->next;
+ }
return true;
}
if(raw.len < sizeof(IP6Dest))
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
if ( codec.ip6_extension_count >= IP6_EXTMAX )
{
- codec_events::decoder_event(DECODE_IP6_EXCESS_EXT_HDR);
+ codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
}
if (dsthdr->ip6dest_nxt == IPPROTO_ROUTING)
- codec_events::decoder_event(DECODE_IPV6_DSTOPTS_WITH_ROUTING);
+ codec_events::decoder_event(codec, DECODE_IPV6_DSTOPTS_WITH_ROUTING);
codec.lyr_len = sizeof(IP6Dest) + (dsthdr->ip6dest_len << 3);
if(codec.lyr_len > raw.len)
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
codec.proto_bits |= PROTO_BIT__IP6_EXT;
codec.ip6_extension_count++;
codec.next_prot_id = dsthdr->ip6dest_nxt;
+ codec.ip6_csum_proto = dsthdr->ip6dest_nxt;
// must be called AFTER setting next_prot_id
ip_util::CheckIPv6ExtensionOrder(codec, IPPROTO_ID_DSTOPTS);
- if ( ip_util::CheckIPV6HopOptions(raw))
+ if ( ip_util::CheckIPV6HopOptions(raw, codec))
return true;
return false;
}
if (raw.len < (ESP_HEADER_LEN + ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN))
{
/* Truncated ESP traffic. Bail out here and inspect the rest as payload. */
- codec_events::decoder_event(DECODE_ESP_HEADER_TRUNC);
+ codec_events::decoder_event(codec, DECODE_ESP_HEADER_TRUNC);
return false;
}
// must be called AFTER setting next_prot_id
if (snort.ip_api.is_ip6())
+ {
ip_util::CheckIPv6ExtensionOrder(codec, IPPROTO_ID_ESP);
-
+ codec.proto_bits |= PROTO_BIT__IP6_EXT;
+ codec.ip6_csum_proto = codec.next_prot_id;
+ }
// TODO: Leftover from Snort. Do we really want thsi?
if(raw.len < ip::MIN_EXT_LEN )
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
if ( codec.ip6_extension_count >= IP6_EXTMAX )
{
- codec_events::decoder_event(DECODE_IP6_EXCESS_EXT_HDR);
+ codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
}
// already checked for short pacekt above
if (raw.len == sizeof(ip::IP6Frag))
{
- codec_events::decoder_event(DECODE_ZERO_LENGTH_FRAG);
+ codec_events::decoder_event(codec, DECODE_ZERO_LENGTH_FRAG);
return false;
}
if (frag_offset || (snort.decode_flags & DECODE_MF))
snort.decode_flags |= DECODE_FRAG;
else
- codec_events::decoder_event(DECODE_IPV6_BAD_FRAG_PKT);
+ codec_events::decoder_event(codec, DECODE_IPV6_BAD_FRAG_PKT);
codec.lyr_len = sizeof(ip::IP6Frag);
codec.next_prot_id = ip6frag_hdr->ip6f_nxt;
+ codec.ip6_csum_proto = ip6frag_hdr->ip6f_nxt;
codec.proto_bits |= PROTO_BIT__IP6_EXT;
codec.ip6_extension_count++;
{
if (raw.len < GRE_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_GRE_DGRAM_LT_GREHDR);
+ codec_events::decoder_event(codec, DECODE_GRE_DGRAM_LT_GREHDR);
return false;
}
/* these must not be set */
if (GRE_RECUR(greh) || GRE_FLAGS(greh))
{
- codec_events::decoder_event(DECODE_GRE_INVALID_HEADER);
+ codec_events::decoder_event(codec, DECODE_GRE_INVALID_HEADER);
return false;
}
if (GRE_CHKSUM(greh) || GRE_ROUTE(greh) || GRE_SSR(greh) ||
GRE_RECUR(greh) || GRE_V1_FLAGS(greh))
{
- codec_events::decoder_event(DECODE_GRE_V1_INVALID_HEADER);
+ codec_events::decoder_event(codec, DECODE_GRE_V1_INVALID_HEADER);
return false;
}
/* protocol must be 0x880B - PPP */
if (greh->get_proto() != ETHERTYPE_PPP)
{
- codec_events::decoder_event(DECODE_GRE_V1_INVALID_HEADER);
+ codec_events::decoder_event(codec, DECODE_GRE_V1_INVALID_HEADER);
return false;
}
/* this flag should always be present */
if (!(GRE_KEY(greh)))
{
- codec_events::decoder_event(DECODE_GRE_V1_INVALID_HEADER);
+ codec_events::decoder_event(codec, DECODE_GRE_V1_INVALID_HEADER);
return false;
}
break;
default:
- codec_events::decoder_event(DECODE_GRE_INVALID_VERSION);
+ codec_events::decoder_event(codec, DECODE_GRE_INVALID_VERSION);
return false;
}
if (len > raw.len)
{
- codec_events::decoder_event(DECODE_GRE_DGRAM_LT_GREHDR);
+ codec_events::decoder_event(codec, DECODE_GRE_DGRAM_LT_GREHDR);
return false;
}
if (raw.len < sizeof(IP6HopByHop))
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
if ( codec.ip6_extension_count >= IP6_EXTMAX )
{
- codec_events::decoder_event(DECODE_IP6_EXCESS_EXT_HDR);
+ codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
}
codec.lyr_len = sizeof(IP6HopByHop) + (hbh_hdr->ip6hbh_len << 3);
if(codec.lyr_len > raw.len)
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
codec.next_prot_id = (uint16_t) hbh_hdr->ip6hbh_nxt;
+ codec.ip6_csum_proto = hbh_hdr->ip6hbh_nxt;
codec.ip6_extension_count++;
codec.proto_bits |= PROTO_BIT__IP6_EXT;
// must be called AFTER setting next_prot_id
ip_util::CheckIPv6ExtensionOrder(codec, IPPROTO_ID_HOPOPTS);
- if ( ip_util::CheckIPV6HopOptions(raw))
+ if ( ip_util::CheckIPV6HopOptions(raw, codec))
return true;
return false;
const Packet* const);
private:
- void ICMP4AddrTests(const SnortData&);
+ void ICMP4AddrTests(const SnortData& snort, const CodecData& codec);
void ICMP4MiscTests(const ICMPHdr* const, const CodecData&, const uint16_t);
};
if(raw.len < icmp::ICMP_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_ICMP4_HDR_TRUNC);
+ codec_events::decoder_event(codec, DECODE_ICMP4_HDR_TRUNC);
return false;
}
case icmp::IcmpType::INFO_REPLY:
if (raw.len < 8)
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
case icmp::IcmpType::TIMESTAMPREPLY:
if (raw.len < 20)
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR);
return false;
}
break;
case icmp::IcmpType::ADDRESSREPLY:
if (raw.len < 12)
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ADDRHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ADDRHDR);
return false;
}
break;
default:
- codec_events::decoder_event(DECODE_ICMP4_TYPE_OTHER);
+ codec_events::decoder_event(codec, DECODE_ICMP4_TYPE_OTHER);
break;
}
switch(icmph->type)
{
case icmp::IcmpType::ECHO_4:
- ICMP4AddrTests(snort);
+ ICMP4AddrTests(snort, codec);
// fall through ...
case icmp::IcmpType::ECHOREPLY:
if ((icmph->code == icmp::IcmpCode::FRAG_NEEDED)
&& (ntohs(icmph->s_icmp_nextmtu) < 576))
{
- codec_events::decoder_event(DECODE_ICMP_PATH_MTU_DOS);
+ codec_events::decoder_event(codec, DECODE_ICMP_PATH_MTU_DOS);
}
/* Fall through */
return true;
}
-void Icmp4Codec::ICMP4AddrTests(const SnortData& snort)
+void Icmp4Codec::ICMP4AddrTests(const SnortData& snort, const CodecData& codec)
{
uint32_t dst = snort.ip_api.get_dst()->ip32[0];
// check all 32 bits; all set so byte order is irrelevant ...
if ( dst == ip::IP4_BROADCAST )
- codec_events::decoder_event(DECODE_ICMP4_DST_BROADCAST);
+ codec_events::decoder_event(codec, DECODE_ICMP4_DST_BROADCAST);
/* - don't use htonl for speed reasons -
* s_addr is always in network order */
msb_dst >>= 4;
if( msb_dst == ip::IP4_MULTICAST )
- codec_events::decoder_event(DECODE_ICMP4_DST_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_ICMP4_DST_MULTICAST);
}
{
if ((dsize == 0) &&
(icmph->type == icmp::IcmpType::ECHO_4))
- codec_events::decoder_event(DECODE_ICMP_PING_NMAP);
+ codec_events::decoder_event(codec, DECODE_ICMP_PING_NMAP);
if ((dsize == 0) &&
(icmph->s_icmp_seq == 666))
- codec_events::decoder_event(DECODE_ICMP_ICMPENUM);
+ codec_events::decoder_event(codec, DECODE_ICMP_ICMPENUM);
if ((icmph->type == icmp::IcmpType::REDIRECT) &&
(icmph->code == icmp::IcmpCode::REDIR_HOST))
- codec_events::decoder_event(DECODE_ICMP_REDIRECT_HOST);
+ codec_events::decoder_event(codec, DECODE_ICMP_REDIRECT_HOST);
if ((icmph->type == icmp::IcmpType::REDIRECT) &&
(icmph->code == icmp::IcmpCode::REDIR_NET))
- codec_events::decoder_event(DECODE_ICMP_REDIRECT_NET);
+ codec_events::decoder_event(codec, DECODE_ICMP_REDIRECT_NET);
if ((icmph->type == icmp::IcmpType::ECHOREPLY) &&
(codec.codec_flags & CODEC_IPOPT_RR_SEEN))
- codec_events::decoder_event(DECODE_ICMP_TRACEROUTE_IPOPTS);
+ codec_events::decoder_event(codec, DECODE_ICMP_TRACEROUTE_IPOPTS);
if ((icmph->type == icmp::IcmpType::SOURCE_QUENCH) &&
(icmph->code == icmp::IcmpCode::SOURCE_QUENCH_CODE))
- codec_events::decoder_event(DECODE_ICMP_SOURCE_QUENCH);
+ codec_events::decoder_event(codec, DECODE_ICMP_SOURCE_QUENCH);
if ((dsize == 4) &&
(icmph->type == icmp::IcmpType::ECHO_4) &&
(icmph->s_icmp_seq == 0) &&
(icmph->code == icmp::IcmpCode::ECHO_CODE))
- codec_events::decoder_event(DECODE_ICMP_BROADSCAN_SMURF_SCANNER);
+ codec_events::decoder_event(codec, DECODE_ICMP_BROADSCAN_SMURF_SCANNER);
if ((icmph->type == icmp::IcmpType::DEST_UNREACH) &&
(icmph->code == icmp::IcmpCode::PKT_FILTERED))
- codec_events::decoder_event(DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED);
+ codec_events::decoder_event(codec, DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED);
if ((icmph->type == icmp::IcmpType::DEST_UNREACH) &&
(icmph->code == icmp::IcmpCode::PKT_FILTERED_HOST))
- codec_events::decoder_event(DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED);
+ codec_events::decoder_event(codec, DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED);
if ((icmph->type == icmp::IcmpType::DEST_UNREACH) &&
(icmph->code == icmp::IcmpCode::PKT_FILTERED_NET))
- codec_events::decoder_event(DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED);
+ codec_events::decoder_event(codec, DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED);
}
/******************************************************************
DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
"WARNING: Truncated ICMP6 header (%d bytes).\n", raw.len););
- codec_events::decoder_event(DECODE_ICMP6_HDR_TRUNC);
+ codec_events::decoder_event(codec, DECODE_ICMP6_HDR_TRUNC);
return false;
}
COPY4(ph6.sip, snort.ip_api.get_src()->ip32);
COPY4(ph6.dip, snort.ip_api.get_dst()->ip32);
ph6.zero = 0;
- ph6.protocol = snort.ip_api.proto();
+ ph6.protocol = codec.ip6_csum_proto;
ph6.len = htons((u_short)raw.len);
csum = checksum::icmp_cksum((uint16_t *)(icmp6h), raw.len, &ph6);
len = icmp::ICMP6_HEADER_NORMAL_LEN;
if ( snort.ip_api.get_ip6h()->is_dst_multicast() )
- codec_events::decoder_event(DECODE_ICMP6_DST_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_ICMP6_DST_MULTICAST);
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
icmp::ICMP6TooBig *too_big = (icmp::ICMP6TooBig *)raw.data;
if (ntohl(too_big->mtu) < 1280)
- codec_events::decoder_event(DECODE_ICMPV6_TOO_BIG_BAD_MTU);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_TOO_BIG_BAD_MTU);
len = icmp::ICMP6_HEADER_NORMAL_LEN;
codec.next_prot_id = IP_EMBEDDED_IN_ICMP6;
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
if (icmp6h->type == icmp::Icmp6Types::UNREACH)
{
if (icmp6h->code == icmp::Icmp6Code::UNREACH_INVALID) // UNREACH_INVALID == 2
- codec_events::decoder_event(DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE);
else if (static_cast<uint8_t>(icmp6h->code) > 6)
- codec_events::decoder_event(DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE);
}
len = icmp::ICMP6_HEADER_NORMAL_LEN;
codec.next_prot_id = IP_EMBEDDED_IN_ICMP6;
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
icmp::ICMP6RouterAdvertisement *ra = (icmp::ICMP6RouterAdvertisement *)raw.data;
if (icmp6h->code != icmp::Icmp6Code::ADVERTISEMENT)
- codec_events::decoder_event(DECODE_ICMPV6_ADVERT_BAD_CODE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_ADVERT_BAD_CODE);
if (ntohl(ra->reachable_time) > 3600000)
- codec_events::decoder_event(DECODE_ICMPV6_ADVERT_BAD_REACHABLE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_ADVERT_BAD_REACHABLE);
len = icmp::ICMP6_HEADER_MIN_LEN;
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
{
icmp::ICMP6RouterSolicitation *rs = (icmp::ICMP6RouterSolicitation *)raw.data;
if (rs->code != 0)
- codec_events::decoder_event(DECODE_ICMPV6_SOLICITATION_BAD_CODE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_SOLICITATION_BAD_CODE);
if (ntohl(rs->reserved) != 0)
- codec_events::decoder_event(DECODE_ICMPV6_SOLICITATION_BAD_RESERVED);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_SOLICITATION_BAD_RESERVED);
len = icmp::ICMP6_HEADER_MIN_LEN;
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
{
icmp::ICMP6NodeInfo *ni = (icmp::ICMP6NodeInfo *)raw.data;
if (ni->code > 2)
- codec_events::decoder_event(DECODE_ICMPV6_NODE_INFO_BAD_CODE);
+ codec_events::decoder_event(codec, DECODE_ICMPV6_NODE_INFO_BAD_CODE);
/* TODO: Add alert for INFO Response, code == 1 || code == 2)
* and there is data.
}
else
{
- codec_events::decoder_event(DECODE_ICMP_DGRAM_LT_ICMPHDR);
+ codec_events::decoder_event(codec, DECODE_ICMP_DGRAM_LT_ICMPHDR);
return false;
}
break;
default:
- codec_events::decoder_event(DECODE_ICMP6_TYPE_OTHER);
+ codec_events::decoder_event(codec, DECODE_ICMP6_TYPE_OTHER);
len = icmp::ICMP6_HEADER_MIN_LEN;
break;
}
if (snort.ip_api.get_ip_opt_len() >= 2) {
if (*(ip_opt_data) == 0 && *(ip_opt_data+1) == 0)
{
- codec_events::decoder_event(DECODE_IGMP_OPTIONS_DOS);
+ codec_events::decoder_event(codec, DECODE_IGMP_OPTIONS_DOS);
return false;
}
}
if ((!(codec.codec_flags & CODEC_IPOPT_RTRALT_SEEN)) &&
(codec.codec_flags & CODEC_IPOPT_LEN_THREE))
{
- codec_events::decoder_event(DECODE_IGMP_OPTIONS_DOS);
+ codec_events::decoder_event(codec, DECODE_IGMP_OPTIONS_DOS);
}
}
return true;
} // namespace
-static inline void IP4AddrTests (const IP4Hdr*);
-static inline void IPMiscTests(const IP4Hdr* const, uint16_t len);
+static inline void IP4AddrTests(const IP4Hdr*, const CodecData&);
+static inline void IPMiscTests(const IP4Hdr* const ip4h, const CodecData& codec, uint16_t len);
static void DecodeIPOptions(const uint8_t *start, uint8_t& o_len, CodecData& data);
"WARNING: Truncated IP4 header (%d bytes).\n", raw.len););
if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0)
- codec_events::decoder_event(DECODE_IP4_HDR_TRUNC);
+ codec_events::decoder_event(codec, DECODE_IP4_HDR_TRUNC);
return false;
}
codec.ip_layer_cnt++;
// FIXIT-H -j allow configure IP and IP6 encapsulation limits
if (codec.ip_layer_cnt > 1)
- codec_events::decoder_event(DECODE_IP_MULTIPLE_ENCAPSULATION);
+ codec_events::decoder_event(codec, DECODE_IP_MULTIPLE_ENCAPSULATION);
/* lay the IP struct over the raw data */
const IP4Hdr* const iph = reinterpret_cast<const IP4Hdr*>(raw.data);
if (iph->get_ver() != 4)
{
if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0)
- codec_events::decoder_event(DECODE_NOT_IPV4_DGRAM);
+ codec_events::decoder_event(codec, DECODE_NOT_IPV4_DGRAM);
return false;
}
DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
"Bogus IP header length of %i bytes\n", hlen););
- codec_events::decoder_event(DECODE_IPV4_INVALID_HEADER_LEN);
+ codec_events::decoder_event(codec, DECODE_IPV4_INVALID_HEADER_LEN);
return false;
}
" (ip.len: %lu, cap.len: %lu)\n",
ip_len - raw.len, ip_len, raw.len););
- codec_events::decoder_event(DECODE_IPV4_DGRAM_GT_CAPLEN);
+ codec_events::decoder_event(codec, DECODE_IPV4_DGRAM_GT_CAPLEN);
return false;
}
#if 0
"IP dgm len (%d bytes) < IP hdr "
"len (%d bytes), packet discarded\n", ip_len, hlen););
- codec_events::decoder_event(DECODE_IPV4_DGRAM_LT_IPHDR);
+ codec_events::decoder_event(codec, DECODE_IPV4_DGRAM_LT_IPHDR);
return false;
}
/*
* IP Header tests: Land attack, and Loop back test
*/
- IP4AddrTests(iph);
+ IP4AddrTests(iph, codec);
if (ScIpChecksums())
{
frag_off &= 0x1FFF;
if ((codec.codec_flags & CODEC_DF) && frag_off )
- codec_events::decoder_event(DECODE_IP4_DF_OFFSET);
+ codec_events::decoder_event(codec, DECODE_IP4_DF_OFFSET);
if ( frag_off + ip_len > IP_MAXPACKET )
- codec_events::decoder_event(DECODE_IP4_LEN_OFFSET);
+ codec_events::decoder_event(codec, DECODE_IP4_LEN_OFFSET);
if(frag_off || (snort.decode_flags & DECODE_MF))
{
if ( !ip_len)
{
- codec_events::decoder_event(DECODE_ZERO_LENGTH_FRAG);
+ codec_events::decoder_event(codec, DECODE_ZERO_LENGTH_FRAG);
snort.decode_flags &= ~DECODE_FRAG;
}
else
}
if( (snort.decode_flags & DECODE_MF) && (codec.codec_flags & CODEC_DF))
- codec_events::decoder_event(DECODE_BAD_FRAGBITS);
+ codec_events::decoder_event(codec, DECODE_BAD_FRAGBITS);
snort.set_pkt_type(PktType::IP);
codec.proto_bits |= PROTO_BIT__IP;
- IPMiscTests(iph, ip::IP4_HEADER_LEN + ip_opt_len);
+ IPMiscTests(iph, codec, ip::IP4_HEADER_LEN + ip_opt_len);
codec.lyr_len = hlen;
(iph->get_proto() == IPPROTO_UDP)))
{
if (iph->get_proto() >= MIN_UNASSIGNED_IP_PROTO)
- codec_events::decoder_event(DECODE_IP_UNASSIGNED_PROTO);
+ codec_events::decoder_event(codec, DECODE_IP_UNASSIGNED_PROTO);
else
codec.next_prot_id = iph->get_proto();
}
//--------------------------------------------------------------------
-static inline void IP4AddrTests(const IP4Hdr* iph)
+static inline void IP4AddrTests(const IP4Hdr* iph, const CodecData& codec)
{
uint8_t msb_src, msb_dst;
// check all 32 bits ...
if( iph->ip_src == iph->ip_dst )
{
- codec_events::decoder_event(DECODE_BAD_TRAFFIC_SAME_SRCDST);
+ codec_events::decoder_event(codec, DECODE_BAD_TRAFFIC_SAME_SRCDST);
}
// check all 32 bits ...
if (iph->is_src_broadcast())
- codec_events::decoder_event(DECODE_IP4_SRC_BROADCAST);
+ codec_events::decoder_event(codec, DECODE_IP4_SRC_BROADCAST);
if (iph->is_dst_broadcast())
- codec_events::decoder_event(DECODE_IP4_DST_BROADCAST);
+ codec_events::decoder_event(codec, DECODE_IP4_DST_BROADCAST);
/* Loopback traffic - don't use htonl for speed reasons -
* s_addr is always in network order */
// check the msb ...
if ( (msb_src == ip::IP4_LOOPBACK) || (msb_dst == ip::IP4_LOOPBACK) )
{
- codec_events::decoder_event(DECODE_BAD_TRAFFIC_LOOPBACK);
+ codec_events::decoder_event(codec, DECODE_BAD_TRAFFIC_LOOPBACK);
}
// check the msb ...
if ( msb_src == ip::IP4_THIS_NET )
- codec_events::decoder_event(DECODE_IP4_SRC_THIS_NET);
+ codec_events::decoder_event(codec, DECODE_IP4_SRC_THIS_NET);
if ( msb_dst == ip::IP4_THIS_NET )
- codec_events::decoder_event(DECODE_IP4_DST_THIS_NET);
+ codec_events::decoder_event(codec, DECODE_IP4_DST_THIS_NET);
// check the 'msn' (most significant nibble) ...
msb_src >>= 4;
msb_dst >>= 4;
if ( msb_src == ip::IP4_MULTICAST )
- codec_events::decoder_event(DECODE_IP4_SRC_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IP4_SRC_MULTICAST);
if ( msb_src == ip::IP4_RESERVED )
- codec_events::decoder_event(DECODE_IP4_SRC_RESERVED);
+ codec_events::decoder_event(codec, DECODE_IP4_SRC_RESERVED);
if ( msb_dst == ip::IP4_RESERVED )
- codec_events::decoder_event(DECODE_IP4_DST_RESERVED);
+ codec_events::decoder_event(codec, DECODE_IP4_DST_RESERVED);
}
/* IPv4-layer decoder rules */
-static inline void IPMiscTests(const IP4Hdr* const ip4h, uint16_t len)
+static inline void IPMiscTests(const IP4Hdr* const ip4h, const CodecData& codec, uint16_t len)
{
/* Yes, it's an ICMP-related vuln in IP options. */
/* If the remaining space in the option isn't a multiple of 4
bytes, alert. */
if (((length + 1) - pointer) % 4)
- codec_events::decoder_event(DECODE_ICMP_DOS_ATTEMPT);
+ codec_events::decoder_event(codec, DECODE_ICMP_DOS_ATTEMPT);
}
else if (opt.code == ip::IPOptionCodes::TS)
{
/* If the remaining space in the option isn't a multiple of 4
bytes, alert. */
if (((length + 1) - pointer) % 4)
- codec_events::decoder_event(DECODE_ICMP_DOS_ATTEMPT);
+ codec_events::decoder_event(codec, DECODE_ICMP_DOS_ATTEMPT);
/* If there is a timestamp + address, we need a multiple of 8
bytes instead. */
if ((opt.data[1] & 0x01) && /* address flag */
(((length + 1) - pointer) % 8))
- codec_events::decoder_event(DECODE_ICMP_DOS_ATTEMPT);
+ codec_events::decoder_event(codec, DECODE_ICMP_DOS_ATTEMPT);
}
}
}
{
/* Yes, we use TCP_OPT_* for the IP option decoder. */
if(code == tcp::OPT_BADLEN)
- codec_events::decoder_event(DECODE_IPV4OPT_BADLEN);
+ codec_events::decoder_event(codec, DECODE_IPV4OPT_BADLEN);
else if(code == tcp::OPT_TRUNC)
- codec_events::decoder_event(DECODE_IPV4OPT_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_IPV4OPT_TRUNCATED);
codec.invalid_bytes = o_len - tot_len;
o_len = tot_len;
} // namespace
-static inline void IPV6CheckIsatap(const ip::IP6Hdr* const, const SnortData&);
-static inline void IPV6MiscTests(const SnortData&);
-static void CheckIPV6Multicast(const ip::IP6Hdr* const);
-static inline int CheckTeredoPrefix(const ip::IP6Hdr* const hdr);
+static inline void IPV6CheckIsatap(const ip::IP6Hdr* const,
+ const SnortData&,
+ const CodecData&);
+static inline void IPV6MiscTests(const SnortData&, const CodecData&);
+static void CheckIPV6Multicast(const ip::IP6Hdr* const, const CodecData&);
+static inline bool CheckTeredoPrefix(const ip::IP6Hdr* const hdr);
/********************************************************************
************************* CLASS FUNCTIONS ************************
if(raw.len < ip::IP6_HEADER_LEN)
{
if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0)
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED);
// Taken from prot_ipv4.cc
- codec_events::decoder_event(DECODE_IPV6_TUNNELED_IPV4_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_IPV6_TUNNELED_IPV4_TRUNCATED);
goto decodeipv6_fail;
}
if(ip6h->get_ver() != 6)
{
if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0)
- codec_events::decoder_event(DECODE_IPV6_IS_NOT);
+ codec_events::decoder_event(codec, DECODE_IPV6_IS_NOT);
goto decodeipv6_fail;
}
// FIXIT-H -J alert on user configured encapsulated
- if (codec.ip_layer_cnt > 1)
- codec_events::decoder_event(DECODE_IP_MULTIPLE_ENCAPSULATION);
+ if (codec.ip_layer_cnt++ > 1)
+ codec_events::decoder_event(codec, DECODE_IP_MULTIPLE_ENCAPSULATION);
const uint32_t payload_len = ntohs(ip6h->ip6_payload_len) + ip::IP6_HEADER_LEN;
if (payload_len > raw.len)
{
if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0)
- codec_events::decoder_event(DECODE_IPV6_DGRAM_GT_CAPLEN);
+ codec_events::decoder_event(codec, DECODE_IPV6_DGRAM_GT_CAPLEN);
goto decodeipv6_fail;
}
If we ever start decoding more than 2 layers of IP in a packet, this
check against snort.proto_bits will need to be refactored. */
- if ((codec.codec_flags & CODEC_TEREDO_SEEN) && (CheckTeredoPrefix(ip6h) == 0))
+ if ((codec.codec_flags & CODEC_TEREDO_SEEN) && (!CheckTeredoPrefix(ip6h)))
{
goto decodeipv6_fail;
}
const_cast<uint32_t&>(raw.len) = ntohs(ip6h->get_len()) + ip::IP6_HEADER_LEN;
// check for isatap before overwriting the ip_api.
- IPV6CheckIsatap(ip6h, snort);
+ IPV6CheckIsatap(ip6h, snort, codec);
snort.ip_api.set(ip6h);
- codec.curr_ip6_extension = 0;
- codec.ip6_extension_count = 0;
- codec.codec_flags &= ~CODEC_ROUTING_SEEN;
- IPV6MiscTests(snort);
- CheckIPV6Multicast(ip6h);
+ IPV6MiscTests(snort, codec);
+ CheckIPV6Multicast(ip6h, codec);
snort.set_pkt_type(PktType::IP);
codec.next_prot_id = ip6h->get_next();
codec.lyr_len = ip::IP6_HEADER_LEN;
+ codec.curr_ip6_extension = 0;
+ codec.ip6_extension_count = 0;
+ codec.ip6_csum_proto = ip6h->get_next();
+ codec.codec_flags &= ~CODEC_ROUTING_SEEN;
// FIXIT-M J tunnel-byppas is NOT checked!!
return true;
-
}
decodeipv6_fail:
return false;
}
-static inline void IPV6CheckIsatap(const ip::IP6Hdr* const ip6h, const SnortData& snort)
+static inline void IPV6CheckIsatap(const ip::IP6Hdr* const ip6h,
+ const SnortData& snort,
+ const CodecData& codec)
{
/* Only check for IPv6 over IPv4 */
if (snort.ip_api.is_ip4() && snort.ip_api.proto() == IPPROTO_ID_IPV6)
if (isatap_interface_id == 0x00005EFE)
{
if (snort.ip_api.get_src()->ip32[0] != ip6h->ip6_src.u6_addr32[3])
- codec_events::decoder_event(DECODE_IPV6_ISATAP_SPOOF);
+ codec_events::decoder_event(codec, DECODE_IPV6_ISATAP_SPOOF);
}
}
}
*
* Returns: void function
*/
-static inline void IPV6MiscTests(const SnortData& snort)
+static inline void IPV6MiscTests(const SnortData& snort, const CodecData& codec)
{
const sfip_t *ip_src = snort.ip_api.get_src();
const sfip_t *ip_dst = snort.ip_api.get_dst();
* is used here in the interrim. */
if( sfip_contains(ip_src, ip_dst) == SFIP_CONTAINS)
{
- codec_events::decoder_event(DECODE_BAD_TRAFFIC_SAME_SRCDST);
+ codec_events::decoder_event(codec, DECODE_BAD_TRAFFIC_SAME_SRCDST);
}
if(sfip_is_loopback(ip_src) || sfip_is_loopback(ip_dst))
{
- codec_events::decoder_event(DECODE_BAD_TRAFFIC_LOOPBACK);
+ codec_events::decoder_event(codec, DECODE_BAD_TRAFFIC_LOOPBACK);
}
/* Other decoder alerts for IPv6 addresses
Added: 5/24/10 (Snort 2.9.0) */
if (!sfip_is_set(ip_dst))
{
- codec_events::decoder_event(DECODE_IPV6_DST_ZERO);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_ZERO);
}
}
/* Check for multiple IPv6 Multicast-related alerts */
-static void CheckIPV6Multicast(const ip::IP6Hdr* const ip6h)
+static void CheckIPV6Multicast(const ip::IP6Hdr* const ip6h, const CodecData& codec)
{
ip::MulticastScope multicast_scope;
if (ip6h->is_src_multicast())
{
- codec_events::decoder_event(DECODE_IPV6_SRC_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_SRC_MULTICAST);
}
if (!ip6h->is_dst_multicast())
{
break;
default:
- codec_events::decoder_event(DECODE_IPV6_BAD_MULTICAST_SCOPE);
+ codec_events::decoder_event(codec, DECODE_IPV6_BAD_MULTICAST_SCOPE);
}
/* Check against assigned multicast addresses. These are listed at:
(ip6h->ip6_dst.u6_addr16[4] != 0) ||
(ip6h->ip6_dst.u6_addr8[10] != 0))
{
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
return;
}
(ip6h->ip6_dst.u6_addr16[6] != 0))
{
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
else
{
case 0x000000FB: // mDNSv6
break;
default:
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
}
{
break; // Node Information Queries
}
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
else if (ip6h->is_dst_multicast_scope_site())
case 0x00010005: // SL-MANET-ROUTERS
break;
default:
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
else if ((ip6h->ip6_dst.u6_addr8[1] & 0xF0) == 0)
break; // SAP Dynamic Assignments
}
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
else if ((ip6h->ip6_dst.u6_addr8[1] & 0xF0) == 0x30)
else
{
// Other addresses in this block are reserved.
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
else
{
/* Addresses not listed above are reserved. */
- codec_events::decoder_event(DECODE_IPV6_DST_RESERVED_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_IPV6_DST_RESERVED_MULTICAST);
}
}
/* Teredo packets need to have one of their IPs use either the Teredo prefix,
or a link-local prefix (in the case of Router Solicitation messages) */
-static inline int CheckTeredoPrefix(const ip::IP6Hdr* const hdr)
+static inline bool CheckTeredoPrefix(const ip::IP6Hdr* const hdr)
{
/* Check if src address matches 2001::/32 */
if ((hdr->ip6_src.u6_addr8[0] == 0x20) &&
(hdr->ip6_src.u6_addr8[1] == 0x01) &&
(hdr->ip6_src.u6_addr8[2] == 0x00) &&
(hdr->ip6_src.u6_addr8[3] == 0x00))
- return 1;
+ return true;
/* Check if src address matches fe80::/64 */
if ((hdr->ip6_src.u6_addr8[0] == 0xfe) &&
(hdr->ip6_src.u6_addr8[5] == 0x00) &&
(hdr->ip6_src.u6_addr8[6] == 0x00) &&
(hdr->ip6_src.u6_addr8[7] == 0x00))
- return 1;
+ return true;
/* Check if dst address matches 2001::/32 */
if ((hdr->ip6_dst.u6_addr8[0] == 0x20) &&
(hdr->ip6_dst.u6_addr8[1] == 0x01) &&
(hdr->ip6_dst.u6_addr8[2] == 0x00) &&
(hdr->ip6_dst.u6_addr8[3] == 0x00))
- return 1;
+ return true;
/* Check if dst address matches fe80::/64 */
if ((hdr->ip6_dst.u6_addr8[0] == 0xfe) &&
(hdr->ip6_dst.u6_addr8[5] == 0x00) &&
(hdr->ip6_dst.u6_addr8[6] == 0x00) &&
(hdr->ip6_dst.u6_addr8[7] == 0x00))
- return 1;
+ return true;
/* No Teredo prefix found. */
- return 0;
+ return false;
}
bool MobilityCodec::decode(const RawData&, CodecData& codec, SnortData&)
{
- codec_events::decoder_event(DECODE_IP_BAD_PROTO);
+ codec_events::decoder_event(codec, DECODE_IP_BAD_PROTO);
codec.proto_bits |= PROTO_BIT__IP6_EXT; // check for any IP related rules
return true;
}
// private functions
//-------------------------------------------------------------------------
-bool PgmCodec::decode(const RawData& raw, CodecData&, SnortData&)
+bool PgmCodec::decode(const RawData& raw, CodecData& codec, SnortData&)
{
if ( pgm_nak_detect(raw) == PGM_NAK_VULN )
- codec_events::decoder_event(DECODE_PGM_NAK_OVERFLOW);
+ codec_events::decoder_event(codec, DECODE_PGM_NAK_OVERFLOW);
return true;
}
if(raw.len < ip::MIN_EXT_LEN)
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
if ( codec.ip6_extension_count >= IP6_EXTMAX)
{
- codec_events::decoder_event(DECODE_IP6_EXCESS_EXT_HDR);
+ codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
}
if (raw.len < sizeof(IP6Route))
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
/* Routing type 0 extension headers are evil creatures. */
if (rte->ip6rte_type == 0)
- codec_events::decoder_event(DECODE_IPV6_ROUTE_ZERO);
+ codec_events::decoder_event(codec, DECODE_IPV6_ROUTE_ZERO);
if (rte->ip6rte_nxt == IPPROTO_ID_HOPOPTS)
- codec_events::decoder_event(DECODE_IPV6_ROUTE_AND_HOPBYHOP);
+ codec_events::decoder_event(codec, DECODE_IPV6_ROUTE_AND_HOPBYHOP);
if (rte->ip6rte_nxt == IPPROTO_ID_ROUTING)
- codec_events::decoder_event(DECODE_IPV6_TWO_ROUTE_HEADERS);
+ codec_events::decoder_event(codec, DECODE_IPV6_TWO_ROUTE_HEADERS);
codec.lyr_len = ip::MIN_EXT_LEN + (rte->ip6rte_len << 3);
if(codec.lyr_len > raw.len)
{
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
return false;
}
codec.proto_bits |= PROTO_BIT__IP6_EXT; // check ip proto rules against this layer
codec.ip6_extension_count++;
codec.next_prot_id = rte->ip6rte_nxt;
+ codec.ip6_csum_proto = rte->ip6rte_nxt;
// must be called AFTER setting next_prot_id
ip_util::CheckIPv6ExtensionOrder(codec, IPPROTO_ID_ROUTING);
v.push_back(IPPROTO_ID_SUN_ND);
}
-bool SunNdCodec::decode(const RawData&, CodecData&, SnortData&)
+bool SunNdCodec::decode(const RawData&, CodecData& codec, SnortData&)
{
- codec_events::decoder_event(DECODE_IP_BAD_PROTO);
+ codec_events::decoder_event(codec, DECODE_IP_BAD_PROTO);
return true;
}
}
-bool SwipeCodec::decode(const RawData&, CodecData&, SnortData&)
+bool SwipeCodec::decode(const RawData&, CodecData& codec, SnortData&)
{
// currently unsupported
- codec_events::decoder_event(DECODE_IP_BAD_PROTO);
+ codec_events::decoder_event(codec, DECODE_IP_BAD_PROTO);
return true;
}
static void DecodeTCPOptions(const uint8_t *, uint32_t, CodecData&);
-static inline void TCPMiscTests(const SnortData& codec,
- const tcp::TCPHdr* const tcph);
+static inline void TCPMiscTests(const tcp::TCPHdr* const tcph,
+ const SnortData& snort,
+ const CodecData& codec);
void TcpCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
{
if(raw.len < tcp::TCP_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_TCP_DGRAM_LT_TCPHDR);
+ codec_events::decoder_event(codec, DECODE_TCP_DGRAM_LT_TCPHDR);
return false;
}
if(tcph_len < tcp::TCP_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_TCP_INVALID_OFFSET);
+ codec_events::decoder_event(codec, DECODE_TCP_INVALID_OFFSET);
return false;
}
if(tcph_len > raw.len)
{
- codec_events::decoder_event(DECODE_TCP_LARGE_OFFSET);
+ codec_events::decoder_event(codec, DECODE_TCP_LARGE_OFFSET);
return false;
}
COPY4(ph6.sip, ip6h->get_src()->u6_addr32);
COPY4(ph6.dip, ip6h->get_dst()->u6_addr32);
ph6.zero = 0;
- ph6.protocol = ip6h->get_next();
+ ph6.protocol = codec.ip6_csum_proto;
ph6.len = htons((uint16_t)raw.len);
if(tcph->are_flags_set(TH_FIN|TH_PUSH|TH_URG))
{
if(tcph->are_flags_set(TH_SYN|TH_ACK|TH_RST))
- codec_events::decoder_event(DECODE_TCP_XMAS);
+ codec_events::decoder_event(codec, DECODE_TCP_XMAS);
else
- codec_events::decoder_event(DECODE_TCP_NMAP_XMAS);
+ codec_events::decoder_event(codec, DECODE_TCP_NMAP_XMAS);
// Allowing this packet for further processing
// (in case there is a valid data inside it).
{
if( snort.ip_api.id() == 413 )
{
- codec_events::decoder_event(DECODE_DOS_NAPTHA);
+ codec_events::decoder_event(codec, DECODE_DOS_NAPTHA);
}
}
}
if( sfvar_ip_in(SynToMulticastDstIp, snort.ip_api.get_dst()) )
{
- codec_events::decoder_event(DECODE_SYN_TO_MULTICAST);
+ codec_events::decoder_event(codec, DECODE_SYN_TO_MULTICAST);
}
if ( (tcph->th_flags & TH_RST) )
- codec_events::decoder_event(DECODE_TCP_SYN_RST);
+ codec_events::decoder_event(codec, DECODE_TCP_SYN_RST);
if ( (tcph->th_flags & TH_FIN) )
- codec_events::decoder_event(DECODE_TCP_SYN_FIN);
+ codec_events::decoder_event(codec, DECODE_TCP_SYN_FIN);
}
else
{ // we already know there is no SYN
if ( !(tcph->th_flags & (TH_ACK|TH_RST)) )
- codec_events::decoder_event(DECODE_TCP_NO_SYN_ACK_RST);
+ codec_events::decoder_event(codec, DECODE_TCP_NO_SYN_ACK_RST);
}
if ( (tcph->th_flags & (TH_FIN|TH_PUSH|TH_URG)) &&
!(tcph->th_flags & TH_ACK) )
- codec_events::decoder_event(DECODE_TCP_MUST_ACK);
+ codec_events::decoder_event(codec, DECODE_TCP_MUST_ACK);
/* if options are present, decode them */
if ( (tcph->th_flags & TH_URG) &&
((dsize == 0) || ntohs(tcph->th_urp) > dsize) )
- codec_events::decoder_event(DECODE_TCP_BAD_URP);
+ codec_events::decoder_event(codec, DECODE_TCP_BAD_URP);
// Now that we are returning true, set the tcp header
codec.lyr_len = tcph_len;
snort.dp = tcph->dst_port();
snort.set_pkt_type(PktType::TCP);
- TCPMiscTests(snort, tcph);
+ TCPMiscTests(tcph, snort, codec);
return true;
}
if (((uint16_t) opt->data[0] > 14))
{
/* LOG INVALID WINDOWSCALE alert */
- codec_events::decoder_event(DECODE_TCPOPT_WSCALE_INVALID);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_WSCALE_INVALID);
}
}
break;
break;
case tcp::TcpOptCode::CC_ECHO:
- codec_events::decoder_event(DECODE_TCPOPT_TTCP);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_TTCP);
/* fall through */
case tcp::TcpOptCode::CC: /* all 3 use the same lengths / T/TCP */
case tcp::TcpOptCode::CC_NEW:
{
if(code == tcp::OPT_BADLEN)
{
- codec_events::decoder_event(DECODE_TCPOPT_BADLEN);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_BADLEN);
}
else if(code == tcp::OPT_TRUNC)
{
- codec_events::decoder_event(DECODE_TCPOPT_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_TRUNCATED);
}
/* set the option count to the number of valid
if (experimental_option_found)
{
- codec_events::decoder_event(DECODE_TCPOPT_EXPERIMENTAL);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_EXPERIMENTAL);
}
else if (obsolete_option_found)
{
- codec_events::decoder_event(DECODE_TCPOPT_OBSOLETE);
+ codec_events::decoder_event(codec, DECODE_TCPOPT_OBSOLETE);
}
return;
/* TCP-layer decoder alerts */
-static inline void TCPMiscTests(const SnortData& snort, const tcp::TCPHdr* const tcph)
+static inline void TCPMiscTests(const tcp::TCPHdr* const tcph,
+ const SnortData& snort,
+ const CodecData& codec)
{
if ( ((tcph->th_flags & TH_NORESERVED) == TH_SYN ) &&
(tcph->seq() == 674711609) )
- codec_events::decoder_event(DECODE_TCP_SHAFT_SYNFLOOD);
+ codec_events::decoder_event(codec, DECODE_TCP_SHAFT_SYNFLOOD);
if (snort.sp == 0 || snort.dp == 0)
- codec_events::decoder_event(DECODE_TCP_PORT_ZERO);
+ codec_events::decoder_event(codec, DECODE_TCP_PORT_ZERO);
}
-static inline void UDPMiscTests(SnortData& snort, uint32_t pay_len);
+static inline void UDPMiscTests(const SnortData&,
+ const CodecData&,
+ uint32_t pay_len);
if(raw.len < sizeof(udp::UDPHdr))
{
- codec_events::decoder_event(DECODE_UDP_DGRAM_LT_UDPHDR);
+ codec_events::decoder_event(codec, DECODE_UDP_DGRAM_LT_UDPHDR);
return false;
}
/* verify that the header raw.len is a valid value */
if(uhlen < udp::UDP_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_UDP_DGRAM_INVALID_LENGTH);
+ codec_events::decoder_event(codec, DECODE_UDP_DGRAM_INVALID_LENGTH);
return false;
}
/* make sure there are enough bytes as designated by length field */
if(uhlen > raw.len)
{
- codec_events::decoder_event(DECODE_UDP_DGRAM_SHORT_PACKET);
+ codec_events::decoder_event(codec, DECODE_UDP_DGRAM_SHORT_PACKET);
return false;
}
else if(uhlen < raw.len)
{
- codec_events::decoder_event(DECODE_UDP_DGRAM_LONG_PACKET);
+ codec_events::decoder_event(codec, DECODE_UDP_DGRAM_LONG_PACKET);
return false;
}
if(!udph->uh_chk)
{
csum = 1;
- codec_events::decoder_event(DECODE_UDP_IPV6_ZERO_CHECKSUM);
+ codec_events::decoder_event(codec, DECODE_UDP_IPV6_ZERO_CHECKSUM);
}
/* Don't do checksum calculation if
* 1) Fragmented
COPY4(ph6.sip, ip6h->ip6_src.u6_addr32);
COPY4(ph6.dip, ip6h->ip6_dst.u6_addr32);
ph6.zero = 0;
- ph6.protocol = ip6h->get_next();
+ ph6.protocol = codec.ip6_csum_proto;
ph6.len = htons((u_short)raw.len);
csum = checksum::udp_cksum((uint16_t *)(udph), uhlen, &ph6);
snort.set_pkt_type(PktType::UDP);
// set in packet manager
- UDPMiscTests(snort, uhlen - udp::UDP_HEADER_LEN);
+ UDPMiscTests(snort, codec, uhlen - udp::UDP_HEADER_LEN);
if (ScGTPDecoding() &&
(ScIsGTPPort(src_port)||ScIsGTPPort(dst_port)))
/* UDP-layer decoder alerts */
-static inline void UDPMiscTests(SnortData& snort, uint32_t pay_len)
+static inline void UDPMiscTests(const SnortData& snort,
+ const CodecData& codec,
+ uint32_t pay_len)
{
if (pay_len > 4000)
- codec_events::decoder_event(DECODE_UDP_LARGE_PACKET);
+ codec_events::decoder_event(codec, DECODE_UDP_LARGE_PACKET);
if (snort.sp == 0 || snort.dp == 0)
- codec_events::decoder_event(DECODE_UDP_PORT_ZERO);
+ codec_events::decoder_event(codec, DECODE_UDP_PORT_ZERO);
}
void UdpCodec::log(TextLog* const text_log, const uint8_t* raw_pkt, const Packet* const)
}
-bool CheckIPV6HopOptions(const RawData& raw)
+bool CheckIPV6HopOptions(const RawData& raw, const CodecData& codec)
{
const ip::IP6Extension* const exthdr =
reinterpret_cast<const ip::IP6Extension*>(raw.data);
uint8_t oplen;
if (raw.len < total_octets)
- codec_events::decoder_event(DECODE_IPV6_TRUNCATED_EXT);
+ codec_events::decoder_event(codec, DECODE_IPV6_TRUNCATED_EXT);
/* Skip to the options */
pkt += 2;
oplen = *(++pkt);
if ((pkt + oplen + 1) > hdr_end)
{
- codec_events::decoder_event(DECODE_IPV6_BAD_OPT_LEN);
+ codec_events::decoder_event(codec, DECODE_IPV6_BAD_OPT_LEN);
return false;
}
pkt += oplen + 1;
break;
default:
- codec_events::decoder_event(DECODE_IPV6_BAD_OPT_TYPE);
+ codec_events::decoder_event(codec, DECODE_IPV6_BAD_OPT_TYPE);
return false;
}
}
(proto == IPPROTO_ID_DSTOPTS) &&
(next_order == IPV6_ORDER_MAX)))
{
- codec_events::decoder_event(DECODE_IPV6_UNORDERED_EXTENSIONS);
+ codec_events::decoder_event(codec, DECODE_IPV6_UNORDERED_EXTENSIONS);
}
}
else
!(p->ip6_extensions[i].type == IPPROTO_DSTOPTS) ||
!(i+1 == p->ip6_extension_count))
{
- codec_events::decoder_event(DECODE_IPV6_UNORDERED_EXTENSIONS);
+ codec_events::decoder_event(codec, DECODE_IPV6_UNORDERED_EXTENSIONS);
}
}
{
-SO_PUBLIC bool CheckIPV6HopOptions(const RawData&);
+SO_PUBLIC bool CheckIPV6HopOptions(const RawData&, const CodecData& codec);
// NOTE:: data.next_prot_id MUST be set before calling this!!
void CheckIPv6ExtensionOrder(CodecData& codec, const uint8_t proto);
{
if(raw.len < sizeof(arp::EtherARP))
{
- codec_events::decoder_event(DECODE_ARP_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_ARP_TRUNCATED);
return false;
}
*
* Returns: void function
*/
-void DecodeEAP(const RawData& raw)
+void DecodeEAP(const RawData& raw, const CodecData& codec)
{
if(raw.len < sizeof(eapol::EAPHdr))
- codec_events::decoder_event(DECODE_EAP_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_EAP_TRUNCATED);
}
*
* Returns: void function
*/
-void DecodeEapolKey(const RawData& raw)
+void DecodeEapolKey(const RawData& raw, const CodecData& codec)
{
if(raw.len < sizeof(eapol::EapolKey))
- codec_events::decoder_event(DECODE_EAPKEY_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_EAPKEY_TRUNCATED);
}
************** main codec functions ************
*************************************************/
-bool EapolCodec::decode(const RawData& raw, CodecData&, SnortData&)
+bool EapolCodec::decode(const RawData& raw, CodecData& codec, SnortData&)
{
const eapol::EtherEapol* const eplh =
reinterpret_cast<const eapol::EtherEapol*>(raw.data);
if(raw.len < sizeof(eapol::EtherEapol))
{
- codec_events::decoder_event(DECODE_EAPOL_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_EAPOL_TRUNCATED);
return false;
}
if (eplh->eaptype == EAPOL_TYPE_EAP)
- DecodeEAP(raw);
+ DecodeEAP(raw, codec);
else if(eplh->eaptype == EAPOL_TYPE_KEY)
- DecodeEapolKey(raw);
+ DecodeEapolKey(raw, codec);
return true;
}
if (raw.len < sizeof(ERSpanType2Hdr))
{
- codec_events::decoder_event(DECODE_ERSPAN2_DGRAM_LT_HDR);
+ codec_events::decoder_event(codec, DECODE_ERSPAN2_DGRAM_LT_HDR);
return false;
}
*/
if (erSpan2Hdr->version() != 0x01) /* Type 2 == version 0x01 */
{
- codec_events::decoder_event(DECODE_ERSPAN_HDR_VERSION_MISMATCH);
+ codec_events::decoder_event(codec, DECODE_ERSPAN_HDR_VERSION_MISMATCH);
return false;
}
if (raw.len < sizeof(ERSpanType3Hdr))
{
- codec_events::decoder_event(DECODE_ERSPAN3_DGRAM_LT_HDR);
+ codec_events::decoder_event(codec, DECODE_ERSPAN3_DGRAM_LT_HDR);
return false;
}
*/
if (erSpan3Hdr->version() != 0x02) /* Type 3 == version 0x02 */
{
- codec_events::decoder_event(DECODE_ERSPAN_HDR_VERSION_MISMATCH);
+ codec_events::decoder_event(codec, DECODE_ERSPAN_HDR_VERSION_MISMATCH);
return false;
}
} // namespace
-static int checkMplsHdr(uint32_t label, uint8_t bos);
+static int checkMplsHdr(const CodecData&, uint32_t label, uint8_t bos);
void MplsCodec::get_protocol_ids(std::vector<uint16_t>& v)
{
if(stack_len < MPLS_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_BAD_MPLS);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS);
return false;
}
exp = (uint8_t)(mpls_h & 0x0000000E);
label = (mpls_h>>4) & 0x000FFFFF;
- if((label<NUM_RESERVED_LABELS)&&((iRet = checkMplsHdr(label, bos)) < 0))
+ if((label<NUM_RESERVED_LABELS)&&((iRet = checkMplsHdr(codec, label, bos)) < 0))
return false;
if( bos )
if ((ScMplsStackDepth() != -1) && (chainLen++ >= ScMplsStackDepth()))
{
- codec_events::decoder_event(DECODE_MPLS_LABEL_STACK);
+ codec_events::decoder_event(codec, DECODE_MPLS_LABEL_STACK);
codec.proto_bits &= ~PROTO_BIT__MPLS;
return false;
/*
* check if reserved labels are used properly
*/
-static int checkMplsHdr(uint32_t label, uint8_t bos)
+static int checkMplsHdr(const CodecData& codec, uint32_t label, uint8_t bos)
{
int iRet = 0;
switch(label)
||((!label)&&(ScMplsPayloadType() != MPLS_PAYLOADTYPE_IPV4)))
{
if( !label )
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL0);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL0);
else
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL2);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL2);
}
break;
}
* and move on to the next one.
*/
if( !label )
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL0);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL0);
else
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL2);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL2);
p->iph = NULL;
p->family = NO_IP;
case 1:
if(!bos) break;
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL1);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL1);
iRet = MPLS_PAYLOADTYPE_ERROR;
break;
case 3:
- codec_events::decoder_event(DECODE_BAD_MPLS_LABEL3);
+ codec_events::decoder_event(codec, DECODE_BAD_MPLS_LABEL3);
iRet = MPLS_PAYLOADTYPE_ERROR;
break;
case 13:
case 14:
case 15:
- codec_events::decoder_event(DECODE_MPLS_RESERVED_LABEL);
+ codec_events::decoder_event(codec, DECODE_MPLS_RESERVED_LABEL);
break;
default:
break;
/* do a little validation */
if(raw.len < PPPOE_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_BAD_PPPOE);
+ codec_events::decoder_event(codec, DECODE_BAD_PPPOE);
return false;
}
{
if(raw.len < eth::ETH_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR);
+ codec_events::decoder_event(codec, DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR);
return false;
}
{
if(raw.len < sizeof(vlan::VlanTagHdr))
{
- codec_events::decoder_event(DECODE_BAD_VLAN);
+ codec_events::decoder_event(codec, DECODE_BAD_VLAN);
return false;
}
// Vlan IDs 0 and 4095 are reserved.
const uint16_t vid = vh->vid();
if (vid == 0 || vid == 4095)
- codec_events::decoder_event(DECODE_BAD_VLAN);
+ codec_events::decoder_event(codec, DECODE_BAD_VLAN);
codec.lyr_len = sizeof(vlan::VlanTagHdr);
/*Check header fields*/
if (raw.len < len)
{
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
{
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n",
raw.len - len, ntohs(hdr->length)););
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
/*Check optional fields*/
if (raw.len < GTP_V1_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
next_hdr_type = *(raw.data + len - 1);
/*check length before reading data*/
if (raw.len < (uint32_t)(len + 4))
{
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
if (!ext_hdr_len)
{
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
/*Extension header length is a unit of 4 octets*/
/*check length before reading data*/
if (raw.len < len)
{
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
next_hdr_type = *(raw.data + len - 1);
{
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n",
raw.len - GTP_MIN_LEN, ntohs(hdr->length)););
- codec_events::decoder_event(DECODE_GTP_BAD_LEN);
+ codec_events::decoder_event(codec, DECODE_GTP_BAD_LEN);
return false;
}
/* do a little validation */
if(raw.len < ip::IP4_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_IP_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_IP_TRUNCATED);
return false;
}
*/
if((ip4h->get_ver() != 4) && !snort.ip_api.is_ip6())
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_IP_VER_MISMATCH);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_IP_VER_MISMATCH);
return false;
}
if(raw.len < hlen)
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
return false;
}
/* Original IP payload should be 64 bits */
if (ip_len < 8)
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_PAYLOAD_LT_64);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_PAYLOAD_LT_64);
return false;
}
*/
else if (ntohs(snort.ip_api.len()) > 576)
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_PAYLOAD_GT_576);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_PAYLOAD_GT_576);
}
}
else
{
/* RFC states that only first frag will get an ICMP response */
- codec_events::decoder_event(DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET);
return false;
}
/* do a little validation */
if ( raw.len < ip::IP6_HEADER_LEN )
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_IP_TRUNCATED);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_IP_TRUNCATED);
return false;
}
*/
if(ip6h->get_ver() != 6)
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_IP_VER_MISMATCH);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_IP_VER_MISMATCH);
return false;
}
if ( raw.len < ip::IP6_HEADER_LEN )
{
- codec_events::decoder_event(DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
+ codec_events::decoder_event(codec, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
return false;
}
if(raw.len < sizeof(EthLlc))
{
// FIXIT-L - J - Need a better alert
- codec_events::decoder_event(DECODE_BAD_VLAN_ETHLLC);
+ codec_events::decoder_event(codec, DECODE_BAD_VLAN_ETHLLC);
return false;
}
{
if (raw.len < sizeof(EthLlc) + sizeof(EthLlcOther))
{
- codec_events::decoder_event(DECODE_BAD_VLAN_ETHLLC);
+ codec_events::decoder_event(codec, DECODE_BAD_VLAN_ETHLLC);
return false;
}
/* do a little validation */
if(raw.len < eth::ETH_HEADER_LEN)
{
- codec_events::decoder_event(DECODE_ETH_HDR_TRUNC);
+ codec_events::decoder_event(codec, DECODE_ETH_HDR_TRUNC);
return false;
}
/* Codec specific fields. These fields are only relevent to codecs. */
uint16_t proto_bits; /* protocols contained within this packet */
/* -- will be propogated to Snort++ Packet struct*/
- uint8_t codec_flags; /* flags used while decoding */
+ uint16_t codec_flags; /* flags used while decoding */
uint8_t ip_layer_cnt;
+
+ /* The following values have junk values after initialization */
uint8_t ip6_extension_count; /* initialized in cd_ipv6.cc */
uint8_t curr_ip6_extension; /* initialized in cd_ipv6.cc */
+ uint8_t ip6_csum_proto; /* initalized in cd_ipv6.cc. Used for IPv6 checksums */
// FIXIT-H-J - most of these don't needs to be zeroed
CodecData(uint16_t init_prot) : lyr_len(0),
/* Decode Flags */
-constexpr uint8_t CODEC_DF = 0x01; /* don't fragment flag */
-constexpr uint8_t CODEC_UNSURE_ENCAP = 0x02; /* packet may have incorrect encapsulation layer.
- * don't alert if "next layer" is invalid.
- * If decode fails with this bit set, PacketManager
- * will back out to the previous layer.
- * IMPORTANT: This bit can ONLY be set if the
- * DECODE_ENCAP_LAYER flag was
- * was previously set.
- */
-constexpr uint8_t CODEC_SAVE_LAYER = 0x04; /* DO NOT USE THIS LAYER!!
- * -- use DECODE_ENCAP_LAYER
- */
-constexpr uint8_t CODEC_ENCAP_LAYER = (CODEC_SAVE_LAYER | CODEC_UNSURE_ENCAP );
+constexpr uint16_t CODEC_DF = 0x0001; /* don't fragment flag */
+constexpr uint16_t CODEC_UNSURE_ENCAP = 0x0002; /* packet may have incorrect encapsulation layer.
+ * don't alert if "next layer" is invalid.
+ * If decode fails with this bit set, PacketManager
+ * will back out to the previous layer.
+ * IMPORTANT: This bit can ONLY be set if the
+ * DECODE_ENCAP_LAYER flag was
+ * was previously set.
+ */
+constexpr uint16_t CODEC_SAVE_LAYER = 0x0004; /* DO NOT USE THIS LAYER!!
+ * -- use DECODE_ENCAP_LAYER
+ */
+constexpr uint16_t CODEC_ENCAP_LAYER = (CODEC_SAVE_LAYER | CODEC_UNSURE_ENCAP );
/* If encapsulation decode fails, back out to this layer
* This will be cleared by PacketManager between decodes
* This flag automatically sets DECODE_ENCAP_LAYER for
* the next layer (and only the next layer).
*/
-constexpr uint8_t CODEC_ROUTING_SEEN = 0X08; /* used to check ip6 extensino order */
-constexpr uint8_t CODEC_IPOPT_RR_SEEN = 0x10; /* used by icmp4 for alerting */
-constexpr uint8_t CODEC_IPOPT_RTRALT_SEEN = 0x20; /* used by IGMP for alerting */
-constexpr uint8_t CODEC_IPOPT_LEN_THREE = 0x40; /* used by IGMP for alerting */
-constexpr uint8_t CODEC_TEREDO_SEEN = 0x80; /* used in IPv6 Codec */
-
-constexpr uint8_t CODEC_IPOPT_FLAGS = (CODEC_IPOPT_RR_SEEN |
+constexpr uint16_t CODEC_ROUTING_SEEN = 0x0008; /* used to check ip6 extensino order */
+constexpr uint16_t CODEC_IPOPT_RR_SEEN = 0x0010; /* used by icmp4 for alerting */
+constexpr uint16_t CODEC_IPOPT_RTRALT_SEEN = 0x0020; /* used by IGMP for alerting */
+constexpr uint16_t CODEC_IPOPT_LEN_THREE = 0x0040; /* used by IGMP for alerting */
+constexpr uint16_t CODEC_TEREDO_SEEN = 0x0080; /* used in IPv6 Codec */
+constexpr uint16_t CODEC_STREAM_REBUILT = 0x0100; /* Set by PacketManager. used by codec_event */
+
+constexpr uint16_t CODEC_IPOPT_FLAGS = (CODEC_IPOPT_RR_SEEN |
CODEC_IPOPT_RTRALT_SEEN |
CODEC_IPOPT_LEN_THREE);
/* D E F I N E S ************************************************************/
/* packet status flags */
-#if 0
-#define PKT_TRUST 0x00000001 /* this packet should fallback to being whitelisted if no other verdict was specified */
- /* this flag must equal DECODE_PKT_TRUST*/
-#define PKT_FRAG 0x00000002 /* flag to indicate a fragmented packet */
- /* this flag must equal DECODE_FRAG */
-#define PKT_FRAG_MF 0x00000004 /* flag to indicate the 'more frag' flag is set */
- /* this flag must be equal to DECODE_MF */
-#endif
-
-#define PKT_REBUILT_FRAG 0x00000008 /* is a rebuilt fragment */
-#define PKT_REBUILT_STREAM 0x00000010 /* is a rebuilt stream */
-#define PKT_STREAM_UNEST_UNI 0x00000020 /* is from an unestablished stream and
+#define PKT_REBUILT_FRAG 0x00000001 /* is a rebuilt fragment */
+#define PKT_REBUILT_STREAM 0x00000002 /* is a rebuilt stream */
+#define PKT_STREAM_UNEST_UNI 0x00000004 /* is from an unestablished stream and
* we've only seen traffic in one direction */
-#define PKT_STREAM_EST 0x00000040 /* is from an established stream */
+#define PKT_STREAM_EST 0x00000008 /* is from an established stream */
-#define PKT_STREAM_INSERT 0x00000080 /* this packet has been queued for stream reassembly */
-#define PKT_STREAM_TWH 0x00000100 /* packet completes the 3-way handshake */
-#define PKT_FROM_SERVER 0x00000200 /* this packet came from the server
+#define PKT_STREAM_INSERT 0x00000010 /* this packet has been queued for stream reassembly */
+#define PKT_STREAM_TWH 0x00000020 /* packet completes the 3-way handshake */
+#define PKT_FROM_SERVER 0x00000040 /* this packet came from the server
side of a connection (TCP) */
-#define PKT_FROM_CLIENT 0x00000400 /* this packet came from the client
+#define PKT_FROM_CLIENT 0x00000080 /* this packet came from the client
side of a connection (TCP) */
-#define PKT_PDU_HEAD 0x00000800 /* start of PDU */
-#define PKT_PDU_TAIL 0x00001000 /* end of PDU */
-#define PKT_HTTP_DECODE 0x00002000 /* this packet has normalized http */
+#define PKT_PDU_HEAD 0x00000100 /* start of PDU */
+#define PKT_PDU_TAIL 0x00000200 /* end of PDU */
+#define PKT_HTTP_DECODE 0x00000400 /* this packet has normalized http */
-#define PKT_ALLOW_MULTIPLE_DETECT 0x00004000 /* packet has either pipelined mime attachements */
+#define PKT_ALLOW_MULTIPLE_DETECT 0x00000800 /* packet has either pipelined mime attachements */
/* or pipeline http requests */
-#define PKT_PAYLOAD_OBFUSCATE 0x00008000
+#define PKT_PAYLOAD_OBFUSCATE 0x00001000
-#define PKT_STATELESS 0x00010000 /* Packet has matched a stateless rule */
-#define PKT_PASS_RULE 0x00020000 /* this packet has matched a pass rule */
-#define PKT_IP_RULE 0x00040000 /* this packet is being evaluated against an IP rule */
-#define PKT_IP_RULE_2ND 0x00080000 /* this packet is being evaluated against an IP rule */
+#define PKT_STATELESS 0x00002000 /* Packet has matched a stateless rule */
+#define PKT_PASS_RULE 0x00004000 /* this packet has matched a pass rule */
+#define PKT_IP_RULE 0x00008000 /* this packet is being evaluated against an IP rule */
+#define PKT_IP_RULE_2ND 0x00010000 /* this packet is being evaluated against an IP rule */
-#define PKT_PSEUDO 0x00100000 /* is a pseudo packet */
-#define PKT_MODIFIED 0x00200000 /* packet had normalizations, etc. */
-#define PKT_RESIZED 0x00600000 /* packet has new size; must set modified too */
+#define PKT_PSEUDO 0x00020000 /* is a pseudo packet */
+#define PKT_MODIFIED 0x00040000 /* packet had normalizations, etc. */
+#define PKT_RESIZED 0x000c0000 /* packet has new size; must set modified too */
// neither of these flags will be set for (full) retransmissions or non-data segments
// a partial overlap results in out of sequence condition
// out of sequence condition is sticky
-#define PKT_STREAM_ORDER_OK 0x00800000 /* this segment is in order, w/o gaps */
-#define PKT_STREAM_ORDER_BAD 0x01000000 /* this stream had at least one gap */
+#define PKT_STREAM_ORDER_OK 0x00100000 /* this segment is in order, w/o gaps */
+#define PKT_STREAM_ORDER_BAD 0x00200000 /* this stream had at least one gap */
-#define PKT_FILE_EVENT_SET 0x02000000
-#define PKT_IGNORE 0x04000000 /* this packet should be ignored, based on port */
-#define PKT_UNUSED_FLAGS 0xf8000000
+#define PKT_FILE_EVENT_SET 0x00400000
+#define PKT_IGNORE 0x00800000 /* this packet should be ignored, based on port */
+#define PKT_UNUSED_FLAGS 0xff000000
// 0x40000000 are available
#define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL)
RawData raw{pkt, pkthdr->caplen};
CodecData codec_data(FINISHED_DECODE);
+ if (p->packet_flags & PKT_REBUILT_STREAM)
+ codec_data.codec_flags |= CODEC_STREAM_REBUILT;
+
MODULE_PROFILE_START(decodePerfStats);
s_stats[total_processed]++;
{ return ntohl(th_seq); }
inline bool has_options() const
- { return (th_offx2 & 0xf0) == 0x50; }
+ { return ((th_offx2 & 0xf0) > 0x50); }
inline bool are_flags_set(uint8_t flags) const
{ return (th_flags & flags) == flags; }