DECODE_ICMP6_HDR_TRUNC,
DECODE_IP4_MIN_TTL,
DECODE_IP6_ZERO_HOP_LIMIT,
- DECODE_IP4_DF_OFFSET,
+ DECODE_IP4_DF_OFFSET, // = 430
DECODE_ICMP6_TYPE_OTHER,
DECODE_ICMP6_DST_MULTICAST,
DECODE_TCP_SHAFT_SYNFLOOD,
DECODE_ICMP_REDIRECT_NET,
DECODE_ICMP_TRACEROUTE_IPOPTS,
DECODE_ICMP_SOURCE_QUENCH,
- DECODE_ICMP_BROADSCAN_SMURF_SCANNER,
+ DECODE_ICMP_BROADSCAN_SMURF_SCANNER, // = 440
DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED,
DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED,
DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED,
DECODE_UDP_PORT_ZERO,
DECODE_IP_RESERVED_FRAG_BIT,
DECODE_IP_UNASSIGNED_PROTO,
- DECODE_IP_BAD_PROTO,
+ DECODE_IP_BAD_PROTO, // = 450
DECODE_ICMP_PATH_MTU_DOS,
DECODE_ICMP_DOS_ATTEMPT,
DECODE_IPV6_ISATAP_SPOOF,
DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE,
DECODE_IPV6_BAD_FRAG_PKT,
DECODE_ZERO_LENGTH_FRAG,
- DECODE_ICMPV6_NODE_INFO_BAD_CODE,
+ DECODE_ICMPV6_NODE_INFO_BAD_CODE, // = 460
DECODE_IPV6_ROUTE_ZERO,
DECODE_ERSPAN_HDR_VERSION_MISMATCH,
DECODE_ERSPAN2_DGRAM_LT_HDR,
DECODE_AUTH_HDR_TRUNC,
DECODE_AUTH_HDR_BAD_LEN,
DECODE_TOO_MANY_LAYERS,
- DECODE_INDEX_MAX
+ DECODE_INDEX_MAX // = 468
};
/* If this is an IP Fragment, set some data... */
codec.codec_flags &= ~CODEC_DF;
- if (ntohs(ip6frag_hdr->ip6f_offlg) & ip::IP6F_MF_MASK)
+ if (ip6frag_hdr->mf())
snort.decode_flags |= DECODE_MF;
#if 0
#endif
// three least signifigant bits are all flags
- const uint16_t frag_offset = ip6frag_hdr->off() >> 3;
+ const uint16_t frag_offset = ip6frag_hdr->off();
if (frag_offset || (snort.decode_flags & DECODE_MF))
snort.decode_flags |= DECODE_FRAG;
TextLog_Print(text_log, "Next:0x%02X Off:%u ID:%u",
- fragh->ip6f_nxt, (offlg >> 3), fragh->id());
+ fragh->ip6f_nxt, offlg, fragh->id());
- if (offlg & ip::IP6F_MF_MASK)
+ if (fragh->mf())
TextLog_Puts(text_log, " MF");
- if (offlg & ip::IP6F_RES_MASK)
+ if (fragh->rb())
TextLog_Puts(text_log, " RB");
}
ip_len -= hlen;
/* check for fragmented packets */
- uint16_t frag_off = iph->off();
+ uint16_t frag_off = iph->off_w_flags();
/*
* get the values of the reserved, more
/* mask off the high bits in the fragment offset field */
frag_off &= 0x1FFF;
+ // to get the real frag_off, we need to multiply by 8. However, since
+ // the actual frag_off is never used, we can comment this out
+// frag_off = frag_off << 3;
+
if ((codec.codec_flags & CODEC_DF) && frag_off )
codec_events::decoder_event(codec, DECODE_IP4_DF_OFFSET);
const uint16_t hlen = ip4h->hlen();
const uint16_t len = ip4h->len();
- const uint16_t frag_off = ip4h->off();
+ const uint16_t frag_off = ip4h->off_w_flags();
TextLog_Print(text_log, "Next:0x%02X TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
ip4h->proto(), ip4h->ttl(), ip4h->tos(),
TextLog_NewLine(text_log);
TextLog_Putc(text_log, '\t');
TextLog_Print(text_log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n",
- (frag_off & 0x1FFF), (len - hlen));
+ (frag_off & 0x1FFF) * 8, (len - hlen));
}
}
"Win: 0x%X TcpLen: %d",ntohs(tcph->th_sport),
ntohs(tcph->th_dport), (u_long) ntohl(tcph->th_seq),
(u_long) ntohl(tcph->th_ack),
- ntohs(tcph->th_win), tcph->off() << 2);
+ ntohs(tcph->th_win), tcph->off());
if((tcph->th_flags & TH_URG) != 0)
TextLog_Print(text_log, "UrgPtr: 0x%X", tcph->urp());
bool Icmp4IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort)
{
- uint32_t ip_len; /* length from the start of the ip hdr to the
- * pkt end */
/* do a little validation */
if(raw.len < ip::IP4_HEADER_LEN)
}
/* set the remaining packet length */
- ip_len = raw.len - hlen;
-
- uint16_t orig_frag_offset = ip4h->off();
- orig_frag_offset &= 0x1FFF;
-
- if (orig_frag_offset == 0)
+ if (ip4h->off() == 0)
{
+ const uint32_t ip_len = raw.len - hlen;
+
/* Original IP payload should be 64 bits */
if (ip_len < 8)
{
codec_events::decoder_event(codec, DECODE_ICMP_ORIG_PAYLOAD_LT_64);
-
return false;
}
/* ICMP error packets could contain as much of original payload
const uint16_t hlen = ip4h->hlen();
const uint16_t len = ip4h->len();
- const uint16_t frag_off = ip4h->off();
+ const uint16_t frag_off = ip4h->off_w_flags();
TextLog_Print(text_log, "Next:%s(%02X) TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
PacketManager::get_proto_name(ip4h->proto()),
"Ack: 0x%lX Win: 0x%X TcpLen: %d",ntohs(tcph->th_sport),
ntohs(tcph->th_dport), (u_long) ntohl(tcph->th_seq),
(u_long) ntohl(tcph->th_ack),
- ntohs(tcph->th_win), tcph->off() << 2);
+ ntohs(tcph->th_win), tcph->off());
break;
}
// unfortunately necessary due to use of Ipapi in struct
#include "protocols/ip.h"
#include "protocols/mpls.h" // FIXIT-M remove MPLS from Convenience pointers
+#include "protocols/layer.h"
#include "framework/decode_data.h"
struct TextLog;
{ return true; }
// update function
- virtual bool update(Packet*, Layer*, uint32_t* /*len*/)
- { return true; }
+ virtual bool update(Packet*, Layer* lyr, uint32_t* len)
+ { *len += lyr->length; return true; }
// formatter
virtual void format(EncodeFlags, const Packet* /*orig*/, Packet* /*clone*/, Layer*)
return rval;
}
- const uint16_t frag_offset = p->ptrs.ip_api.off();
+ const uint16_t frag_offset = p->ptrs.ip_api.off_w_flags();
MODULE_PROFILE_START(fragBitsPerfStats);
DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, " <!!> CheckFragBits: ");
int FragOffsetOption::eval(Cursor&, Packet *p)
{
- int p_offset = p->ptrs.ip_api.off() * 8;
+ int p_offset = p->ptrs.ip_api.off();
int rval = DETECTION_OPTION_NO_MATCH;
PROFILE_VARS;
- if(!p->ptrs.ip_api.is_valid())
+ if(!p->has_ip())
{
return rval;
}
}
else
{
- frag_off = ip6_frag->off();
- if(frag_off & ip::IP6F_RES_MASK)
+ if(ip6_frag->rb())
TextLog_Puts(log, " RB");
- if(frag_off & ip::IP6F_MF_MASK)
+ if(ip6_frag->mf())
TextLog_Puts(log, " MF");
- frag_off = (frag_off >> 3);
+ frag_off = ip6_frag->off();
}
}
else
if (frag_off)
{
/* print the reserved bit if it's set */
- if(frag_off & 0x8000)
+ if(ip4h->rb())
TextLog_Puts(log, " RB");
/* printf more frags/don't frag bits */
- if(frag_off & 0x4000)
+ if(ip4h->df())
TextLog_Puts(log, " DF");
- if(frag_off & 0x2000)
+ if(ip4h->mf())
TextLog_Puts(log, " MF");
frag_off = (frag_off & 0x1FFF);
TextLog_Print(log, " Seq: 0x%lX Ack: 0x%lX Win: 0x%X TcpLen: %d",
(u_long) ntohl(tcph->th_seq),
(u_long) ntohl(tcph->th_ack),
- ntohs(tcph->th_win), tcph->off() << 2);
+ ntohs(tcph->th_win), tcph->off());
if((tcph->th_flags & TH_URG) != 0)
{
else if (!strcasecmp("tcp_len", type))
{
if (p->ptrs.tcph != NULL)
- TextLog_Print(csv_log, "%d", (p->ptrs.tcph->off()) << 2);
+ TextLog_Print(csv_log, "%d", (p->ptrs.tcph->off()));
}
else if (!strcasecmp("tcp_win", type))
{
return 0;
}
+uint16_t IpApi::off_w_flags() const
+{
+ if (ip4h)
+ return ip4h->off_w_flags();
+
+ const IP6Frag* const frag_hdr = layer::get_inner_ip6_frag();
+
+ if (frag_hdr)
+ return frag_hdr->off_w_flags();
+ return 0;
+}
const uint8_t* IpApi::ip_data() const
{
void set(const IP6Hdr* h6);
bool set(const uint8_t* raw_ip_data);
void reset();
- uint32_t id() const; // return the frag_id
- uint16_t off() const; // return the frag_offset
+ // return the 16 bits associated with this IP layers frag_offset/flags
+ uint16_t off_w_flags() const;
+ // return the frag_offset associated with this IP layers in word size.
+ // (the value is internally masked and multiplied)
+ uint16_t off() const;
+ // return the frag_id associated with this IP layers
+ uint32_t id() const;
const uint8_t* ip_data() const; // return a pointer to the ip layers data
// FIXIT-L J get rid of the unnecessary ones
inline uint8_t proto() const
{ return ip_proto; }
- inline uint16_t off() const
+ inline uint16_t off_w_flags() const
{ return ntohs(ip_off); }
+ inline uint16_t rb() const
+ { return ntohs(ip_off) & 0x8000; }
+
+ inline uint16_t mf() const
+ { return ntohs(ip_off) & 0x2000; }
+
+ inline uint16_t df() const
+ { return ntohs(ip_off) & 0x4000; }
+
+ inline uint16_t off() const
+ { return (ntohs(ip_off) & 0x1FFF) << 3; }
+
inline uint16_t id() const
{ return ntohs(ip_id); }
uint16_t ip6f_offlg; /* offset, reserved, and flag */
uint32_t ip6f_ident; /* identification */
- inline uint16_t off() const
+ inline uint16_t off_w_flags() const
{ return ntohs(ip6f_offlg); }
-// { return ntohs(ip6f_offlg) >> 3; } // FIXIT-M This will return the actual offset
+
+ inline uint16_t off() const
+ { return ntohs(ip6f_offlg) & 0xFFF8; }
+
+ inline uint16_t mf() const
+ { return ntohs(ip6f_offlg) & IP6F_MF_MASK; }
+
+ inline uint16_t rb() const
+ { return ntohs(ip6f_offlg) & IP6F_RES_MASK; }
+
inline uint32_t id() const
{ return ntohl(ip6f_ident); }
- inline uint16_t raw_off() const
+ inline uint16_t raw_off_w_flags() const
{ return ip6f_offlg; }
inline uint32_t raw_id() const
void PacketManager::encode_update (Packet* p)
{
int i;
- uint32_t len = 0;
+ uint32_t len = p->dsize;
DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)p->pkth;
Layer *lyr = p->layers;
{ return (th_offx2 & 0xf0) >> 2; }
inline uint8_t off() const
- { return th_offx2 >> 4; }
+ { return (th_offx2 & 0xf0) >> 2; }
inline uint8_t options_len() const
{ return hdr_len() - TCP_MIN_HEADER_LEN; }
/* P R O T O T Y P E S ********************************************/
static void FragRebuild(FragTracker *, Packet *);
static inline int FragIsComplete(FragTracker *);
-static int FragHandleIPOptions(FragTracker *, const Packet* const);
+static int FragHandleIPOptions(FragTracker *,
+ const Packet* const,
+ const uint16_t frag_off);
/* deletion funcs */
static THREAD_LOCAL struct timeval *pkttime; /* packet timestamp */
* between the last sucesfully decoded layer (which is ip6_frag
* or ipv4) and the end of packet, */
fragLength = p->dsize;
- endOfThisFrag = (frag_offset << 3) + fragLength;
+ endOfThisFrag = frag_offset + fragLength;
if (ft->frag_flags & FRAG_GOT_LAST)
{
* @retval 1 on success
*/
static int FragHandleIPOptions(FragTracker *ft,
- const Packet* const p)
+ const Packet* const p,
+ const uint16_t frag_offset)
{
- // FIXIT-J pass in frag_offset as a parameter
- const uint16_t frag_offset = p->ptrs.ip_api.off();
+ // Is this for ipv6 too?
const uint16_t ip_options_len = p->ptrs.ip_api.get_ip_opt_len();
if(frag_offset == 0)
/* Set the 'next' protocol */
if (fragh != nullptr)
+ {
fragh->ip6f_nxt = ft->protocol;
+ fragh->ip6f_offlg = 0x0000;
+ }
else
+ {
rawHdr->ip6_next = ft->protocol;
+ }
dpkt->dsize = (uint16_t)ft->calculated_size;
PacketManager::encode_update(dpkt);
* Disable Inspection since we'll look at the payload in
* a rebuilt packet later. So don't process it further.
*/
- if ((frag_offset != 0) ||
- ((p->get_ip_proto_next() != IPPROTO_UDP) && (p->ptrs.decode_flags & DECODE_MF)))
+ // FIXIT-M Since we no longer let UDP through, does this detection still work?
+ if ((frag_offset != 0)) /* ||
+ ((p->get_ip_proto_next() != IPPROTO_UDP) && (p->ptrs.decode_flags & DECODE_MF))) */
{
DisableDetect(p);
}
MODULE_PROFILE_START(fragInsertPerfStats);
- if (p->ptrs.ip_api.is_ip6() && (net_frag_offset == 0))
+ if (p->is_ip6() && (net_frag_offset == 0))
{
const ip::IP6Frag* const fragHdr = layer::get_inner_ip6_frag();
/*
* setup local variables for tracking this frag
*/
- orig_offset = frag_offset = net_frag_offset << 3;
+ orig_offset = frag_offset = net_frag_offset;
/* Reset the offset to handle the weird Solaris case */
if (firstLastOk == FRAG_LAST_OFFSET_ADJUST)
frag_offset = (uint16_t)ft->calculated_size;
}
// ft->frag_flags |= FRAG_GOT_LAST;
- // ft->calculated_size = (p->frag_offset << 3) + fragLength;
+ // ft->calculated_size = (p->frag_offset) + fragLength;
lastfrag = 1;
}
else
* This may alert on bad options, but we still want to
* insert the packet
*/
- FragHandleIPOptions(ft, p);
+ FragHandleIPOptions(ft, p, frag_offset);
ft->frag_pkts++;
DEBUG_WRAP(DebugMessage(DEBUG_FRAG,
"Overly large fragment %d 0x%x 0x%x %d\n",
fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off(),
- net_frag_offset << 3););
+ net_frag_offset););
MODULE_PROFILE_END(fragInsertPerfStats);
return FRAG_INSERT_FAILED;
}
{
DEBUG_WRAP(DebugMessage(DEBUG_FRAG,
"Overly large fragment length:%d(0x%x) off:0x%x(%d)\n",
- fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off() << 3,
- p->ptrs.ip_api.off() << 3););
+ fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off(),
+ p->ptrs.ip_api.off()););
/* Ah, crap. Return that tracker. */
return 0;
ft->protocol = p->ptrs.ip_api.get_ip4h()->proto();
const ip::IP4Hdr *ip4h = reinterpret_cast<const ip::IP4Hdr*>(lyr.start);
- frag_off = ip4h->off() & 0x1FFF;
+ frag_off = ip4h->off();
}
else /* IPv6 */
{
- const ip::IP6Frag *fragHdr = reinterpret_cast<const ip::IP6Frag*>(lyr.start);
+ const ip::IP6Frag* const fragHdr = reinterpret_cast<const ip::IP6Frag*>(lyr.start);
frag_off = fragHdr->off();
if (frag_off == 0)
memcpy(f->fptr, fragStart, fragLength);
f->size = f->flen = fragLength;
- f->offset = frag_off << 3;
+ f->offset = frag_off;
frag_end = f->offset + fragLength;
f->ord = ft->ordinal++;
f->data = f->fptr; /* ptr to adjusted start position */
ft->frag_bytes += fragLength;
- FragHandleIPOptions(ft, p);
+ FragHandleIPOptions(ft, p, frag_off);
t_stats.trackers_created++;
return 1;
std::string s(elem);
util::trim(elem);
+ // FIXIT-M J. Variables do not need to start with a '$'/ for instance. !$HOME_NET
if(s.front() == '$')
{
// add a space between strings
std::vector<std::string> port_list;
bool retval = true;
+ // FIXIT-M J --- Should not be removing the '[' from a PORT_LIST
if(ports.front() == '[')
ports.erase(ports.begin());
alert tcp any any -> any any ( sid:26817; msg:"tunnel"; flow:established; content:"250-localhost"; stream_reassemble:enable,client,fastpath,noalert; )
alert tcp any any -> any any ( sid:26818; msg:"tunnel"; flow:established; content:"250-localhost"; stream_reassemble:enable,server,fastpath,noalert; )
+
+alert tcp $EXTERNAL_NET any -> $HOME_NET 2401 (msg:"MISC CVS non-relative path access attempt"; flow:to_server,established; content:"Argument"; pcre:"m?^Argument\s+/?smi"; pcre:"/^Directory/smiR"; reference:bugtraq,9178; reference:cve,2003-0977; reference:nessus,11947; classtype:misc-attack; sid:2318; rev:4;)