Add handling for IPv6 extension header chains (addresses #531)

- The script-layer 'pkt_hdr' type is extended with a new 'ip6' field
  representing the full IPv6 header chain.

- The 'new_packet' event is now raised for IPv6 packets (addresses #523)

- A new event called 'ipv6_ext_header' is raised for any IPv6 packet
  containing extension headers.

- A new event called 'esp_packet' is raised for any packets using ESP
  ('new_packet' and 'ipv6_ext_header' events provide connection info,
  but that info can't be provided here since the upper-layer payload
  is encrypted).

- The 'unknown_protocol' weird is now raised more reliably when Bro
  sees a transport protocol or IPv6 extension header it can't handle.
  (addresses #522)

Still need to do IPv6 fragment reassembly and needs more testing.
This commit is contained in:
Jon Siwek 2012-03-02 20:01:01 -06:00
parent 0639487aad
commit eb9f686bb2
11 changed files with 724 additions and 110 deletions

View file

@ -27,7 +27,7 @@ void FragTimer::Dispatch(double t, int /* is_expire */)
FragReassembler::FragReassembler(NetSessions* arg_s,
const IP_Hdr* ip, const u_char* pkt,
uint32 frag_field, HashKey* k, double t)
HashKey* k, double t)
: Reassembler(0, ip->DstAddr(), REASSEM_IP)
{
s = arg_s;
@ -41,7 +41,7 @@ FragReassembler::FragReassembler(NetSessions* arg_s,
reassembled_pkt = 0;
frag_size = 0; // flag meaning "not known"
AddFragment(t, ip, pkt, frag_field);
AddFragment(t, ip, pkt);
if ( frag_timeout != 0.0 )
{
@ -60,8 +60,7 @@ FragReassembler::~FragReassembler()
delete key;
}
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt,
uint32 frag_field)
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
{
const struct ip* ip4 = ip->IP4_Hdr();
@ -72,16 +71,16 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt,
// attack.
s->Weird("fragment_protocol_inconsistency", ip);
if ( frag_field & 0x4000 )
if ( ip->DF() )
// Linux MTU discovery for UDP can do this, for example.
s->Weird("fragment_with_DF", ip);
int offset = (ntohs(ip4->ip_off) & 0x1fff) * 8;
int offset = ip->FragOffset();
int len = ntohs(ip4->ip_len);
int hdr_len = proto_hdr->ip_hl * 4;
int upper_seq = offset + len - hdr_len;
if ( (frag_field & 0x2000) == 0 )
if ( ! ip->MF() )
{
// Last fragment.
if ( frag_size == 0 )