From eb9f686bb20fc1fe5021cd0b92eea3b5a147a1cd Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 2 Mar 2012 20:01:01 -0600 Subject: [PATCH 01/27] 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. --- scripts/base/init-bare.bro | 156 ++++++++++++++++++++- src/CMakeLists.txt | 1 + src/Frag.cc | 13 +- src/Frag.h | 5 +- src/IP.cc | 273 +++++++++++++++++++++++++++++++++++++ src/IP.h | 196 +++++++++++++++++++++++--- src/PacketSort.cc | 2 +- src/Sessions.cc | 151 ++++++++++---------- src/Sessions.h | 10 +- src/TCP.cc | 6 +- src/event.bif | 21 ++- 11 files changed, 724 insertions(+), 110 deletions(-) create mode 100644 src/IP.cc diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index c4ae4b134a..91c6b7856d 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -939,11 +939,154 @@ const IPPROTO_IGMP = 2; ##< Group management protocol. const IPPROTO_IPIP = 4; ##< IP encapsulation in IP. const IPPROTO_TCP = 6; ##< TCP. const IPPROTO_UDP = 17; ##< User datagram protocol. +const IPPROTO_IPV6 = 41; ##< IPv6 header. const IPPROTO_RAW = 255; ##< Raw IP packet. -## Values extracted from an IP header. +# Definitions for IPv6 extension headers. +const IPPROTO_HOPOPTS = 0; ##< IPv6 hop-by-hop-options header. +const IPPROTO_ROUTING = 43; ##< IPv6 routing header. +const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. +const IPPROTO_ESP = 50; ##< IPv6 encapsulating security payload header. +const IPPROTO_AH = 51; ##< IPv6 authentication header. +const IPPROTO_NONE = 59; ##< IPv6 no next header. +const IPPROTO_DSTOPTS = 60; ##< IPv6 destination options header. + +## Values extracted from an IPv6 header. ## -## .. bro:see:: pkt_hdr discarder_check_ip +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts ip6_routing +## ip6_fragment ip6_ah ip6_esp +type ip6_hdr: record { + class: count; ##< Traffic class. + flow: count; ##< Flow label. + len: count; ##< Payload length. + nxt: count; ##< Next header (RFC 1700 assigned number). + hlim: count; ##< Hop limit. + src: addr; ##< Source address. + dst: addr; ##< Destination address. +}; + +## Values extracted from an IPv6 extension header's (e.g. hop-by-hop or +## destination option headers) option field. +## +## .. bro:see:: ip6_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts +type ip6_option: record { + otype: count; ##< Option type. + len: count; ##< Option data length. + data: string; ##< Option data. +}; + +## Values extracted from an IPv6 Hop-by-Hop options extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain ip6_option +type ip6_hopopts: record { + ## Next header (RFC 1700 assigned number). + nxt: count; + ## Length of header in 8-octet units, excluding first unit. + len: count; + ## The TLV encoded options; + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Destination options extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain ip6_option +type ip6_dstopts: record { + ## Next header (RFC 1700 assigned number). + nxt: count; + ## Length of header in 8-octet units, excluding first unit. + len: count; + ## The TLV encoded options; + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Routing extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +type ip6_routing: record { + ## Next header (RFC 1700 assigned number). + nxt: count; + ## Length of header in 8-octet units, excluding first unit. + len: count; + ## Routing type. + rtype: count; + ## Segments left. + segleft: count; + ## Type-specific data. + data: string; +}; + +## Values extracted from an IPv6 Fragment extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +type ip6_fragment: record { + ## Next header (RFC 1700 assigned number). + nxt: count; + ## 8-bit reserved field. + rsv1: count; + ## Fragmentation offset. + offset: count; + ## 2-bit reserved field. + rsv2: count; + ## More fragments. + more: bool; + ## Fragment identification. + id: count; +}; + +## Values extracted from an IPv6 Authentication extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +type ip6_ah: record { + ## Next header (RFC 1700 assigned number). + nxt: count; + ## Length of header in 4-octet units, excluding first two units. + len: count; + ## Reserved field. + rsv: count; + ## Security Parameter Index. + spi: count; + ## Sequence number. + seq: count; + ## Authentication data. + data: string; +}; + +## Values extracted from an IPv6 ESP extension header. +## +## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +type ip6_esp: record { + ## Security Parameters Index. + spi: count; + ## Sequence number. + seq: count; +}; + +## An IPv6 header chain. +## +## .. bro:see:: pkt_hdr ip_hdr +type ip6_hdr_chain: record { + ## The main IPv6 header. + hdr: ip6_hdr; + ## Hop-by-hop option extension header. + hopopts: vector of ip6_hopopts; + ## Destination option extension headers. + dstopts: vector of ip6_dstopts; + ## Routing extension headers. + routing: vector of ip6_routing; + ## Fragment headers. + fragment: vector of ip6_fragment; + ## Authentication extension headers. + ah: vector of ip6_ah; + ## Encapsulating security payload headers. + esp: vector of ip6_esp; + + ## Order of extension headers identified by RFC 1700 assigned numbers. + ext_order: vector of count; +}; + +## Values extracted from an IPv4 header. +## +## .. bro:see:: pkt_hdr ip6_hdr discarder_check_ip type ip_hdr: record { hl: count; ##< Header length in bytes. tos: count; ##< Type of service. @@ -1000,10 +1143,11 @@ type icmp_hdr: record { ## ## .. bro:see:: new_packet type pkt_hdr: record { - ip: ip_hdr; ##< The IP header. - tcp: tcp_hdr &optional; ##< The TCP header if a TCP packet. - udp: udp_hdr &optional; ##< The UDP header if a UDP packet. - icmp: icmp_hdr &optional; ##< The ICMP header if an ICMP packet. + ip: ip_hdr &optional; ##< The IPv4 header if an IPv4 packet. + ip6: ip6_hdr_chain &optional; ##< The IPv6 header chain if an IPv6 packet. + tcp: tcp_hdr &optional; ##< The TCP header if a TCP packet. + udp: udp_hdr &optional; ##< The UDP header if a UDP packet. + icmp: icmp_hdr &optional; ##< The ICMP header if an ICMP packet. }; ## Definition of "secondary filters". A secondary filter is a BPF filter given as diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d51211f0d1..26807a184f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -330,6 +330,7 @@ set(bro_SRCS IntSet.cc InterConn.cc IOSource.cc + IP.cc IPAddr.cc IRC.cc List.cc diff --git a/src/Frag.cc b/src/Frag.cc index 21abc324f8..b5c5e371d4 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -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 ) diff --git a/src/Frag.h b/src/Frag.h index 92bf1b3bbd..4c9886faa2 100644 --- a/src/Frag.h +++ b/src/Frag.h @@ -20,11 +20,10 @@ typedef void (FragReassembler::*frag_timer_func)(double t); class FragReassembler : public Reassembler { public: FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt, - uint32 frag_field, HashKey* k, double t); + HashKey* k, double t); ~FragReassembler(); - void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt, - uint32 frag_field); + void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt); void Expire(double t); void DeleteTimer(); diff --git a/src/IP.cc b/src/IP.cc new file mode 100644 index 0000000000..826ae544f6 --- /dev/null +++ b/src/IP.cc @@ -0,0 +1,273 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IP.h" +#include "Type.h" +#include "Val.h" +#include "Var.h" + +static RecordType* ip_hdr_type = 0; +static RecordType* ip6_hdr_type = 0; +static RecordType* ip6_hdr_chain_type = 0; +static RecordType* ip6_option_type = 0; +static RecordType* ip6_hopopts_type = 0; +static RecordType* ip6_dstopts_type = 0; +static RecordType* ip6_routing_type = 0; +static RecordType* ip6_fragment_type = 0; +static RecordType* ip6_ah_type = 0; +static RecordType* ip6_esp_type = 0; + +static inline RecordType* hdrType(RecordType*& type, const char* name) + { + if ( ! type ) type = internal_type(name)->AsRecordType(); + return type; + } + +RecordVal* IPv6_Hdr::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_hdr_type, "ip6_hdr")); + const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; + rv->Assign(0, new Val(ntohl(ip6->ip6_flow) & 0x0ff00000, TYPE_COUNT)); + rv->Assign(1, new Val(ntohl(ip6->ip6_flow) & 0x000fffff, TYPE_COUNT)); + rv->Assign(2, new Val(ntohs(ip6->ip6_plen), TYPE_COUNT)); + rv->Assign(3, new Val(ip6->ip6_nxt, TYPE_COUNT)); + rv->Assign(4, new Val(ip6->ip6_hlim, TYPE_COUNT)); + rv->Assign(5, new AddrVal(ip6->ip6_src)); + rv->Assign(6, new AddrVal(ip6->ip6_dst)); + return rv; + } + +static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) + { + VectorVal* vv = new VectorVal(new VectorType(ip6_option_type->Ref())); + while ( len > 0 ) + { + const struct ip6_opt* opt = (const struct ip6_opt*) data; + RecordVal* rv = new RecordVal(hdrType(ip6_option_type, "ip6_option")); + rv->Assign(0, new Val(opt->ip6o_type, TYPE_COUNT)); + rv->Assign(1, new Val(opt->ip6o_len, TYPE_COUNT)); + uint16 off = 2 * sizeof(uint8); + rv->Assign(2, new StringVal( + new BroString(data + off, opt->ip6o_len - off, 1))); + data += opt->ip6o_len + off; + len -= opt->ip6o_len + off; + vv->Assign(vv->Size(), rv, 0); + } + return vv; + } + +RecordVal* IPv6_HopOpts::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_hopopts_type, "ip6_hopopts")); + const struct ip6_hbh* hbh = (const struct ip6_hbh*)data; + rv->Assign(0, new Val(hbh->ip6h_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(hbh->ip6h_len, TYPE_COUNT)); + uint16 off = 2 * sizeof(uint8); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + return rv; + } + +RecordVal* IPv6_DstOpts::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_dstopts_type, "ip6_dstopts")); + const struct ip6_dest* dst = (const struct ip6_dest*)data; + rv->Assign(0, new Val(dst->ip6d_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(dst->ip6d_len, TYPE_COUNT)); + uint16 off = 2 * sizeof(uint8); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + return rv; + } + +RecordVal* IPv6_Routing::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_routing_type, "ip6_routing")); + const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data; + rv->Assign(0, new Val(rt->ip6r_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(rt->ip6r_len, TYPE_COUNT)); + rv->Assign(2, new Val(rt->ip6r_type, TYPE_COUNT)); + rv->Assign(3, new Val(rt->ip6r_segleft, TYPE_COUNT)); + uint16 off = 4 * sizeof(uint8); + rv->Assign(4, new StringVal(new BroString(data + off, Length() - off, 1))); + return rv; + } + +RecordVal* IPv6_Fragment::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_fragment_type, "ip6_fragment")); + const struct ip6_frag* frag = (const struct ip6_frag*)data; + rv->Assign(0, new Val(frag->ip6f_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(frag->ip6f_reserved, TYPE_COUNT)); + rv->Assign(2, new Val(ntohs(frag->ip6f_offlg) & 0xfff8, TYPE_COUNT)); + rv->Assign(3, new Val(ntohs(frag->ip6f_offlg) & 0x0006, TYPE_COUNT)); + rv->Assign(4, new Val(ntohs(frag->ip6f_offlg) & 0x0001, TYPE_BOOL)); + rv->Assign(5, new Val(ntohl(frag->ip6f_ident), TYPE_COUNT)); + return rv; + } + +RecordVal* IPv6_AH::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_ah_type, "ip6_ah")); + rv->Assign(0, new Val(((ip6_ext*)data)->ip6e_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(((ip6_ext*)data)->ip6e_len, TYPE_COUNT)); + rv->Assign(2, new Val(ntohs(((uint16*)data)[1]), TYPE_COUNT)); + rv->Assign(3, new Val(ntohl(((uint32*)data)[1]), TYPE_COUNT)); + rv->Assign(4, new Val(ntohl(((uint32*)data)[2]), TYPE_COUNT)); + uint16 off = 3 * sizeof(uint32); + rv->Assign(5, new StringVal(new BroString(data + off, Length() - off, 1))); + return rv; + } + +RecordVal* IPv6_ESP::BuildRecordVal() const + { + RecordVal* rv = new RecordVal(hdrType(ip6_esp_type, "ip6_esp")); + const uint32* esp = (const uint32*)data; + rv->Assign(0, new Val(ntohl(esp[0]), TYPE_COUNT)); + rv->Assign(1, new Val(ntohl(esp[1]), TYPE_COUNT)); + return rv; + } + +RecordVal* IP_Hdr::BuildRecordVal() const + { + RecordVal* rval = 0; + + if ( ! ip_hdr_type ) + { + ip_hdr_type = internal_type("ip_hdr")->AsRecordType(); + ip6_hdr_type = internal_type("ip6_hdr")->AsRecordType(); + ip6_hdr_chain_type = internal_type("ip6_hdr_chain")->AsRecordType(); + ip6_hopopts_type = internal_type("ip6_hopopts")->AsRecordType(); + ip6_dstopts_type = internal_type("ip6_dstopts")->AsRecordType(); + ip6_routing_type = internal_type("ip6_routing")->AsRecordType(); + ip6_fragment_type = internal_type("ip6_fragment")->AsRecordType(); + ip6_ah_type = internal_type("ip6_ah")->AsRecordType(); + ip6_esp_type = internal_type("ip6_esp")->AsRecordType(); + } + + if ( ip4 ) + { + rval = new RecordVal(ip_hdr_type); + rval->Assign(0, new Val(ip4->ip_hl * 4, TYPE_COUNT)); + rval->Assign(1, new Val(ip4->ip_tos, TYPE_COUNT)); + rval->Assign(2, new Val(ntohs(ip4->ip_len), TYPE_COUNT)); + rval->Assign(3, new Val(ntohs(ip4->ip_id), TYPE_COUNT)); + rval->Assign(4, new Val(ip4->ip_ttl, TYPE_COUNT)); + rval->Assign(5, new Val(ip4->ip_p, TYPE_COUNT)); + rval->Assign(6, new AddrVal(ip4->ip_src.s_addr)); + rval->Assign(7, new AddrVal(ip4->ip_dst.s_addr)); + } + else + { + rval = new RecordVal(ip6_hdr_chain_type); + + VectorVal* hopopts = new VectorVal(new VectorType(ip6_hopopts_type->Ref())); + VectorVal* dstopts = new VectorVal(new VectorType(ip6_dstopts_type->Ref())); + VectorVal* routing = new VectorVal(new VectorType(ip6_routing_type->Ref())); + VectorVal* fragment = new VectorVal(new VectorType(ip6_fragment_type->Ref())); + VectorVal* ah = new VectorVal(new VectorType(ip6_ah_type->Ref())); + VectorVal* esp = new VectorVal(new VectorType(ip6_esp_type->Ref())); + VectorVal* order = new VectorVal(new VectorType(base_type(TYPE_COUNT))); + + for ( size_t i = 1; i < ip6_hdrs->Size(); ++i ) + { + RecordVal* v = ((*ip6_hdrs)[i])->BuildRecordVal(); + uint8 type = ((*ip6_hdrs)[i])->Type(); + switch (type) { + case IPPROTO_HOPOPTS: + hopopts->Assign(hopopts->Size(), v, 0); + break; + case IPPROTO_ROUTING: + routing->Assign(routing->Size(), v, 0); + break; + case IPPROTO_DSTOPTS: + dstopts->Assign(dstopts->Size(), v, 0); + break; + case IPPROTO_FRAGMENT: + fragment->Assign(fragment->Size(), v, 0); + break; + case IPPROTO_AH: + ah->Assign(ah->Size(), v, 0); + break; + case IPPROTO_ESP: + esp->Assign(esp->Size(), v, 0); + break; + case IPPROTO_IPV6: + default: + reporter->InternalError("pkt_hdr assigned bad header %d", type); + break; + } + order->Assign(i, new Val(type, TYPE_COUNT), 0); + } + + rval->Assign(0, ((*ip6_hdrs)[0])->BuildRecordVal()); + rval->Assign(1, hopopts); + rval->Assign(2, dstopts); + rval->Assign(3, routing); + rval->Assign(4, fragment); + rval->Assign(5, ah); + rval->Assign(6, esp); + rval->Assign(7, order); + } + + return rval; + } + +static inline IPv6_Hdr* getIPv6Header(uint8 type, const u_char* d) + { + switch (type) { + case IPPROTO_IPV6: + return new IPv6_Hdr(d); + case IPPROTO_HOPOPTS: + return new IPv6_HopOpts(d); + case IPPROTO_ROUTING: + return new IPv6_Routing(d); + case IPPROTO_DSTOPTS: + return new IPv6_DstOpts(d); + case IPPROTO_FRAGMENT: + return new IPv6_Fragment(d); + case IPPROTO_AH: + return new IPv6_AH(d); + case IPPROTO_ESP: + return new IPv6_ESP(d); + default: + // should never get here if calls are protected by isIPv6ExtHeader() + reporter->InternalError("Unknown IPv6 header type: %d", type); + break; + } + // can't be reached + assert(false); + return 0; + } + +static inline bool isIPv6ExtHeader(uint8 type) + { + switch (type) { + case IPPROTO_HOPOPTS: + case IPPROTO_ROUTING: + case IPPROTO_DSTOPTS: + case IPPROTO_FRAGMENT: + case IPPROTO_AH: + case IPPROTO_ESP: + return true; + default: + return false; + } + } + +IPv6_Hdr_Chain::IPv6_Hdr_Chain(const struct ip6_hdr* ip6) + { + length = 0; + uint8 current_type, next_type; + next_type = IPPROTO_IPV6; + const u_char* hdrs = (const u_char*) ip6; + + do + { + current_type = next_type; + chain.push_back(getIPv6Header(current_type, hdrs)); + next_type = chain[chain.size()-1]->NextHdr(); + uint16 len = chain[chain.size()-1]->Length(); + hdrs += len; + length += len; + } while ( current_type != IPPROTO_FRAGMENT && + current_type != IPPROTO_ESP && + isIPv6ExtHeader(next_type) ); + } diff --git a/src/IP.h b/src/IP.h index 36e8634912..09640f47b9 100644 --- a/src/IP.h +++ b/src/IP.h @@ -4,8 +4,139 @@ #define ip_h #include "config.h" +#include "net_util.h" #include "IPAddr.h" -#include +#include "Reporter.h" +#include "Val.h" +#include "Type.h" +#include +#include +#include +#include + +/** + * Base class for IPv6 header/extensions. + */ +class IPv6_Hdr { +public: + IPv6_Hdr() : type(0), data(0) {} + + /** + * Construct the main IPv6 header. + */ + IPv6_Hdr(const u_char* d) : type(IPPROTO_IPV6), data(d) {} + + /** + * Construct an IPv6 header or extension header from assigned type number. + */ + IPv6_Hdr(uint8 t, const u_char* d) : type(t), data(d) {} + + virtual ~IPv6_Hdr() {} + + /** + * Returns the assigned IPv6 extension header type number of the header + * that immediately follows this one. + */ + virtual uint8 NextHdr() const { return ((ip6_hdr*)data)->ip6_nxt; } + + /** + * Returns the length of the header in bytes. + */ + virtual uint16 Length() const { return 40; } + + /** + * Returns the RFC 1700 assigned number indicating the header type. + */ + uint8 Type() const { return type; } + + /** + * Returns the script-layer record representation of the header. + */ + virtual RecordVal* BuildRecordVal() const; + +protected: + uint8 type; + const u_char* data; +}; + +class IPv6_HopOpts : public IPv6_Hdr { +public: + IPv6_HopOpts(const u_char* d) : IPv6_Hdr(IPPROTO_HOPOPTS, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_DstOpts : public IPv6_Hdr { +public: + IPv6_DstOpts(const u_char* d) : IPv6_Hdr(IPPROTO_DSTOPTS, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_Routing : public IPv6_Hdr { +public: + IPv6_Routing(const u_char* d) : IPv6_Hdr(IPPROTO_ROUTING, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_Fragment : public IPv6_Hdr { +public: + IPv6_Fragment(const u_char* d) : IPv6_Hdr(IPPROTO_FRAGMENT, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + uint16 Length() const { return 8; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_AH : public IPv6_Hdr { +public: + IPv6_AH(const u_char* d) : IPv6_Hdr(IPPROTO_AH, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + uint16 Length() const { return 8 + 4 * ((ip6_ext*)data)->ip6e_len; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_ESP : public IPv6_Hdr { +public: + IPv6_ESP(const u_char* d) : IPv6_Hdr(IPPROTO_ESP, d) {} + uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + // encrypted payload begins after 8 bytes + uint16 Length() const { return 8; } + RecordVal* BuildRecordVal() const; +}; + +class IPv6_Hdr_Chain { +public: + /** + * Initializes the header chain from an IPv6 header structure. + */ + IPv6_Hdr_Chain(const struct ip6_hdr* ip6); + + ~IPv6_Hdr_Chain() + { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; } + + /** + * Returns the number of headers in the chain. + */ + size_t Size() const { return chain.size(); } + + /** + * Returns the sum of the length of all headers in the chain in bytes. + */ + uint16 TotalLength() const { return length; } + + /** + * Accesses the header at the given location in the chain. + */ + const IPv6_Hdr* operator[](const size_t i) const { return chain[i]; } + +protected: + vector chain; + uint16 length; // The summation of all header lengths in the chain in bytes. +}; class IP_Hdr { public: @@ -17,10 +148,12 @@ public: IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del) : ip4(0), ip6(arg_ip6), del(arg_del) { + ip6_hdrs = new IPv6_Hdr_Chain(ip6); } ~IP_Hdr() { + if ( ip6 ) delete ip6_hdrs; if ( del ) { if ( ip4 ) @@ -30,23 +163,23 @@ public: } } + //TODO: audit usages of this for correct IPv6 support or IPv4 assumptions const struct ip* IP4_Hdr() const { return ip4; } + const struct ip6_hdr* IP6_Hdr() const { return ip6; } IPAddr SrcAddr() const { return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); } + IPAddr DstAddr() const { return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); } - //TODO: needs adapting/replacement for IPv6 support - uint16 ID4() const { return ip4 ? ip4->ip_id : 0; } - const u_char* Payload() const { if ( ip4 ) return ((const u_char*) ip4) + ip4->ip_hl * 4; else - return ((const u_char*) ip6) + 40; + return ((const u_char*) ip6) + ip6_hdrs->TotalLength(); } uint16 PayloadLen() const @@ -54,33 +187,60 @@ public: if ( ip4 ) return ntohs(ip4->ip_len) - ip4->ip_hl * 4; else - return ntohs(ip6->ip6_plen); + return ntohs(ip6->ip6_plen) - ip6_hdrs->TotalLength(); } uint16 TotalLen() const - { - if ( ip4 ) - return ntohs(ip4->ip_len); - else - return ntohs(ip6->ip6_plen) + 40; - } + { return ip4 ? ntohs(ip4->ip_len) : ntohs(ip6->ip6_plen) + 40; } + + uint16 HdrLen() const + { return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); } + + uint8 LastHeader() const + { return ip4 ? IPPROTO_RAW : + ((*ip6_hdrs)[ip6_hdrs->Size()-1])->Type(); } - uint16 HdrLen() const { return ip4 ? ip4->ip_hl * 4 : 40; } unsigned char NextProto() const - { return ip4 ? ip4->ip_p : ip6->ip6_nxt; } + { return ip4 ? ip4->ip_p : + ((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); } + unsigned char TTL() const { return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; } + + //TODO: check for IPv6 Fragment ext. header + bool IsFragment() const + { return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : false; } + + //TODO: check for IPv6 Fragment ext. header + uint16 FragOffset() const + { return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : 0; } + + //TODO: check for IPv6 Fragment ext. header uint16 FragField() const - { return ntohs(ip4 ? ip4->ip_off : 0); } + { return ip4 ? ntohs(ip4->ip_off) : 0; } + + //TODO: check for IPv6 Fragment ext. header + uint16 ID() const + { return ip4 ? ntohs(ip4->ip_id) : 0; } + + //TODO: check for IPv6 Fragment ext. header + int MF() const + { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : 0; } + + // IPv6 has no "Don't Fragment" flag. int DF() const - { return ip4 ? ((ntohs(ip4->ip_off) & IP_DF) != 0) : 0; } - uint16 IP_ID() const - { return ip4 ? (ntohs(ip4->ip_id)) : 0; } + { return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; } + + size_t NumHeaders() const + { return ip4 ? 1 : ip6_hdrs->Size(); } + + RecordVal* BuildRecordVal() const; private: const struct ip* ip4; const struct ip6_hdr* ip6; bool del; + IPv6_Hdr_Chain* ip6_hdrs; }; #endif diff --git a/src/PacketSort.cc b/src/PacketSort.cc index d0e04a37ea..7bfdaba9a0 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -33,7 +33,7 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, if ( ip_hdr->NextProto() == IPPROTO_TCP && // Note: can't sort fragmented packets - (ip_hdr->FragField() & 0x3fff) == 0 ) + ( ! ip_hdr->IsFragment() ) ) { tcp_offset = hdr_size + ip_hdr->HdrLen(); if ( caplen >= tcp_offset + sizeof(struct tcphdr) ) diff --git a/src/Sessions.cc b/src/Sessions.cc index 04b877dfe0..e8cece9e46 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -332,7 +332,8 @@ void NetSessions::NextPacketSecondary(double /* t */, const struct pcap_pkthdr* StringVal* cmd_val = new StringVal(sp->Event()->Filter()); args->append(cmd_val); - args->append(BuildHeader(ip)); + IP_Hdr ip_hdr(ip, false); + args->append(BuildHeader(&ip_hdr)); // ### Need to queue event here. try { @@ -400,18 +401,6 @@ int NetSessions::CheckConnectionTag(Connection* conn) return 1; } - -static bool looks_like_IPv4_packet(int len, const struct ip* ip_hdr) - { - if ( (unsigned int) len < sizeof(struct ip) ) - return false; - - if ( ip_hdr->ip_v == 4 && ntohs(ip_hdr->ip_len) == len ) - return true; - else - return false; - } - void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, int hdr_size) @@ -441,18 +430,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( discarder && discarder->NextPacket(ip_hdr, len, caplen) ) return; - int proto = ip_hdr->NextProto(); - if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && - proto != IPPROTO_ICMP ) - { - dump_this_packet = 1; - return; - } - FragReassembler* f = 0; - uint32 frag_field = ip_hdr->FragField(); - if ( (frag_field & 0x3fff) != 0 ) + if ( ip_hdr->IsFragment() ) { dump_this_packet = 1; // always record fragments @@ -463,12 +443,12 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, // Don't try to reassemble, that's doomed. // Discard all except the first fragment (which // is useful in analyzing header-only traces) - if ( (frag_field & 0x1fff) != 0 ) + if ( ip_hdr->FragOffset() != 0 ) return; } else { - f = NextFragment(t, ip_hdr, pkt + hdr_size, frag_field); + f = NextFragment(t, ip_hdr, pkt + hdr_size); const IP_Hdr* ih = f->ReassembledPkt(); if ( ! ih ) // It didn't reassemble into anything yet. @@ -485,21 +465,24 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; - uint32 min_hdr_len = (proto == IPPROTO_TCP) ? sizeof(struct tcphdr) : - (proto == IPPROTO_UDP ? sizeof(struct udphdr) : ICMP_MINLEN); - - if ( len < min_hdr_len ) + if ( ip_hdr->LastHeader() == IPPROTO_ESP ) { - Weird("truncated_header", hdr, pkt); - if ( f ) - Remove(f); // ### + if ( esp_packet ) + { + val_list* vl = new val_list(); + vl->append(ip_hdr->BuildRecordVal()); + mgr.QueueEvent(esp_packet, vl); + } + Remove(f); + // Can't do more since upper-layer payloads are going to be encrypted return; } - if ( caplen < min_hdr_len ) + + int proto = ip_hdr->NextProto(); + + if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) ) { - Weird("internally_truncated_header", hdr, pkt); - if ( f ) - Remove(f); // ### + Remove(f); return; } @@ -549,6 +532,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, default: Weird(fmt("unknown_protocol %d", proto), hdr, pkt); + Remove(f); return; } @@ -574,6 +558,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( consistent < 0 ) { delete h; + Remove(f); return; } @@ -592,10 +577,11 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } if ( ! conn ) + { delete h; - - if ( ! conn ) + Remove(f); return; + } int record_packet = 1; // whether to record the packet at all int record_content = 1; // whether to record its data @@ -603,8 +589,17 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, int is_orig = (id.src_addr == conn->OrigAddr()) && (id.src_port == conn->OrigPort()); - if ( new_packet && ip4 ) - conn->Event(new_packet, 0, BuildHeader(ip4)); + Val* pkt_hdr_val = 0; + + if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 ) + { + pkt_hdr_val = BuildHeader(ip_hdr); + conn->Event(new_packet, 0, pkt_hdr_val); + } + + if ( new_packet ) + conn->Event(new_packet, 0, + pkt_hdr_val ? pkt_hdr_val->Ref() : BuildHeader(ip_hdr)); conn->NextPacket(t, is_orig, ip_hdr, len, caplen, data, record_packet, record_content, @@ -614,7 +609,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, { // Above we already recorded the fragment in its entirety. f->DeleteTimer(); - Remove(f); // ### + Remove(f); } else if ( record_packet ) @@ -630,10 +625,39 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } -Val* NetSessions::BuildHeader(const struct ip* ip) +bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, + const struct pcap_pkthdr* h, const u_char* p) + { + uint32 min_hdr_len = 0; + switch ( proto ) { + case IPPROTO_TCP: + min_hdr_len = sizeof(struct tcphdr); + break; + case IPPROTO_UDP: + min_hdr_len = sizeof(struct udphdr); + break; + case IPPROTO_ICMP: + default: + min_hdr_len = ICMP_MINLEN; + break; + } + if ( len < min_hdr_len ) + { + Weird("truncated_header", h, p); + return true; + } + if ( caplen < min_hdr_len ) + { + Weird("internally_truncated_header", h, p); + return true; + } + return false; + } + + +Val* NetSessions::BuildHeader(const IP_Hdr* ip) { static RecordType* pkt_hdr_type = 0; - static RecordType* ip_hdr_type = 0; static RecordType* tcp_hdr_type = 0; static RecordType* udp_hdr_type = 0; static RecordType* icmp_hdr_type; @@ -641,7 +665,6 @@ Val* NetSessions::BuildHeader(const struct ip* ip) if ( ! pkt_hdr_type ) { pkt_hdr_type = internal_type("pkt_hdr")->AsRecordType(); - ip_hdr_type = internal_type("ip_hdr")->AsRecordType(); tcp_hdr_type = internal_type("tcp_hdr")->AsRecordType(); udp_hdr_type = internal_type("udp_hdr")->AsRecordType(); icmp_hdr_type = internal_type("icmp_hdr")->AsRecordType(); @@ -649,26 +672,15 @@ Val* NetSessions::BuildHeader(const struct ip* ip) RecordVal* pkt_hdr = new RecordVal(pkt_hdr_type); - RecordVal* ip_hdr = new RecordVal(ip_hdr_type); - - int ip_hdr_len = ip->ip_hl * 4; - int ip_pkt_len = ntohs(ip->ip_len); - - ip_hdr->Assign(0, new Val(ip->ip_hl * 4, TYPE_COUNT)); - ip_hdr->Assign(1, new Val(ip->ip_tos, TYPE_COUNT)); - ip_hdr->Assign(2, new Val(ip_pkt_len, TYPE_COUNT)); - ip_hdr->Assign(3, new Val(ntohs(ip->ip_id), TYPE_COUNT)); - ip_hdr->Assign(4, new Val(ip->ip_ttl, TYPE_COUNT)); - ip_hdr->Assign(5, new Val(ip->ip_p, TYPE_COUNT)); - ip_hdr->Assign(6, new AddrVal(ip->ip_src.s_addr)); - ip_hdr->Assign(7, new AddrVal(ip->ip_dst.s_addr)); - - pkt_hdr->Assign(0, ip_hdr); + if ( ip->IP4_Hdr() ) + pkt_hdr->Assign(0, ip->BuildRecordVal()); + else + pkt_hdr->Assign(1, ip->BuildRecordVal()); // L4 header. - const u_char* data = ((const u_char*) ip) + ip_hdr_len; + const u_char* data = ip->Payload(); - int proto = ip->ip_p; + int proto = ip->NextProto(); switch ( proto ) { case IPPROTO_TCP: { @@ -676,7 +688,7 @@ Val* NetSessions::BuildHeader(const struct ip* ip) RecordVal* tcp_hdr = new RecordVal(tcp_hdr_type); int tcp_hdr_len = tp->th_off * 4; - int data_len = ip_pkt_len - ip_hdr_len - tcp_hdr_len; + int data_len = ip->PayloadLen() - tcp_hdr_len; tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); @@ -687,7 +699,7 @@ Val* NetSessions::BuildHeader(const struct ip* ip) tcp_hdr->Assign(6, new Val(tp->th_flags, TYPE_COUNT)); tcp_hdr->Assign(7, new Val(ntohs(tp->th_win), TYPE_COUNT)); - pkt_hdr->Assign(1, tcp_hdr); + pkt_hdr->Assign(2, tcp_hdr); break; } @@ -700,7 +712,7 @@ Val* NetSessions::BuildHeader(const struct ip* ip) udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); - pkt_hdr->Assign(2, udp_hdr); + pkt_hdr->Assign(3, udp_hdr); break; } @@ -711,7 +723,7 @@ Val* NetSessions::BuildHeader(const struct ip* ip) icmp_hdr->Assign(0, new Val(icmpp->icmp_type, TYPE_COUNT)); - pkt_hdr->Assign(3, icmp_hdr); + pkt_hdr->Assign(4, icmp_hdr); break; } @@ -725,9 +737,9 @@ Val* NetSessions::BuildHeader(const struct ip* ip) } FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, - const u_char* pkt, uint32 frag_field) + const u_char* pkt) { - uint32 frag_id = ntohs(ip->ID4()); // we actually could skip conv. + uint32 frag_id = ip->ID(); ListVal* key = new ListVal(TYPE_ANY); key->Append(new AddrVal(ip->SrcAddr())); @@ -741,7 +753,7 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, FragReassembler* f = fragments.Lookup(h); if ( ! f ) { - f = new FragReassembler(this, ip, pkt, frag_field, h, t); + f = new FragReassembler(this, ip, pkt, h, t); fragments.Insert(h, f); Unref(key); return f; @@ -750,7 +762,7 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, delete h; Unref(key); - f->AddFragment(t, ip, pkt, frag_field); + f->AddFragment(t, ip, pkt); return f; } @@ -909,6 +921,7 @@ void NetSessions::Remove(Connection* c) void NetSessions::Remove(FragReassembler* f) { + if ( ! f ) return; HashKey* k = f->Key(); if ( ! k ) reporter->InternalError("fragment block not in dictionary"); diff --git a/src/Sessions.h b/src/Sessions.h index 0a6338899b..ac5fcacfb5 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -79,7 +79,7 @@ public: // Returns a reassembled packet, or nil if there are still // some missing fragments. FragReassembler* NextFragment(double t, const IP_Hdr* ip, - const u_char* pkt, uint32 frag_field); + const u_char* pkt); int Get_OS_From_SYN(struct os_type* retval, uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS, @@ -193,7 +193,13 @@ protected: // Builds a record encapsulating a packet. This should be more // general, including the equivalent of a union of tcp/udp/icmp // headers . - Val* BuildHeader(const struct ip* ip); + Val* BuildHeader(const IP_Hdr* ip); + + // For a given protocol, checks whether the header's length as derived + // from lower-level headers or the length actually captured is less + // than that protocol's minimum header size. + bool CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, + const struct pcap_pkthdr* hdr, const u_char* pkt); CompositeHash* ch; PDict(Connection) tcp_conns; diff --git a/src/TCP.cc b/src/TCP.cc index 3315db79f3..57e4449bf8 100644 --- a/src/TCP.cc +++ b/src/TCP.cc @@ -1203,7 +1203,7 @@ RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, if ( ip->HdrLen() > 20 ) quirks |= QUIRK_IPOPT; - if ( ip->IP_ID() == 0 ) + if ( ip->ID() == 0 ) quirks |= QUIRK_ZEROID; if ( tcp->th_seq == 0 ) @@ -1942,11 +1942,11 @@ int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, { if ( ++num_pkts == 1 ) { // First packet. - last_id = ntohs(ip->ID4()); + last_id = ip->ID(); return 0; } - int id = ntohs(ip->ID4()); + int id = ip->ID(); if ( id == last_id ) { diff --git a/src/event.bif b/src/event.bif index 1423750f29..1745139f11 100644 --- a/src/event.bif +++ b/src/event.bif @@ -454,11 +454,30 @@ event expected_connection_seen%(c: connection, a: count%); ## ## c: The connection the packet is part of. ## -## p: Informattion from the header of the packet that triggered the event. +## p: Information from the header of the packet that triggered the event. ## ## .. bro:see:: tcp_packet packet_contents event new_packet%(c: connection, p: pkt_hdr%); +## Generated for every IPv6 packet that contains extension headers. +## This is potentially an expensive event to handle if analysiing IPv6 traffic +## that happens to utilize extension headers frequently. +## +## c: The connection the packet is part of. +## +## p: Information from the header of the packet that triggered the event. +## +## .. bro:see:: new_packet tcp_packet packet_contents esp_packet +event ipv6_ext_headers%(c: connection, p: pkt_hdr%); + +## Generated for any packets using the IPv6 Encapsulating Security Payload (ESP) +## extension header. +## +## p: Information from the header of the packet that triggered the event. +## +## .. bro:see:: new_packet tcp_packet ipv6_ext_headers +event esp_packet%(p: pkt_hdr%); + ## Generated for every packet that has non-empty transport-layer payload. This is a ## very low-level and expensive event that should be avoided when at all possible. ## It's usually infeasible to handle when processing even medium volumes of From 9d590456b00628ba258cb0a3eedbe167dbeaf39c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 Mar 2012 16:08:28 -0600 Subject: [PATCH 02/27] Add IPv6 fragment reassembly. --- src/Frag.cc | 57 +++++++++++++++---- src/Frag.h | 3 +- src/IP.cc | 27 ++++----- src/IP.h | 154 +++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 180 insertions(+), 61 deletions(-) diff --git a/src/Frag.cc b/src/Frag.cc index b5c5e371d4..cbdae92883 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -33,13 +33,23 @@ FragReassembler::FragReassembler(NetSessions* arg_s, s = arg_s; key = k; const struct ip* ip4 = ip->IP4_Hdr(); - proto_hdr_len = ip4->ip_hl * 4; - proto_hdr = (struct ip*) new u_char[64]; // max IP header + slop - // Don't do a structure copy - need to pick up options, too. - memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len); + if ( ip4 ) + { + proto_hdr_len = ip4->ip_hl * 4; + proto_hdr = new u_char[64]; // max IP header + slop + // Don't do a structure copy - need to pick up options, too. + memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len); + } + else + { + proto_hdr_len = ip->HdrLen() - 8; // minus length of fragment header + proto_hdr = new u_char[proto_hdr_len]; + memcpy(proto_hdr, ip->IP6_Hdr(), proto_hdr_len); + } reassembled_pkt = 0; frag_size = 0; // flag meaning "not known" + next_proto = ip->NextProto(); AddFragment(t, ip, pkt); @@ -64,22 +74,37 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) { const struct ip* ip4 = ip->IP4_Hdr(); - if ( ip4->ip_p != proto_hdr->ip_p || ip4->ip_hl != proto_hdr->ip_hl ) + if ( ip4 ) + { + if ( ip4->ip_p != ((const struct ip*)proto_hdr)->ip_p || + ip4->ip_hl != ((const struct ip*)proto_hdr)->ip_hl ) // || ip4->ip_tos != proto_hdr->ip_tos // don't check TOS, there's at least one stack that actually // uses different values, and it's hard to see an associated // attack. s->Weird("fragment_protocol_inconsistency", ip); + } + else + { + if ( ip->NextProto() != next_proto || + ip->HdrLen() - 8 != proto_hdr_len ) + s->Weird("fragment_protocol_inconsistency", ip); + //TODO: more detailed unfrag header consistency checks? + } if ( ip->DF() ) // Linux MTU discovery for UDP can do this, for example. s->Weird("fragment_with_DF", ip); int offset = ip->FragOffset(); - int len = ntohs(ip4->ip_len); - int hdr_len = proto_hdr->ip_hl * 4; + int len = ip->TotalLen(); + int hdr_len = ip->HdrLen(); int upper_seq = offset + len - hdr_len; + if ( ! offset ) + // Make sure to use the first fragment header's next field. + next_proto = ip->NextProto(); + if ( ! ip->MF() ) { // Last fragment. @@ -192,8 +217,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) u_char* pkt = new u_char[n]; memcpy((void*) pkt, (const void*) proto_hdr, proto_hdr_len); - struct ip* reassem4 = (struct ip*) pkt; - reassem4->ip_len = htons(frag_size + proto_hdr_len); + u_char* pkt_start = pkt; pkt += proto_hdr_len; @@ -213,7 +237,20 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) } delete reassembled_pkt; - reassembled_pkt = new IP_Hdr(reassem4, true); + + if ( ((const struct ip*)pkt_start)->ip_v == 4 ) + { + struct ip* reassem4 = (struct ip*) pkt_start; + reassem4->ip_len = htons(frag_size + proto_hdr_len); + reassembled_pkt = new IP_Hdr(reassem4, true); + } + else + { + struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; + reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40); + const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto); + reassembled_pkt = new IP_Hdr(reassem6, true, chain); + } DeleteTimer(); } diff --git a/src/Frag.h b/src/Frag.h index 4c9886faa2..86cf3a9dd4 100644 --- a/src/Frag.h +++ b/src/Frag.h @@ -36,11 +36,12 @@ protected: void BlockInserted(DataBlock* start_block); void Overlap(const u_char* b1, const u_char* b2, int n); - struct ip* proto_hdr; + u_char* proto_hdr; IP_Hdr* reassembled_pkt; int proto_hdr_len; NetSessions* s; int frag_size; // size of fully reassembled fragment + uint16 next_proto; // first IPv6 fragment header's next proto field HashKey* key; FragTimer* expire_timer; diff --git a/src/IP.cc b/src/IP.cc index 826ae544f6..ce8514519a 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -26,7 +26,7 @@ RecordVal* IPv6_Hdr::BuildRecordVal() const { RecordVal* rv = new RecordVal(hdrType(ip6_hdr_type, "ip6_hdr")); const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; - rv->Assign(0, new Val(ntohl(ip6->ip6_flow) & 0x0ff00000, TYPE_COUNT)); + rv->Assign(0, new Val((ntohl(ip6->ip6_flow) & 0x0ff00000)>>20, TYPE_COUNT)); rv->Assign(1, new Val(ntohl(ip6->ip6_flow) & 0x000fffff, TYPE_COUNT)); rv->Assign(2, new Val(ntohs(ip6->ip6_plen), TYPE_COUNT)); rv->Assign(3, new Val(ip6->ip6_nxt, TYPE_COUNT)); @@ -96,8 +96,8 @@ RecordVal* IPv6_Fragment::BuildRecordVal() const const struct ip6_frag* frag = (const struct ip6_frag*)data; rv->Assign(0, new Val(frag->ip6f_nxt, TYPE_COUNT)); rv->Assign(1, new Val(frag->ip6f_reserved, TYPE_COUNT)); - rv->Assign(2, new Val(ntohs(frag->ip6f_offlg) & 0xfff8, TYPE_COUNT)); - rv->Assign(3, new Val(ntohs(frag->ip6f_offlg) & 0x0006, TYPE_COUNT)); + rv->Assign(2, new Val((ntohs(frag->ip6f_offlg) & 0xfff8)>>3, TYPE_COUNT)); + rv->Assign(3, new Val((ntohs(frag->ip6f_offlg) & 0x0006)>>1, TYPE_COUNT)); rv->Assign(4, new Val(ntohs(frag->ip6f_offlg) & 0x0001, TYPE_BOOL)); rv->Assign(5, new Val(ntohl(frag->ip6f_ident), TYPE_COUNT)); return rv; @@ -210,23 +210,24 @@ RecordVal* IP_Hdr::BuildRecordVal() const return rval; } -static inline IPv6_Hdr* getIPv6Header(uint8 type, const u_char* d) +static inline IPv6_Hdr* getIPv6Header(uint8 type, const u_char* d, + bool set_next = false, uint16 nxt = 0) { switch (type) { case IPPROTO_IPV6: - return new IPv6_Hdr(d); + return set_next ? new IPv6_Hdr(d, nxt) : new IPv6_Hdr(d); case IPPROTO_HOPOPTS: - return new IPv6_HopOpts(d); + return set_next ? new IPv6_HopOpts(d, nxt) : new IPv6_HopOpts(d); case IPPROTO_ROUTING: - return new IPv6_Routing(d); + return set_next ? new IPv6_Routing(d, nxt) : new IPv6_Routing(d); case IPPROTO_DSTOPTS: - return new IPv6_DstOpts(d); + return set_next ? new IPv6_DstOpts(d, nxt) : new IPv6_DstOpts(d); case IPPROTO_FRAGMENT: - return new IPv6_Fragment(d); + return set_next ? new IPv6_Fragment(d, nxt) : new IPv6_Fragment(d); case IPPROTO_AH: - return new IPv6_AH(d); + return set_next ? new IPv6_AH(d, nxt) : new IPv6_AH(d); case IPPROTO_ESP: - return new IPv6_ESP(d); + return new IPv6_ESP(d); // never able to set ESP header's next default: // should never get here if calls are protected by isIPv6ExtHeader() reporter->InternalError("Unknown IPv6 header type: %d", type); @@ -252,7 +253,7 @@ static inline bool isIPv6ExtHeader(uint8 type) } } -IPv6_Hdr_Chain::IPv6_Hdr_Chain(const struct ip6_hdr* ip6) +void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) { length = 0; uint8 current_type, next_type; @@ -262,7 +263,7 @@ IPv6_Hdr_Chain::IPv6_Hdr_Chain(const struct ip6_hdr* ip6) do { current_type = next_type; - chain.push_back(getIPv6Header(current_type, hdrs)); + chain.push_back(getIPv6Header(current_type, hdrs, set_next, next)); next_type = chain[chain.size()-1]->NextHdr(); uint16 len = chain[chain.size()-1]->Length(); hdrs += len; diff --git a/src/IP.h b/src/IP.h index 09640f47b9..be3d568375 100644 --- a/src/IP.h +++ b/src/IP.h @@ -26,6 +26,16 @@ public: */ IPv6_Hdr(const u_char* d) : type(IPPROTO_IPV6), data(d) {} + /** + * Construct the main IPv6 header, but replace the next protocol field + * if it points to a fragment. + */ + IPv6_Hdr(const u_char* d, uint16 nxt) : type(IPPROTO_IPV6), data(d) + { + if ( ((ip6_hdr*)data)->ip6_nxt == IPPROTO_FRAGMENT ) + ((ip6_hdr*)data)->ip6_nxt = nxt; + } + /** * Construct an IPv6 header or extension header from assigned type number. */ @@ -49,6 +59,11 @@ public: */ uint8 Type() const { return type; } + /** + * Returns pointer to the start of where header structure resides in memory. + */ + const u_char* Data() const { return data; } + /** * Returns the script-layer record representation of the header. */ @@ -59,50 +74,63 @@ protected: const u_char* data; }; -class IPv6_HopOpts : public IPv6_Hdr { +class IPv6_Ext : public IPv6_Hdr { public: - IPv6_HopOpts(const u_char* d) : IPv6_Hdr(IPPROTO_HOPOPTS, d) {} + IPv6_Ext(uint16 type, const u_char* d) : IPv6_Hdr(type, d) {} + IPv6_Ext(uint16 type, const u_char* d, uint16 nxt) : IPv6_Hdr(type, d) + { + if ( ((ip6_ext*)data)->ip6e_nxt == IPPROTO_FRAGMENT ) + ((ip6_ext*)data)->ip6e_nxt = nxt; + } uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + virtual uint16 Length() const = 0; + virtual RecordVal* BuildRecordVal() const = 0; +}; + +class IPv6_HopOpts : public IPv6_Ext { +public: + IPv6_HopOpts(const u_char* d) : IPv6_Ext(IPPROTO_HOPOPTS, d) {} + IPv6_HopOpts(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_HOPOPTS, d, n) {} uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } RecordVal* BuildRecordVal() const; }; -class IPv6_DstOpts : public IPv6_Hdr { +class IPv6_DstOpts : public IPv6_Ext { public: - IPv6_DstOpts(const u_char* d) : IPv6_Hdr(IPPROTO_DSTOPTS, d) {} - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + IPv6_DstOpts(const u_char* d) : IPv6_Ext(IPPROTO_DSTOPTS, d) {} + IPv6_DstOpts(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_DSTOPTS, d, n) {} uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } RecordVal* BuildRecordVal() const; }; -class IPv6_Routing : public IPv6_Hdr { +class IPv6_Routing : public IPv6_Ext { public: - IPv6_Routing(const u_char* d) : IPv6_Hdr(IPPROTO_ROUTING, d) {} - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + IPv6_Routing(const u_char* d) : IPv6_Ext(IPPROTO_ROUTING, d) {} + IPv6_Routing(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_ROUTING, d, n) {} uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } RecordVal* BuildRecordVal() const; }; -class IPv6_Fragment : public IPv6_Hdr { +class IPv6_Fragment : public IPv6_Ext { public: - IPv6_Fragment(const u_char* d) : IPv6_Hdr(IPPROTO_FRAGMENT, d) {} - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + IPv6_Fragment(const u_char* d) : IPv6_Ext(IPPROTO_FRAGMENT, d) {} + IPv6_Fragment(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_FRAGMENT, d, n) + {} uint16 Length() const { return 8; } RecordVal* BuildRecordVal() const; }; -class IPv6_AH : public IPv6_Hdr { +class IPv6_AH : public IPv6_Ext { public: - IPv6_AH(const u_char* d) : IPv6_Hdr(IPPROTO_AH, d) {} - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + IPv6_AH(const u_char* d) : IPv6_Ext(IPPROTO_AH, d) {} + IPv6_AH(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_AH, d, n) {} uint16 Length() const { return 8 + 4 * ((ip6_ext*)data)->ip6e_len; } RecordVal* BuildRecordVal() const; }; -class IPv6_ESP : public IPv6_Hdr { +class IPv6_ESP : public IPv6_Ext { public: - IPv6_ESP(const u_char* d) : IPv6_Hdr(IPPROTO_ESP, d) {} - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } + IPv6_ESP(const u_char* d) : IPv6_Ext(IPPROTO_ESP, d) {} // encrypted payload begins after 8 bytes uint16 Length() const { return 8; } RecordVal* BuildRecordVal() const; @@ -113,7 +141,14 @@ public: /** * Initializes the header chain from an IPv6 header structure. */ - IPv6_Hdr_Chain(const struct ip6_hdr* ip6); + IPv6_Hdr_Chain(const struct ip6_hdr* ip6) { Init(ip6, false); } + + /** + * Initializes the header chain from an IPv6 header structure, and replaces + * the first next protocol pointer field that points to a fragment header. + */ + IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) + { Init(ip6, true, next); } ~IPv6_Hdr_Chain() { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; } @@ -133,22 +168,73 @@ public: */ const IPv6_Hdr* operator[](const size_t i) const { return chain[i]; } + /** + * Returns whether the header chain indicates a fragmented packet. + */ + bool IsFragment() const + { return chain[chain.size()-1]->Type() == IPPROTO_FRAGMENT; } + + /** + * Returns pointer to fragment header structure if the chain contains one. + */ + const struct ip6_frag* GetFragHdr() const + { return IsFragment() ? + (const struct ip6_frag*)chain[chain.size()-1]->Data(): 0; } + + /** + * If the header chain is a fragment, returns the offset in number of bytes + * relative to the start of the Fragmentable Part of the original packet. + */ + uint16 FragOffset() const + { return IsFragment() ? + (ntohs(GetFragHdr()->ip6f_offlg) & 0xfff8) : 0; } + + /** + * If the header chain is a fragment, returns the identification field. + */ + uint32 ID() const + { return IsFragment() ? ntohl(GetFragHdr()->ip6f_ident) : 0; } + + /** + * If the header chain is a fragment, returns the M (more fragments) flag. + */ + int MF() const + { return IsFragment() ? + (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } + protected: + void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0); + vector chain; uint16 length; // The summation of all header lengths in the chain in bytes. }; class IP_Hdr { public: + IP_Hdr(const u_char* p, bool arg_del) + : ip4(0), ip6(0), del(arg_del), ip6_hdrs(0) + { + if ( ((const struct ip*)p)->ip_v == 4 ) + ip4 = (const struct ip*)p; + else if ( ((const struct ip*)p)->ip_v == 6 ) + { + ip6 = (const struct ip6_hdr*)p; + ip6_hdrs = new IPv6_Hdr_Chain(ip6); + } + else if ( arg_del ) + delete [] p; + } + IP_Hdr(const struct ip* arg_ip4, bool arg_del) - : ip4(arg_ip4), ip6(0), del(arg_del) + : ip4(arg_ip4), ip6(0), del(arg_del), ip6_hdrs(0) { } - IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del) - : ip4(0), ip6(arg_ip6), del(arg_del) + IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, + const IPv6_Hdr_Chain* c = 0) + : ip4(0), ip6(arg_ip6), del(arg_del), + ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6)) { - ip6_hdrs = new IPv6_Hdr_Chain(ip6); } ~IP_Hdr() @@ -190,7 +276,7 @@ public: return ntohs(ip6->ip6_plen) - ip6_hdrs->TotalLength(); } - uint16 TotalLen() const + uint32 TotalLen() const { return ip4 ? ntohs(ip4->ip_len) : ntohs(ip6->ip6_plen) + 40; } uint16 HdrLen() const @@ -207,25 +293,19 @@ public: unsigned char TTL() const { return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; } - //TODO: check for IPv6 Fragment ext. header bool IsFragment() const - { return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : false; } + { return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : + ip6_hdrs->IsFragment(); } - //TODO: check for IPv6 Fragment ext. header uint16 FragOffset() const - { return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : 0; } + { return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : + ip6_hdrs->FragOffset(); } - //TODO: check for IPv6 Fragment ext. header - uint16 FragField() const - { return ip4 ? ntohs(ip4->ip_off) : 0; } + uint32 ID() const + { return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); } - //TODO: check for IPv6 Fragment ext. header - uint16 ID() const - { return ip4 ? ntohs(ip4->ip_id) : 0; } - - //TODO: check for IPv6 Fragment ext. header int MF() const - { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : 0; } + { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); } // IPv6 has no "Don't Fragment" flag. int DF() const @@ -240,7 +320,7 @@ private: const struct ip* ip4; const struct ip6_hdr* ip6; bool del; - IPv6_Hdr_Chain* ip6_hdrs; + const IPv6_Hdr_Chain* ip6_hdrs; }; #endif From 65307764f476c9f06804f26712b3adde3450ef8e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 7 Mar 2012 12:40:01 -0600 Subject: [PATCH 03/27] Fix some IPv6 header related bugs. - IPv6 payload length calculation didn't count main 40 byte IPv6 header. - Fix how IPv6 headers that use TLV options are built. - Fix ip6_hdr_chain$ext_order starting index at 1 instead of 0. --- src/IP.cc | 34 +++++++++++++++++++++++++--------- src/IP.h | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/IP.cc b/src/IP.cc index ce8514519a..8a102e8542 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -38,18 +38,34 @@ RecordVal* IPv6_Hdr::BuildRecordVal() const static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) { - VectorVal* vv = new VectorVal(new VectorType(ip6_option_type->Ref())); + VectorVal* vv = new VectorVal(new VectorType( + hdrType(ip6_option_type, "ip6_option")->Ref())); + while ( len > 0 ) { const struct ip6_opt* opt = (const struct ip6_opt*) data; - RecordVal* rv = new RecordVal(hdrType(ip6_option_type, "ip6_option")); + RecordVal* rv = new RecordVal(ip6_option_type); rv->Assign(0, new Val(opt->ip6o_type, TYPE_COUNT)); - rv->Assign(1, new Val(opt->ip6o_len, TYPE_COUNT)); - uint16 off = 2 * sizeof(uint8); - rv->Assign(2, new StringVal( - new BroString(data + off, opt->ip6o_len - off, 1))); - data += opt->ip6o_len + off; - len -= opt->ip6o_len + off; + + if ( opt->ip6o_type == 0 ) + { + // Pad1 option + rv->Assign(1, new Val(0, TYPE_COUNT)); + rv->Assign(2, new StringVal("")); + data += sizeof(uint8); + len -= sizeof(uint8); + } + else + { + // PadN or other option + uint16 off = 2 * sizeof(uint8); + rv->Assign(1, new Val(opt->ip6o_len, TYPE_COUNT)); + rv->Assign(2, new StringVal( + new BroString(data + off, opt->ip6o_len, 1))); + data += opt->ip6o_len + off; + len -= opt->ip6o_len + off; + } + vv->Assign(vv->Size(), rv, 0); } return vv; @@ -194,7 +210,7 @@ RecordVal* IP_Hdr::BuildRecordVal() const reporter->InternalError("pkt_hdr assigned bad header %d", type); break; } - order->Assign(i, new Val(type, TYPE_COUNT), 0); + order->Assign(i-1, new Val(type, TYPE_COUNT), 0); } rval->Assign(0, ((*ip6_hdrs)[0])->BuildRecordVal()); diff --git a/src/IP.h b/src/IP.h index be3d568375..8918f9da5b 100644 --- a/src/IP.h +++ b/src/IP.h @@ -273,7 +273,7 @@ public: if ( ip4 ) return ntohs(ip4->ip_len) - ip4->ip_hl * 4; else - return ntohs(ip6->ip6_plen) - ip6_hdrs->TotalLength(); + return ntohs(ip6->ip6_plen) + 40 - ip6_hdrs->TotalLength(); } uint32 TotalLen() const From 76ef36e048c5ccf6298da06b3aee63e5a2864720 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 7 Mar 2012 14:17:56 -0600 Subject: [PATCH 04/27] Add a few comments to IP.h --- src/IP.h | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/IP.h b/src/IP.h index 8918f9da5b..62391ca8fc 100644 --- a/src/IP.h +++ b/src/IP.h @@ -260,6 +260,10 @@ public: IPAddr DstAddr() const { return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); } + /** + * Returns a pointer to the payload of the IP packet, usually an + * upper-layer protocol. + */ const u_char* Payload() const { if ( ip4 ) @@ -268,6 +272,10 @@ public: return ((const u_char*) ip6) + ip6_hdrs->TotalLength(); } + /** + * Returns the length of the IP packet's payload (length of packet minus + * header length or, for IPv6, also minus length of all extension headers). + */ uint16 PayloadLen() const { if ( ip4 ) @@ -276,16 +284,30 @@ public: return ntohs(ip6->ip6_plen) + 40 - ip6_hdrs->TotalLength(); } + /** + * Returns the length of the IP packet (length of headers and payload). + */ uint32 TotalLen() const { return ip4 ? ntohs(ip4->ip_len) : ntohs(ip6->ip6_plen) + 40; } + /** + * Returns length of IP packet header (includes extension headers for IPv6). + */ uint16 HdrLen() const { return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); } + /** + * For IPv6 header chains, returns the type of the last header in the chain. + */ uint8 LastHeader() const { return ip4 ? IPPROTO_RAW : ((*ip6_hdrs)[ip6_hdrs->Size()-1])->Type(); } + /** + * Returns the protocol type of the IP packet's payload, usually an + * upper-layer protocol. For IPv6, this returns the last (extension) + * header's Next Header value. + */ unsigned char NextProto() const { return ip4 ? ip4->ip_p : ((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); } @@ -297,23 +319,42 @@ public: { return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : ip6_hdrs->IsFragment(); } + /** + * Returns the fragment packet's offset in relation to the original + * packet in bytes. + */ uint16 FragOffset() const { return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : ip6_hdrs->FragOffset(); } + /** + * Returns the fragment packet's identification field. + */ uint32 ID() const { return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); } + /** + * Returns whether a fragment packet's "More Fragments" field is set. + */ int MF() const { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); } - // IPv6 has no "Don't Fragment" flag. + /** + * Returns whether a fragment packet's "Don't Fragment" field is set. + * Note that IPv6 has no such field. + */ int DF() const { return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; } + /** + * Returns number of IP headers in packet (includes IPv6 extension headers). + */ size_t NumHeaders() const { return ip4 ? 1 : ip6_hdrs->Size(); } + /** + * Returns an ip_hdr or ip6_hdr_chain RecordVal. + */ RecordVal* BuildRecordVal() const; private: From 0b32c980bf6117d3149d4ce8d41aa46df11c27e4 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 8 Mar 2012 13:12:04 -0600 Subject: [PATCH 05/27] Update PacketFilter/Discarder code for IP version independence. The signatures of script-layer functions 'discarder_check_ip', 'discarder_check_tcp', 'discarder_check_udp', and 'discarder_check_icmp' were changed to use the more general 'pkt_hdr' type as a parameter instead of individual header types. --- scripts/base/init-bare.bro | 21 ++-- src/Discard.cc | 83 ++-------------- src/Discard.h | 9 -- src/IP.cc | 84 +++++++++++++++- src/IP.h | 9 +- src/PacketFilter.cc | 7 +- src/Sessions.cc | 90 +---------------- src/Sessions.h | 5 - .../bifs.install_src_addr_filter/output | 8 ++ testing/btest/Baseline/core.discarder/output | 24 +++++ testing/btest/Traces/icmp-unreach.trace | Bin 0 -> 234 bytes .../btest/bifs/install_src_addr_filter.test | 13 +++ testing/btest/core/discarder.bro | 92 ++++++++++++++++++ 13 files changed, 251 insertions(+), 194 deletions(-) create mode 100644 testing/btest/Baseline/bifs.install_src_addr_filter/output create mode 100644 testing/btest/Baseline/core.discarder/output create mode 100644 testing/btest/Traces/icmp-unreach.trace create mode 100644 testing/btest/bifs/install_src_addr_filter.test create mode 100644 testing/btest/core/discarder.bro diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index c007bd8262..a031080f0e 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1167,7 +1167,7 @@ global discarder_maxlen = 128 &redef; ## analysis. If the function signals to discard a packet, no further processing ## will be performed on it. ## -## i: The IP header of the considered packet. +## p: The IP header of the considered packet. ## ## Returns: True if the packet should not be analyzed any further. ## @@ -1176,15 +1176,15 @@ global discarder_maxlen = 128 &redef; ## ## .. note:: This is very low-level functionality and potentially expensive. ## Avoid using it. -global discarder_check_ip: function(i: ip_hdr): bool; +global discarder_check_ip: function(p: pkt_hdr): bool; ## Function for skipping packets based on their TCP header. If defined, this ## function will be called for all TCP packets before Bro performs any further ## analysis. If the function signals to discard a packet, no further processing ## will be performed on it. ## -## i: The IP header of the considered packet. -## t: The TCP header. +## p: The IP and TCP headers of the considered packet. +## ## d: Up to :bro:see:`discarder_maxlen` bytes of the TCP payload. ## ## Returns: True if the packet should not be analyzed any further. @@ -1194,15 +1194,15 @@ global discarder_check_ip: function(i: ip_hdr): bool; ## ## .. note:: This is very low-level functionality and potentially expensive. ## Avoid using it. -global discarder_check_tcp: function(i: ip_hdr, t: tcp_hdr, d: string): bool; +global discarder_check_tcp: function(p: pkt_hdr, d: string): bool; ## Function for skipping packets based on their UDP header. If defined, this ## function will be called for all UDP packets before Bro performs any further ## analysis. If the function signals to discard a packet, no further processing ## will be performed on it. ## -## i: The IP header of the considered packet. -## t: The UDP header. +## p: The IP and UDP headers of the considered packet. +## ## d: Up to :bro:see:`discarder_maxlen` bytes of the UDP payload. ## ## Returns: True if the packet should not be analyzed any further. @@ -1212,15 +1212,14 @@ global discarder_check_tcp: function(i: ip_hdr, t: tcp_hdr, d: string): bool; ## ## .. note:: This is very low-level functionality and potentially expensive. ## Avoid using it. -global discarder_check_udp: function(i: ip_hdr, u: udp_hdr, d: string): bool; +global discarder_check_udp: function(p: pkt_hdr, d: string): bool; ## Function for skipping packets based on their ICMP header. If defined, this ## function will be called for all ICMP packets before Bro performs any further ## analysis. If the function signals to discard a packet, no further processing ## will be performed on it. ## -## i: The IP header of the considered packet. -## ih: The ICMP header. +## p: The IP and ICMP headers of the considered packet. ## ## Returns: True if the packet should not be analyzed any further. ## @@ -1229,7 +1228,7 @@ global discarder_check_udp: function(i: ip_hdr, u: udp_hdr, d: string): bool; ## ## .. note:: This is very low-level functionality and potentially expensive. ## Avoid using it. -global discarder_check_icmp: function(i: ip_hdr, ih: icmp_hdr): bool; +global discarder_check_icmp: function(p: pkt_hdr): bool; ## Bro's watchdog interval. const watchdog_interval = 10 sec &redef; diff --git a/src/Discard.cc b/src/Discard.cc index a71b810601..edfeea1408 100644 --- a/src/Discard.cc +++ b/src/Discard.cc @@ -10,11 +10,6 @@ Discarder::Discarder() { - ip_hdr = internal_type("ip_hdr")->AsRecordType(); - tcp_hdr = internal_type("tcp_hdr")->AsRecordType(); - udp_hdr = internal_type("udp_hdr")->AsRecordType(); - icmp_hdr = internal_type("icmp_hdr")->AsRecordType(); - check_ip = internal_func("discarder_check_ip"); check_tcp = internal_func("discarder_check_tcp"); check_udp = internal_func("discarder_check_udp"); @@ -36,12 +31,10 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) { int discard_packet = 0; - const struct ip* ip4 = ip->IP4_Hdr(); - if ( check_ip ) { val_list* args = new val_list; - args->append(BuildHeader(ip4)); + args->append(ip->BuildPktHdrVal()); try { @@ -59,19 +52,18 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) return discard_packet; } - int proto = ip4->ip_p; + int proto = ip->NextProto(); if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && proto != IPPROTO_ICMP ) // This is not a protocol we understand. return 0; // XXX shall we only check the first packet??? - uint32 frag_field = ntohs(ip4->ip_off); - if ( (frag_field & 0x3fff) != 0 ) + if ( ip->IsFragment() ) // Never check any fragment. return 0; - int ip_hdr_len = ip4->ip_hl * 4; + int ip_hdr_len = ip->HdrLen(); len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; @@ -87,7 +79,7 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) // Where the data starts - if this is a protocol we know about, // this gets advanced past the transport header. - const u_char* data = ((u_char*) ip4 + ip_hdr_len); + const u_char* data = ip->Payload(); if ( is_tcp ) { @@ -97,8 +89,7 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) int th_len = tp->th_off * 4; val_list* args = new val_list; - args->append(BuildHeader(ip4)); - args->append(BuildHeader(tp, len)); + args->append(ip->BuildPktHdrVal()); args->append(BuildData(data, th_len, len, caplen)); try @@ -123,8 +114,7 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) int uh_len = sizeof (struct udphdr); val_list* args = new val_list; - args->append(BuildHeader(ip4)); - args->append(BuildHeader(up)); + args->append(ip->BuildPktHdrVal()); args->append(BuildData(data, uh_len, len, caplen)); try @@ -148,8 +138,7 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) const struct icmp* ih = (const struct icmp*) data; val_list* args = new val_list; - args->append(BuildHeader(ip4)); - args->append(BuildHeader(ih)); + args->append(ip->BuildPktHdrVal()); try { @@ -168,62 +157,6 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen) return discard_packet; } -Val* Discarder::BuildHeader(const struct ip* ip) - { - RecordVal* hdr = new RecordVal(ip_hdr); - - hdr->Assign(0, new Val(ip->ip_hl * 4, TYPE_COUNT)); - hdr->Assign(1, new Val(ip->ip_tos, TYPE_COUNT)); - hdr->Assign(2, new Val(ntohs(ip->ip_len), TYPE_COUNT)); - hdr->Assign(3, new Val(ntohs(ip->ip_id), TYPE_COUNT)); - hdr->Assign(4, new Val(ip->ip_ttl, TYPE_COUNT)); - hdr->Assign(5, new Val(ip->ip_p, TYPE_COUNT)); - hdr->Assign(6, new AddrVal(ip->ip_src.s_addr)); - hdr->Assign(7, new AddrVal(ip->ip_dst.s_addr)); - - return hdr; - } - -Val* Discarder::BuildHeader(const struct tcphdr* tp, int tcp_len) - { - RecordVal* hdr = new RecordVal(tcp_hdr); - - hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); - hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); - hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT)); - hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT)); - - int tcp_hdr_len = tp->th_off * 4; - - hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT)); - hdr->Assign(5, new Val(tcp_len - tcp_hdr_len, TYPE_COUNT)); - - hdr->Assign(6, new Val(tp->th_flags, TYPE_COUNT)); - hdr->Assign(7, new Val(ntohs(tp->th_win), TYPE_COUNT)); - - return hdr; - } - -Val* Discarder::BuildHeader(const struct udphdr* up) - { - RecordVal* hdr = new RecordVal(udp_hdr); - - hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP)); - hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); - hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); - - return hdr; - } - -Val* Discarder::BuildHeader(const struct icmp* icmp) - { - RecordVal* hdr = new RecordVal(icmp_hdr); - - hdr->Assign(0, new Val(icmp->icmp_type, TYPE_COUNT)); - - return hdr; - } - Val* Discarder::BuildData(const u_char* data, int hdrlen, int len, int caplen) { len -= hdrlen; diff --git a/src/Discard.h b/src/Discard.h index 16f7a58e6e..f4daabefa7 100644 --- a/src/Discard.h +++ b/src/Discard.h @@ -25,17 +25,8 @@ public: int NextPacket(const IP_Hdr* ip, int len, int caplen); protected: - Val* BuildHeader(const struct ip* ip); - Val* BuildHeader(const struct tcphdr* tp, int tcp_len); - Val* BuildHeader(const struct udphdr* up); - Val* BuildHeader(const struct icmp* icmp); Val* BuildData(const u_char* data, int hdrlen, int len, int caplen); - RecordType* ip_hdr; - RecordType* tcp_hdr; - RecordType* udp_hdr; - RecordType* icmp_hdr; - Func* check_ip; Func* check_tcp; Func* check_udp; diff --git a/src/IP.cc b/src/IP.cc index 8a102e8542..77797ece8f 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -141,7 +141,7 @@ RecordVal* IPv6_ESP::BuildRecordVal() const return rv; } -RecordVal* IP_Hdr::BuildRecordVal() const +RecordVal* IP_Hdr::BuildIPHdrVal() const { RecordVal* rval = 0; @@ -226,6 +226,88 @@ RecordVal* IP_Hdr::BuildRecordVal() const return rval; } +RecordVal* IP_Hdr::BuildPktHdrVal() const + { + static RecordType* pkt_hdr_type = 0; + static RecordType* tcp_hdr_type = 0; + static RecordType* udp_hdr_type = 0; + static RecordType* icmp_hdr_type = 0; + + if ( ! pkt_hdr_type ) + { + pkt_hdr_type = internal_type("pkt_hdr")->AsRecordType(); + tcp_hdr_type = internal_type("tcp_hdr")->AsRecordType(); + udp_hdr_type = internal_type("udp_hdr")->AsRecordType(); + icmp_hdr_type = internal_type("icmp_hdr")->AsRecordType(); + } + + RecordVal* pkt_hdr = new RecordVal(pkt_hdr_type); + + if ( ip4 ) + pkt_hdr->Assign(0, BuildIPHdrVal()); + else + pkt_hdr->Assign(1, BuildIPHdrVal()); + + // L4 header. + const u_char* data = Payload(); + + int proto = NextProto(); + switch ( proto ) { + case IPPROTO_TCP: + { + const struct tcphdr* tp = (const struct tcphdr*) data; + RecordVal* tcp_hdr = new RecordVal(tcp_hdr_type); + + int tcp_hdr_len = tp->th_off * 4; + int data_len = PayloadLen() - tcp_hdr_len; + + tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); + tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); + tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT)); + tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT)); + tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT)); + tcp_hdr->Assign(5, new Val(data_len, TYPE_COUNT)); + tcp_hdr->Assign(6, new Val(tp->th_flags, TYPE_COUNT)); + tcp_hdr->Assign(7, new Val(ntohs(tp->th_win), TYPE_COUNT)); + + pkt_hdr->Assign(2, tcp_hdr); + break; + } + + case IPPROTO_UDP: + { + const struct udphdr* up = (const struct udphdr*) data; + RecordVal* udp_hdr = new RecordVal(udp_hdr_type); + + udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP)); + udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); + udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); + + pkt_hdr->Assign(3, udp_hdr); + break; + } + + case IPPROTO_ICMP: + { + const struct icmp* icmpp = (const struct icmp *) data; + RecordVal* icmp_hdr = new RecordVal(icmp_hdr_type); + + icmp_hdr->Assign(0, new Val(icmpp->icmp_type, TYPE_COUNT)); + + pkt_hdr->Assign(4, icmp_hdr); + break; + } + + default: + { + // This is not a protocol we understand. + break; + } + } + + return pkt_hdr; + } + static inline IPv6_Hdr* getIPv6Header(uint8 type, const u_char* d, bool set_next = false, uint16 nxt = 0) { diff --git a/src/IP.h b/src/IP.h index 62391ca8fc..53fe1daf84 100644 --- a/src/IP.h +++ b/src/IP.h @@ -249,7 +249,6 @@ public: } } - //TODO: audit usages of this for correct IPv6 support or IPv4 assumptions const struct ip* IP4_Hdr() const { return ip4; } const struct ip6_hdr* IP6_Hdr() const { return ip6; } @@ -355,7 +354,13 @@ public: /** * Returns an ip_hdr or ip6_hdr_chain RecordVal. */ - RecordVal* BuildRecordVal() const; + RecordVal* BuildIPHdrVal() const; + + /** + * Returns a pkt_hdr RecordVal, which includes not only the IP header, but + * also upper-layer (tcp/udp/icmp) headers. + */ + RecordVal* BuildPktHdrVal() const; private: const struct ip* ip4; diff --git a/src/PacketFilter.cc b/src/PacketFilter.cc index 93a452482f..4fb3b1c8f7 100644 --- a/src/PacketFilter.cc +++ b/src/PacketFilter.cc @@ -71,9 +71,7 @@ bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip, if ( ip.NextProto() == IPPROTO_TCP && f.tcp_flags ) { // Caution! The packet sanity checks have not been performed yet - const struct ip* ip4 = ip.IP4_Hdr(); - - int ip_hdr_len = ip4->ip_hl * 4; + int ip_hdr_len = ip.HdrLen(); len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; @@ -82,8 +80,7 @@ bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip, // Packet too short, will be dropped anyway. return false; - const struct tcphdr* tp = - (const struct tcphdr*) ((u_char*) ip4 + ip_hdr_len); + const struct tcphdr* tp = (const struct tcphdr*) ip.Payload(); if ( tp->th_flags & f.tcp_flags ) // At least one of the flags is set, so don't drop diff --git a/src/Sessions.cc b/src/Sessions.cc index e8cece9e46..b4115f5c16 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -333,7 +333,7 @@ void NetSessions::NextPacketSecondary(double /* t */, const struct pcap_pkthdr* new StringVal(sp->Event()->Filter()); args->append(cmd_val); IP_Hdr ip_hdr(ip, false); - args->append(BuildHeader(&ip_hdr)); + args->append(ip_hdr.BuildPktHdrVal()); // ### Need to queue event here. try { @@ -470,7 +470,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( esp_packet ) { val_list* vl = new val_list(); - vl->append(ip_hdr->BuildRecordVal()); + vl->append(ip_hdr->BuildPktHdrVal()); mgr.QueueEvent(esp_packet, vl); } Remove(f); @@ -593,13 +593,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 ) { - pkt_hdr_val = BuildHeader(ip_hdr); + pkt_hdr_val = ip_hdr->BuildPktHdrVal(); conn->Event(new_packet, 0, pkt_hdr_val); } if ( new_packet ) conn->Event(new_packet, 0, - pkt_hdr_val ? pkt_hdr_val->Ref() : BuildHeader(ip_hdr)); + pkt_hdr_val ? pkt_hdr_val->Ref() : ip_hdr->BuildPktHdrVal()); conn->NextPacket(t, is_orig, ip_hdr, len, caplen, data, record_packet, record_content, @@ -654,88 +654,6 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, return false; } - -Val* NetSessions::BuildHeader(const IP_Hdr* ip) - { - static RecordType* pkt_hdr_type = 0; - static RecordType* tcp_hdr_type = 0; - static RecordType* udp_hdr_type = 0; - static RecordType* icmp_hdr_type; - - if ( ! pkt_hdr_type ) - { - pkt_hdr_type = internal_type("pkt_hdr")->AsRecordType(); - tcp_hdr_type = internal_type("tcp_hdr")->AsRecordType(); - udp_hdr_type = internal_type("udp_hdr")->AsRecordType(); - icmp_hdr_type = internal_type("icmp_hdr")->AsRecordType(); - } - - RecordVal* pkt_hdr = new RecordVal(pkt_hdr_type); - - if ( ip->IP4_Hdr() ) - pkt_hdr->Assign(0, ip->BuildRecordVal()); - else - pkt_hdr->Assign(1, ip->BuildRecordVal()); - - // L4 header. - const u_char* data = ip->Payload(); - - int proto = ip->NextProto(); - switch ( proto ) { - case IPPROTO_TCP: - { - const struct tcphdr* tp = (const struct tcphdr*) data; - RecordVal* tcp_hdr = new RecordVal(tcp_hdr_type); - - int tcp_hdr_len = tp->th_off * 4; - int data_len = ip->PayloadLen() - tcp_hdr_len; - - tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); - tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); - tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT)); - tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT)); - tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT)); - tcp_hdr->Assign(5, new Val(data_len, TYPE_COUNT)); - tcp_hdr->Assign(6, new Val(tp->th_flags, TYPE_COUNT)); - tcp_hdr->Assign(7, new Val(ntohs(tp->th_win), TYPE_COUNT)); - - pkt_hdr->Assign(2, tcp_hdr); - break; - } - - case IPPROTO_UDP: - { - const struct udphdr* up = (const struct udphdr*) data; - RecordVal* udp_hdr = new RecordVal(udp_hdr_type); - - udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP)); - udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); - udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); - - pkt_hdr->Assign(3, udp_hdr); - break; - } - - case IPPROTO_ICMP: - { - const struct icmp* icmpp = (const struct icmp *) data; - RecordVal* icmp_hdr = new RecordVal(icmp_hdr_type); - - icmp_hdr->Assign(0, new Val(icmpp->icmp_type, TYPE_COUNT)); - - pkt_hdr->Assign(4, icmp_hdr); - break; - } - - default: - { - // This is not a protocol we understand. - } - } - - return pkt_hdr; - } - FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, const u_char* pkt) { diff --git a/src/Sessions.h b/src/Sessions.h index ac5fcacfb5..06c6057dbf 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -190,11 +190,6 @@ protected: void Internal(const char* msg, const struct pcap_pkthdr* hdr, const u_char* pkt); - // Builds a record encapsulating a packet. This should be more - // general, including the equivalent of a union of tcp/udp/icmp - // headers . - Val* BuildHeader(const IP_Hdr* ip); - // For a given protocol, checks whether the header's length as derived // from lower-level headers or the length actually captured is less // than that protocol's minimum header size. diff --git a/testing/btest/Baseline/bifs.install_src_addr_filter/output b/testing/btest/Baseline/bifs.install_src_addr_filter/output new file mode 100644 index 0000000000..bf99083391 --- /dev/null +++ b/testing/btest/Baseline/bifs.install_src_addr_filter/output @@ -0,0 +1,8 @@ +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] diff --git a/testing/btest/Baseline/core.discarder/output b/testing/btest/Baseline/core.discarder/output new file mode 100644 index 0000000000..82b4b3e622 --- /dev/null +++ b/testing/btest/Baseline/core.discarder/output @@ -0,0 +1,24 @@ +################ IP Discarder ################ +[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +################ TCP Discarder ################ +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp] +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] +################ UDP Discarder ################ +[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp] +[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp] +[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp] +[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp] +[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp] +################ ICMP Discarder ################ +Discard icmp packet: [icmp_type=3] diff --git a/testing/btest/Traces/icmp-unreach.trace b/testing/btest/Traces/icmp-unreach.trace new file mode 100644 index 0000000000000000000000000000000000000000..60137bb6fe9a7c942ca6039b194277bb9e0bdca3 GIT binary patch literal 234 zcmca|c+)~A1{MYw`2U}Qff2|_v1ai$7Gh#J1Z0CSgXH7qvC0hGx0555aWJ?tFl^9} zV_;}t>?=R8f-wz<8JU@xcY_oHLh)|9+r10%N7iu{z) Y;sfGHQXF6@!vjtjVkS_rlOp-L0Av?6tN;K2 literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/install_src_addr_filter.test b/testing/btest/bifs/install_src_addr_filter.test new file mode 100644 index 0000000000..5b387832de --- /dev/null +++ b/testing/btest/bifs/install_src_addr_filter.test @@ -0,0 +1,13 @@ +# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +event bro_init() + { + install_src_addr_filter(141.142.220.118, TH_SYN, 100.0); + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( p?$tcp && p$ip$src == 141.142.220.118 ) + print c$id; + } diff --git a/testing/btest/core/discarder.bro b/testing/btest/core/discarder.bro new file mode 100644 index 0000000000..9dfa9a2cea --- /dev/null +++ b/testing/btest/core/discarder.bro @@ -0,0 +1,92 @@ +# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-ip.bro >output +# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-tcp.bro >>output +# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-udp.bro >>output +# @TEST-EXEC: bro -C -r $TRACES/icmp-unreach.trace discarder-icmp.bro >>output +# @TEST-EXEC: btest-diff output + +@TEST-START-FILE discarder-ip.bro + +event bro_init() + { + print "################ IP Discarder ################"; + } + +function discarder_check_ip(p: pkt_hdr): bool + { + if ( p?$ip && p$ip$src == 141.142.220.118 && p$ip$dst == 208.80.152.2 ) + return F; + return T; + } + + +event new_packet(c: connection, p: pkt_hdr) + { + print c$id; + } + +@TEST-END-FILE + +@TEST-START-FILE discarder-tcp.bro + +event bro_init() + { + print "################ TCP Discarder ################"; + } + +function discarder_check_tcp(p: pkt_hdr, d: string): bool + { + if ( p$tcp$flags == TH_SYN ) + return F; + return T; + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( p?$tcp ) + print c$id; + } + +@TEST-END-FILE + +@TEST-START-FILE discarder-udp.bro + +event bro_init() + { + print "################ UDP Discarder ################"; + } + +function discarder_check_udp(p: pkt_hdr, d: string): bool + { + if ( p?$ip6 ) + return F; + return T; + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( p?$udp ) + print c$id; + } + +@TEST-END-FILE + +@TEST-START-FILE discarder-icmp.bro + +event bro_init() + { + print "################ ICMP Discarder ################"; + } + +function discarder_check_icmp(p: pkt_hdr): bool + { + print fmt("Discard icmp packet: %s", p$icmp); + return T; + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( p?$icmp ) + print c$id; + } + +@TEST-END-FILE From e74cbbf77484528334e5137d73a1e041d9206590 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 12 Mar 2012 15:26:51 -0500 Subject: [PATCH 06/27] Add unit test for IPv6 fragment reassembly. --- testing/btest/Baseline/core.ipv6-frag/dns.log | 9 +++++++++ testing/btest/Baseline/core.ipv6-frag/output | 5 +++++ testing/btest/Traces/ipv6-fragmented-dns.trace | Bin 0 -> 4772 bytes testing/btest/core/ipv6-frag.test | 9 +++++++++ 4 files changed, 23 insertions(+) create mode 100644 testing/btest/Baseline/core.ipv6-frag/dns.log create mode 100644 testing/btest/Baseline/core.ipv6-frag/output create mode 100755 testing/btest/Traces/ipv6-fragmented-dns.trace create mode 100644 testing/btest/core/ipv6-frag.test diff --git a/testing/btest/Baseline/core.ipv6-frag/dns.log b/testing/btest/Baseline/core.ipv6-frag/dns.log new file mode 100644 index 0000000000..50c9684bac --- /dev/null +++ b/testing/btest/Baseline/core.ipv6-frag/dns.log @@ -0,0 +1,9 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name QR AA TC RD RA Z answers TTLs +#types time string addr port addr port enum count string count string count string count string bool bool bool bool bool count vector[string] vector[interval] +1331084278.438444 UWkUyAuUGXf 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR F T F T F 0 This TXT record should be ignored 1.000000 +1331084293.592245 arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR F T F T F 0 This TXT record should be ignored 1.000000 diff --git a/testing/btest/Baseline/core.ipv6-frag/output b/testing/btest/Baseline/core.ipv6-frag/output new file mode 100644 index 0000000000..5020d94e8d --- /dev/null +++ b/testing/btest/Baseline/core.ipv6-frag/output @@ -0,0 +1,5 @@ +ip6=[hdr=[class=0, flow=0, len=81, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51850/udp, dport=53/udp, ulen=81] +ip6=[hdr=[class=0, flow=0, len=331, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=53/udp, dport=51850/udp, ulen=331] +ip6=[hdr=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[hdr=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[hdr=[class=0, flow=0, len=3238, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=53/udp, dport=51851/udp, ulen=3238] diff --git a/testing/btest/Traces/ipv6-fragmented-dns.trace b/testing/btest/Traces/ipv6-fragmented-dns.trace new file mode 100755 index 0000000000000000000000000000000000000000..9dda47a8a9f6a4b89c12c3b26577aad3f6effc86 GIT binary patch literal 4772 zcmca|c+)~A1{MYw`2U}Qff300wmZy!%?37xb|4#sZx|$b9Nl_EhuJ!3RomSJpa?^t zpo0PpHckwKr=zc0!hA-ijsoF zl$6Z8^mt<8#GJ~iB9_eL;!KXD)S~RvoYYF@)Ra;N1_6*hO#z_J1|SAG ztKb<7o)dQ2fuwQ$XOuBM7pyM@IV{~)O}Df zBqOs}AtWM1p(r&uzbHkaI3vF_Cq*GCRUtDyFTW@?MbxoaA+tmQs4A9 z1RRiNU;=uCfgy!KkgX^`CowMt7#o>I%=ty>Kv8%E925r!7f2n;foZ$tS@(qbmvVA4 zbO05BFqU)@L_|922Bwpsoz3$n0-XSI1(4)NO(zDVB@~dm4yJH1OaYn(!dMbYoDRW+ zBFMlU0CEdWBk2H5O{at52V{s#J7output +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff dns.log + +event new_packet(c: connection, p: pkt_hdr) + { + if ( p?$ip6 && p?$ udp ) + print fmt("ip6=%s, udp = %s", p$ip6, p$udp); + } From 79948c79741e005565ab0aa29006249014428905 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 13 Mar 2012 14:34:53 -0700 Subject: [PATCH 07/27] Merge remote-tracking branch 'origin/topic/jsiwek/ipv6-ext-headers' * origin/topic/jsiwek/ipv6-ext-headers: Update PacketFilter/Discarder code for IP version independence. Add a few comments to IP.h Fix some IPv6 header related bugs. Add IPv6 fragment reassembly. Add handling for IPv6 extension header chains (addresses #531) --- aux/broccoli | 2 +- scripts/base/init-bare.bro | 265 ++++++++++++++++++++----------------- src/Frag.cc | 10 +- src/IP.h | 16 +++ src/Sessions.cc | 9 +- 5 files changed, 175 insertions(+), 127 deletions(-) diff --git a/aux/broccoli b/aux/broccoli index 2602eb53e7..ca13601450 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 2602eb53e70d7f0afae8fac58d7636b9291974a4 +Subproject commit ca13601450803b48d70122609764e51252a0d86e diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index a031080f0e..98da9f331d 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -303,10 +303,10 @@ type gap_info: record { gap_bytes: count; ##< How many bytes were missing in the gaps. }; -## Deprecated. -## +## Deprecated. +## ## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere -## else. +## else. type packet: record { conn: connection; is_orig: bool; @@ -933,7 +933,7 @@ const ICMP_UNREACH_ADMIN_PROHIB = 13; ##< Adminstratively prohibited. # Definitions for access to packet headers. Currently only used for # discarders. # todo::these should go into an enum to make them autodoc'able -const IPPROTO_IP = 0; ##< Dummy for IP. +const IPPROTO_IP = 0; ##< Dummy for IP. [Robin] Rename to IPPROTO_IP4? const IPPROTO_ICMP = 1; ##< Control message protocol. const IPPROTO_IGMP = 2; ##< Group management protocol. const IPPROTO_IPIP = 4; ##< IP encapsulation in IP. @@ -943,6 +943,7 @@ const IPPROTO_IPV6 = 41; ##< IPv6 header. const IPPROTO_RAW = 255; ##< Raw IP packet. # Definitions for IPv6 extension headers. +# [Robin] Do we need a constant for unknown extensions? const IPPROTO_HOPOPTS = 0; ##< IPv6 hop-by-hop-options header. const IPPROTO_ROUTING = 43; ##< IPv6 routing header. const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. @@ -959,7 +960,7 @@ type ip6_hdr: record { class: count; ##< Traffic class. flow: count; ##< Flow label. len: count; ##< Payload length. - nxt: count; ##< Next header (RFC 1700 assigned number). + nxt: count; ##< Next header (RFC 1700 assigned number). # [Robin] That's just the IPPROTO_* constant right. Then we should refer to them. hlim: count; ##< Hop limit. src: addr; ##< Source address. dst: addr; ##< Destination address. @@ -1037,7 +1038,7 @@ type ip6_fragment: record { ## ## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain type ip6_ah: record { - ## Next header (RFC 1700 assigned number). + ## Next header (RFC 1700 assigned number). # [Robin] Same as above. nxt: count; ## Length of header in 4-octet units, excluding first two units. len: count; @@ -1064,7 +1065,17 @@ type ip6_esp: record { ## An IPv6 header chain. ## ## .. bro:see:: pkt_hdr ip_hdr +# +# [Robin] How about turning ip6_hdr_chain and ip6_hdr around, making the latter +# the top-level record that then contains an ip6_hdr_chain instance. That way, the +# pkt_hdr record would have ip4_hdr and ip6_hdr members, which seems more natural. +# +# [Robin] What happens to unknown extension headers? We should keep them too so that +# one can at least identify what one can't analyze. type ip6_hdr_chain: record { + # [Robin] This looses the order of the headers (partially at least, even with ext_order I believe). + # Not sure how to do it differently, but can order be important for us? + ## The main IPv6 header. hdr: ip6_hdr; ## Hop-by-hop option extension header. @@ -1081,12 +1092,15 @@ type ip6_hdr_chain: record { esp: vector of ip6_esp; ## Order of extension headers identified by RFC 1700 assigned numbers. + # [Robin] I don't understand how this works. ext_order: vector of count; }; ## Values extracted from an IPv4 header. ## ## .. bro:see:: pkt_hdr ip6_hdr discarder_check_ip +## +# [Robin] Rename to ip4_hdr? type ip_hdr: record { hl: count; ##< Header length in bytes. tos: count; ##< Type of service. @@ -1142,6 +1156,9 @@ type icmp_hdr: record { ## A packet header, consisting of an IP header and transport-layer header. ## ## .. bro:see:: new_packet +# +# [Robin] Add flags saying whether it's v4/v6, tcp/udp/icmp? The day will come where +# we can't infer that from the connection anymore (tunnels). type pkt_hdr: record { ip: ip_hdr &optional; ##< The IPv4 header if an IPv4 packet. ip6: ip6_hdr_chain &optional; ##< The IPv6 header chain if an IPv6 packet. @@ -1459,7 +1476,7 @@ export { ## NFS file attributes. Field names are based on RFC 1813. ## - ## .. bro:see:: nfs_proc_getattr + ## .. bro:see:: nfs_proc_getattr type fattr_t: record { ftype: file_type_t; ##< File type. mode: count; ##< Mode @@ -1478,8 +1495,8 @@ export { }; ## NFS *readdir* arguments. - ## - ## .. bro:see:: nfs_proc_readdir + ## + ## .. bro:see:: nfs_proc_readdir type diropargs_t : record { dirfh: string; ##< The file handle of the directory. fname: string; ##< The name of the file we are interested in. @@ -1488,7 +1505,7 @@ export { ## NFS lookup reply. If the lookup failed, *dir_attr* may be set. If the lookup ## succeeded, *fh* is always set and *obj_attr* and *dir_attr* may be set. ## - ## .. bro:see:: nfs_proc_lookup + ## .. bro:see:: nfs_proc_lookup type lookup_reply_t: record { fh: string &optional; ##< File handle of object looked up. obj_attr: fattr_t &optional; ##< Optional attributes associated w/ file @@ -1505,7 +1522,7 @@ export { }; ## NFS *read* reply. If the lookup fails, *attr* may be set. If the lookup succeeds, - ## *attr* may be set and all other fields are set. + ## *attr* may be set and all other fields are set. type read_reply_t: record { attr: fattr_t &optional; ##< Attributes. size: count &optional; ##< Number of bytes read. @@ -1514,7 +1531,7 @@ export { }; ## NFS *readline* reply. If the request fails, *attr* may be set. If the request - ## succeeds, *attr* may be set and all other fields are set. + ## succeeds, *attr* may be set and all other fields are set. ## ## .. bro:see:: nfs_proc_readlink type readlink_reply_t: record { @@ -1524,7 +1541,7 @@ export { ## NFS *write* arguments. ## - ## .. bro:see:: nfs_proc_write + ## .. bro:see:: nfs_proc_write type writeargs_t: record { fh: string; ##< File handle to write to. offset: count; ##< Offset in file. @@ -1534,18 +1551,18 @@ export { }; ## NFS *wcc* attributes. - ## + ## ## .. bro:see:: NFS3::write_reply_t type wcc_attr_t: record { - size: count; ##< The dize. + size: count; ##< The dize. atime: time; ##< Access time. mtime: time; ##< Modification time. }; ## NFS *write* reply. If the request fails, *pre|post* attr may be set. If the - ## request succeeds, *pre|post* attr may be set and all other fields are set. + ## request succeeds, *pre|post* attr may be set and all other fields are set. ## - ## .. bro:see:: nfs_proc_write + ## .. bro:see:: nfs_proc_write type write_reply_t: record { preattr: wcc_attr_t &optional; ##< Pre operation attributes. postattr: fattr_t &optional; ##< Post operation attributes. @@ -1556,9 +1573,9 @@ export { ## NFS reply for *create*, *mkdir*, and *symlink*. If the proc ## failed, *dir_\*_attr* may be set. If the proc succeeded, *fh* and the *attr*'s - ## may be set. Note: no guarantee that *fh* is set after success. + ## may be set. Note: no guarantee that *fh* is set after success. ## - ## .. bro:see:: nfs_proc_create nfs_proc_mkdir + ## .. bro:see:: nfs_proc_create nfs_proc_mkdir type newobj_reply_t: record { fh: string &optional; ##< File handle of object created. obj_attr: fattr_t &optional; ##< Optional attributes associated w/ new object. @@ -1566,17 +1583,17 @@ export { dir_post_attr: fattr_t &optional; ##< Optional attributes associated w/ dir. }; - ## NFS reply for *remove*, *rmdir*. Corresponds to *wcc_data* in the spec. + ## NFS reply for *remove*, *rmdir*. Corresponds to *wcc_data* in the spec. ## - ## .. bro:see:: nfs_proc_remove nfs_proc_rmdir + ## .. bro:see:: nfs_proc_remove nfs_proc_rmdir type delobj_reply_t: record { dir_pre_attr: wcc_attr_t &optional; ##< Optional attributes associated w/ dir. dir_post_attr: fattr_t &optional; ##< Optional attributes associated w/ dir. }; ## NFS *readdir* arguments. Used for both *readdir* and *readdirplus*. - ## - ## .. bro:see:: nfs_proc_readdir + ## + ## .. bro:see:: nfs_proc_readdir type readdirargs_t: record { isplus: bool; ##< Is this a readdirplus request? dirfh: string; ##< The directory filehandle. @@ -1589,7 +1606,7 @@ export { ## NFS *direntry*. *fh* and *attr* are used for *readdirplus*. However, even ## for *readdirplus* they may not be filled out. ## - ## .. bro:see:: NFS3::direntry_vec_t NFS3::readdir_reply_t + ## .. bro:see:: NFS3::direntry_vec_t NFS3::readdir_reply_t type direntry_t: record { fileid: count; ##< E.g., inode number. fname: string; ##< Filename. @@ -1600,7 +1617,7 @@ export { ## Vector of NFS *direntry*. ## - ## .. bro:see:: NFS3::readdir_reply_t + ## .. bro:see:: NFS3::readdir_reply_t type direntry_vec_t: vector of direntry_t; ## NFS *readdir* reply. Used for *readdir* and *readdirplus*. If an is @@ -1631,7 +1648,7 @@ module GLOBAL; ## An NTP message. ## -## .. bro:see:: ntp_message +## .. bro:see:: ntp_message type ntp_msg: record { id: count; ##< Message ID. code: count; ##< Message code. @@ -1653,7 +1670,7 @@ global samba_cmds: table[count] of string &redef { return fmt("samba-unknown-%d", c); }; ## An SMB command header. -## +## ## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx ## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx ## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot @@ -1672,9 +1689,9 @@ type smb_hdr : record { }; ## An SMB transaction. -## +## ## .. bro:see:: smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 +## smb_com_transaction smb_com_transaction2 type smb_trans : record { word_count: count; ##< TODO. total_param_count: count; ##< TODO. @@ -1688,7 +1705,7 @@ type smb_trans : record { param_offset: count; ##< TODO. data_count: count; ##< TODO. data_offset: count; ##< TODO. - setup_count: count; ##< TODO. + setup_count: count; ##< TODO. setup0: count; ##< TODO. setup1: count; ##< TODO. setup2: count; ##< TODO. @@ -1699,19 +1716,19 @@ type smb_trans : record { ## SMB transaction data. -## +## ## .. bro:see:: smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 -## +## smb_com_transaction smb_com_transaction2 +## ## .. todo:: Should this really be a record type? type smb_trans_data : record { data : string; ##< The transaction's data. }; -## Deprecated. -## +## Deprecated. +## ## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere -## else. +## else. type smb_tree_connect : record { flags: count; password: string; @@ -1719,21 +1736,21 @@ type smb_tree_connect : record { service: string; }; -## Deprecated. -## +## Deprecated. +## ## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere -## else. +## else. type smb_negotiate : table[count] of string; ## A list of router addresses offered by a DHCP server. ## -## .. bro:see:: dhcp_ack dhcp_offer +## .. bro:see:: dhcp_ack dhcp_offer type dhcp_router_list: table[count] of addr; ## A DHCP message. ## ## .. bro:see:: dhcp_ack dhcp_decline dhcp_discover dhcp_inform dhcp_nak -## dhcp_offer dhcp_release dhcp_request +## dhcp_offer dhcp_release dhcp_request type dhcp_msg: record { op: count; ##< Message OP code. 1 = BOOTREQUEST, 2 = BOOTREPLY m_type: count; ##< The type of DHCP message. @@ -1770,7 +1787,7 @@ type dns_msg: record { ## A DNS SOA record. ## -## .. bro:see:: dns_SOA_reply +## .. bro:see:: dns_SOA_reply type dns_soa: record { mname: string; ##< Primary source of data for zone. rname: string; ##< Mailbox for responsible person. @@ -1783,7 +1800,7 @@ type dns_soa: record { ## An additional DNS EDNS record. ## -## .. bro:see:: dns_EDNS_addl +## .. bro:see:: dns_EDNS_addl type dns_edns_additional: record { query: string; ##< Query. qtype: count; ##< Query type. @@ -1798,7 +1815,7 @@ type dns_edns_additional: record { ## An additional DNS TSIG record. ## -## bro:see:: dns_TSIG_addl +## bro:see:: dns_TSIG_addl type dns_tsig_additional: record { query: string; ##< Query. qtype: count; ##< Query type. @@ -1812,9 +1829,9 @@ type dns_tsig_additional: record { }; # DNS answer types. -# +# # .. .. bro:see:: dns_answerr -# +# # todo::use enum to make them autodoc'able const DNS_QUERY = 0; ##< A query. This shouldn't occur, just for completeness. const DNS_ANS = 1; ##< An answer record. @@ -1828,7 +1845,7 @@ const DNS_ADDL = 3; ##< An additional record. ## dns_TXT_reply dns_WKS_reply type dns_answer: record { ## Answer type. One of :bro:see:`DNS_QUERY`, :bro:see:`DNS_ANS`, - ## :bro:see:`DNS_AUTH` and :bro:see:`DNS_ADDL`. + ## :bro:see:`DNS_AUTH` and :bro:see:`DNS_ADDL`. answer_type: count; query: string; ##< Query. qtype: count; ##< Query type. @@ -1848,27 +1865,27 @@ global dns_skip_auth: set[addr] &redef; ## .. bro:see:: dns_skip_all_addl dns_skip_auth global dns_skip_addl: set[addr] &redef; -## If true, all DNS AUTH records are skipped. +## If true, all DNS AUTH records are skipped. ## ## .. bro:see:: dns_skip_all_addl dns_skip_auth global dns_skip_all_auth = T &redef; -## If true, all DNS ADDL records are skipped. +## If true, all DNS ADDL records are skipped. ## ## .. bro:see:: dns_skip_all_auth dns_skip_addl global dns_skip_all_addl = T &redef; ## If a DNS request includes more than this many queries, assume it's non-DNS -## traffic and do not process it. Set to 0 to turn off this functionality. +## traffic and do not process it. Set to 0 to turn off this functionality. global dns_max_queries = 5; ## An X509 certificate. ## -## .. bro:see:: x509_certificate +## .. bro:see:: x509_certificate type X509: record { version: count; ##< Version number. serial: string; ##< Serial number. - subject: string; ##< Subject. + subject: string; ##< Subject. issuer: string; ##< Issuer. not_valid_before: time; ##< Timestamp before when certificate is not valid. not_valid_after: time; ##< Timestamp after when certificate is not valid. @@ -1876,7 +1893,7 @@ type X509: record { ## HTTP session statistics. ## -## .. bro:see:: http_stats +## .. bro:see:: http_stats type http_stats_rec: record { num_requests: count; ##< Number of requests. num_replies: count; ##< Number of replies. @@ -1886,7 +1903,7 @@ type http_stats_rec: record { ## HTTP message statistics. ## -## .. bro:see:: http_message_done +## .. bro:see:: http_message_done type http_message_stat: record { ## When the request/reply line was complete. start: time; @@ -1903,26 +1920,26 @@ type http_message_stat: record { }; ## Maximum number of HTTP entity data delivered to events. The amount of data -## can be limited for better performance, zero disables truncation. -## +## can be limited for better performance, zero disables truncation. +## ## .. bro:see:: http_entity_data skip_http_entity_data skip_http_data global http_entity_data_delivery_size = 1500 &redef; ## Skip HTTP data for performance considerations. The skipped -## portion will not go through TCP reassembly. -## +## portion will not go through TCP reassembly. +## ## .. bro:see:: http_entity_data skip_http_entity_data http_entity_data_delivery_size const skip_http_data = F &redef; ## Maximum length of HTTP URIs passed to events. Longer ones will be truncated ## to prevent over-long URIs (usually sent by worms) from slowing down event ## processing. A value of -1 means "do not truncate". -## +## ## .. bro:see:: http_request const truncate_http_URI = -1 &redef; -## IRC join information. -## +## IRC join information. +## ## .. bro:see:: irc_join_list type irc_join_info: record { nick: string; @@ -1933,13 +1950,13 @@ type irc_join_info: record { ## Set of IRC join information. ## -## .. bro:see:: irc_join_message +## .. bro:see:: irc_join_message type irc_join_list: set[irc_join_info]; -## Deprecated. -## +## Deprecated. +## ## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere -## else. +## else. global irc_servers : set[addr] &redef; ## Internal to the stepping stone detector. @@ -2003,7 +2020,7 @@ type backdoor_endp_stats: record { ## Description of a signature match. ## -## .. bro:see:: signature_match +## .. bro:see:: signature_match type signature_state: record { sig_id: string; ##< ID of the matching signature. conn: connection; ##< Matching connection. @@ -2011,10 +2028,10 @@ type signature_state: record { payload_size: count; ##< Payload size of the first matching packet of current endpoint. }; -# Deprecated. -# +# Deprecated. +# # .. todo:: This type is no longer used. Remove any reference of this from the -# core. +# core. type software_version: record { major: int; minor: int; @@ -2022,10 +2039,10 @@ type software_version: record { addl: string; }; -# Deprecated. -# +# Deprecated. +# # .. todo:: This type is no longer used. Remove any reference of this from the -# core. +# core. type software: record { name: string; version: software_version; @@ -2042,7 +2059,7 @@ type OS_version_inference: enum { ## Passive fingerprinting match. ## -## .. bro:see:: OS_version_found +## .. bro:see:: OS_version_found type OS_version: record { genre: string; ##< Linux, Windows, AIX, ... detail: string; ##< Lernel version or such. @@ -2052,20 +2069,20 @@ type OS_version: record { ## Defines for which subnets we should do passive fingerprinting. ## -## .. bro:see:: OS_version_found +## .. bro:see:: OS_version_found global generate_OS_version_event: set[subnet] &redef; # Type used to report load samples via :bro:see:`load_sample`. For now, it's a # set of names (event names, source file names, and perhaps ````, which were seen during the sample. +# number>``, which were seen during the sample. type load_sample_info: set[string]; ## ID for NetFlow header. This is primarily a means to sort together NetFlow -## headers and flow records at the script level. +## headers and flow records at the script level. type nfheader_id: record { ## Name of the NetFlow file (e.g., ``netflow.dat``) or the receiving socket address ## (e.g., ``127.0.0.1:5555``), or an explicit name if specified to - ## ``-y`` or ``-Y``. + ## ``-y`` or ``-Y``. rcvr_id: string; ## A serial number, ignoring any overflows. pdu_id: count; @@ -2073,7 +2090,7 @@ type nfheader_id: record { ## A NetFlow v5 header. ## -## .. bro:see:: netflow_v5_header +## .. bro:see:: netflow_v5_header type nf_v5_header: record { h_id: nfheader_id; ##< ID for sorting. cnt: count; ##< TODO. @@ -2089,7 +2106,7 @@ type nf_v5_header: record { ## A NetFlow v5 record. ## ## .. bro:see:: netflow_v5_record -type nf_v5_record: record { +type nf_v5_record: record { h_id: nfheader_id; ##< ID for sorting. id: conn_id; ##< Connection ID. nexthop: addr; ##< Address of next hop. @@ -2123,7 +2140,7 @@ type bittorrent_peer: record { }; ## A set of BitTorrent peers. -## +## ## .. bro:see:: bt_tracker_response type bittorrent_peer_set: set[bittorrent_peer]; @@ -2146,12 +2163,12 @@ type bittorrent_benc_dir: table[string] of bittorrent_benc_value; ## Header table type used by BitTorrent analyzer. ## ## .. bro:see:: bt_tracker_request bt_tracker_response -## bt_tracker_response_not_ok +## bt_tracker_response_not_ok type bt_tracker_headers: table[string] of string; @load base/event.bif -## BPF filter the user has set via the -f command line options. Empty if none. +## BPF filter the user has set via the -f command line options. Empty if none. const cmd_line_bpf_filter = "" &redef; ## Deprecated. @@ -2169,24 +2186,24 @@ const log_encryption_key = "" &redef; ## Write profiling info into this file in regular intervals. The easiest way to ## activate profiling is loading :doc:`/scripts/policy/misc/profiling`. ## -## .. bro:see:: profiling_interval expensive_profiling_multiple segment_profiling +## .. bro:see:: profiling_interval expensive_profiling_multiple segment_profiling global profiling_file: file &redef; ## Update interval for profiling (0 disables). The easiest way to activate ## profiling is loading :doc:`/scripts/policy/misc/profiling`. ## -## .. bro:see:: profiling_file expensive_profiling_multiple segment_profiling +## .. bro:see:: profiling_file expensive_profiling_multiple segment_profiling const profiling_interval = 0 secs &redef; ## Multiples of profiling_interval at which (more expensive) memory profiling is ## done (0 disables). ## -## .. bro:see:: profiling_interval profiling_file segment_profiling +## .. bro:see:: profiling_interval profiling_file segment_profiling const expensive_profiling_multiple = 0 &redef; ## If true, then write segment profiling information (very high volume!) ## in addition to profiling statistics. -## +## ## .. bro:see:: profiling_interval expensive_profiling_multiple profiling_file const segment_profiling = F &redef; @@ -2225,42 +2242,42 @@ global load_sample_freq = 20 &redef; ## Rate at which to generate :bro:see:`gap_report` events assessing to what degree ## the measurement process appears to exhibit loss. -## +## ## .. bro:see:: gap_report const gap_report_freq = 1.0 sec &redef; ## Whether we want :bro:see:`content_gap` and :bro:see:`gap_report` for partial ## connections. A connection is partial if it is missing a full handshake. Note ## that gap reports for partial connections might not be reliable. -## +## ## .. bro:see:: content_gap gap_report partial_connection const report_gaps_for_partial = F &redef; ## The CA certificate file to authorize remote Bros/Broccolis. -## +## ## .. bro:see:: ssl_private_key ssl_passphrase const ssl_ca_certificate = "" &redef; ## File containing our private key and our certificate. -## +## ## .. bro:see:: ssl_ca_certificate ssl_passphrase const ssl_private_key = "" &redef; ## The passphrase for our private key. Keeping this undefined ## causes Bro to prompt for the passphrase. -## +## ## .. bro:see:: ssl_private_key ssl_ca_certificate const ssl_passphrase = "" &redef; ## Default mode for Bro's user-space dynamic packet filter. If true, packets that -## aren't explicitly allowed through, are dropped from any further processing. -## +## aren't explicitly allowed through, are dropped from any further processing. +## ## .. note:: This is not the BPF packet filter but an additional dynamic filter -## that Bro optionally applies just before normal processing starts. -## -## .. bro:see:: install_dst_addr_filter install_dst_net_filter +## that Bro optionally applies just before normal processing starts. +## +## .. bro:see:: install_dst_addr_filter install_dst_net_filter ## install_src_addr_filter install_src_net_filter uninstall_dst_addr_filter -## uninstall_dst_net_filter uninstall_src_addr_filter uninstall_src_net_filter +## uninstall_dst_net_filter uninstall_src_addr_filter uninstall_src_net_filter const packet_filter_default = F &redef; ## Maximum size of regular expression groups for signature matching. @@ -2272,17 +2289,17 @@ const enable_syslog = F &redef; ## Description transmitted to remote communication peers for identification. const peer_description = "bro" &redef; -## If true, broadcast events received from one peer to all other peers. -## +## If true, broadcast events received from one peer to all other peers. +## ## .. bro:see:: forward_remote_state_changes ## ## .. note:: This option is only temporary and will disappear once we get a more ## sophisticated script-level communication framework. const forward_remote_events = F &redef; -## If true, broadcast state updates received from one peer to all other peers. -## -## .. bro:see:: forward_remote_events +## If true, broadcast state updates received from one peer to all other peers. +## +## .. bro:see:: forward_remote_events ## ## .. note:: This option is only temporary and will disappear once we get a more ## sophisticated script-level communication framework. @@ -2311,23 +2328,23 @@ const REMOTE_SRC_PARENT = 2; ##< Message from the parent process. const REMOTE_SRC_SCRIPT = 3; ##< Message from a policy script. ## Synchronize trace processing at a regular basis in pseudo-realtime mode. -## +## ## .. bro:see:: remote_trace_sync_peers const remote_trace_sync_interval = 0 secs &redef; ## Number of peers across which to synchronize trace processing in -## pseudo-realtime mode. -## +## pseudo-realtime mode. +## ## .. bro:see:: remote_trace_sync_interval const remote_trace_sync_peers = 0 &redef; ## Whether for :bro:attr:`&synchronized` state to send the old value as a -## consistency check. +## consistency check. const remote_check_sync_consistency = F &redef; ## Analyzer tags. The core automatically defines constants ## ``ANALYZER_*``, e.g., ``ANALYZER_HTTP``. -## +## ## .. bro:see:: dpd_config ## ## .. todo::We should autodoc these automaticallty generated constants. @@ -2345,7 +2362,7 @@ type dpd_protocol_config: record { ## This table defines the ports. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size -## dpd_match_only_beginning dpd_ignore_ports +## dpd_match_only_beginning dpd_ignore_ports const dpd_config: table[AnalyzerTag] of dpd_protocol_config = {} &redef; ## Reassemble the beginning of all TCP connections before doing @@ -2353,10 +2370,10 @@ const dpd_config: table[AnalyzerTag] of dpd_protocol_config = {} &redef; ## expensive of CPU cycles. ## ## .. bro:see:: dpd_config dpd_buffer_size -## dpd_match_only_beginning dpd_ignore_ports -## +## dpd_match_only_beginning dpd_ignore_ports +## ## .. note:: Despite the name, this option affects *all* signature matching, not -## only signatures used for dynamic protocol detection. +## only signatures used for dynamic protocol detection. const dpd_reassemble_first_packets = T &redef; ## Size of per-connection buffer used for dynamic protocol detection. For each @@ -2365,23 +2382,23 @@ const dpd_reassemble_first_packets = T &redef; ## already passed through (i.e., when a DPD signature matches only later). ## However, once the buffer is full, data is deleted and lost to analyzers that are ## activated afterwards. Then only analyzers that can deal with partial -## connections will be able to analyze the session. +## connections will be able to analyze the session. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_config dpd_match_only_beginning -## dpd_ignore_ports +## dpd_ignore_ports const dpd_buffer_size = 1024 &redef; ## If true, stops signature matching if dpd_buffer_size has been reached. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size -## dpd_config dpd_ignore_ports -## +## dpd_config dpd_ignore_ports +## ## .. note:: Despite the name, this option affects *all* signature matching, not -## only signatures used for dynamic protocol detection. +## only signatures used for dynamic protocol detection. const dpd_match_only_beginning = T &redef; ## If true, don't consider any ports for deciding which protocol analyzer to -## use. If so, the value of :bro:see:`dpd_config` is ignored. +## use. If so, the value of :bro:see:`dpd_config` is ignored. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size ## dpd_match_only_beginning dpd_config @@ -2389,14 +2406,14 @@ const dpd_ignore_ports = F &redef; ## Ports which the core considers being likely used by servers. For ports in ## this set, is may heuristically decide to flip the direction of the -## connection if it misses the initial handshake. +## connection if it misses the initial handshake. const likely_server_ports: set[port] &redef; ## Deprated. Set of all ports for which we know an analyzer, built by -## :doc:`/scripts/base/frameworks/dpd/main`. +## :doc:`/scripts/base/frameworks/dpd/main`. ## ## .. todo::This should be defined by :doc:`/scripts/base/frameworks/dpd/main` -## itself we still need it. +## itself we still need it. global dpd_analyzer_ports: table[port] of set[AnalyzerTag]; ## Per-incident timer managers are drained after this amount of inactivity. @@ -2409,7 +2426,7 @@ const time_machine_profiling = F &redef; const check_for_unused_event_handlers = F &redef; # If true, dumps all invoked event handlers at startup. -# todo::Still used? +# todo::Still used? # const dump_used_event_handlers = F &redef; ## Deprecated. @@ -2425,7 +2442,7 @@ const trace_output_file = ""; ## of setting this to true is that we can write the packets out before we actually ## process them, which can be helpful for debugging in case the analysis triggers a ## crash. -## +## ## .. bro:see:: trace_output_file const record_all_packets = F &redef; @@ -2438,7 +2455,7 @@ const record_all_packets = F &redef; const ignore_keep_alive_rexmit = F &redef; ## Whether the analysis engine parses IP packets encapsulated in -## UDP tunnels. +## UDP tunnels. ## ## .. bro:see:: tunnel_port const parse_udp_tunnels = F &redef; @@ -2446,6 +2463,6 @@ const parse_udp_tunnels = F &redef; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; -# Load the logging framework here because it uses fairly deep integration with +# Load the logging framework here because it uses fairly deep integration with # BiFs and script-land defined types. @load base/frameworks/logging diff --git a/src/Frag.cc b/src/Frag.cc index cbdae92883..68c5c108f1 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -32,10 +32,12 @@ FragReassembler::FragReassembler(NetSessions* arg_s, { s = arg_s; key = k; + + // [Robin] Can't we merge these two cases now? const struct ip* ip4 = ip->IP4_Hdr(); if ( ip4 ) { - proto_hdr_len = ip4->ip_hl * 4; + proto_hdr_len = ip4->ip_hl * 4; // [Robin] HdrLen? proto_hdr = new u_char[64]; // max IP header + slop // Don't do a structure copy - need to pick up options, too. memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len); @@ -244,6 +246,12 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) reassem4->ip_len = htons(frag_size + proto_hdr_len); reassembled_pkt = new IP_Hdr(reassem4, true); } + + // [Robin] Please always check for IP version explicitly, like here + // do "if ... ip_v == 6", and then catch other values via + // weird/errors. Even of it shouldn't happen (because of earlier + // checks), it's better to be safe. I believe there are more places + // like this elsewhere, please check. else { struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; diff --git a/src/IP.h b/src/IP.h index 53fe1daf84..b876a2ac3b 100644 --- a/src/IP.h +++ b/src/IP.h @@ -14,6 +14,15 @@ #include #include +// [Robin] I'm concerced about the virtual methods here. These methods will +// be called *a lot* and that may add to some significant overhead I'm afraid +// (at least eventually as IPv6 is picking up). +// +// [Robin] Similar concern for the vector and ip6_hdrs data +// members: we're creating/allocating those for every IPv6 packet, right? +// +// Any idea how to avoid these? + /** * Base class for IPv6 header/extensions. */ @@ -32,6 +41,13 @@ public: */ IPv6_Hdr(const u_char* d, uint16 nxt) : type(IPPROTO_IPV6), data(d) { + // [Robin]. This looks potentially dangerous as it's changing + // the data passed in, which the caller may not realize. From + // quick look, it's only used from Frag.cc, so that may be + // ok. But could we guard against accidental use somehome? + // Like making this protected and then declare a friend; or a + // seperate method ChangeNext(). (I saw it's used by derived + // classes so not sure wehat works best.) if ( ((ip6_hdr*)data)->ip6_nxt == IPPROTO_FRAGMENT ) ((ip6_hdr*)data)->ip6_nxt = nxt; } diff --git a/src/Sessions.cc b/src/Sessions.cc index b4115f5c16..a5b054b933 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -430,6 +430,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( discarder && discarder->NextPacket(ip_hdr, len, caplen) ) return; + // [Robin] dump_this_packet = 1 for non-ICMP/UDP/TCP removed here. Why? + FragReassembler* f = 0; if ( ip_hdr->IsFragment() ) @@ -465,6 +467,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; + // [Robin] Does ESP need to be the last header? if ( ip_hdr->LastHeader() == IPPROTO_ESP ) { if ( esp_packet ) @@ -474,7 +477,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, mgr.QueueEvent(esp_packet, vl); } Remove(f); - // Can't do more since upper-layer payloads are going to be encrypted + // Can't do more since upper-layer payloads are going to be encrypted. return; } @@ -486,6 +489,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } + // [Robin] The Remove(f) used to be here, while it's now before every + // return statement. I'm not seeing why? + const u_char* data = ip_hdr->Payload(); ConnID id; @@ -594,6 +600,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 ) { pkt_hdr_val = ip_hdr->BuildPktHdrVal(); + // [Robin] This should be ipv6_ext_headers, right? conn->Event(new_packet, 0, pkt_hdr_val); } From 7af14ec1fe0ff4ed4088f127eeae2eeb79eac887 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 14 Mar 2012 10:00:48 -0500 Subject: [PATCH 08/27] Remove the default "tcp or udp or icmp" filter. In default mode, Bro would load the packet filter script framework which installs a filter that allows all packets, but in bare mode (the -b option), this old filter would not follow IPv6 protocol chains and thus filter out packets with extension headers. --- src/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cc b/src/main.cc index 6313528980..f5a5b5282f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -837,7 +837,7 @@ int main(int argc, char** argv) if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, netflows, flow_files, - writefile, "tcp or udp or icmp", + writefile, "", secondary_path->Filter(), do_watchdog); BroFile::SetDefaultRotation(log_rotate_interval, log_max_size); From 5312a904ab2e1a242a03486b8ed2b59e2f274514 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 14 Mar 2012 10:31:08 -0500 Subject: [PATCH 09/27] Fix ipv6_ext_headers event and add routing0_data_to_addrs BIF. Also add unit tests for ipv6_ext_headers and esp_packet events. --- src/Sessions.cc | 2 +- src/bro.bif | 32 +++++ .../bifs.routing0_data_to_addrs/output | 4 + testing/btest/Baseline/core.ipv6_esp/output | 120 ++++++++++++++++++ .../Baseline/core.ipv6_ext_headers/output | 1 + .../btest/Traces/ext_hdr_hbh_routing.trace | Bin 0 -> 153 bytes testing/btest/Traces/ip6_esp.trace | Bin 0 -> 20210 bytes .../btest/bifs/routing0_data_to_addrs.test | 9 ++ testing/btest/core/ipv6_esp.test | 10 ++ testing/btest/core/ipv6_ext_headers.test | 10 ++ 10 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/bifs.routing0_data_to_addrs/output create mode 100644 testing/btest/Baseline/core.ipv6_esp/output create mode 100644 testing/btest/Baseline/core.ipv6_ext_headers/output create mode 100644 testing/btest/Traces/ext_hdr_hbh_routing.trace create mode 100644 testing/btest/Traces/ip6_esp.trace create mode 100644 testing/btest/bifs/routing0_data_to_addrs.test create mode 100644 testing/btest/core/ipv6_esp.test create mode 100644 testing/btest/core/ipv6_ext_headers.test diff --git a/src/Sessions.cc b/src/Sessions.cc index b4115f5c16..e70540b598 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -594,7 +594,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 ) { pkt_hdr_val = ip_hdr->BuildPktHdrVal(); - conn->Event(new_packet, 0, pkt_hdr_val); + conn->Event(ipv6_ext_headers, 0, pkt_hdr_val); } if ( new_packet ) diff --git a/src/bro.bif b/src/bro.bif index ff06288940..375a1c64c1 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2049,6 +2049,38 @@ function is_v6_addr%(a: addr%): bool # # =========================================================================== +## Converts the *data* field of :bro:type:`ip6_routing` records that have +## *rtype* of 0 into a set of addresses. +## +## s: The *data* field of an :bro:type:`ip6_routing` record that has +## an *rtype* of 0. +## +## Returns: The set of addresses contained in the routing header data. +function routing0_data_to_addrs%(s: string%): addr_set + %{ + BroType* index_type = base_type(TYPE_ADDR); + TypeList* set_index = new TypeList(index_type); + set_index->Append(index_type); + TableVal* tv = new TableVal(new SetType(set_index, 0)); + + int len = s->Len(); + const u_char* bytes = s->Bytes(); + bytes += 4; // go past 32-bit reserved field + len -= 4; + if ( ( len % 16 ) != 0 ) + reporter->Warning("Bad ip6_routing data length: %d", s->Len()); + + while ( len > 0 ) + { + IPAddr a(IPAddr::IPv6, (const uint32*) bytes, IPAddr::Network); + tv->Assign(new AddrVal(a), 0); + bytes += 16; + len -= 16; + } + + return tv; + %} + ## Converts a :bro:type:`addr` to a :bro:type:`index_vec`. ## ## a: The address to convert into a vector of counts. diff --git a/testing/btest/Baseline/bifs.routing0_data_to_addrs/output b/testing/btest/Baseline/bifs.routing0_data_to_addrs/output new file mode 100644 index 0000000000..7179bf8564 --- /dev/null +++ b/testing/btest/Baseline/bifs.routing0_data_to_addrs/output @@ -0,0 +1,4 @@ +{ +2001:78:1:32::1, +2001:78:1:32::2 +} diff --git a/testing/btest/Baseline/core.ipv6_esp/output b/testing/btest/Baseline/core.ipv6_esp/output new file mode 100644 index 0000000000..645b4c8c56 --- /dev/null +++ b/testing/btest/Baseline/core.ipv6_esp/output @@ -0,0 +1,120 @@ +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output new file mode 100644 index 0000000000..4cc9c706ae --- /dev/null +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -0,0 +1 @@ +[ip=, ip6=[hdr=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b], hopopts=[[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]]], dstopts=[], routing=[[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B]], fragment=[], ah=[], esp=[], ext_order=[0, 43]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] diff --git a/testing/btest/Traces/ext_hdr_hbh_routing.trace b/testing/btest/Traces/ext_hdr_hbh_routing.trace new file mode 100644 index 0000000000000000000000000000000000000000..2a294ed58ea254aa88049e4287324bd05111eaf0 GIT binary patch literal 153 zcmca|c+)~A1{MYwaA0F#U<7jR?~eEPY-MC91hPT+KNvt%wcSksF{~LJ6c|~405!8S zJ!t&@FX;b&RQ{}NZ3afL(Sj@tOdu@^j0_b($jfgh8yN)nEXRP#nmY z40s(L;RP>gHKxO8up=oUL)MP z5A~q~2SO^f;(f8SkG&p&VpYp{gTog}f#sGc1Ii!*tNj~kqaQ_#A`j}G2W1=~t#a=z zr6|?P{~avOcJ16A3wg*t*@4gbcdLzHEFTN&9811FBTn8!BAX#=RO@0L>+|F?3+=0_ zS9Q;vI+vHU?;Xjl0CF%PoaBhNn^1GcY9iie((`Rd;f|@*&;80_odR2$1o}OgGAJ7t zp)p%t5KMV9iksz(M{bx#=b=-t&#L$i+?dF!lb1NODq|Li7OItsC;z}J-N~|MT|ynR zp09jyxxipWOK%mBXArBeWv6#tP?qFo)8)hxQN-Sa-q zZj$0R<>fjcXM&d;a=R&#ylHZmYq3%llk7zmWgZIg4KY^#54YSiwPcT4+@9Z;=V=F5 z$dyv{dPd4WwJe_CkPl&ntwbgTu;(5wIb#Nmyhw;W-!@`8ZjYd8{8jlbPA{iw_R)w_ zV?KTI1|Z+Xhtq69zTJd(xqO&Wq4g{`m8g+u?^u<5PUh>|p|UpFt^#_bU6OY=x)?lIQG ztV@;}Rr8~-EtQSa1m(5f!L~H9E0@uMFTMN4wobqljeGZ<9}AB^mJWS6a0C6or!V;>h*D@~M%chQ@oG%P=!pFfT!6 z0ZB3GP&}F*4N>6E@BJ|9BeL74FD@sU(ByxoLY}CF5A?O{^RFB2Z z4j?b7g_9ipcGLW?{gWihVQZb`FQ3yV@gM0o>NTENnnw@lY12JG{H}@nJTsU(rqb~b zAjfS+17!e9AoTd>hV-vB)apO3p-8|e4B$X`tdU6(-#rj!-c%*h==uJ|Um9D|Q|8&z zF4RfYkCUXfyfff2ZUKAU;z5P-ur1rM9`sU;b)4KE&XubY?<<;{M=mkCtYjay;Yc#k z85|j|bV!@DkG7iF;~r&6oB~pm2{=g+VGS~nviYu*D9^KnX`zlHHOh`sjEVLOoPeN& zP3=7^1l3E7Ey`m-+PWAn4E%DwLiS-(rF}`2`Tdt(hX-Dz794NZGhay^8d!R*WaW`n zGQUt_Az?iOq|)PXk|MzxKG#ak_rI5vj9NO5-49sBeay}D-HCrNerGcR&rNJfXsuB? zXvr?YY4pl0V_N}1m$gsOm2z~oWZ)*!zv=u9O1N(z!;w>rdy~<#`zB*3BggbD_2+VbCU zA>azz#YxTIT7&d7T5(KAUWO=6js5ggMnC(^>n;H)C%mM{u!efa(IByee#$9<(WQ;a zN|*PC9HnH_CiDW%V4^Jo7W^N$A0{87Qc3twImU3*kwv8KK33taB$9olB5gCi&*B_g zD>_V>8#n5*2?%VAU*#Mr*nz|YuKTGS+Tbs9sDT3J+etdMSl#n!uOs3 zw;WJU;!tt}F7J2p8eAi>Bgk1#T;8yNbG+HoP{{HX_v_+phw0Akq-09pMf@8xy|fo! zgY2v`(KVaQ-)39^(gJu%QDF@^%#T~o=ye{M^`#fRlSFr0Y_zu~nRPGdKV!kbC1OU+ zz!S0l?Ia*~z5M2MVHE6}wA$tx*ZH7%XXq6Zi=O{vxtPnw>&XqizF)-z>2=TTUV0LU zUjx!XcuCP<4bRnMQm_tZdg(vA;T&JQ9H@7jNcV{KL|f3^sT6QY>o^$HRpT9eZpc=Q}?- ztU=GqH@D8gpv>@_legA#xT@5*w|0)7zwODjhGU&1SD5znHeX+glW=H3^ppQjjwLe0lO|Pc|h1?lL*VQ5rk9G4dQQT?EEyiWoB$$gU zAMO0vuSl{1iy!Z~L`6I54xxMDw7Q=AJQM%3;EfQytcRh&e%l)o!<-;l&-WVeH6&;4X(8g+y%AfKD~_r)x5G z9MUCx?Z8@i<-a&!i3Lcd;3b8?8btiqR34qYNeD!)=b2jR!DuAa8ljAs`mz1D6gxGo zsrHjsV^08Tk}a9*8&c<7RFOiH8iJ_OcgD2!=}L(-wqHhPXS{t(gs~i`a3CBpfzJ|LZxnijTwp%y zl6RxF@*Z6?yWNLzOKR$+Z9rs*TCxZ==Qm2rV&|Wk(q)vp$48AOO$Ar|&)9JQ=@7i6 zD6oc~^Qnjrb($WL(aBK<6;q81I)9QnK8*AUt!oeYW+u$8#08{r@RFj!8gimBORb%Y zXe4$_+fX?6?NwD`0Bss=~#Ff5afagCx)z47GA3dno(qFMnC)B7I^Ac^&ZpX(YU)Xs`yXSiiz^V#cnQX4Z+;-QpGx zgFLVT9@E|zw2oU0zThsf=jlC6Cn~7kF;-nN9mOKOJc#%K8nzr}B*seEYTnu5x%ryL zJsK_UFV>TLNDq1Du{^7f4@j}#B}Iod^omxb=>~zfNm|7;2HZ6xoj-Y0&JpX;q0U#v zdkX6+)K?u_34r3{a>D}r7Z$2z?5c@f@rXJ}eA(jTJf~g_y(*}GYAT(GIT-ZtSUUW} zaq^m<7X=`7Uq%PT0!s|^_~!=s*BWK;AAgU60Hd&g10fLfMej@(gaAzy22xSc&@nKv zuyJtl@CgWsh)GDv$nQ~5Qc=^;($O<8GBLBTvaxe;a&hzU^6?7@-WNhZL=@E&ywYBs zYk9e^%H2Q-*spfaofkPb@a??8d<`Rrhsev39c4h&7Dy`%1n`UFa{1%;VZhWQ>1 zki!5k9V8G$0o6gEsWS_AyRy4nhOGO)^|K2YZe(eJoD(1iE>{*g5TvUE=#ZhQd3V&2 zIesCQ_@F-gA(S_p4#@ckFC9uCC`B94p+Hkj@2G3*G&5aHV;V<#A)r7HoTypB$KJltDR`kk4wpCPf46Ui53Cda>|1$Q zDs#!$)2eZd6M}rhtb?ux9MtIquP@nNp;^_Sh+guM8K`b@)!)w7^VGih@p4c(%c!lI9UyB%u?pK8sL*pAbtu_N1%$MYv>|eh#%x zV=QtQARqLAlN|AOQ$t4hb?|u4yaAUg`NTukzxwRDJHkK7MDuID>tjXfzo--r@x1U` zzP!;pIbatr2QNS^!j@wF1gkMxwrqR!I9+QGm7pdJL1-^)pOU8*7EN^>%rcwnoz^mk}{11 zhO}I z{(qV*S6#P@(^|e^+1Xw$YEfX+tlC^=zBk|I5_WJ~wmXY1da;DELV(7>VW$1suHJf_ znGZ_c`}K_v-PKvBEl~5tNmTC0r`y^oMsE! z?Iy0?-ScRD?B6L(uDbOGLDJ`<$|173&kB^V2@@3dW{Kx6!oS&(G8NpLSoQ@8yP_{7 zS;utCb7T_+MG^Nl?h$OLGOu5v7p~mHOjG~psR+rqfMy`yUoH=3vc_+N&=(n4a zZsMN=kLc^}dyrzC&{a5e>I(>aJUT^<4MF(2^4yViC%*<%!0v58$BmTgcS9P9t|?6p zQvNpk5OXE)$*&D1yr6xFHx{Jfr@}41m70|E1Tlk$_Y$?*M{?|y(g1nBALf7e=p_NL zhW@i}b&^YVdem08@^arLVoaUFK|h^)6;BrjgIGi?rWm*iq|EFD+&=R}pRH=iE1^rQpQxL!C( z5n&BnZeSCe6UNJPUfh6o+s*zqK7rHS=LBD@9B4gvXom;{NpzO7QY;v$6p{%v$Asq; z&&~xJMeZ}6_PA**dHMSeii*)Xho0}a?#wI|rs4fWV8b5H0HihDaFQay8a5~rsfk(R zk%}K4UhmQQ7Ru_5et+U$GdrVt5Z|eI=wlcE(N{M8&k?fk&<~S3&lBz&le!E>qkyUb zny~!f$Ro5bpb4uwo}J6Cd+blG$bFA^ii|S>sXn}*SoXkL4%xM#%^h@=6`nu zV&_;ZB!hiFtms((ofXb3N1NKdDKcVE6mH{x+RZ>vD_{LAk9AXd>HP4CA)&^)caKP) zj~;W2;+_~zWWlBe>ZYh*79hogmlOhP=zBs@t3o4=D28Kb&=T)KP#6?4o9>x2Us{`? z5FY%cSJKhVa*<{FQ_HTw>N^J3e)VMjuo~(Lze|#D3WGFQjrvOTV#$>pt4p$z5vbe} z?|4`PpS}g8OI>if`pB?`=`JitXC97j_rN{OVewW5_syyz%-sjtp}!cNeiSF1`);{# zG&IuxPVS`<@QWvZM^_ey$5m~Kr6*QYd`}vKfJE*&vz1F>-|=eTHmlEuNc$KwLpC6d zgqIWr)?mqRn};#>ArgbQE!b85Dkl@IT-=`!gV}x0^yN5DHuZ#Wkht7xhzbX;y`8~S zuu@#>hfj$Tu^=IXxyemmj{xO&3iOWCugk;DmhEK}Um4F3qmASMQWJPdQDF@)rrvMH zCmpjj=^H=9Y`<}6)=kLWHI(|0c=39dq}oFEM9Cqtr?x$uD64X{iQ6;HwbrQhg8JHM1@aa`m zNPKCw#BZnC&r(m$Rm&7H@-PpO9(;k*JVl2!EIo_FeNd7-S6N>kF-%01RL+4NWX__QS3oVat7RhfAPjZyEsEqcXXPAAu+_@x) zQeQY}9qRW%%qat;{X@5;|F`>Aguoj0&%TvB^5OwoK^OLyvDMhTeO>=TfiBQ6La|7E zP;z;L<5iJ@NfY&jwN*LCAAi+o!L(0aI*wrh5B4qUtmedr!PebJ0(I&pU;-KPmO($h z@D44~hcC5nQho`_Eb=`l2c#E+aFQaz8glrj`kTYYvNlOtqlH9+Ia?w5x)O7d*u@pI zmcP5y_y^CCj&>JG0^KEFmBe5KA7ZRxKS=aU@|_63N7Kg;bzZgt=0Id+qOZhBWqp7C z>e&JBdz1=5Y7Q?c60AYTZj+GN4$<1@Kn17JM3z1AAi~8n0QuK?;ESvC|2)x&kvjvGddLI}sv?`VS0gzh2 zOA3ZHNdJ29`4{KTxT<)|{7K_B$6BLcLzfh>Y6yz$GJa6(pj7BPMQc4DP(1Sc#G#Zh zzHeEAm7Tu42^BIUAo&Ng$YuP-1F=s$FiQdrNH?%$8mgm8)GGn$=2tjfeF&_9`%yS9 z)o*(e7R1NsUR9d|AqG8c-_2PU)-~M}hfB7Tby*fAg|cxSz*h>U>G7de#mFx=8{5gP zmo@Sly^Q0{R^}xOvdqs{m;MyrjsmhS*&4bs29Nt($Qi{g;7= z%&N#&6&d7+MYZ%#I8^0L#Iy4%GIy5%{@7w9$MPP?;T5!wRAtVcQ_`J z_V`lr_`Y_ufbDmNOxxz^My6^&>IN?<3akO+z1=V$1+Ii$?#FD|VujuNC_`o6O$j|q zgc+xPXN4nY6j*xvj2?0cD3~!wFngvqswCERN{wYGfy4ht!urKb)&OF6k8-6lo`>pF z`=R-*@+KLZ8bHbiFDWXl0hdBT%V!}=)37;eqoYli@>~4WXEDEF2qDhsWeXNsB_w=-9t}l)84pZJZgG;rO=DGxCPk^8sFLnwgg@hoh*trTovH?5x2p-`%)* zJQv=MBVn)fVRAA{nn4XpzqJyC+QZb*{N)@4(T_nl!Uh7Eld*v8Pbx}Tp3~>e5GfB~hVGt)OFs*g`$L>uPu4=`Ks!Mj`Hr`G2i&>5%9Eq!m zdbw(}|K7J^SO04S zLV%{S0I7G`x5`F@SdUZ1Jy*NLP-q8o8dS01qXYJ><|Y9hA~e+lNWF^=-Dp_$E51%y zxE7DpXCTKOUOHgkiW90sf~L~nQI~&z&dy7aXG?=mUbX|sVTG3t90+or0CZqz>VnGM z&K>R_x&k_afmEg4=hvM;4(B5{U0Gn?>gfoegFsW4)bFOlLEb#!2_aL&FuYd!0^~#j zIseuE0qm;+*tf!f>X4zSvUk*J@u;eO%}pC4XP@uv0&>vcr33b@!iNDJ3N*D_?QZ8T zar0NaQmXB2eHQ2aZXm}<6Hez2*tg;z0CcF(R8k=IE?=|xT>A)x!{7BnWn74QfE*Sr zIO%|WEBih`hXzeuyrYg-;{1CGkDugZ5UEKokh5U{CmpbFl~WJs(4ncNKF|plsmVJ@okJ_V4Fg+5N}Aai9Z6L4T(~7^K!)59qeN5q`l$ z3c)mZ&&-C_F_|T)l#=zaUT&I<{L;xb2<7Be)TZgk0KTlJdC0xUIqN=j&&Q@o9@IsD z=SQ7+jY5)&RoZ9_bgEXg{eGw_9?@ue(o1r-8{WUtsbc}O25;b`MZBG^!`$O08FF|i zimKo5B;!CvW%~&{oFD%ORkwx;@g%Xv#BcUXqujaHWiMlZWgv;`kz~%$-dA>Y7RDS@ zu!cHFAQoLgsP|b5=lGf8hn7)nRzOPwFD=sT^ss@ewHzfwdBSg-5C(6_y$(x>9H)=z zq%~}U9i2j2)Ej(g*aRsNyzPdV_vlO>jq8{78YYdtHk_(G=H`hwO=fhbM6!`;YHu7Q zs<6ijU}Xcef$-9TZ>LYpNKhsU7&1q^s?vPP(Pv(}`(kNACc=d#H@DmY1wE@7x#9=ZN!${3cw zZ*@k$rp=q41b4{tc>1v*k-sh^j@?x6FV%d!O9TgW-oi_Zd^_EGnIBJmQ3Q!urV^5q zveG@HXm5@eRxIJVCWeZtLkMrv#M7vdyp~Yd+qBGQov5A1hm-37Z`2RrC}&)3o1(t1ooc zueboMOd6bK0_yE_!+rs#R(iGTt{%~(r`2d1Z@bTwMLDSOy%qbFCwLg8h8xg2rNT*zc01i^ zc6+)S`BRI}m9@u^bndrzYa)mUQz~EE+5MulEK!OX`*Mid8-s_UviHTJ8pZk8@VGWH zrIfxYEYs2QEm0~|0* zN+0(uyceb_+bZy$yT^#fCe~k?%TMvov5CB0H);CQMu=#*IK?#ROqc3K;g{$sDxRcQ zf$#OCbHnKx1~7H@EcN-s0A0`woOFn=)QgI71*1SbX}U9)NJ`acwsw}7VKvNG(q7Mg zS0J~h|AZVIJO0%B<3G2Y!6aZhptacyvOvL)?_p6Rpuhf$WfPMZ#OmLN94!v$9Dc${ zhXhOI{H}ejj*qv0*sy(>%*HA%^2seW@%nl`(*8%P;9u2>nLNWPRm*X@k~0QV2Ujm{ zlOd8(759h`84SV(DywuWPtx3X5nYK~5`c~gUOF%=_1hOmud%kLtx+n|Ec>}Gtv3_v z*&{jrE|1rxPjO?Sv7eK>R|_rFZHY+ocz@ZJ{d-WJA)x%8z?#~|0q5fLssyT<_xqs+ zMqmf|T<+=zoX#BtmP*I-c;S15r)e!un41mE38hx{}#KSKiyhfRiM_$~Ro~8eBPa(Hf0xxDk+Pwwg)9a#^ow2=_S;R7jzGEl* zzn5s=Tqs3l7%lh_N&`A)ceIP=qPGGUax> zXt^V#ODcN`ZS)>Rvdb469Vm~HNQ7>eZ7uZTRdeI;RLKB3MtJE^VX2cB zh)SUFX|6yV<5Qd7`7rwpA6IquZv&czgb~-Q29-7bCSlGXO2#>~cklb2NG#;xEe zQ0&LNu1dwbAZTS^;<3+sq=SEwP#r=jlw&3RRV#@~x8MHsa`JgnnC^1q;A8pmqI5Yx zR|zj2IxH1$+P$#hCSPyo;O}e17&8MJ%k5to*7^RXXAD}}Z!GlOVm(74h9HF92V+R4 zr^W^?R_6@Pg!uCL`wX=pIYut32ZzCOyykdnfR1wpQKkrDYnv4Vm(QR(@oUp%*?&^Rpa1l;AL|CfgYK7F!$WRy!{d$p%*)^t- zM(bAu0Zbh`h{wbOthY~I+3GGS^Jq$=T5;gMdl~Fu+EF_%CVL&f8X~&LIod~L^F1#~ zsXI*L5uj6pmktS*T0m#PtDN@6uEH!6(*9 zm9%gQ;ePU@1&_}-ou%usmp*MDnfQ^ADDgY)?R{A|qpr%oIDL(?A8f1R%LLvpM5WW}x#9jxTiCsM82fKCNoIuuyyD(&a+-0QcJ;@-^S<@uzCa)NK)di(2^ zPorwn^ca~IA8(GEOeUd*H&C{}vOU~6;Q6p-nKidt+|;Exl8)N$Lt6R7)1+iEK?l&` zz)Ob;OReE>V#_wnX~dmMteCE2~7pH*T6eAnLefT8iQs{VMfnb%<88- zi)&w&<|TwO&0-2yn95sNS^3D|S+FPZ$68%L*Zd1k^9~J`y1che8GeZOh0s*t`~cs6 z_CA$dAMs9uL02i(k#~M?nKU>@3$-#&d{G?pE4XOVP*;YmI?Peq?akPm&kWTZGx)!% z&~e_8XzBsF=kU^@!%`u#2BMK$*6PlI9W*R4=aRjf9{VoQTPH8b+n3a9nU z33!QseG>+#2nm{cwthE}B`|ge82bu1>Coe!+g-03I1uDS2Z+GX)QUTbtbnoKxp3ek z0`^DzegYy0H1#czdY7wa1B|61{h#ymU!No7K#=@CAVP+wE&_A?E+SiCEMgp-M8H0X z&2vD60!?iPHh%6RvIEB2Xa7I{BkjMMN5J04p)DXng{JZXsdo|C17jIW;3NX}JEV*O j5gIggx%h4(2Vm?DFcvOfYrr0dmk}UBho+X@QS`q61hT$Z literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test new file mode 100644 index 0000000000..f150ec2a35 --- /dev/null +++ b/testing/btest/bifs/routing0_data_to_addrs.test @@ -0,0 +1,9 @@ +# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +event ipv6_ext_headers(c: connection, p: pkt_hdr) + { + for ( h in p$ip6$routing ) + if ( p$ip6$routing[h]$rtype == 0 ) + print routing0_data_to_addrs(p$ip6$routing[h]$data); + } diff --git a/testing/btest/core/ipv6_esp.test b/testing/btest/core/ipv6_esp.test new file mode 100644 index 0000000000..b606c23400 --- /dev/null +++ b/testing/btest/core/ipv6_esp.test @@ -0,0 +1,10 @@ +# @TEST-EXEC: bro -r $TRACES/ip6_esp.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# Just check that the event is raised correctly for a packet containing +# ESP extension headers. + +event esp_packet(p: pkt_hdr) + { + print p; + } diff --git a/testing/btest/core/ipv6_ext_headers.test b/testing/btest/core/ipv6_ext_headers.test new file mode 100644 index 0000000000..170a67bc72 --- /dev/null +++ b/testing/btest/core/ipv6_ext_headers.test @@ -0,0 +1,10 @@ +# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# Just check that the event is raised correctly for a packet containing +# extension headers. + +event ipv6_ext_headers(c: connection, p: pkt_hdr) + { + print p; + } From 94864da465a134bea251461adf588442e2d6d2bd Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 14 Mar 2012 15:25:08 -0500 Subject: [PATCH 10/27] Update documentation for new syntax of IPv6 literals. --- doc/scripts/builtins.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/scripts/builtins.rst b/doc/scripts/builtins.rst index 5da551ed1f..30b344ca6b 100644 --- a/doc/scripts/builtins.rst +++ b/doc/scripts/builtins.rst @@ -162,7 +162,11 @@ The Bro scripting language supports the following built-in types. ``A1.A2.A3.A4``, where Ai all lie between 0 and 255. IPv6 address constants are written as colon-separated hexadecimal form - as described by :rfc:`2373`. + as described by :rfc:`2373`, but additionally encased in square brackets. + The mixed notation with embedded IPv4 addresses as dotted-quads in the + lower 32 bits is also allowed. + Some examples: ``[2001:db8::1]``, ``[::ffff:192.168.1.100]``, or + ``[aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222]``. Hostname constants can also be used, but since a hostname can correspond to multiple IP addresses, the type of such variable is a @@ -196,7 +200,7 @@ The Bro scripting language supports the following built-in types. A type representing a block of IP addresses in CIDR notation. A ``subnet`` constant is written as an :bro:type:`addr` followed by a slash (/) and then the network prefix size specified as a decimal - number. For example, ``192.168.0.0/16``. + number. For example, ``192.168.0.0/16`` or ``[fe80::]/64``. .. bro:type:: any From 667487cec927bcdba148f5a58d5dbc86f723e48f Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 19 Mar 2012 11:26:31 -0500 Subject: [PATCH 11/27] Adapt FreeBSD's inet_ntop implementation for internal use. So we get consistent text representations of IPv6 addresses across platforms. --- src/CMakeLists.txt | 1 + src/IPAddr.cc | 5 +- src/RemoteSerializer.cc | 3 +- src/bro_inet_ntop.c | 189 ++++++++++++++++++ src/bro_inet_ntop.h | 18 ++ .../Baseline/language.ipv6-literals/output | 2 + testing/btest/language/ipv6-literals.bro | 2 + 7 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/bro_inet_ntop.c create mode 100644 src/bro_inet_ntop.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d51211f0d1..785001b920 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -402,6 +402,7 @@ set(bro_SRCS XDR.cc ZIP.cc bsd-getopt-long.c + bro_inet_ntop.c cq.c md5.c patricia.c diff --git a/src/IPAddr.cc b/src/IPAddr.cc index ff124025f9..52c3f9b35c 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -6,6 +6,7 @@ #include "Reporter.h" #include "Conn.h" #include "DPM.h" +#include "bro_inet_ntop.h" const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -159,7 +160,7 @@ string IPAddr::AsString() const { char s[INET_ADDRSTRLEN]; - if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) + if ( ! bro_inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) ) return " +#include +#include + +#include +#include +#include + +#include +#include +#include + +/*% + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *bro_inet_ntop4(const u_char *src, char *dst, socklen_t size); +static const char *bro_inet_ntop6(const u_char *src, char *dst, socklen_t size); + +/* char * + * bro_inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +bro_inet_ntop(int af, const void * __restrict src, char * __restrict dst, + socklen_t size) +{ + switch (af) { + case AF_INET: + return (bro_inet_ntop4(src, dst, size)); + case AF_INET6: + return (bro_inet_ntop6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * bro_inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. Modified by Jon Siwek, 2012, to replace strlcpy + */ +static const char * +bro_inet_ntop4(const u_char *src, char *dst, socklen_t size) +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + int l; + + l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || (socklen_t) l >= size) { + errno = ENOSPC; + return (NULL); + } + strncpy(dst, tmp, size - 1); + dst[size - 1] = 0; + return (dst); +} + +/* const char * + * bro_inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. Modified by Jon Siwek, 2012, for IPv4-translated format + */ +static const char * +bro_inet_ntop6(const u_char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff) || + (best.len == 4 && words[4] == 0xffff && words[5] == 0))) { + if (!bro_inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += sprintf(tp, "%x", words[i]); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((socklen_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} diff --git a/src/bro_inet_ntop.h b/src/bro_inet_ntop.h new file mode 100644 index 0000000000..00326b092e --- /dev/null +++ b/src/bro_inet_ntop.h @@ -0,0 +1,18 @@ +#ifndef BRO_INET_NTOP_H +#define BRO_INET_NTOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +const char * +bro_inet_ntop(int af, const void * __restrict src, char * __restrict dst, + socklen_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/testing/btest/Baseline/language.ipv6-literals/output b/testing/btest/Baseline/language.ipv6-literals/output index f2b9a985f0..8542af7f91 100644 --- a/testing/btest/Baseline/language.ipv6-literals/output +++ b/testing/btest/Baseline/language.ipv6-literals/output @@ -15,8 +15,10 @@ aaaa::ffff 192.168.1.100 ffff::c0a8:164 ::192.168.1.100 +::ffff:0:192.168.1.100 805b:2d9d:dc28::fc57:d4c8:1fff aaaa::bbbb aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222 aaaa:bbbb:cccc:dddd:eeee:ffff:1:2222 aaaa:bbbb:cccc:dddd:eeee:ffff:0:2222 +aaaa:bbbb:cccc:dddd:eeee::2222 diff --git a/testing/btest/language/ipv6-literals.bro b/testing/btest/language/ipv6-literals.bro index 6f1f9d59fb..004d104c6e 100644 --- a/testing/btest/language/ipv6-literals.bro +++ b/testing/btest/language/ipv6-literals.bro @@ -20,11 +20,13 @@ v[|v|] = [aaaa:0::ffff]; v[|v|] = [::ffff:192.168.1.100]; v[|v|] = [ffff::192.168.1.100]; v[|v|] = [::192.168.1.100]; +v[|v|] = [::ffff:0:192.168.1.100]; v[|v|] = [805B:2D9D:DC28::FC57:212.200.31.255]; v[|v|] = [0xaaaa::bbbb]; v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222]; v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:1:2222]; v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:0:2222]; +v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:0:0:2222]; for (i in v) print v[i]; From 1c1d6570395432b9bfef8fb9ab1c27f02491f754 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 20 Mar 2012 15:38:37 -0500 Subject: [PATCH 12/27] Changes to IPv6 ext. header parsing (addresses #795). In response to feedback from Robin: - rename "ip_hdr" to "ip4_hdr" - pkt_hdr$ip6 is now of type "ip6_hdr" instead of "ip6_hdr_chain" - "ip6_hdr_chain" no longer contains an "ip6_hdr" field, instead it's the other way around, "ip6_hdr" contains an "ip6_hdr_chain" - other internal refactoring --- scripts/base/init-bare.bro | 108 ++++-- src/Frag.cc | 18 +- src/IP.cc | 345 +++++++++--------- src/IP.h | 190 +++++----- src/PacketSort.cc | 5 +- src/Sessions.cc | 16 + testing/btest/Baseline/core.ipv6-frag/output | 10 +- testing/btest/Baseline/core.ipv6_esp/output | 240 ++++++------ .../Baseline/core.ipv6_ext_headers/output | 2 +- .../btest/bifs/routing0_data_to_addrs.test | 6 +- 10 files changed, 491 insertions(+), 449 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 98da9f331d..42215839c0 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -934,6 +934,10 @@ const ICMP_UNREACH_ADMIN_PROHIB = 13; ##< Adminstratively prohibited. # discarders. # todo::these should go into an enum to make them autodoc'able const IPPROTO_IP = 0; ##< Dummy for IP. [Robin] Rename to IPPROTO_IP4? +# [Jon] I'd say leave it be or remove it because from +# IPPROTO_IPV4 can actually be the same as IPPROTO_IPIP (4)... +# IPPROTO_IP seems to be just for use with the socket API and not +# actually identifying protocol numbers in packet headers const IPPROTO_ICMP = 1; ##< Control message protocol. const IPPROTO_IGMP = 2; ##< Group management protocol. const IPPROTO_IPIP = 4; ##< IP encapsulation in IP. @@ -944,6 +948,13 @@ const IPPROTO_RAW = 255; ##< Raw IP packet. # Definitions for IPv6 extension headers. # [Robin] Do we need a constant for unknown extensions? +# [Jon] I don't think so, these constants are just conveniences to improve +# script readability, but they also identify the actual assigned protocol +# number of the header type. If the core were to actually pass to the +# script-layer a next-header value of something we don't know about yet, +# that value would be the actual value seen in the packet, not something +# we should make up. We could provide a "KNOWN_PROTOCOLS" set for +# convenience that one could check membership against. const IPPROTO_HOPOPTS = 0; ##< IPv6 hop-by-hop-options header. const IPPROTO_ROUTING = 43; ##< IPv6 routing header. const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. @@ -952,20 +963,6 @@ const IPPROTO_AH = 51; ##< IPv6 authentication header. const IPPROTO_NONE = 59; ##< IPv6 no next header. const IPPROTO_DSTOPTS = 60; ##< IPv6 destination options header. -## Values extracted from an IPv6 header. -## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts ip6_routing -## ip6_fragment ip6_ah ip6_esp -type ip6_hdr: record { - class: count; ##< Traffic class. - flow: count; ##< Flow label. - len: count; ##< Payload length. - nxt: count; ##< Next header (RFC 1700 assigned number). # [Robin] That's just the IPPROTO_* constant right. Then we should refer to them. - hlim: count; ##< Hop limit. - src: addr; ##< Source address. - dst: addr; ##< Destination address. -}; - ## Values extracted from an IPv6 extension header's (e.g. hop-by-hop or ## destination option headers) option field. ## @@ -978,9 +975,10 @@ type ip6_option: record { ## Values extracted from an IPv6 Hop-by-Hop options extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain ip6_option +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain ip6_option type ip6_hopopts: record { - ## Next header (RFC 1700 assigned number). + ## Protocol number of the next header (RFC 1700 et seq., IANA assigned + ## number), e.g. :bro:id:`IPPROTO_ICMP`. nxt: count; ## Length of header in 8-octet units, excluding first unit. len: count; @@ -990,9 +988,10 @@ type ip6_hopopts: record { ## Values extracted from an IPv6 Destination options extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain ip6_option +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain ip6_option type ip6_dstopts: record { - ## Next header (RFC 1700 assigned number). + ## Protocol number of the next header (RFC 1700 et seq., IANA assigned + ## number), e.g. :bro:id:`IPPROTO_ICMP`. nxt: count; ## Length of header in 8-octet units, excluding first unit. len: count; @@ -1002,9 +1001,10 @@ type ip6_dstopts: record { ## Values extracted from an IPv6 Routing extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain type ip6_routing: record { - ## Next header (RFC 1700 assigned number). + ## Protocol number of the next header (RFC 1700 et seq., IANA assigned + ## number), e.g. :bro:id:`IPPROTO_ICMP`. nxt: count; ## Length of header in 8-octet units, excluding first unit. len: count; @@ -1018,9 +1018,10 @@ type ip6_routing: record { ## Values extracted from an IPv6 Fragment extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain type ip6_fragment: record { - ## Next header (RFC 1700 assigned number). + ## Protocol number of the next header (RFC 1700 et seq., IANA assigned + ## number), e.g. :bro:id:`IPPROTO_ICMP`. nxt: count; ## 8-bit reserved field. rsv1: count; @@ -1036,9 +1037,10 @@ type ip6_fragment: record { ## Values extracted from an IPv6 Authentication extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain type ip6_ah: record { - ## Next header (RFC 1700 assigned number). # [Robin] Same as above. + ## Protocol number of the next header (RFC 1700 et seq., IANA assigned + ## number), e.g. :bro:id:`IPPROTO_ICMP`. nxt: count; ## Length of header in 4-octet units, excluding first two units. len: count; @@ -1054,7 +1056,7 @@ type ip6_ah: record { ## Values extracted from an IPv6 ESP extension header. ## -## .. bro:see:: pkt_hdr ip_hdr ip6_hdr ip6_hdr_chain +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain type ip6_esp: record { ## Security Parameters Index. spi: count; @@ -1064,20 +1066,24 @@ type ip6_esp: record { ## An IPv6 header chain. ## -## .. bro:see:: pkt_hdr ip_hdr -# -# [Robin] How about turning ip6_hdr_chain and ip6_hdr around, making the latter -# the top-level record that then contains an ip6_hdr_chain instance. That way, the -# pkt_hdr record would have ip4_hdr and ip6_hdr members, which seems more natural. +## .. bro:see:: pkt_hdr ip4_hdr # # [Robin] What happens to unknown extension headers? We should keep them too so that # one can at least identify what one can't analyze. +# [Jon] Currently, they show up as "unknown_protocol" weirds and those packets +# are skipped before any "new_packet" or "ipv6_ext_headers" events are +# raised as those depend on a connection parameter which can't be +# created since we can't parse past unknown extension headers to get +# at the upper layer protocol. Does that seem reasonable for at +# being able to identify things that couldn't be analyzed? type ip6_hdr_chain: record { # [Robin] This looses the order of the headers (partially at least, even with ext_order I believe). # Not sure how to do it differently, but can order be important for us? + # [Jon] I do think order can be interesting as RFC 2460 specifies some + # ordering constraints, and I think I provide enough info in this + # record for one to reconstruct the order. Reread my new comments + # for the "ext_order" field below and see if you change your mind. - ## The main IPv6 header. - hdr: ip6_hdr; ## Hop-by-hop option extension header. hopopts: vector of ip6_hopopts; ## Destination option extension headers. @@ -1091,17 +1097,39 @@ type ip6_hdr_chain: record { ## Encapsulating security payload headers. esp: vector of ip6_esp; - ## Order of extension headers identified by RFC 1700 assigned numbers. - # [Robin] I don't understand how this works. + ## Order of extension headers as seen in the packet header. + ## The value at an index indicates the protocol number (RFC 1700 et seq., + ## IANA assigned number) of the header at that same position in the chain. + ## e.g. if :bro:id:`IPPROTO_DSTOPTS` is at index 0 and index 2 and + ## :bro:id:`IPPROTO_ROUTING` is at index 1, then the order of the headers + ## in the chain is the header at index 0 of *dstopts* followed by + ## the header at index 0 of *routing* and then the header at index 1 of + ## *dstopts* (tracking of duplicate header types to know where to + ## index into each vector would be up to the script following the chain). ext_order: vector of count; }; +## Values extracted from an IPv6 header. +## +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts +## ip6_routing ip6_fragment ip6_ah ip6_esp +type ip6_hdr: record { + class: count; ##< Traffic class. + flow: count; ##< Flow label. + len: count; ##< Payload length. + nxt: count; ##< Protocol number of the next header + ##< (RFC 1700 et seq., IANA assigned number), e.g. + ##< :bro:id:`IPPROTO_ICMP`. + hlim: count; ##< Hop limit. + src: addr; ##< Source address. + dst: addr; ##< Destination address. + exts: ip6_hdr_chain;##< Extension header chain. +}; + ## Values extracted from an IPv4 header. ## ## .. bro:see:: pkt_hdr ip6_hdr discarder_check_ip -## -# [Robin] Rename to ip4_hdr? -type ip_hdr: record { +type ip4_hdr: record { hl: count; ##< Header length in bytes. tos: count; ##< Type of service. len: count; ##< Total length. @@ -1159,9 +1187,11 @@ type icmp_hdr: record { # # [Robin] Add flags saying whether it's v4/v6, tcp/udp/icmp? The day will come where # we can't infer that from the connection anymore (tunnels). +# [Jon] I'm not sure what you mean, doesn't checking result of ?$ operator +# always work for finding out protocols involved? type pkt_hdr: record { - ip: ip_hdr &optional; ##< The IPv4 header if an IPv4 packet. - ip6: ip6_hdr_chain &optional; ##< The IPv6 header chain if an IPv6 packet. + ip: ip4_hdr &optional; ##< The IPv4 header if an IPv4 packet. + ip6: ip6_hdr &optional; ##< The IPv6 header if an IPv6 packet. tcp: tcp_hdr &optional; ##< The TCP header if a TCP packet. udp: udp_hdr &optional; ##< The UDP header if a UDP packet. icmp: icmp_hdr &optional; ##< The ICMP header if an ICMP packet. diff --git a/src/Frag.cc b/src/Frag.cc index 68c5c108f1..5fcad35560 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -34,10 +34,13 @@ FragReassembler::FragReassembler(NetSessions* arg_s, key = k; // [Robin] Can't we merge these two cases now? + // [Jon] I think we'll always have to check v4 versus v6 to get the correct + // proto_hdr_len unless IP_Hdr::HdrLen itself makes a special case for + // IPv6 fragments (but that seems more confusing to me) const struct ip* ip4 = ip->IP4_Hdr(); if ( ip4 ) { - proto_hdr_len = ip4->ip_hl * 4; // [Robin] HdrLen? + proto_hdr_len = ip->HdrLen(); proto_hdr = new u_char[64]; // max IP header + slop // Don't do a structure copy - need to pick up options, too. memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len); @@ -247,12 +250,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) reassembled_pkt = new IP_Hdr(reassem4, true); } - // [Robin] Please always check for IP version explicitly, like here - // do "if ... ip_v == 6", and then catch other values via - // weird/errors. Even of it shouldn't happen (because of earlier - // checks), it's better to be safe. I believe there are more places - // like this elsewhere, please check. - else + else if ( ((const struct ip*)pkt_start)->ip_v == 6 ) { struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40); @@ -260,6 +258,12 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) reassembled_pkt = new IP_Hdr(reassem6, true, chain); } + else + { + reporter->InternalError("bad IP version in fragment reassembly"); + } + + DeleteTimer(); } diff --git a/src/IP.cc b/src/IP.cc index 77797ece8f..9dcb372d3f 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -5,7 +5,7 @@ #include "Val.h" #include "Var.h" -static RecordType* ip_hdr_type = 0; +static RecordType* ip4_hdr_type = 0; static RecordType* ip6_hdr_type = 0; static RecordType* ip6_hdr_chain_type = 0; static RecordType* ip6_option_type = 0; @@ -22,20 +22,6 @@ static inline RecordType* hdrType(RecordType*& type, const char* name) return type; } -RecordVal* IPv6_Hdr::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_hdr_type, "ip6_hdr")); - const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; - rv->Assign(0, new Val((ntohl(ip6->ip6_flow) & 0x0ff00000)>>20, TYPE_COUNT)); - rv->Assign(1, new Val(ntohl(ip6->ip6_flow) & 0x000fffff, TYPE_COUNT)); - rv->Assign(2, new Val(ntohs(ip6->ip6_plen), TYPE_COUNT)); - rv->Assign(3, new Val(ip6->ip6_nxt, TYPE_COUNT)); - rv->Assign(4, new Val(ip6->ip6_hlim, TYPE_COUNT)); - rv->Assign(5, new AddrVal(ip6->ip6_src)); - rv->Assign(6, new AddrVal(ip6->ip6_dst)); - return rv; - } - static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) { VectorVal* vv = new VectorVal(new VectorType( @@ -71,73 +57,100 @@ static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) return vv; } -RecordVal* IPv6_HopOpts::BuildRecordVal() const +RecordVal* IPv6_Hdr::BuildRecordVal() const { - RecordVal* rv = new RecordVal(hdrType(ip6_hopopts_type, "ip6_hopopts")); - const struct ip6_hbh* hbh = (const struct ip6_hbh*)data; - rv->Assign(0, new Val(hbh->ip6h_nxt, TYPE_COUNT)); - rv->Assign(1, new Val(hbh->ip6h_len, TYPE_COUNT)); - uint16 off = 2 * sizeof(uint8); - rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); - return rv; + RecordVal* rv = 0; + + switch ( type ) { + case IPPROTO_IPV6: + { + rv = new RecordVal(hdrType(ip6_hdr_type, "ip6_hdr")); + const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; + rv->Assign(0, new Val((ntohl(ip6->ip6_flow) & 0x0ff00000)>>20, TYPE_COUNT)); + rv->Assign(1, new Val(ntohl(ip6->ip6_flow) & 0x000fffff, TYPE_COUNT)); + rv->Assign(2, new Val(ntohs(ip6->ip6_plen), TYPE_COUNT)); + rv->Assign(3, new Val(ip6->ip6_nxt, TYPE_COUNT)); + rv->Assign(4, new Val(ip6->ip6_hlim, TYPE_COUNT)); + rv->Assign(5, new AddrVal(ip6->ip6_src)); + rv->Assign(6, new AddrVal(ip6->ip6_dst)); + } + break; + + case IPPROTO_HOPOPTS: + { + rv = new RecordVal(hdrType(ip6_hopopts_type, "ip6_hopopts")); + const struct ip6_hbh* hbh = (const struct ip6_hbh*)data; + rv->Assign(0, new Val(hbh->ip6h_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(hbh->ip6h_len, TYPE_COUNT)); + uint16 off = 2 * sizeof(uint8); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + + } + break; + + case IPPROTO_DSTOPTS: + { + rv = new RecordVal(hdrType(ip6_dstopts_type, "ip6_dstopts")); + const struct ip6_dest* dst = (const struct ip6_dest*)data; + rv->Assign(0, new Val(dst->ip6d_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(dst->ip6d_len, TYPE_COUNT)); + uint16 off = 2 * sizeof(uint8); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + } + break; + + case IPPROTO_ROUTING: + { + rv = new RecordVal(hdrType(ip6_routing_type, "ip6_routing")); + const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data; + rv->Assign(0, new Val(rt->ip6r_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(rt->ip6r_len, TYPE_COUNT)); + rv->Assign(2, new Val(rt->ip6r_type, TYPE_COUNT)); + rv->Assign(3, new Val(rt->ip6r_segleft, TYPE_COUNT)); + uint16 off = 4 * sizeof(uint8); + rv->Assign(4, new StringVal(new BroString(data + off, Length() - off, 1))); + } + break; + + case IPPROTO_FRAGMENT: + { + rv = new RecordVal(hdrType(ip6_fragment_type, "ip6_fragment")); + const struct ip6_frag* frag = (const struct ip6_frag*)data; + rv->Assign(0, new Val(frag->ip6f_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(frag->ip6f_reserved, TYPE_COUNT)); + rv->Assign(2, new Val((ntohs(frag->ip6f_offlg) & 0xfff8)>>3, TYPE_COUNT)); + rv->Assign(3, new Val((ntohs(frag->ip6f_offlg) & 0x0006)>>1, TYPE_COUNT)); + rv->Assign(4, new Val(ntohs(frag->ip6f_offlg) & 0x0001, TYPE_BOOL)); + rv->Assign(5, new Val(ntohl(frag->ip6f_ident), TYPE_COUNT)); + } + break; + + case IPPROTO_AH: + { + rv = new RecordVal(hdrType(ip6_ah_type, "ip6_ah")); + rv->Assign(0, new Val(((ip6_ext*)data)->ip6e_nxt, TYPE_COUNT)); + rv->Assign(1, new Val(((ip6_ext*)data)->ip6e_len, TYPE_COUNT)); + rv->Assign(2, new Val(ntohs(((uint16*)data)[1]), TYPE_COUNT)); + rv->Assign(3, new Val(ntohl(((uint32*)data)[1]), TYPE_COUNT)); + rv->Assign(4, new Val(ntohl(((uint32*)data)[2]), TYPE_COUNT)); + uint16 off = 3 * sizeof(uint32); + rv->Assign(5, new StringVal(new BroString(data + off, Length() - off, 1))); + } + break; + + case IPPROTO_ESP: + { + rv = new RecordVal(hdrType(ip6_esp_type, "ip6_esp")); + const uint32* esp = (const uint32*)data; + rv->Assign(0, new Val(ntohl(esp[0]), TYPE_COUNT)); + rv->Assign(1, new Val(ntohl(esp[1]), TYPE_COUNT)); + } + break; + + default: + break; } -RecordVal* IPv6_DstOpts::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_dstopts_type, "ip6_dstopts")); - const struct ip6_dest* dst = (const struct ip6_dest*)data; - rv->Assign(0, new Val(dst->ip6d_nxt, TYPE_COUNT)); - rv->Assign(1, new Val(dst->ip6d_len, TYPE_COUNT)); - uint16 off = 2 * sizeof(uint8); - rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); - return rv; - } - -RecordVal* IPv6_Routing::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_routing_type, "ip6_routing")); - const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data; - rv->Assign(0, new Val(rt->ip6r_nxt, TYPE_COUNT)); - rv->Assign(1, new Val(rt->ip6r_len, TYPE_COUNT)); - rv->Assign(2, new Val(rt->ip6r_type, TYPE_COUNT)); - rv->Assign(3, new Val(rt->ip6r_segleft, TYPE_COUNT)); - uint16 off = 4 * sizeof(uint8); - rv->Assign(4, new StringVal(new BroString(data + off, Length() - off, 1))); - return rv; - } - -RecordVal* IPv6_Fragment::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_fragment_type, "ip6_fragment")); - const struct ip6_frag* frag = (const struct ip6_frag*)data; - rv->Assign(0, new Val(frag->ip6f_nxt, TYPE_COUNT)); - rv->Assign(1, new Val(frag->ip6f_reserved, TYPE_COUNT)); - rv->Assign(2, new Val((ntohs(frag->ip6f_offlg) & 0xfff8)>>3, TYPE_COUNT)); - rv->Assign(3, new Val((ntohs(frag->ip6f_offlg) & 0x0006)>>1, TYPE_COUNT)); - rv->Assign(4, new Val(ntohs(frag->ip6f_offlg) & 0x0001, TYPE_BOOL)); - rv->Assign(5, new Val(ntohl(frag->ip6f_ident), TYPE_COUNT)); - return rv; - } - -RecordVal* IPv6_AH::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_ah_type, "ip6_ah")); - rv->Assign(0, new Val(((ip6_ext*)data)->ip6e_nxt, TYPE_COUNT)); - rv->Assign(1, new Val(((ip6_ext*)data)->ip6e_len, TYPE_COUNT)); - rv->Assign(2, new Val(ntohs(((uint16*)data)[1]), TYPE_COUNT)); - rv->Assign(3, new Val(ntohl(((uint32*)data)[1]), TYPE_COUNT)); - rv->Assign(4, new Val(ntohl(((uint32*)data)[2]), TYPE_COUNT)); - uint16 off = 3 * sizeof(uint32); - rv->Assign(5, new StringVal(new BroString(data + off, Length() - off, 1))); - return rv; - } - -RecordVal* IPv6_ESP::BuildRecordVal() const - { - RecordVal* rv = new RecordVal(hdrType(ip6_esp_type, "ip6_esp")); - const uint32* esp = (const uint32*)data; - rv->Assign(0, new Val(ntohl(esp[0]), TYPE_COUNT)); - rv->Assign(1, new Val(ntohl(esp[1]), TYPE_COUNT)); return rv; } @@ -145,22 +158,9 @@ RecordVal* IP_Hdr::BuildIPHdrVal() const { RecordVal* rval = 0; - if ( ! ip_hdr_type ) - { - ip_hdr_type = internal_type("ip_hdr")->AsRecordType(); - ip6_hdr_type = internal_type("ip6_hdr")->AsRecordType(); - ip6_hdr_chain_type = internal_type("ip6_hdr_chain")->AsRecordType(); - ip6_hopopts_type = internal_type("ip6_hopopts")->AsRecordType(); - ip6_dstopts_type = internal_type("ip6_dstopts")->AsRecordType(); - ip6_routing_type = internal_type("ip6_routing")->AsRecordType(); - ip6_fragment_type = internal_type("ip6_fragment")->AsRecordType(); - ip6_ah_type = internal_type("ip6_ah")->AsRecordType(); - ip6_esp_type = internal_type("ip6_esp")->AsRecordType(); - } - if ( ip4 ) { - rval = new RecordVal(ip_hdr_type); + rval = new RecordVal(hdrType(ip4_hdr_type, "ip4_hdr")); rval->Assign(0, new Val(ip4->ip_hl * 4, TYPE_COUNT)); rval->Assign(1, new Val(ip4->ip_tos, TYPE_COUNT)); rval->Assign(2, new Val(ntohs(ip4->ip_len), TYPE_COUNT)); @@ -172,55 +172,8 @@ RecordVal* IP_Hdr::BuildIPHdrVal() const } else { - rval = new RecordVal(ip6_hdr_chain_type); - - VectorVal* hopopts = new VectorVal(new VectorType(ip6_hopopts_type->Ref())); - VectorVal* dstopts = new VectorVal(new VectorType(ip6_dstopts_type->Ref())); - VectorVal* routing = new VectorVal(new VectorType(ip6_routing_type->Ref())); - VectorVal* fragment = new VectorVal(new VectorType(ip6_fragment_type->Ref())); - VectorVal* ah = new VectorVal(new VectorType(ip6_ah_type->Ref())); - VectorVal* esp = new VectorVal(new VectorType(ip6_esp_type->Ref())); - VectorVal* order = new VectorVal(new VectorType(base_type(TYPE_COUNT))); - - for ( size_t i = 1; i < ip6_hdrs->Size(); ++i ) - { - RecordVal* v = ((*ip6_hdrs)[i])->BuildRecordVal(); - uint8 type = ((*ip6_hdrs)[i])->Type(); - switch (type) { - case IPPROTO_HOPOPTS: - hopopts->Assign(hopopts->Size(), v, 0); - break; - case IPPROTO_ROUTING: - routing->Assign(routing->Size(), v, 0); - break; - case IPPROTO_DSTOPTS: - dstopts->Assign(dstopts->Size(), v, 0); - break; - case IPPROTO_FRAGMENT: - fragment->Assign(fragment->Size(), v, 0); - break; - case IPPROTO_AH: - ah->Assign(ah->Size(), v, 0); - break; - case IPPROTO_ESP: - esp->Assign(esp->Size(), v, 0); - break; - case IPPROTO_IPV6: - default: - reporter->InternalError("pkt_hdr assigned bad header %d", type); - break; - } - order->Assign(i-1, new Val(type, TYPE_COUNT), 0); - } - - rval->Assign(0, ((*ip6_hdrs)[0])->BuildRecordVal()); - rval->Assign(1, hopopts); - rval->Assign(2, dstopts); - rval->Assign(3, routing); - rval->Assign(4, fragment); - rval->Assign(5, ah); - rval->Assign(6, esp); - rval->Assign(7, order); + rval = ((*ip6_hdrs)[0])->BuildRecordVal(); + rval->Assign(7, ip6_hdrs->BuildRecordVal()); } return rval; @@ -308,34 +261,6 @@ RecordVal* IP_Hdr::BuildPktHdrVal() const return pkt_hdr; } -static inline IPv6_Hdr* getIPv6Header(uint8 type, const u_char* d, - bool set_next = false, uint16 nxt = 0) - { - switch (type) { - case IPPROTO_IPV6: - return set_next ? new IPv6_Hdr(d, nxt) : new IPv6_Hdr(d); - case IPPROTO_HOPOPTS: - return set_next ? new IPv6_HopOpts(d, nxt) : new IPv6_HopOpts(d); - case IPPROTO_ROUTING: - return set_next ? new IPv6_Routing(d, nxt) : new IPv6_Routing(d); - case IPPROTO_DSTOPTS: - return set_next ? new IPv6_DstOpts(d, nxt) : new IPv6_DstOpts(d); - case IPPROTO_FRAGMENT: - return set_next ? new IPv6_Fragment(d, nxt) : new IPv6_Fragment(d); - case IPPROTO_AH: - return set_next ? new IPv6_AH(d, nxt) : new IPv6_AH(d); - case IPPROTO_ESP: - return new IPv6_ESP(d); // never able to set ESP header's next - default: - // should never get here if calls are protected by isIPv6ExtHeader() - reporter->InternalError("Unknown IPv6 header type: %d", type); - break; - } - // can't be reached - assert(false); - return 0; - } - static inline bool isIPv6ExtHeader(uint8 type) { switch (type) { @@ -361,12 +286,86 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) do { current_type = next_type; - chain.push_back(getIPv6Header(current_type, hdrs, set_next, next)); - next_type = chain[chain.size()-1]->NextHdr(); - uint16 len = chain[chain.size()-1]->Length(); + IPv6_Hdr* p = new IPv6_Hdr(current_type, hdrs); + + next_type = p->NextHdr(); + uint16 len = p->Length(); + + if ( set_next && next_type == IPPROTO_FRAGMENT ) + { + p->ChangeNext(next); + next_type = next; + } + + chain.push_back(p); + hdrs += len; length += len; } while ( current_type != IPPROTO_FRAGMENT && current_type != IPPROTO_ESP && isIPv6ExtHeader(next_type) ); } + +RecordVal* IPv6_Hdr_Chain::BuildRecordVal() const + { + if ( ! ip6_hdr_chain_type ) + { + ip6_hdr_chain_type = internal_type("ip6_hdr_chain")->AsRecordType(); + ip6_hopopts_type = internal_type("ip6_hopopts")->AsRecordType(); + ip6_dstopts_type = internal_type("ip6_dstopts")->AsRecordType(); + ip6_routing_type = internal_type("ip6_routing")->AsRecordType(); + ip6_fragment_type = internal_type("ip6_fragment")->AsRecordType(); + ip6_ah_type = internal_type("ip6_ah")->AsRecordType(); + ip6_esp_type = internal_type("ip6_esp")->AsRecordType(); + } + + RecordVal* rval = new RecordVal(ip6_hdr_chain_type); + + VectorVal* hopopts = new VectorVal(new VectorType(ip6_hopopts_type->Ref())); + VectorVal* dstopts = new VectorVal(new VectorType(ip6_dstopts_type->Ref())); + VectorVal* routing = new VectorVal(new VectorType(ip6_routing_type->Ref())); + VectorVal* fragment = new VectorVal(new VectorType(ip6_fragment_type->Ref())); + VectorVal* ah = new VectorVal(new VectorType(ip6_ah_type->Ref())); + VectorVal* esp = new VectorVal(new VectorType(ip6_esp_type->Ref())); + VectorVal* order = new VectorVal(new VectorType(base_type(TYPE_COUNT))); + + for ( size_t i = 1; i < chain.size(); ++i ) + { + RecordVal* v = chain[i]->BuildRecordVal(); + uint8 type = chain[i]->Type(); + switch (type) { + case IPPROTO_HOPOPTS: + hopopts->Assign(hopopts->Size(), v, 0); + break; + case IPPROTO_ROUTING: + routing->Assign(routing->Size(), v, 0); + break; + case IPPROTO_DSTOPTS: + dstopts->Assign(dstopts->Size(), v, 0); + break; + case IPPROTO_FRAGMENT: + fragment->Assign(fragment->Size(), v, 0); + break; + case IPPROTO_AH: + ah->Assign(ah->Size(), v, 0); + break; + case IPPROTO_ESP: + esp->Assign(esp->Size(), v, 0); + break; + case IPPROTO_IPV6: + default: + reporter->InternalError("pkt_hdr assigned bad header %d", type); + break; + } + order->Assign(i-1, new Val(type, TYPE_COUNT), 0); + } + + rval->Assign(0, hopopts); + rval->Assign(1, dstopts); + rval->Assign(2, routing); + rval->Assign(3, fragment); + rval->Assign(4, ah); + rval->Assign(5, esp); + rval->Assign(6, order); + return rval; + } diff --git a/src/IP.h b/src/IP.h index b876a2ac3b..5e5e3c0748 100644 --- a/src/IP.h +++ b/src/IP.h @@ -22,56 +22,94 @@ // members: we're creating/allocating those for every IPv6 packet, right? // // Any idea how to avoid these? +// +// [Jon] Seems fair enough to just remove the virtual method concern at this +// point by replacing the class hierarchy with some inline functions that +// do switch statements. I don't know what to do about the +// vector and ip6_hdrs data members being allocated for every +// IPv6 packet, maybe it's too early to try to optimize before we know +// the frequency at which extension headers appear in real IPv6 traffic? /** * Base class for IPv6 header/extensions. */ class IPv6_Hdr { public: - IPv6_Hdr() : type(0), data(0) {} - - /** - * Construct the main IPv6 header. - */ - IPv6_Hdr(const u_char* d) : type(IPPROTO_IPV6), data(d) {} - - /** - * Construct the main IPv6 header, but replace the next protocol field - * if it points to a fragment. - */ - IPv6_Hdr(const u_char* d, uint16 nxt) : type(IPPROTO_IPV6), data(d) - { - // [Robin]. This looks potentially dangerous as it's changing - // the data passed in, which the caller may not realize. From - // quick look, it's only used from Frag.cc, so that may be - // ok. But could we guard against accidental use somehome? - // Like making this protected and then declare a friend; or a - // seperate method ChangeNext(). (I saw it's used by derived - // classes so not sure wehat works best.) - if ( ((ip6_hdr*)data)->ip6_nxt == IPPROTO_FRAGMENT ) - ((ip6_hdr*)data)->ip6_nxt = nxt; - } - /** * Construct an IPv6 header or extension header from assigned type number. */ IPv6_Hdr(uint8 t, const u_char* d) : type(t), data(d) {} - virtual ~IPv6_Hdr() {} + /** + * Replace the value of the next protocol field. + */ + void ChangeNext(uint8 next_type) + { + switch ( type ) { + case IPPROTO_IPV6: + ((ip6_hdr*)data)->ip6_nxt = next_type; + break; + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + case IPPROTO_FRAGMENT: + case IPPROTO_AH: + ((ip6_ext*)data)->ip6e_nxt = next_type; + break; + case IPPROTO_ESP: + default: + break; + } + } + + ~IPv6_Hdr() {} /** * Returns the assigned IPv6 extension header type number of the header * that immediately follows this one. */ - virtual uint8 NextHdr() const { return ((ip6_hdr*)data)->ip6_nxt; } + uint8 NextHdr() const + { + switch ( type ) { + case IPPROTO_IPV6: + return ((ip6_hdr*)data)->ip6_nxt; + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + case IPPROTO_FRAGMENT: + case IPPROTO_AH: + return ((ip6_ext*)data)->ip6e_nxt; + case IPPROTO_ESP: + default: + return IPPROTO_NONE; + } + } /** * Returns the length of the header in bytes. */ - virtual uint16 Length() const { return 40; } + uint16 Length() const + { + switch ( type ) { + case IPPROTO_IPV6: + return 40; + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + return 8 + 8 * ((ip6_ext*)data)->ip6e_len; + case IPPROTO_FRAGMENT: + return 8; + case IPPROTO_AH: + return 8 + 4 * ((ip6_ext*)data)->ip6e_len; + case IPPROTO_ESP: + return 8; //encrypted payload begins after 8 bytes + default: + return 0; + } + } /** - * Returns the RFC 1700 assigned number indicating the header type. + * Returns the RFC 1700 et seq. IANA assigned number for the header. */ uint8 Type() const { return type; } @@ -83,75 +121,13 @@ public: /** * Returns the script-layer record representation of the header. */ - virtual RecordVal* BuildRecordVal() const; + RecordVal* BuildRecordVal() const; protected: uint8 type; const u_char* data; }; -class IPv6_Ext : public IPv6_Hdr { -public: - IPv6_Ext(uint16 type, const u_char* d) : IPv6_Hdr(type, d) {} - IPv6_Ext(uint16 type, const u_char* d, uint16 nxt) : IPv6_Hdr(type, d) - { - if ( ((ip6_ext*)data)->ip6e_nxt == IPPROTO_FRAGMENT ) - ((ip6_ext*)data)->ip6e_nxt = nxt; - } - uint8 NextHdr() const { return ((ip6_ext*)data)->ip6e_nxt; } - virtual uint16 Length() const = 0; - virtual RecordVal* BuildRecordVal() const = 0; -}; - -class IPv6_HopOpts : public IPv6_Ext { -public: - IPv6_HopOpts(const u_char* d) : IPv6_Ext(IPPROTO_HOPOPTS, d) {} - IPv6_HopOpts(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_HOPOPTS, d, n) {} - uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } - RecordVal* BuildRecordVal() const; -}; - -class IPv6_DstOpts : public IPv6_Ext { -public: - IPv6_DstOpts(const u_char* d) : IPv6_Ext(IPPROTO_DSTOPTS, d) {} - IPv6_DstOpts(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_DSTOPTS, d, n) {} - uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } - RecordVal* BuildRecordVal() const; -}; - -class IPv6_Routing : public IPv6_Ext { -public: - IPv6_Routing(const u_char* d) : IPv6_Ext(IPPROTO_ROUTING, d) {} - IPv6_Routing(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_ROUTING, d, n) {} - uint16 Length() const { return 8 + 8 * ((ip6_ext*)data)->ip6e_len; } - RecordVal* BuildRecordVal() const; -}; - -class IPv6_Fragment : public IPv6_Ext { -public: - IPv6_Fragment(const u_char* d) : IPv6_Ext(IPPROTO_FRAGMENT, d) {} - IPv6_Fragment(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_FRAGMENT, d, n) - {} - uint16 Length() const { return 8; } - RecordVal* BuildRecordVal() const; -}; - -class IPv6_AH : public IPv6_Ext { -public: - IPv6_AH(const u_char* d) : IPv6_Ext(IPPROTO_AH, d) {} - IPv6_AH(const u_char* d, uint16 n) : IPv6_Ext(IPPROTO_AH, d, n) {} - uint16 Length() const { return 8 + 4 * ((ip6_ext*)data)->ip6e_len; } - RecordVal* BuildRecordVal() const; -}; - -class IPv6_ESP : public IPv6_Ext { -public: - IPv6_ESP(const u_char* d) : IPv6_Ext(IPPROTO_ESP, d) {} - // encrypted payload begins after 8 bytes - uint16 Length() const { return 8; } - RecordVal* BuildRecordVal() const; -}; - class IPv6_Hdr_Chain { public: /** @@ -159,13 +135,6 @@ public: */ IPv6_Hdr_Chain(const struct ip6_hdr* ip6) { Init(ip6, false); } - /** - * Initializes the header chain from an IPv6 header structure, and replaces - * the first next protocol pointer field that points to a fragment header. - */ - IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) - { Init(ip6, true, next); } - ~IPv6_Hdr_Chain() { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; } @@ -218,7 +187,24 @@ public: { return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } + /** + * Returns an ip6_hdr_chain RecordVal that includes script-layer + * representation of all extension headers in the chain. + */ + RecordVal* BuildRecordVal() const; + protected: + // for access to protected ctor that changes next header values that + // point to a fragment + friend class FragReassembler; + + /** + * Initializes the header chain from an IPv6 header structure, and replaces + * the first next protocol pointer field that points to a fragment header. + */ + IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) + { Init(ip6, true, next); } + void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0); vector chain; @@ -237,8 +223,12 @@ public: ip6 = (const struct ip6_hdr*)p; ip6_hdrs = new IPv6_Hdr_Chain(ip6); } - else if ( arg_del ) - delete [] p; + else + { + if ( arg_del ) + delete [] p; + reporter->InternalError("bad IP version in IP_Hdr ctor"); + } } IP_Hdr(const struct ip* arg_ip4, bool arg_del) diff --git a/src/PacketSort.cc b/src/PacketSort.cc index 7bfdaba9a0..aec7639f4a 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -28,8 +28,11 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, const struct ip* ip = (const struct ip*) (pkt + hdr_size); if ( ip->ip_v == 4 ) ip_hdr = new IP_Hdr(ip, false); - else + else if ( ip->ip_v == 6 ) ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false); + else + // weird will be generated later in NetSessions::NextPacket + return; if ( ip_hdr->NextProto() == IPPROTO_TCP && // Note: can't sort fragmented packets diff --git a/src/Sessions.cc b/src/Sessions.cc index 675cc240c6..9e91fdc304 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -431,6 +431,11 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; // [Robin] dump_this_packet = 1 for non-ICMP/UDP/TCP removed here. Why? + // [Jon] The default case of the "switch ( proto )" calls Weird() which + // should set dump_this_packet = 1. The old code also returned + // at this point for non-ICMP/UDP/TCP, but for IPv6 fragments + // we need to do the reassembly first before knowing for sure what + // upper-layer protocol it is. FragReassembler* f = 0; @@ -468,8 +473,12 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, caplen -= ip_hdr_len; // [Robin] Does ESP need to be the last header? + // [Jon] In terms of what we try to parse, yes, we can't go any further + // in parsing a header chain once we reach an ESP one since + // encrypted payload immediately follows. if ( ip_hdr->LastHeader() == IPPROTO_ESP ) { + dump_this_packet = 1; if ( esp_packet ) { val_list* vl = new val_list(); @@ -491,6 +500,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, // [Robin] The Remove(f) used to be here, while it's now before every // return statement. I'm not seeing why? + // [Jon] That Remove(f) is still here above in the CheckHeaderTrunc() + // conditional that's just a refactoring of the old code. + // The reason why it's not done unconditionally after the reassembly + // is because doing that could cause the object that ip_hdr points + // to to be freed when we still need to use that below. + // I added Remove(f)'s before other "abnormal" return points that + // looked like they'd otherwise leak the memory. const u_char* data = ip_hdr->Payload(); diff --git a/testing/btest/Baseline/core.ipv6-frag/output b/testing/btest/Baseline/core.ipv6-frag/output index 5020d94e8d..80c1a2cc93 100644 --- a/testing/btest/Baseline/core.ipv6-frag/output +++ b/testing/btest/Baseline/core.ipv6-frag/output @@ -1,5 +1,5 @@ -ip6=[hdr=[class=0, flow=0, len=81, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51850/udp, dport=53/udp, ulen=81] -ip6=[hdr=[class=0, flow=0, len=331, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=53/udp, dport=51850/udp, ulen=331] -ip6=[hdr=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] -ip6=[hdr=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] -ip6=[hdr=[class=0, flow=0, len=3238, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]], udp = [sport=53/udp, dport=51851/udp, ulen=3238] +ip6=[class=0, flow=0, len=81, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51850/udp, dport=53/udp, ulen=81] +ip6=[class=0, flow=0, len=331, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=53/udp, dport=51850/udp, ulen=331] +ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[class=0, flow=0, len=3238, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=53/udp, dport=51851/udp, ulen=3238] diff --git a/testing/btest/Baseline/core.ipv6_esp/output b/testing/btest/Baseline/core.ipv6_esp/output index 645b4c8c56..db27689364 100644 --- a/testing/btest/Baseline/core.ipv6_esp/output +++ b/testing/btest/Baseline/core.ipv6_esp/output @@ -1,120 +1,120 @@ -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=1]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=2]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=3]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=4]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=5]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=6]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=7]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=8]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=9]], ext_order=[50]], tcp=, udp=, icmp=] -[ip=, ip6=[hdr=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25], hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=10]], ext_order=[50]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output index 4cc9c706ae..9348cc41c8 100644 --- a/testing/btest/Baseline/core.ipv6_ext_headers/output +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -1 +1 @@ -[ip=, ip6=[hdr=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b], hopopts=[[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]]], dstopts=[], routing=[[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B]], fragment=[], ah=[], esp=[], ext_order=[0, 43]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] +[ip=, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[hopopts=[[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]]], dstopts=[], routing=[[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B]], fragment=[], ah=[], esp=[], ext_order=[0, 43]]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test index f150ec2a35..eb6ebbc614 100644 --- a/testing/btest/bifs/routing0_data_to_addrs.test +++ b/testing/btest/bifs/routing0_data_to_addrs.test @@ -3,7 +3,7 @@ event ipv6_ext_headers(c: connection, p: pkt_hdr) { - for ( h in p$ip6$routing ) - if ( p$ip6$routing[h]$rtype == 0 ) - print routing0_data_to_addrs(p$ip6$routing[h]$data); + for ( h in p$ip6$exts$routing ) + if ( p$ip6$exts$routing[h]$rtype == 0 ) + print routing0_data_to_addrs(p$ip6$exts$routing[h]$data); } From c765f43fe3eb6fd4cb49b2b947654881a225e145 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 21 Mar 2012 10:32:39 -0500 Subject: [PATCH 13/27] Refactor script-layer IPv6 ext. header chain (addresses #795) This replaces the "ip6_hdr_chain" in the "ip6_hdr" record with a vector of "ip6_ext_hdr" to make it easier to traverse the chain. --- scripts/base/init-bare.bro | 70 ++--- src/IP.cc | 58 ++--- src/IP.h | 6 +- testing/btest/Baseline/core.ipv6-frag/output | 10 +- testing/btest/Baseline/core.ipv6_esp/output | 240 +++++++++--------- .../Baseline/core.ipv6_ext_headers/output | 2 +- .../btest/bifs/routing0_data_to_addrs.test | 7 +- 7 files changed, 185 insertions(+), 208 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 42215839c0..b3c997a750 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1064,9 +1064,10 @@ type ip6_esp: record { seq: count; }; -## An IPv6 header chain. +## A general container for a more specific IPv6 extension header. ## -## .. bro:see:: pkt_hdr ip4_hdr +## .. bro:see:: pkt_hdr ip4_hdr ip6_hopopts ip6_dstopts ip6_routing ip6_fragment +## ip6_ah ip6_esp # # [Robin] What happens to unknown extension headers? We should keep them too so that # one can at least identify what one can't analyze. @@ -1076,37 +1077,22 @@ type ip6_esp: record { # created since we can't parse past unknown extension headers to get # at the upper layer protocol. Does that seem reasonable for at # being able to identify things that couldn't be analyzed? -type ip6_hdr_chain: record { - # [Robin] This looses the order of the headers (partially at least, even with ext_order I believe). - # Not sure how to do it differently, but can order be important for us? - # [Jon] I do think order can be interesting as RFC 2460 specifies some - # ordering constraints, and I think I provide enough info in this - # record for one to reconstruct the order. Reread my new comments - # for the "ext_order" field below and see if you change your mind. - +type ip6_ext_hdr: record { + ## The RFC 1700 et seq. IANA assigned number identifying the type of + ## the extension header. + id: count; ## Hop-by-hop option extension header. - hopopts: vector of ip6_hopopts; - ## Destination option extension headers. - dstopts: vector of ip6_dstopts; - ## Routing extension headers. - routing: vector of ip6_routing; - ## Fragment headers. - fragment: vector of ip6_fragment; - ## Authentication extension headers. - ah: vector of ip6_ah; - ## Encapsulating security payload headers. - esp: vector of ip6_esp; - - ## Order of extension headers as seen in the packet header. - ## The value at an index indicates the protocol number (RFC 1700 et seq., - ## IANA assigned number) of the header at that same position in the chain. - ## e.g. if :bro:id:`IPPROTO_DSTOPTS` is at index 0 and index 2 and - ## :bro:id:`IPPROTO_ROUTING` is at index 1, then the order of the headers - ## in the chain is the header at index 0 of *dstopts* followed by - ## the header at index 0 of *routing* and then the header at index 1 of - ## *dstopts* (tracking of duplicate header types to know where to - ## index into each vector would be up to the script following the chain). - ext_order: vector of count; + hopopts: ip6_hopopts &optional; + ## Destination option extension header. + dstopts: ip6_dstopts &optional; + ## Routing extension header. + routing: ip6_routing &optional; + ## Fragment header. + fragment: ip6_fragment &optional; + ## Authentication extension header. + ah: ip6_ah &optional; + ## Encapsulating security payload header. + esp: ip6_esp &optional; }; ## Values extracted from an IPv6 header. @@ -1114,16 +1100,16 @@ type ip6_hdr_chain: record { ## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts ## ip6_routing ip6_fragment ip6_ah ip6_esp type ip6_hdr: record { - class: count; ##< Traffic class. - flow: count; ##< Flow label. - len: count; ##< Payload length. - nxt: count; ##< Protocol number of the next header - ##< (RFC 1700 et seq., IANA assigned number), e.g. - ##< :bro:id:`IPPROTO_ICMP`. - hlim: count; ##< Hop limit. - src: addr; ##< Source address. - dst: addr; ##< Destination address. - exts: ip6_hdr_chain;##< Extension header chain. + class: count; ##< Traffic class. + flow: count; ##< Flow label. + len: count; ##< Payload length. + nxt: count; ##< Protocol number of the next header + ##< (RFC 1700 et seq., IANA assigned number) + ##< e.g. :bro:id:`IPPROTO_ICMP`. + hlim: count; ##< Hop limit. + src: addr; ##< Source address. + dst: addr; ##< Destination address. + exts: vector of ip6_ext_hdr; ##< Extension header chain. }; ## Values extracted from an IPv4 header. diff --git a/src/IP.cc b/src/IP.cc index 9dcb372d3f..d6d1df0c31 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -7,7 +7,7 @@ static RecordType* ip4_hdr_type = 0; static RecordType* ip6_hdr_type = 0; -static RecordType* ip6_hdr_chain_type = 0; +static RecordType* ip6_ext_hdr_type = 0; static RecordType* ip6_option_type = 0; static RecordType* ip6_hopopts_type = 0; static RecordType* ip6_dstopts_type = 0; @@ -57,7 +57,7 @@ static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) return vv; } -RecordVal* IPv6_Hdr::BuildRecordVal() const +RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const { RecordVal* rv = 0; @@ -73,6 +73,10 @@ RecordVal* IPv6_Hdr::BuildRecordVal() const rv->Assign(4, new Val(ip6->ip6_hlim, TYPE_COUNT)); rv->Assign(5, new AddrVal(ip6->ip6_src)); rv->Assign(6, new AddrVal(ip6->ip6_dst)); + if ( ! chain ) + chain = new VectorVal(new VectorType( + hdrType(ip6_ext_hdr_type, "ip6_ext_hdr")->Ref())); + rv->Assign(7, chain); } break; @@ -172,8 +176,7 @@ RecordVal* IP_Hdr::BuildIPHdrVal() const } else { - rval = ((*ip6_hdrs)[0])->BuildRecordVal(); - rval->Assign(7, ip6_hdrs->BuildRecordVal()); + rval = ((*ip6_hdrs)[0])->BuildRecordVal(ip6_hdrs->BuildVal()); } return rval; @@ -306,11 +309,11 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) isIPv6ExtHeader(next_type) ); } -RecordVal* IPv6_Hdr_Chain::BuildRecordVal() const +VectorVal* IPv6_Hdr_Chain::BuildVal() const { - if ( ! ip6_hdr_chain_type ) + if ( ! ip6_ext_hdr_type ) { - ip6_hdr_chain_type = internal_type("ip6_hdr_chain")->AsRecordType(); + ip6_ext_hdr_type = internal_type("ip6_ext_hdr")->AsRecordType(); ip6_hopopts_type = internal_type("ip6_hopopts")->AsRecordType(); ip6_dstopts_type = internal_type("ip6_dstopts")->AsRecordType(); ip6_routing_type = internal_type("ip6_routing")->AsRecordType(); @@ -319,53 +322,40 @@ RecordVal* IPv6_Hdr_Chain::BuildRecordVal() const ip6_esp_type = internal_type("ip6_esp")->AsRecordType(); } - RecordVal* rval = new RecordVal(ip6_hdr_chain_type); - - VectorVal* hopopts = new VectorVal(new VectorType(ip6_hopopts_type->Ref())); - VectorVal* dstopts = new VectorVal(new VectorType(ip6_dstopts_type->Ref())); - VectorVal* routing = new VectorVal(new VectorType(ip6_routing_type->Ref())); - VectorVal* fragment = new VectorVal(new VectorType(ip6_fragment_type->Ref())); - VectorVal* ah = new VectorVal(new VectorType(ip6_ah_type->Ref())); - VectorVal* esp = new VectorVal(new VectorType(ip6_esp_type->Ref())); - VectorVal* order = new VectorVal(new VectorType(base_type(TYPE_COUNT))); + VectorVal* rval = new VectorVal(new VectorType(ip6_ext_hdr_type->Ref())); for ( size_t i = 1; i < chain.size(); ++i ) { RecordVal* v = chain[i]->BuildRecordVal(); + RecordVal* ext_hdr = new RecordVal(ip6_ext_hdr_type); uint8 type = chain[i]->Type(); + ext_hdr->Assign(0, new Val(type, TYPE_COUNT)); + switch (type) { case IPPROTO_HOPOPTS: - hopopts->Assign(hopopts->Size(), v, 0); - break; - case IPPROTO_ROUTING: - routing->Assign(routing->Size(), v, 0); + ext_hdr->Assign(1, v); break; case IPPROTO_DSTOPTS: - dstopts->Assign(dstopts->Size(), v, 0); + ext_hdr->Assign(2, v); + break; + case IPPROTO_ROUTING: + ext_hdr->Assign(3, v); break; case IPPROTO_FRAGMENT: - fragment->Assign(fragment->Size(), v, 0); + ext_hdr->Assign(4, v); break; case IPPROTO_AH: - ah->Assign(ah->Size(), v, 0); + ext_hdr->Assign(5, v); break; case IPPROTO_ESP: - esp->Assign(esp->Size(), v, 0); + ext_hdr->Assign(6, v); break; - case IPPROTO_IPV6: default: - reporter->InternalError("pkt_hdr assigned bad header %d", type); + reporter->InternalError("IPv6_Hdr_Chain bad header %d", type); break; } - order->Assign(i-1, new Val(type, TYPE_COUNT), 0); + rval->Assign(rval->Size(), ext_hdr, 0); } - rval->Assign(0, hopopts); - rval->Assign(1, dstopts); - rval->Assign(2, routing); - rval->Assign(3, fragment); - rval->Assign(4, ah); - rval->Assign(5, esp); - rval->Assign(6, order); return rval; } diff --git a/src/IP.h b/src/IP.h index 5e5e3c0748..a989b04d76 100644 --- a/src/IP.h +++ b/src/IP.h @@ -121,7 +121,7 @@ public: /** * Returns the script-layer record representation of the header. */ - RecordVal* BuildRecordVal() const; + RecordVal* BuildRecordVal(VectorVal* chain = 0) const; protected: uint8 type; @@ -188,10 +188,10 @@ public: (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } /** - * Returns an ip6_hdr_chain RecordVal that includes script-layer + * Returns a vector of ip6_ext_hdr RecordVals that includes script-layer * representation of all extension headers in the chain. */ - RecordVal* BuildRecordVal() const; + VectorVal* BuildVal() const; protected: // for access to protected ctor that changes next header values that diff --git a/testing/btest/Baseline/core.ipv6-frag/output b/testing/btest/Baseline/core.ipv6-frag/output index 80c1a2cc93..12dfc3a841 100644 --- a/testing/btest/Baseline/core.ipv6-frag/output +++ b/testing/btest/Baseline/core.ipv6-frag/output @@ -1,5 +1,5 @@ -ip6=[class=0, flow=0, len=81, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51850/udp, dport=53/udp, ulen=81] -ip6=[class=0, flow=0, len=331, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=53/udp, dport=51850/udp, ulen=331] -ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51851/udp, dport=53/udp, ulen=82] -ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=51851/udp, dport=53/udp, ulen=82] -ip6=[class=0, flow=0, len=3238, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[], ext_order=[]]], udp = [sport=53/udp, dport=51851/udp, ulen=3238] +ip6=[class=0, flow=0, len=81, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[]], udp = [sport=51850/udp, dport=53/udp, ulen=81] +ip6=[class=0, flow=0, len=331, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[]], udp = [sport=53/udp, dport=51850/udp, ulen=331] +ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[class=0, flow=0, len=82, nxt=17, hlim=64, src=2001:470:1f11:81f:d138:5f55:6d4:1fe2, dst=2607:f740:b::f93, exts=[]], udp = [sport=51851/udp, dport=53/udp, ulen=82] +ip6=[class=0, flow=0, len=3238, nxt=17, hlim=53, src=2607:f740:b::f93, dst=2001:470:1f11:81f:d138:5f55:6d4:1fe2, exts=[]], udp = [sport=53/udp, dport=51851/udp, ulen=3238] diff --git a/testing/btest/Baseline/core.ipv6_esp/output b/testing/btest/Baseline/core.ipv6_esp/output index db27689364..97a8434e7b 100644 --- a/testing/btest/Baseline/core.ipv6_esp/output +++ b/testing/btest/Baseline/core.ipv6_esp/output @@ -1,120 +1,120 @@ -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=10, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=11, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=12, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=13, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=20, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=21, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=22, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=1]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=2]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=3]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=4]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=5]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=6]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=7]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=8]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=9]], ext_order=[50]]], tcp=, udp=, icmp=] -[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[hopopts=[], dstopts=[], routing=[], fragment=[], ah=[], esp=[[spi=23, seq=10]], ext_order=[50]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::2, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::3, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::4, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::5, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=116, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::12, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=10, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::13, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=11, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=100, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::14, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=12, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::15, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=13, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=104, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::22, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=20, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::23, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=21, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=88, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::24, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=22, seq=10]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=1]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=2]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=3]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=4]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=5]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=6]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=7]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=8]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=9]]]], tcp=, udp=, icmp=] +[ip=, ip6=[class=0, flow=0, len=76, nxt=50, hlim=64, src=3ffe::1, dst=3ffe::25, exts=[[id=50, hopopts=, dstopts=, routing=, fragment=, ah=, esp=[spi=23, seq=10]]]], tcp=, udp=, icmp=] diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output index 9348cc41c8..a5a0caf7c6 100644 --- a/testing/btest/Baseline/core.ipv6_ext_headers/output +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -1 +1 @@ -[ip=, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[hopopts=[[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]]], dstopts=[], routing=[[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B]], fragment=[], ah=[], esp=[], ext_order=[0, 43]]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] +[ip=, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=, routing=, fragment=, ah=, esp=], [id=43, hopopts=, dstopts=, routing=[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=, ah=, esp=]]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test index eb6ebbc614..4bf15cae87 100644 --- a/testing/btest/bifs/routing0_data_to_addrs.test +++ b/testing/btest/bifs/routing0_data_to_addrs.test @@ -3,7 +3,8 @@ event ipv6_ext_headers(c: connection, p: pkt_hdr) { - for ( h in p$ip6$exts$routing ) - if ( p$ip6$exts$routing[h]$rtype == 0 ) - print routing0_data_to_addrs(p$ip6$exts$routing[h]$data); + for ( h in p$ip6$exts ) + if ( p$ip6$exts[h]$id == IPPROTO_ROUTING ) + if ( p$ip6$exts[h]$routing$rtype == 0 ) + print routing0_data_to_addrs(p$ip6$exts[h]$routing$data); } From d7c9471818ed60453fc319388277ebaf43939b27 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 15:57:25 -0700 Subject: [PATCH 14/27] Extending queue statistics. --- .../frameworks/cluster/setup-connections.bro | 2 +- src/Stats.cc | 9 ++++- src/logging/WriterFrontend.h | 2 +- src/threading/MsgThread.cc | 2 + src/threading/MsgThread.h | 4 ++ src/threading/Queue.h | 39 +++++++++++++++++++ 6 files changed, 54 insertions(+), 4 deletions(-) diff --git a/scripts/base/frameworks/cluster/setup-connections.bro b/scripts/base/frameworks/cluster/setup-connections.bro index b5a0d25e1f..20646525be 100644 --- a/scripts/base/frameworks/cluster/setup-connections.bro +++ b/scripts/base/frameworks/cluster/setup-connections.bro @@ -44,7 +44,7 @@ event bro_init() &priority=9 { if ( n$node_type == WORKER && n$proxy == node ) Communication::nodes[i] = - [$host=n$ip, $connect=F, $class=i, $sync=T, $auth=T, $events=worker2proxy_events]; + [$host=n$ip, $connect=F, $class=i, $sync=F, $auth=T, $events=worker2proxy_events]; # accepts connections from the previous one. # (This is not ideal for setups with many proxies) diff --git a/src/Stats.cc b/src/Stats.cc index a2e7496c5f..c3035231e9 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -210,11 +210,16 @@ void ProfileLogger::Log() i != thread_stats.end(); ++i ) { threading::MsgThread::Stats s = i->second; - file->Write(fmt("%0.6f %-25s in=%" PRIu64 " out=%" PRIu64 " pending=%" PRIu64 "/%" PRIu64 "\n", + file->Write(fmt("%0.6f %-25s in=%" PRIu64 " out=%" PRIu64 " pending=%" PRIu64 "/%" PRIu64 + " (#queue r/w: in=%" PRIu64 "/%" PRIu64 " out=%" PRIu64 "/%" PRIu64 ")" + "\n", network_time, i->first.c_str(), s.sent_in, s.sent_out, - s.pending_in, s.pending_out)); + s.pending_in, s.pending_out, + s.queue_in_stats.num_reads, s.queue_in_stats.num_writes, + s.queue_out_stats.num_reads, s.queue_out_stats.num_writes + )); } // Script-level state. diff --git a/src/logging/WriterFrontend.h b/src/logging/WriterFrontend.h index 3e05d17c9e..4d22bd9b1f 100644 --- a/src/logging/WriterFrontend.h +++ b/src/logging/WriterFrontend.h @@ -212,7 +212,7 @@ protected: const threading::Field* const* fields; // The log fields. // Buffer for bulk writes. - static const int WRITER_BUFFER_SIZE = 50; + static const int WRITER_BUFFER_SIZE = 1000; int write_buffer_pos; // Position of next write in buffer. threading::Value*** write_buffer; // Buffer of size WRITER_BUFFER_SIZE. }; diff --git a/src/threading/MsgThread.cc b/src/threading/MsgThread.cc index 145e16c57b..ddcd3df1dd 100644 --- a/src/threading/MsgThread.cc +++ b/src/threading/MsgThread.cc @@ -283,5 +283,7 @@ void MsgThread::GetStats(Stats* stats) stats->sent_out = cnt_sent_out; stats->pending_in = queue_in.Size(); stats->pending_out = queue_out.Size(); + queue_in.GetStats(&stats->queue_in_stats); + queue_out.GetStats(&stats->queue_out_stats); } diff --git a/src/threading/MsgThread.h b/src/threading/MsgThread.h index 28c7690dfa..5ac1c0f780 100644 --- a/src/threading/MsgThread.h +++ b/src/threading/MsgThread.h @@ -154,6 +154,10 @@ public: uint64_t sent_out; //! Number of messages sent from the child thread to the main thread uint64_t pending_in; //! Number of messages sent to the child but not yet processed. uint64_t pending_out; //! Number of messages sent from the child but not yet processed by the main thread. + + /// Statistics from our queues. + Queue::Stats queue_in_stats; + Queue::Stats queue_out_stats; }; /** diff --git a/src/threading/Queue.h b/src/threading/Queue.h index a25f897d23..985ba31714 100644 --- a/src/threading/Queue.h +++ b/src/threading/Queue.h @@ -58,6 +58,22 @@ public: */ uint64_t Size(); + /** + * Statistics about inter-thread communication. + */ + struct Stats + { + uint64_t num_reads; //! Number of messages read from the queue. + uint64_t num_writes; //! Number of messages written to the queue. + }; + + /** + * Returns statistics about the queue's usage. + * + * @param stats A pointer to a structure that will be filled with + * current numbers. */ + void GetStats(Stats* stats); + private: static const int NUM_QUEUES = 8; @@ -67,6 +83,10 @@ private: int read_ptr; // Where the next operation will read from int write_ptr; // Where the next operation will write to + + // Statistics. + uint64_t num_reads; + uint64_t num_writes; }; inline static void safe_lock(pthread_mutex_t* mutex) @@ -86,6 +106,7 @@ inline Queue::Queue() { read_ptr = 0; write_ptr = 0; + num_reads = num_writes = 0; for( int i = 0; i < NUM_QUEUES; ++i ) { @@ -121,6 +142,7 @@ inline T Queue::Get() messages[read_ptr].pop(); read_ptr = (read_ptr + 1) % NUM_QUEUES; + ++num_reads; safe_unlock(&mutex[old_read_ptr]); @@ -142,6 +164,7 @@ inline void Queue::Put(T data) pthread_cond_signal(&has_data[write_ptr]); write_ptr = (write_ptr + 1) % NUM_QUEUES; + ++num_writes; safe_unlock(&mutex[old_write_ptr]); } @@ -177,7 +200,23 @@ inline uint64_t Queue::Size() return size; } +template +inline void Queue::GetStats(Stats* stats) + { + // To be safe, we look all queues. That's probably unneccessary, but + // doesn't really hurt. + for ( int i = 0; i < NUM_QUEUES; i++ ) + safe_lock(&mutex[i]); + + stats->num_reads = num_reads; + stats->num_writes = num_writes; + + for ( int i = 0; i < NUM_QUEUES; i++ ) + safe_unlock(&mutex[i]); + } + } + #endif From 1d65f2da42648ac3fdde466509bf22fe3f8dafda Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 16:08:22 -0700 Subject: [PATCH 15/27] Updating submodule(s). [nomail] --- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- cmake | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/aux/binpac b/aux/binpac index 3034da8f08..dd1a3a95f0 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 3034da8f082b61157e234237993ffd7a95be6e62 +Subproject commit dd1a3a95f07082efcd5274b21104a038d523d132 diff --git a/aux/bro-aux b/aux/bro-aux index f53bcb2b49..a59b35bdad 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit f53bcb2b492cb0db3dd288384040abc2ab711767 +Subproject commit a59b35bdada8f70fb1a59bf7bb2976534c86d378 diff --git a/aux/broccoli b/aux/broccoli index a08ca90727..0128c72cbd 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit a08ca90727c5c4b90aa8633106ec33a5cf7378d4 +Subproject commit 0128c72cbdf29925dd146842a9077c631d2cc85c diff --git a/aux/broctl b/aux/broctl index 954538514d..66e9e87bee 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 954538514d71983e7ef3f0e109960466096e1c1d +Subproject commit 66e9e87beebce983fa0f479b0284d5690b0290d4 diff --git a/cmake b/cmake index 2cc1055770..550ab2c8d9 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 2cc105577044a2d214124568f3f2496ed2ccbb34 +Subproject commit 550ab2c8d95b1d3e18e40a903152650e6c7a3c45 From 4321f635acd4bd7f83899c3e4ec7cf2d4e3d1468 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 16:40:14 -0700 Subject: [PATCH 16/27] Removing remaining comments. Looks fine. --- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- cmake | 2 +- scripts/base/init-bare.bro | 28 +--------------------------- src/Frag.cc | 4 ---- src/IP.h | 16 ---------------- src/Net.cc | 1 - src/Sessions.cc | 25 +++---------------------- 10 files changed, 9 insertions(+), 75 deletions(-) diff --git a/aux/binpac b/aux/binpac index 3034da8f08..dd1a3a95f0 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 3034da8f082b61157e234237993ffd7a95be6e62 +Subproject commit dd1a3a95f07082efcd5274b21104a038d523d132 diff --git a/aux/bro-aux b/aux/bro-aux index f53bcb2b49..a59b35bdad 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit f53bcb2b492cb0db3dd288384040abc2ab711767 +Subproject commit a59b35bdada8f70fb1a59bf7bb2976534c86d378 diff --git a/aux/broccoli b/aux/broccoli index a08ca90727..612e95ac62 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit a08ca90727c5c4b90aa8633106ec33a5cf7378d4 +Subproject commit 612e95ac62a06b32b2e9e627f30527012a89a12c diff --git a/aux/broctl b/aux/broctl index 954538514d..66e9e87bee 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 954538514d71983e7ef3f0e109960466096e1c1d +Subproject commit 66e9e87beebce983fa0f479b0284d5690b0290d4 diff --git a/cmake b/cmake index 2cc1055770..550ab2c8d9 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 2cc105577044a2d214124568f3f2496ed2ccbb34 +Subproject commit 550ab2c8d95b1d3e18e40a903152650e6c7a3c45 diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index b3c997a750..7b1b304405 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -933,11 +933,7 @@ const ICMP_UNREACH_ADMIN_PROHIB = 13; ##< Adminstratively prohibited. # Definitions for access to packet headers. Currently only used for # discarders. # todo::these should go into an enum to make them autodoc'able -const IPPROTO_IP = 0; ##< Dummy for IP. [Robin] Rename to IPPROTO_IP4? -# [Jon] I'd say leave it be or remove it because from -# IPPROTO_IPV4 can actually be the same as IPPROTO_IPIP (4)... -# IPPROTO_IP seems to be just for use with the socket API and not -# actually identifying protocol numbers in packet headers +const IPPROTO_IP = 0; ##< Dummy for IP. const IPPROTO_ICMP = 1; ##< Control message protocol. const IPPROTO_IGMP = 2; ##< Group management protocol. const IPPROTO_IPIP = 4; ##< IP encapsulation in IP. @@ -947,14 +943,6 @@ const IPPROTO_IPV6 = 41; ##< IPv6 header. const IPPROTO_RAW = 255; ##< Raw IP packet. # Definitions for IPv6 extension headers. -# [Robin] Do we need a constant for unknown extensions? -# [Jon] I don't think so, these constants are just conveniences to improve -# script readability, but they also identify the actual assigned protocol -# number of the header type. If the core were to actually pass to the -# script-layer a next-header value of something we don't know about yet, -# that value would be the actual value seen in the packet, not something -# we should make up. We could provide a "KNOWN_PROTOCOLS" set for -# convenience that one could check membership against. const IPPROTO_HOPOPTS = 0; ##< IPv6 hop-by-hop-options header. const IPPROTO_ROUTING = 43; ##< IPv6 routing header. const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. @@ -1068,15 +1056,6 @@ type ip6_esp: record { ## ## .. bro:see:: pkt_hdr ip4_hdr ip6_hopopts ip6_dstopts ip6_routing ip6_fragment ## ip6_ah ip6_esp -# -# [Robin] What happens to unknown extension headers? We should keep them too so that -# one can at least identify what one can't analyze. -# [Jon] Currently, they show up as "unknown_protocol" weirds and those packets -# are skipped before any "new_packet" or "ipv6_ext_headers" events are -# raised as those depend on a connection parameter which can't be -# created since we can't parse past unknown extension headers to get -# at the upper layer protocol. Does that seem reasonable for at -# being able to identify things that couldn't be analyzed? type ip6_ext_hdr: record { ## The RFC 1700 et seq. IANA assigned number identifying the type of ## the extension header. @@ -1170,11 +1149,6 @@ type icmp_hdr: record { ## A packet header, consisting of an IP header and transport-layer header. ## ## .. bro:see:: new_packet -# -# [Robin] Add flags saying whether it's v4/v6, tcp/udp/icmp? The day will come where -# we can't infer that from the connection anymore (tunnels). -# [Jon] I'm not sure what you mean, doesn't checking result of ?$ operator -# always work for finding out protocols involved? type pkt_hdr: record { ip: ip4_hdr &optional; ##< The IPv4 header if an IPv4 packet. ip6: ip6_hdr &optional; ##< The IPv6 header if an IPv6 packet. diff --git a/src/Frag.cc b/src/Frag.cc index 5fcad35560..a744526921 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -33,10 +33,6 @@ FragReassembler::FragReassembler(NetSessions* arg_s, s = arg_s; key = k; - // [Robin] Can't we merge these two cases now? - // [Jon] I think we'll always have to check v4 versus v6 to get the correct - // proto_hdr_len unless IP_Hdr::HdrLen itself makes a special case for - // IPv6 fragments (but that seems more confusing to me) const struct ip* ip4 = ip->IP4_Hdr(); if ( ip4 ) { diff --git a/src/IP.h b/src/IP.h index a989b04d76..f3e8272080 100644 --- a/src/IP.h +++ b/src/IP.h @@ -14,22 +14,6 @@ #include #include -// [Robin] I'm concerced about the virtual methods here. These methods will -// be called *a lot* and that may add to some significant overhead I'm afraid -// (at least eventually as IPv6 is picking up). -// -// [Robin] Similar concern for the vector and ip6_hdrs data -// members: we're creating/allocating those for every IPv6 packet, right? -// -// Any idea how to avoid these? -// -// [Jon] Seems fair enough to just remove the virtual method concern at this -// point by replacing the class hierarchy with some inline functions that -// do switch statements. I don't know what to do about the -// vector and ip6_hdrs data members being allocated for every -// IPv6 packet, maybe it's too early to try to optimize before we know -// the frequency at which extension headers appear in real IPv6 traffic? - /** * Base class for IPv6 header/extensions. */ diff --git a/src/Net.cc b/src/Net.cc index c92545cb87..35c3b383f6 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -42,7 +42,6 @@ extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); PList(PktSrc) pkt_srcs; // FIXME: We should really merge PktDumper and PacketDumper. -// It's on my to-do [Robin]. PktDumper* pkt_dumper = 0; int reading_live = 0; diff --git a/src/Sessions.cc b/src/Sessions.cc index 9e91fdc304..4f31d29346 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -430,13 +430,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( discarder && discarder->NextPacket(ip_hdr, len, caplen) ) return; - // [Robin] dump_this_packet = 1 for non-ICMP/UDP/TCP removed here. Why? - // [Jon] The default case of the "switch ( proto )" calls Weird() which - // should set dump_this_packet = 1. The old code also returned - // at this point for non-ICMP/UDP/TCP, but for IPv6 fragments - // we need to do the reassembly first before knowing for sure what - // upper-layer protocol it is. - FragReassembler* f = 0; if ( ip_hdr->IsFragment() ) @@ -472,10 +465,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; - // [Robin] Does ESP need to be the last header? - // [Jon] In terms of what we try to parse, yes, we can't go any further - // in parsing a header chain once we reach an ESP one since - // encrypted payload immediately follows. + // We stop building the chain when seeing IPPROTO_ESP so if it's + // there, it's always the last. if ( ip_hdr->LastHeader() == IPPROTO_ESP ) { dump_this_packet = 1; @@ -498,16 +489,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } - // [Robin] The Remove(f) used to be here, while it's now before every - // return statement. I'm not seeing why? - // [Jon] That Remove(f) is still here above in the CheckHeaderTrunc() - // conditional that's just a refactoring of the old code. - // The reason why it's not done unconditionally after the reassembly - // is because doing that could cause the object that ip_hdr points - // to to be freed when we still need to use that below. - // I added Remove(f)'s before other "abnormal" return points that - // looked like they'd otherwise leak the memory. - const u_char* data = ip_hdr->Payload(); ConnID id; @@ -553,7 +534,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } default: - Weird(fmt("unknown_protocol %d", proto), hdr, pkt); + Weird(fmt("unknown_protocol_%d", proto), hdr, pkt); Remove(f); return; } From 30014ac92010bdf1dca6534303ecee8945c0e657 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 16:49:29 -0700 Subject: [PATCH 17/27] Cosmetics in preparation for merge. --- scripts/base/init-bare.bro | 16 ++++++++-------- src/Frag.cc | 2 +- src/IP.cc | 5 ++++- src/IP.h | 4 +++- src/PacketSort.cc | 2 +- src/Sessions.cc | 6 +++++- src/bro.bif | 1 + 7 files changed, 23 insertions(+), 13 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 7b1b304405..b9eca66d24 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -945,7 +945,7 @@ const IPPROTO_RAW = 255; ##< Raw IP packet. # Definitions for IPv6 extension headers. const IPPROTO_HOPOPTS = 0; ##< IPv6 hop-by-hop-options header. const IPPROTO_ROUTING = 43; ##< IPv6 routing header. -const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. +const IPPROTO_FRAGMENT = 44; ##< IPv6 fragment header. const IPPROTO_ESP = 50; ##< IPv6 encapsulating security payload header. const IPPROTO_AH = 51; ##< IPv6 authentication header. const IPPROTO_NONE = 59; ##< IPv6 no next header. @@ -1081,14 +1081,14 @@ type ip6_ext_hdr: record { type ip6_hdr: record { class: count; ##< Traffic class. flow: count; ##< Flow label. - len: count; ##< Payload length. - nxt: count; ##< Protocol number of the next header - ##< (RFC 1700 et seq., IANA assigned number) - ##< e.g. :bro:id:`IPPROTO_ICMP`. + len: count; ##< Payload length. + nxt: count; ##< Protocol number of the next header + ##< (RFC 1700 et seq., IANA assigned number) + ##< e.g. :bro:id:`IPPROTO_ICMP`. hlim: count; ##< Hop limit. - src: addr; ##< Source address. - dst: addr; ##< Destination address. - exts: vector of ip6_ext_hdr; ##< Extension header chain. + src: addr; ##< Source address. + dst: addr; ##< Destination address. + exts: vector of ip6_ext_hdr; ##< Extension header chain. }; ## Values extracted from an IPv4 header. diff --git a/src/Frag.cc b/src/Frag.cc index a744526921..9bd16a71c9 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -90,7 +90,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) if ( ip->NextProto() != next_proto || ip->HdrLen() - 8 != proto_hdr_len ) s->Weird("fragment_protocol_inconsistency", ip); - //TODO: more detailed unfrag header consistency checks? + // TODO: more detailed unfrag header consistency checks? } if ( ip->DF() ) diff --git a/src/IP.cc b/src/IP.cc index d6d1df0c31..4148c58a33 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -18,7 +18,9 @@ static RecordType* ip6_esp_type = 0; static inline RecordType* hdrType(RecordType*& type, const char* name) { - if ( ! type ) type = internal_type(name)->AsRecordType(); + if ( ! type ) + type = internal_type(name)->AsRecordType(); + return type; } @@ -54,6 +56,7 @@ static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) vv->Assign(vv->Size(), rv, 0); } + return vv; } diff --git a/src/IP.h b/src/IP.h index f3e8272080..cb5bcf77c7 100644 --- a/src/IP.h +++ b/src/IP.h @@ -229,7 +229,9 @@ public: ~IP_Hdr() { - if ( ip6 ) delete ip6_hdrs; + if ( ip6 ) + delete ip6_hdrs; + if ( del ) { if ( ip4 ) diff --git a/src/PacketSort.cc b/src/PacketSort.cc index aec7639f4a..04c525c4d1 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -31,7 +31,7 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, else if ( ip->ip_v == 6 ) ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false); else - // weird will be generated later in NetSessions::NextPacket + // Weird will be generated later in NetSessions::NextPacket. return; if ( ip_hdr->NextProto() == IPPROTO_TCP && diff --git a/src/Sessions.cc b/src/Sessions.cc index 4f31d29346..f03b6d4c63 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -640,20 +640,24 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, min_hdr_len = sizeof(struct udphdr); break; case IPPROTO_ICMP: - default: min_hdr_len = ICMP_MINLEN; break; + default: + internal_error("unknown protocol"); } + if ( len < min_hdr_len ) { Weird("truncated_header", h, p); return true; } + if ( caplen < min_hdr_len ) { Weird("internally_truncated_header", h, p); return true; } + return false; } diff --git a/src/bro.bif b/src/bro.bif index 375a1c64c1..64ed7d1f2f 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2067,6 +2067,7 @@ function routing0_data_to_addrs%(s: string%): addr_set const u_char* bytes = s->Bytes(); bytes += 4; // go past 32-bit reserved field len -= 4; + if ( ( len % 16 ) != 0 ) reporter->Warning("Bad ip6_routing data length: %d", s->Len()); From 72f098cb5955c16e33ca474257fa2598b2b10766 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 17:39:27 -0700 Subject: [PATCH 18/27] Adding btest state file to gitignore. --- testing/btest/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/btest/.gitignore b/testing/btest/.gitignore index 5282177d90..b4c1b7a858 100644 --- a/testing/btest/.gitignore +++ b/testing/btest/.gitignore @@ -1,3 +1,4 @@ .tmp +.btest.failed.dat diag.log coverage.log From d889f1463800c218b4422bf70bfaff4a297d87bf Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Mar 2012 17:43:31 -0700 Subject: [PATCH 19/27] Updating submodule(s). [nomail] --- CHANGES | 46 ++++++++++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- aux/broccoli | 2 +- aux/btest | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 8bbd14fde9..9d5c6dc05f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,50 @@ +2.0-179 | 2012-03-23 17:43:31 -0700 + + * Remove the default "tcp or udp or icmp" filter. In default mode, + Bro would load the packet filter script framework which installs a + filter that allows all packets, but in bare mode (the -b option), + this old filter would not follow IPv6 protocol chains and thus + filter out packets with extension headers. (Jon Siwek) + + * Update PacketFilter/Discarder code for IP version independence. + (Jon Siwek) + + * Fix some IPv6 header related bugs. (Jon Siwek) + + * Add IPv6 fragment reassembly. (Jon Siwek) + + * Add handling for IPv6 extension header chains. Addresses #531. + (Jon Siwek) + + - 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. + + * Add unit tests for IPv6 fragment reassembly, ipv6_ext_headers and + esp_packet events. (Jon Siwek) + + * Adapt FreeBSD's inet_ntop implementation for internal use. Now we + get consistent text representations of IPv6 addresses across + platforms. (Jon Siwek) + + * Update documentation for new syntax of IPv6 literals. (Jon Siwek) + + 2.0-150 | 2012-03-13 16:16:22 -0700 * Changing the regular expression to allow Site::local_nets in diff --git a/VERSION b/VERSION index aeb2df7379..db8d11e293 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-150 +2.0-179 diff --git a/aux/broccoli b/aux/broccoli index 612e95ac62..a4046c2f79 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 612e95ac62a06b32b2e9e627f30527012a89a12c +Subproject commit a4046c2f79b6ab0ac19ae8be94b79c6ce578bea7 diff --git a/aux/btest b/aux/btest index 9c9fde204d..dc78a3ebf5 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 9c9fde204dd5518bdfdb8b4a86d38ed06e597209 +Subproject commit dc78a3ebf5cd8fbd1b3034990e36fa21a51d1a19 From 0ceca706f6d1a465bcb00b28164751e16e7ca0ff Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 26 Mar 2012 14:35:01 -0500 Subject: [PATCH 20/27] Change routing0_data_to_addrs BIF to return vector of addresses. Because the order of addresses in type 0 routing headers is interesting/important. --- scripts/base/init-bare.bro | 7 +++++++ src/bro.bif | 15 ++++++--------- .../Baseline/bifs.routing0_data_to_addrs/output | 5 +---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index b9eca66d24..b2237d7af8 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -46,6 +46,13 @@ type index_vec: vector of count; ## then remove this alias. type string_vec: vector of string; +## A vector of addresses. +## +## .. todo:: We need this type definition only for declaring builtin functions via +## ``bifcl``. We should extend ``bifcl`` to understand composite types directly and +## then remove this alias. +type addr_vec: vector of addr; + ## A table of strings indexed by strings. ## ## .. todo:: We need this type definition only for declaring builtin functions via diff --git a/src/bro.bif b/src/bro.bif index 64ed7d1f2f..5ecc582a07 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2050,18 +2050,15 @@ function is_v6_addr%(a: addr%): bool # =========================================================================== ## Converts the *data* field of :bro:type:`ip6_routing` records that have -## *rtype* of 0 into a set of addresses. +## *rtype* of 0 into a vector of addresses. ## ## s: The *data* field of an :bro:type:`ip6_routing` record that has ## an *rtype* of 0. ## -## Returns: The set of addresses contained in the routing header data. -function routing0_data_to_addrs%(s: string%): addr_set +## Returns: The vector of addresses contained in the routing header data. +function routing0_data_to_addrs%(s: string%): addr_vec %{ - BroType* index_type = base_type(TYPE_ADDR); - TypeList* set_index = new TypeList(index_type); - set_index->Append(index_type); - TableVal* tv = new TableVal(new SetType(set_index, 0)); + VectorVal* rval = new VectorVal(new VectorType(base_type(TYPE_ADDR))); int len = s->Len(); const u_char* bytes = s->Bytes(); @@ -2074,12 +2071,12 @@ function routing0_data_to_addrs%(s: string%): addr_set while ( len > 0 ) { IPAddr a(IPAddr::IPv6, (const uint32*) bytes, IPAddr::Network); - tv->Assign(new AddrVal(a), 0); + rval->Assign(rval->Size(), new AddrVal(a), 0); bytes += 16; len -= 16; } - return tv; + return rval; %} ## Converts a :bro:type:`addr` to a :bro:type:`index_vec`. diff --git a/testing/btest/Baseline/bifs.routing0_data_to_addrs/output b/testing/btest/Baseline/bifs.routing0_data_to_addrs/output index 7179bf8564..c79aef89d0 100644 --- a/testing/btest/Baseline/bifs.routing0_data_to_addrs/output +++ b/testing/btest/Baseline/bifs.routing0_data_to_addrs/output @@ -1,4 +1 @@ -{ -2001:78:1:32::1, -2001:78:1:32::2 -} +[2001:78:1:32::1, 2001:78:1:32::2] From 256cd592a7d4c0bdbf43c3f2e9c4e1cdb0fe995a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 28 Mar 2012 13:49:28 -0500 Subject: [PATCH 21/27] Improve handling of IPv6 Routing Type 0 headers. - For RH0 headers with non-zero segments left, a "routing0_segleft" flow_weird event is raised (with a destination indicating the last address in the routing header), and an "rh0_segleft" event can also be handled if the other contents of the packet header are of interest. No further analysis is done as the complexity required to correctly identify destination endpoints of connections doesn't seem worth it as RH0 has been deprecated by RFC 5095. - For RH0 headers without any segments left, a "routing0_header" flow_weird event is raised, but further analysis still occurs as normal. --- src/IP.cc | 18 ++++++++++++++ src/IP.h | 21 +++++++++++++++++ src/Sessions.cc | 16 +++++++++++++ src/event.bif | 8 +++++++ .../Baseline/core.ipv6_ext_headers/output | 2 +- .../btest/Baseline/core.ipv6_rh0/segleft.out | 2 ++ .../btest/Baseline/core.ipv6_rh0/segleft0.out | 2 ++ ...uting.trace => ipv6-hbh-rh0-segleft.trace} | Bin .../btest/Traces/ipv6-hbh-rh0-segleft0.trace | Bin 0 -> 162 bytes .../btest/bifs/routing0_data_to_addrs.test | 4 ++-- testing/btest/core/ipv6_ext_headers.test | 2 +- testing/btest/core/ipv6_rh0.test | 22 ++++++++++++++++++ 12 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/core.ipv6_rh0/segleft.out create mode 100644 testing/btest/Baseline/core.ipv6_rh0/segleft0.out rename testing/btest/Traces/{ext_hdr_hbh_routing.trace => ipv6-hbh-rh0-segleft.trace} (100%) create mode 100644 testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace create mode 100644 testing/btest/core/ipv6_rh0.test diff --git a/src/IP.cc b/src/IP.cc index 4148c58a33..f82b7a0fd7 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -305,6 +305,24 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) chain.push_back(p); + // RFC 5095 deprecates routing type 0 headers, so raise weirds for that + if ( current_type == IPPROTO_ROUTING && + ((const struct ip6_rthdr*)hdrs)->ip6r_type == 0 ) + { + IPAddr src(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); + + if ( ((const struct ip6_rthdr*)hdrs)->ip6r_segleft > 0 ) + { + const in6_addr* a = (const in6_addr*)(hdrs+len-16); + reporter->Weird(src, *a, "routing0_segleft"); + } + else + { + IPAddr dst(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst); + reporter->Weird(src, dst, "routing0_header"); + } + } + hdrs += len; length += len; } while ( current_type != IPPROTO_FRAGMENT && diff --git a/src/IP.h b/src/IP.h index cb5bcf77c7..daa508db7f 100644 --- a/src/IP.h +++ b/src/IP.h @@ -171,6 +171,20 @@ public: { return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } + /** + * Returns whether the chain contains a routing type 0 extension header + * with nonzero segments left. + */ + bool RH0SegLeft() const + { + for ( size_t i = 0; i < chain.size(); ++i ) + if ( chain[i]->Type() == IPPROTO_ROUTING && + ((const struct ip6_rthdr*)chain[i]->Data())->ip6r_type == 0 && + ((const struct ip6_rthdr*)chain[i]->Data())->ip6r_segleft > 0 ) + return true; + return false; + } + /** * Returns a vector of ip6_ext_hdr RecordVals that includes script-layer * representation of all extension headers in the chain. @@ -343,6 +357,13 @@ public: size_t NumHeaders() const { return ip4 ? 1 : ip6_hdrs->Size(); } + /** + * Returns true if this is an IPv6 header containing a routing type 0 + * extension with nonzero segments left, else returns false. + */ + bool RH0SegLeft() const + { return ip4 ? false : ip6_hdrs->RH0SegLeft(); } + /** * Returns an ip_hdr or ip6_hdr_chain RecordVal. */ diff --git a/src/Sessions.cc b/src/Sessions.cc index 84b57bdc62..b5bb485d72 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -481,6 +481,22 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } + // Stop analyzing IPv6 packets that use routing type 0 headers with segments + // left since RH0 headers are deprecated by RFC 5095 and we'd have to make + // extra effort to get the destination in the connection/flow endpoint right + if ( ip_hdr->RH0SegLeft() ) + { + dump_this_packet = 1; + if ( rh0_segleft ) + { + val_list* vl = new val_list(); + vl->append(ip_hdr->BuildPktHdrVal()); + mgr.QueueEvent(rh0_segleft, vl); + } + Remove(f); + return; + } + int proto = ip_hdr->NextProto(); if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) ) diff --git a/src/event.bif b/src/event.bif index 113c003e37..20714c0931 100644 --- a/src/event.bif +++ b/src/event.bif @@ -478,6 +478,14 @@ event ipv6_ext_headers%(c: connection, p: pkt_hdr%); ## .. bro:see:: new_packet tcp_packet ipv6_ext_headers event esp_packet%(p: pkt_hdr%); +## Generated for any packets using an IPv6 Routing Type 0 extension header +## with non-zero segments left. +## +## p: Information from the header of the packet that triggered the event. +## +## .. bro:see:: new_packet tcp_packet ipv6_ext_headers +event rh0_segleft%(p: pkt_hdr%); + ## Generated for every packet that has non-empty transport-layer payload. This is a ## very low-level and expensive event that should be avoided when at all possible. ## It's usually infeasible to handle when processing even medium volumes of diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output index a5a0caf7c6..58332ca900 100644 --- a/testing/btest/Baseline/core.ipv6_ext_headers/output +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -1 +1 @@ -[ip=, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=, routing=, fragment=, ah=, esp=], [id=43, hopopts=, dstopts=, routing=[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=, ah=, esp=]]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] +[ip=, ip6=[class=0, flow=0, len=68, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=, routing=, fragment=, ah=, esp=], [id=43, hopopts=, dstopts=, routing=[nxt=6, len=4, rtype=0, segleft=0, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=, ah=, esp=]]], tcp=[sport=30000/tcp, dport=80/tcp, seq=0, ack=0, hl=20, dl=0, flags=2, win=8192], udp=, icmp=] diff --git a/testing/btest/Baseline/core.ipv6_rh0/segleft.out b/testing/btest/Baseline/core.ipv6_rh0/segleft.out new file mode 100644 index 0000000000..3c722ee3b4 --- /dev/null +++ b/testing/btest/Baseline/core.ipv6_rh0/segleft.out @@ -0,0 +1,2 @@ +flow_weird routing0_segleft from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:78:1:32::2 +rh0 w/ segments left from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:4f8:4:7:2e0:81ff:fe52:9a6b diff --git a/testing/btest/Baseline/core.ipv6_rh0/segleft0.out b/testing/btest/Baseline/core.ipv6_rh0/segleft0.out new file mode 100644 index 0000000000..ae57c7cc8d --- /dev/null +++ b/testing/btest/Baseline/core.ipv6_rh0/segleft0.out @@ -0,0 +1,2 @@ +flow_weird routing0_header from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:4f8:4:7:2e0:81ff:fe52:9a6b +new_connection: [orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=30000/tcp, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=80/tcp] diff --git a/testing/btest/Traces/ext_hdr_hbh_routing.trace b/testing/btest/Traces/ipv6-hbh-rh0-segleft.trace similarity index 100% rename from testing/btest/Traces/ext_hdr_hbh_routing.trace rename to testing/btest/Traces/ipv6-hbh-rh0-segleft.trace diff --git a/testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace b/testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace new file mode 100644 index 0000000000000000000000000000000000000000..35f5b3afe633cc81fc2444b10fa278a29d81783f GIT binary patch literal 162 zcmca|c+)~A1{MYwaA0F#U<7gw`4#(HHgGdk0ofq@9}FO>+U_QR7%mJB3XCj2fSTEv z9yI>{7xe!>Dt}hCHUlHrXf~(?3XBXDK;w-d<}fg#@tH~u7y_Vj3;|3E4EkLR3;-CU BAFlua literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test index 4bf15cae87..de10dd80e0 100644 --- a/testing/btest/bifs/routing0_data_to_addrs.test +++ b/testing/btest/bifs/routing0_data_to_addrs.test @@ -1,7 +1,7 @@ -# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft.trace %INPUT >output # @TEST-EXEC: btest-diff output -event ipv6_ext_headers(c: connection, p: pkt_hdr) +event rh0_segleft(p: pkt_hdr) { for ( h in p$ip6$exts ) if ( p$ip6$exts[h]$id == IPPROTO_ROUTING ) diff --git a/testing/btest/core/ipv6_ext_headers.test b/testing/btest/core/ipv6_ext_headers.test index 170a67bc72..0cf3f2f3fb 100644 --- a/testing/btest/core/ipv6_ext_headers.test +++ b/testing/btest/core/ipv6_ext_headers.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft0.trace %INPUT >output # @TEST-EXEC: btest-diff output # Just check that the event is raised correctly for a packet containing diff --git a/testing/btest/core/ipv6_rh0.test b/testing/btest/core/ipv6_rh0.test new file mode 100644 index 0000000000..18c23ed3b7 --- /dev/null +++ b/testing/btest/core/ipv6_rh0.test @@ -0,0 +1,22 @@ +# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft0.trace %INPUT >segleft0.out +# @TEST-EXEC: btest-diff segleft0.out +# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft.trace %INPUT >segleft.out +# @TEST-EXEC: btest-diff segleft.out + +# This will be raised only by the packet with RH0 and segments left. +event rh0_segleft(p: pkt_hdr) + { + print fmt("rh0 w/ segments left from %s to %s", p$ip6$src, p$ip6$dst); + } + +# This will be raised only by the packet with RH0 and no segments left. +event new_connection(c: connection) + { + print fmt("new_connection: %s", c$id); + } + +# This will be raised by any packet with RH0 regardless of segments left. +event flow_weird(name: string, src: addr, dst: addr) + { + print fmt("flow_weird %s from %s to %s", name, src, dst); + } From 8a1d71dc0864d33aff81d9ab5e6f5b4265ed7d21 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 28 Mar 2012 14:14:20 -0500 Subject: [PATCH 22/27] Remove dead tcp_checksum function from net_util --- src/net_util.cc | 27 --------------------------- src/net_util.h | 1 - 2 files changed, 28 deletions(-) diff --git a/src/net_util.cc b/src/net_util.cc index 1a4e9f1a7f..9e023a5fc1 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -38,33 +38,6 @@ int ones_complement_checksum(const IPAddr& a, uint32 sum) return ones_complement_checksum(bytes, len*4, sum); } -int tcp_checksum(const struct ip* ip, const struct tcphdr* tp, int len) - { - // ### Note, this is only correct for IPv4. This routine is only - // used by the connection compressor (which we turn off for IPv6 - // traffic). - - int tcp_len = tp->th_off * 4 + len; - uint32 sum; - - if ( len % 2 == 1 ) - // Add in pad byte. - sum = htons(((const u_char*) tp)[tcp_len - 1] << 8); - else - sum = 0; - - sum = ones_complement_checksum((void*) &ip->ip_src.s_addr, 4, sum); - sum = ones_complement_checksum((void*) &ip->ip_dst.s_addr, 4, sum); - - uint32 addl_pseudo = - (htons(IPPROTO_TCP) << 16) | htons((unsigned short) tcp_len); - - sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum); - sum = ones_complement_checksum((void*) tp, tcp_len, sum); - - return sum; - } - int udp_checksum(const struct ip* ip, const struct udphdr* up, int len) { uint32 sum; diff --git a/src/net_util.h b/src/net_util.h index 8787340328..5e39a11714 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -62,7 +62,6 @@ inline int seq_delta(uint32 a, uint32 b) extern int ones_complement_checksum(const void* p, int b, uint32 sum); extern int ones_complement_checksum(const IPAddr& a, uint32 sum); -extern int tcp_checksum(const struct ip* ip, const struct tcphdr* tp, int len); extern int udp_checksum(const struct ip* ip, const struct udphdr* up, int len); extern int udp6_checksum(const struct ip6_hdr* ip, const struct udphdr* up, int len); From 42066cc1fd35ca7b63daeaf588271ec3c040385e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 28 Mar 2012 14:53:59 -0700 Subject: [PATCH 23/27] Teaching cmake to always link in tcmalloc if it finds it. Also renaming --enable-perftools to --enable-perftool-debug to indicate that the switch is only relevant for debugging the heap. It's not needed to pick up tcmalloc for better performance. --with-perftools can still (and always) be used to give a hint where to find the libraries. With the threading, using tcmalloc improves memory usage on FreeBSD significantly when running on a trace. If it fixes the live problems, remains to be seen ... --- CMakeLists.txt | 20 +++++++++++++++----- cmake | 2 +- configure | 9 ++++----- src/DPM.cc | 2 +- src/File.cc | 4 ++-- src/ID.cc | 2 +- src/Login.cc | 2 +- src/PersistenceSerializer.cc | 2 +- src/RemoteSerializer.cc | 4 ++-- src/RuleMatcher.cc | 2 +- src/StateAccess.cc | 2 +- src/main.cc | 18 +++++++++--------- src/util.h | 2 +- 13 files changed, 40 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de3138c20c..febc2d6ec1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,11 +89,20 @@ if (LIBGEOIP_FOUND) endif () set(USE_PERFTOOLS false) -if (ENABLE_PERFTOOLS) - find_package(GooglePerftools) - if (GOOGLEPERFTOOLS_FOUND) - set(USE_PERFTOOLS true) - include_directories(BEFORE ${GooglePerftools_INCLUDE_DIR}) +set(USE_PERFTOOLS_DEBUG false) + +find_package(GooglePerftools) + +if (GOOGLEPERFTOOLS_FOUND) + include_directories(BEFORE ${GooglePerftools_INCLUDE_DIR}) + set(USE_PERFTOOLS true) + + if (ENABLE_PERFTOOLS_DEBUG) + # Enable heap debugging with perftools. + set(USE_PERFTOOLS_DEBUG true) + list(APPEND OPTLIBS ${GooglePerftools_LIBRARIES_DEBUG}) + else () + # Link in tcmalloc for better performance. list(APPEND OPTLIBS ${GooglePerftools_LIBRARIES}) endif () endif () @@ -183,6 +192,7 @@ message( "\n" "\nGeoIP: ${USE_GEOIP}" "\nGoogle perftools: ${USE_PERFTOOLS}" + "\n debugging: ${USE_PERFTOOLS_DEBUG}" "\n" "\n================================================================\n" ) diff --git a/cmake b/cmake index 2cc1055770..4b573ed849 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 2cc105577044a2d214124568f3f2496ed2ccbb34 +Subproject commit 4b573ed849f131ebb8e34fa24786d56f9805e444 diff --git a/configure b/configure index 43afb4ae99..05aa12815b 100755 --- a/configure +++ b/configure @@ -27,7 +27,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... Optional Features: --enable-debug compile in debugging mode - --enable-perftools use Google's perftools + --enable-perftools-debug use Google's perftools for debugging --disable-broccoli don't build or install the Broccoli library --disable-broctl don't install Broctl --disable-auxtools don't build or install auxilliary tools @@ -91,7 +91,7 @@ append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING /usr/local/bro/share/bro append_cache_entry ENABLE_DEBUG BOOL false -append_cache_entry ENABLE_PERFTOOLS BOOL false +append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL false append_cache_entry BinPAC_SKIP_INSTALL BOOL true append_cache_entry BUILD_SHARED_LIBS BOOL true append_cache_entry INSTALL_AUX_TOOLS BOOL true @@ -132,8 +132,8 @@ while [ $# -ne 0 ]; do --enable-debug) append_cache_entry ENABLE_DEBUG BOOL true ;; - --enable-perftools) - append_cache_entry ENABLE_PERFTOOLS BOOL true + --enable-perftools-debug) + append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL true ;; --disable-broccoli) append_cache_entry INSTALL_BROCCOLI BOOL false @@ -178,7 +178,6 @@ while [ $# -ne 0 ]; do append_cache_entry LibGeoIP_ROOT_DIR PATH $optarg ;; --with-perftools=*) - append_cache_entry ENABLE_PERFTOOLS BOOL true append_cache_entry GooglePerftools_ROOT_DIR PATH $optarg ;; --with-python=*) diff --git a/src/DPM.cc b/src/DPM.cc index 595ee42ec8..0902ae9a45 100644 --- a/src/DPM.cc +++ b/src/DPM.cc @@ -74,7 +74,7 @@ void DPM::PostScriptInit() void DPM::AddConfig(const Analyzer::Config& cfg) { -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG HeapLeakChecker::Disabler disabler; #endif diff --git a/src/File.cc b/src/File.cc index 080923ad37..d4e31bcc16 100644 --- a/src/File.cc +++ b/src/File.cc @@ -232,7 +232,7 @@ BroFile::~BroFile() delete [] access; delete [] cipher_buffer; -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG heap_checker->UnIgnoreObject(this); #endif } @@ -255,7 +255,7 @@ void BroFile::Init() cipher_ctx = 0; cipher_buffer = 0; -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG heap_checker->IgnoreObject(this); #endif } diff --git a/src/ID.cc b/src/ID.cc index 3f5c76ca1d..a70aa3fd0e 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -372,7 +372,7 @@ ID* ID::Unserialize(UnserialInfo* info) Ref(id); global_scope()->Insert(id->Name(), id); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG heap_checker->IgnoreObject(id); #endif } diff --git a/src/Login.cc b/src/Login.cc index 56efd12f53..e626fb3a0a 100644 --- a/src/Login.cc +++ b/src/Login.cc @@ -38,7 +38,7 @@ Login_Analyzer::Login_Analyzer(AnalyzerTag::Tag tag, Connection* conn) if ( ! re_skip_authentication ) { -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG HeapLeakChecker::Disabler disabler; #endif re_skip_authentication = init_RE(skip_authentication); diff --git a/src/PersistenceSerializer.cc b/src/PersistenceSerializer.cc index c757467f90..d9baad05bb 100644 --- a/src/PersistenceSerializer.cc +++ b/src/PersistenceSerializer.cc @@ -137,7 +137,7 @@ bool PersistenceSerializer::CheckForFile(UnserialInfo* info, const char* file, bool PersistenceSerializer::ReadAll(bool is_init, bool delete_files) { -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG HeapLeakChecker::Disabler disabler; #endif diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index f29e907790..e9fbe0aab8 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -2645,7 +2645,7 @@ bool RemoteSerializer::ProcessLogCreateWriter() if ( current_peer->state == Peer::CLOSING ) return false; -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG // Don't track allocations here, they'll be released only after the // main loop exists. And it's just a tiny amount anyway. HeapLeakChecker::Disabler disabler; @@ -2866,7 +2866,7 @@ void RemoteSerializer::GotID(ID* id, Val* val) (desc && *desc) ? desc : "not set"), current_peer); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG // May still be cached, but we don't care. heap_checker->IgnoreObject(id); #endif diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index da12b1b679..c9cf1f5c11 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -191,7 +191,7 @@ void RuleMatcher::Delete(RuleHdrTest* node) bool RuleMatcher::ReadFiles(const name_list& files) { -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG HeapLeakChecker::Disabler disabler; #endif diff --git a/src/StateAccess.cc b/src/StateAccess.cc index 7abef72c46..2d0a8dfc5a 100644 --- a/src/StateAccess.cc +++ b/src/StateAccess.cc @@ -678,7 +678,7 @@ bool StateAccess::DoUnserialize(UnserialInfo* info) target.id = new ID(name, SCOPE_GLOBAL, true); Ref(target.id); global_scope()->Insert(name, target.id); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG heap_checker->IgnoreObject(target.id); #endif } diff --git a/src/main.cc b/src/main.cc index e484b58fe2..17a798ea81 100644 --- a/src/main.cc +++ b/src/main.cc @@ -65,7 +65,7 @@ extern "C" { #include "setsignal.h" }; -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG HeapLeakChecker* heap_checker = 0; int perftools_leaks = 0; int perftools_profile = 0; @@ -177,7 +177,7 @@ void usage() fprintf(stderr, " -W|--watchdog | activate watchdog timer\n"); fprintf(stderr, " -Z|--doc-scripts | generate documentation for all loaded scripts\n"); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG fprintf(stderr, " -m|--mem-leaks | show leaks [perftools]\n"); fprintf(stderr, " -M|--mem-profile | record heap [perftools]\n"); #endif @@ -244,7 +244,7 @@ void done_with_network() net_finish(1); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG if ( perftools_profile ) { @@ -424,7 +424,7 @@ int main(int argc, char** argv) #ifdef USE_IDMEF {"idmef-dtd", required_argument, 0, 'n'}, #endif -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG {"mem-leaks", no_argument, 0, 'm'}, {"mem-profile", no_argument, 0, 'M'}, #endif @@ -466,7 +466,7 @@ int main(int argc, char** argv) safe_strncpy(opts, "B:D:e:f:I:i:K:l:n:p:R:r:s:T:t:U:w:x:X:y:Y:z:CFGLOPSWbdghvZ", sizeof(opts)); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG strncat(opts, "mM", 2); #endif @@ -622,7 +622,7 @@ int main(int argc, char** argv) exit(0); break; -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG case 'm': perftools_leaks = 1; break; @@ -758,14 +758,14 @@ int main(int argc, char** argv) // nevertheless reported; see perftools docs), thus // we suppress some messages here. -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG { HeapLeakChecker::Disabler disabler; #endif yyparse(); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG } #endif @@ -1019,7 +1019,7 @@ int main(int argc, char** argv) if ( profiling_logger ) profiling_logger->Log(); -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG if ( perftools_leaks ) heap_checker = new HeapLeakChecker("net_run"); diff --git a/src/util.h b/src/util.h index 498bdf00e4..a4e3aa71b8 100644 --- a/src/util.h +++ b/src/util.h @@ -37,7 +37,7 @@ #endif -#ifdef USE_PERFTOOLS +#ifdef USE_PERFTOOLS_DEBUG #include #include extern HeapLeakChecker* heap_checker; From c382439079755f1ca613881b1699ba77bfe9f246 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 28 Mar 2012 15:39:56 -0700 Subject: [PATCH 24/27] Switching log buffer size back to normal --- src/RemoteSerializer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index e9fbe0aab8..017f260bdf 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -234,7 +234,7 @@ static const int PRINT_BUFFER_SIZE = 10 * 1024; static const int SOCKBUF_SIZE = 1024 * 1024; // Buffer size for remote-log data. -static const int LOG_BUFFER_SIZE = 512; +static const int LOG_BUFFER_SIZE = 50 * 1024; struct ping_args { uint32 seq; From 76af3cf825037353b2a8ae09e59ab0cf7333128f Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 28 Mar 2012 15:52:13 -0700 Subject: [PATCH 25/27] Updating submodule(s). [nomail] --- aux/broctl | 2 +- aux/btest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aux/broctl b/aux/broctl index 66e9e87bee..c86b7e990b 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 66e9e87beebce983fa0f479b0284d5690b0290d4 +Subproject commit c86b7e990b4d39cd48c0cb692077aa081b418149 diff --git a/aux/btest b/aux/btest index dc78a3ebf5..120c978a12 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit dc78a3ebf5cd8fbd1b3034990e36fa21a51d1a19 +Subproject commit 120c978a1236db4f48c6f38a3a99199d85bb904e From 97652bc144df90b63f3ab075e4e3b4e7932ab3ac Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 28 Mar 2012 16:15:52 -0700 Subject: [PATCH 26/27] Updating submodule(s). [nomail] --- aux/btest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/btest b/aux/btest index 120c978a12..c8e8fe477b 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 120c978a1236db4f48c6f38a3a99199d85bb904e +Subproject commit c8e8fe477b5dec635e5ce00f3f764fad069c549c From 6e7faafdb7bbf46306a186a033a85e3b34dd364d Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 30 Mar 2012 12:40:31 -0500 Subject: [PATCH 27/27] Fix compile errors due to now-explicit IPAddr ctors and global IPFamily enum. --- src/IP.cc | 6 +++--- src/bro.bif | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IP.cc b/src/IP.cc index 7f616fbbb0..bb60d17f15 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -74,8 +74,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const rv->Assign(2, new Val(ntohs(ip6->ip6_plen), TYPE_COUNT)); rv->Assign(3, new Val(ip6->ip6_nxt, TYPE_COUNT)); rv->Assign(4, new Val(ip6->ip6_hlim, TYPE_COUNT)); - rv->Assign(5, new AddrVal(ip6->ip6_src)); - rv->Assign(6, new AddrVal(ip6->ip6_dst)); + rv->Assign(5, new AddrVal(IPAddr(ip6->ip6_src))); + rv->Assign(6, new AddrVal(IPAddr(ip6->ip6_dst))); if ( ! chain ) chain = new VectorVal(new VectorType( hdrType(ip6_ext_hdr_type, "ip6_ext_hdr")->Ref())); @@ -314,7 +314,7 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) if ( ((const struct ip6_rthdr*)hdrs)->ip6r_segleft > 0 ) { const in6_addr* a = (const in6_addr*)(hdrs+len-16); - reporter->Weird(src, *a, "routing0_segleft"); + reporter->Weird(src, IPAddr(*a), "routing0_segleft"); } else { diff --git a/src/bro.bif b/src/bro.bif index 6766a89142..fa6766a7bf 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2070,7 +2070,7 @@ function routing0_data_to_addrs%(s: string%): addr_vec while ( len > 0 ) { - IPAddr a(IPAddr::IPv6, (const uint32*) bytes, IPAddr::Network); + IPAddr a(IPv6, (const uint32*) bytes, IPAddr::Network); rval->Assign(rval->Size(), new AddrVal(a), 0); bytes += 16; len -= 16;