From f4101b52659e19bea11a94c7e51fcfa501e4317c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 27 Mar 2012 16:05:45 -0500 Subject: [PATCH 1/5] Improve handling of IPv6 routing type 0 extension headers. - flow_weird event with name argument value of "routing0_hdr" is raised for packets containing an IPv6 routing type 0 header because this type of header is now deprecated according to RFC 5095. - packets with a routing type 0 header and non-zero segments left now use the last address in that header in order to associate with a connection/flow and for calculating TCP/UDP checksums. - added a set of IPv4/IPv6 TCP/UDP checksum unit tests --- src/EventHandler.h | 1 - src/Frag.cc | 2 +- src/IP.cc | 14 ++++ src/IP.h | 56 ++++++++++++- src/PacketFilter.cc | 2 +- src/PacketSort.cc | 2 +- src/Reassem.cc | 3 +- src/Reassem.h | 3 +- src/Reporter.h | 1 - src/Serializer.cc | 2 +- src/Sessions.cc | 6 +- src/TCP_Endpoint.cc | 20 ++--- src/TCP_Endpoint.h | 1 - src/TCP_Reassembler.cc | 2 +- src/UDP.cc | 32 +++++-- src/UDP.h | 5 ++ src/bro.bif | 3 + src/net_util.cc | 79 ------------------ src/net_util.h | 12 +-- testing/btest/Baseline/core.checksums/bad.out | 9 ++ .../btest/Baseline/core.checksums/good.out | 2 + .../Baseline/core.ipv6_ext_headers/output | 2 + .../btest/Traces/chksums/ip4-bad-chksum.pcap | Bin 0 -> 86 bytes .../Traces/chksums/ip4-tcp-bad-chksum.pcap | Bin 0 -> 94 bytes .../Traces/chksums/ip4-tcp-good-chksum.pcap | Bin 0 -> 94 bytes .../Traces/chksums/ip4-udp-bad-chksum.pcap | Bin 0 -> 86 bytes .../Traces/chksums/ip4-udp-good-chksum.pcap | Bin 0 -> 86 bytes .../chksums/ip6-route0-tcp-bad-chksum.pcap | Bin 0 -> 154 bytes .../chksums/ip6-route0-tcp-good-chksum.pcap | Bin 0 -> 154 bytes .../chksums/ip6-route0-udp-bad-chksum.pcap | Bin 0 -> 146 bytes .../chksums/ip6-route0-udp-good-chksum.pcap | Bin 0 -> 146 bytes .../Traces/chksums/ip6-tcp-bad-chksum.pcap | Bin 0 -> 114 bytes .../Traces/chksums/ip6-tcp-good-chksum.pcap | Bin 0 -> 114 bytes .../Traces/chksums/ip6-udp-bad-chksum.pcap | Bin 0 -> 106 bytes .../Traces/chksums/ip6-udp-good-chksum.pcap | Bin 0 -> 106 bytes ..._routing.trace => ipv6-hbh-routing0.trace} | Bin .../btest/bifs/routing0_data_to_addrs.test | 2 +- testing/btest/core/checksums.test | 15 ++++ testing/btest/core/ipv6_ext_headers.test | 16 +++- 39 files changed, 171 insertions(+), 121 deletions(-) create mode 100644 testing/btest/Baseline/core.checksums/bad.out create mode 100644 testing/btest/Baseline/core.checksums/good.out create mode 100644 testing/btest/Traces/chksums/ip4-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip4-tcp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip4-tcp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip4-udp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip4-udp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-route0-tcp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-route0-tcp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-route0-udp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-route0-udp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-tcp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-tcp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-udp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-udp-good-chksum.pcap rename testing/btest/Traces/{ext_hdr_hbh_routing.trace => ipv6-hbh-routing0.trace} (100%) create mode 100644 testing/btest/core/checksums.test diff --git a/src/EventHandler.h b/src/EventHandler.h index 2aebe87584..a86b8a285c 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -7,7 +7,6 @@ #include "List.h" #include "BroList.h" -#include "net_util.h" class Func; class FuncType; diff --git a/src/Frag.cc b/src/Frag.cc index 9bd16a71c9..6c27450f37 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -28,7 +28,7 @@ void FragTimer::Dispatch(double t, int /* is_expire */) FragReassembler::FragReassembler(NetSessions* arg_s, const IP_Hdr* ip, const u_char* pkt, HashKey* k, double t) -: Reassembler(0, ip->DstAddr(), REASSEM_IP) +: Reassembler(0, REASSEM_IP) { s = arg_s; key = k; diff --git a/src/IP.cc b/src/IP.cc index 4148c58a33..620b294d40 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -305,6 +305,20 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) chain.push_back(p); + // Check for routing type 0 header. + if ( current_type == IPPROTO_ROUTING && + ((const struct ip6_rthdr*)hdrs)->ip6r_type == 0 ) + { + if ( ((const struct ip6_rthdr*)hdrs)->ip6r_segleft > 0 ) + // Remember the index for later so we can determine the final + // destination of the packet. + route0_hdr_idx = chain.size() - 1; + + // RFC 5095 deprecates routing type 0 headers, so raise weirds + IPAddr src(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); + reporter->Weird(src, FinalDst(), "routing0_hdr"); + } + hdrs += len; length += len; } while ( current_type != IPPROTO_FRAGMENT && diff --git a/src/IP.h b/src/IP.h index cb5bcf77c7..7ed0968ef3 100644 --- a/src/IP.h +++ b/src/IP.h @@ -117,7 +117,8 @@ public: /** * Initializes the header chain from an IPv6 header structure. */ - IPv6_Hdr_Chain(const struct ip6_hdr* ip6) { Init(ip6, false); } + IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : route0_hdr_idx(0) + { Init(ip6, false); } ~IPv6_Hdr_Chain() { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; } @@ -171,6 +172,27 @@ public: { return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } + /** + * Returns the final destination of the packet this chain belongs to. + * If the chain doesn't contain any routing type 0 header with non-zero + * segments left, this is the destination in the main IP header, else + * it's the last address in the routing header. (If there were to be + * more than one routing type 0 header with non-zero segments left, the + * last one would be the one referenced). + */ + IPAddr FinalDst() const + { + if ( route0_hdr_idx ) + { + const struct in6_addr* a = (const struct in6_addr*) + (chain[route0_hdr_idx]->Data() + + chain[route0_hdr_idx]->Length() - 16); + return IPAddr(*a); + } + else + return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst); + } + /** * Returns a vector of ip6_ext_hdr RecordVals that includes script-layer * representation of all extension headers in the chain. @@ -186,13 +208,24 @@ protected: * 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) + IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) : route0_hdr_idx(0) { Init(ip6, true, next); } 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. + + /** + * The summation of all header lengths in the chain in bytes. + */ + uint16 length; + + /** + * Index of routing type 0 header with non-zero segments left in the header + * chain or zero if none exists (it's fine since the main IP header must + * always be at index zero). + */ + uint8 route0_hdr_idx; }; class IP_Hdr { @@ -248,7 +281,22 @@ public: IPAddr SrcAddr() const { return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); } - IPAddr DstAddr() const + /** + * Returns the final destination address of the header's packet, which + * for IPv6 packets without a routing type 0 extension header and IPv4 + * packets is the destination address in the IP header. For IPv6 packets + * with a routing type 0 extension header and a non-zero number of + * segments left, the final destination is the last address in the routing + * header. If the segments left of a routing type 0 header were zero, + * then the final destination is in the IP header itself. + */ + IPAddr FinalDstAddr() const + { return ip4 ? IPAddr(ip4->ip_dst) : ip6_hdrs->FinalDst(); } + + /** + * Returns the destination address held in the IP header. + */ + IPAddr IPHeaderDstAddr() const { return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); } /** diff --git a/src/PacketFilter.cc b/src/PacketFilter.cc index 4fb3b1c8f7..412bf14587 100644 --- a/src/PacketFilter.cc +++ b/src/PacketFilter.cc @@ -58,7 +58,7 @@ bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen) if ( f ) return MatchFilter(*f, *ip, len, caplen); - f = (Filter*) dst_filter.Lookup(ip->DstAddr(), 128); + f = (Filter*) dst_filter.Lookup(ip->FinalDstAddr(), 128); if ( f ) return MatchFilter(*f, *ip, len, caplen); diff --git a/src/PacketSort.cc b/src/PacketSort.cc index 04c525c4d1..3fb0e9ccbf 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -45,7 +45,7 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, (pkt + tcp_offset); id.src_addr = ip_hdr->SrcAddr(); - id.dst_addr = ip_hdr->DstAddr(); + id.dst_addr = ip_hdr->FinalDstAddr(); id.src_port = tp->th_sport; id.dst_port = tp->th_dport; id.is_one_way = 0; diff --git a/src/Reassem.cc b/src/Reassem.cc index fb445c08f7..c3c19ff0e6 100644 --- a/src/Reassem.cc +++ b/src/Reassem.cc @@ -43,8 +43,7 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq, unsigned int Reassembler::total_size = 0; -Reassembler::Reassembler(int init_seq, const IPAddr& ip_addr, - ReassemblerType arg_type) +Reassembler::Reassembler(int init_seq, ReassemblerType arg_type) { blocks = last_block = 0; trim_seq = last_reassem_seq = init_seq; diff --git a/src/Reassem.h b/src/Reassem.h index c9590ea949..1f65059e02 100644 --- a/src/Reassem.h +++ b/src/Reassem.h @@ -26,8 +26,7 @@ enum ReassemblerType { REASSEM_IP, REASSEM_TCP }; class Reassembler : public BroObj { public: - Reassembler(int init_seq, const IPAddr& ip_addr, - ReassemblerType arg_type); + Reassembler(int init_seq, ReassemblerType arg_type); virtual ~Reassembler(); void NewBlock(double t, int seq, int len, const u_char* data); diff --git a/src/Reporter.h b/src/Reporter.h index 210dd241d2..e610e1519e 100644 --- a/src/Reporter.h +++ b/src/Reporter.h @@ -9,7 +9,6 @@ #include #include "util.h" -#include "net_util.h" #include "EventHandler.h" #include "IPAddr.h" diff --git a/src/Serializer.cc b/src/Serializer.cc index 06bbf73f48..6aa554cc2b 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1105,7 +1105,7 @@ void Packet::Describe(ODesc* d) const const IP_Hdr ip = IP(); d->Add(ip.SrcAddr()); d->Add("->"); - d->Add(ip.DstAddr()); + d->Add(ip.FinalDstAddr()); } bool Packet::Serialize(SerialInfo* info) const diff --git a/src/Sessions.cc b/src/Sessions.cc index 84b57bdc62..4b5f201db5 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -493,7 +493,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, ConnID id; id.src_addr = ip_hdr->SrcAddr(); - id.dst_addr = ip_hdr->DstAddr(); + id.dst_addr = ip_hdr->FinalDstAddr(); Dictionary* d = 0; switch ( proto ) { @@ -667,7 +667,7 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, ListVal* key = new ListVal(TYPE_ANY); key->Append(new AddrVal(ip->SrcAddr())); - key->Append(new AddrVal(ip->DstAddr())); + key->Append(new AddrVal(ip->FinalDstAddr())); key->Append(new Val(frag_id, TYPE_COUNT)); HashKey* h = ch->ComputeHash(key, 1); @@ -1177,7 +1177,7 @@ void NetSessions::Weird(const char* name, void NetSessions::Weird(const char* name, const IP_Hdr* ip) { - reporter->Weird(ip->SrcAddr(), ip->DstAddr(), name); + reporter->Weird(ip->SrcAddr(), ip->FinalDstAddr(), name); } unsigned int NetSessions::ConnectionMemoryUsage() diff --git a/src/TCP_Endpoint.cc b/src/TCP_Endpoint.cc index 69c08870d9..d6f5d1bb84 100644 --- a/src/TCP_Endpoint.cc +++ b/src/TCP_Endpoint.cc @@ -31,14 +31,6 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) tcp_analyzer->Conn()->OrigAddr(); dst_addr = is_orig ? tcp_analyzer->Conn()->OrigAddr() : tcp_analyzer->Conn()->RespAddr(); - - checksum_base = ones_complement_checksum(src_addr, 0); - checksum_base = ones_complement_checksum(dst_addr, checksum_base); - // Note, for IPv6, strictly speaking this field is 32 bits - // rather than 16 bits. But because the upper bits are all zero, - // we get the same checksum either way. The same applies to - // later when we add in the data length in ValidChecksum(). - checksum_base += htons(IPPROTO_TCP); } TCP_Endpoint::~TCP_Endpoint() @@ -108,13 +100,21 @@ void TCP_Endpoint::SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) int TCP_Endpoint::ValidChecksum(const struct tcphdr* tp, int len) const { - uint32 sum = checksum_base; + uint32 sum; int tcp_len = tp->th_off * 4 + len; if ( len % 2 == 1 ) // Add in pad byte. - sum += htons(((const u_char*) tp)[tcp_len - 1] << 8); + sum = htons(((const u_char*) tp)[tcp_len - 1] << 8); + else + sum = 0; + sum = ones_complement_checksum(src_addr, sum); + sum = ones_complement_checksum(dst_addr, sum); + // Note, for IPv6, strictly speaking the protocol and length fields are + // 32 bits rather than 16 bits. But because the upper bits are all zero, + // we get the same checksum either way. + sum += htons(IPPROTO_TCP); sum += htons((unsigned short) tcp_len); // fill out pseudo header sum = ones_complement_checksum((void*) tp, tcp_len, sum); diff --git a/src/TCP_Endpoint.h b/src/TCP_Endpoint.h index 52a757b256..28a114adf3 100644 --- a/src/TCP_Endpoint.h +++ b/src/TCP_Endpoint.h @@ -127,7 +127,6 @@ public: TCP_Reassembler* contents_processor; TCP_Analyzer* tcp_analyzer; BroFile* contents_file; - uint32 checksum_base; double start_time, last_time; IPAddr src_addr; // the other endpoint diff --git a/src/TCP_Reassembler.cc b/src/TCP_Reassembler.cc index ba31ab68d0..215af07bd7 100644 --- a/src/TCP_Reassembler.cc +++ b/src/TCP_Reassembler.cc @@ -29,7 +29,7 @@ TCP_Reassembler::TCP_Reassembler(Analyzer* arg_dst_analyzer, TCP_Analyzer* arg_tcp_analyzer, TCP_Reassembler::Type arg_type, bool arg_is_orig, TCP_Endpoint* arg_endp) -: Reassembler(1, arg_endp->dst_addr, REASSEM_TCP) +: Reassembler(1, REASSEM_TCP) { dst_analyzer = arg_dst_analyzer; tcp_analyzer = arg_tcp_analyzer; diff --git a/src/UDP.cc b/src/UDP.cc index c5dfe2c316..fc559bf59d 100644 --- a/src/UDP.cc +++ b/src/UDP.cc @@ -57,12 +57,14 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, { bool bad = false; - if ( ip->IP4_Hdr() && chksum && - udp_checksum(ip->IP4_Hdr(), up, len) != 0xffff ) - bad = true; + if ( ip->IP4_Hdr() ) + { + if ( chksum && ! ValidateChecksum(ip, up, len) ) + bad = true; + } - if ( ip->IP6_Hdr() && /* checksum is not optional for IPv6 */ - udp6_checksum(ip->IP6_Hdr(), up, len) != 0xffff ) + /* checksum is not optional for IPv6 */ + else if ( ! ValidateChecksum(ip, up, len) ) bad = true; if ( bad ) @@ -204,4 +206,24 @@ unsigned int UDP_Analyzer::MemoryAllocation() const return Analyzer::MemoryAllocation() + padded_sizeof(*this) - 24; } +bool UDP_Analyzer::ValidateChecksum(const IP_Hdr* ip, const udphdr* up, int len) + { + uint32 sum; + if ( len % 2 == 1 ) + // Add in pad byte. + sum = htons(((const u_char*) up)[len - 1] << 8); + else + sum = 0; + + sum = ones_complement_checksum(ip->SrcAddr(), sum); + sum = ones_complement_checksum(ip->FinalDstAddr(), sum); + // Note, for IPv6, strictly speaking the protocol and length fields are + // 32 bits rather than 16 bits. But because the upper bits are all zero, + // we get the same checksum either way. + sum += htons(IPPROTO_UDP); + sum += htons((unsigned short) len); + sum = ones_complement_checksum((void*) up, len, sum); + + return sum == 0xffff; + } diff --git a/src/UDP.h b/src/UDP.h index 5124adf4cd..b93d4da97f 100644 --- a/src/UDP.h +++ b/src/UDP.h @@ -4,6 +4,7 @@ #define udp_h #include "Analyzer.h" +#include typedef enum { UDP_INACTIVE, // no packet seen @@ -31,6 +32,10 @@ protected: virtual bool IsReuse(double t, const u_char* pkt); virtual unsigned int MemoryAllocation() const; + // Returns true if the checksum is valid, false if not + static bool ValidateChecksum(const IP_Hdr* ip, const struct udphdr* up, + int len); + bro_int_t request_len, reply_len; private: diff --git a/src/bro.bif b/src/bro.bif index 64ed7d1f2f..025a238b00 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -4798,6 +4798,9 @@ function uninstall_src_net_filter%(snet: subnet%) : bool ## Installs a filter to drop packets destined to a given IP address with ## a certain probability if none of a given set of TCP flags are set. +## Note that for IPv6 packets with a routing type 0 header and non-zero +## segments left, this filters out against the final destination of the +## packet according to the routing extension header. ## ## ip: Drop packets to this IP address. ## diff --git a/src/net_util.cc b/src/net_util.cc index 1a4e9f1a7f..ef59154304 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -31,85 +31,6 @@ int ones_complement_checksum(const void* p, int b, uint32 sum) return sum; } -int ones_complement_checksum(const IPAddr& a, uint32 sum) - { - const uint32* bytes; - int len = a.GetBytes(&bytes); - 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; - - if ( len % 2 == 1 ) - // Add in pad byte. - sum = htons(((const u_char*) up)[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_UDP) << 16) | htons((unsigned short) len); - - sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum); - sum = ones_complement_checksum((void*) up, len, sum); - - return sum; - } - -int udp6_checksum(const struct ip6_hdr* ip6, const struct udphdr* up, int len) - { - uint32 sum; - - if ( len % 2 == 1 ) - // Add in pad byte. - sum = htons(((const u_char*) up)[len - 1] << 8); - else - sum = 0; - - sum = ones_complement_checksum((void*) ip6->ip6_src.s6_addr, 16, sum); - sum = ones_complement_checksum((void*) ip6->ip6_dst.s6_addr, 16, sum); - - uint32 l = htonl(len); - sum = ones_complement_checksum((void*) &l, 4, sum); - - uint32 addl_pseudo = htons(IPPROTO_UDP); - sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum); - sum = ones_complement_checksum((void*) up, len, sum); - - return sum; - } - int icmp_checksum(const struct icmp* icmpp, int len) { uint32 sum; diff --git a/src/net_util.h b/src/net_util.h index 8787340328..a10b283ca1 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -60,12 +60,14 @@ inline int seq_delta(uint32 a, uint32 b) // Returns the ones-complement checksum of a chunk of b short-aligned bytes. 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); +inline int ones_complement_checksum(const IPAddr& a, uint32 sum) + { + const uint32* bytes; + int len = a.GetBytes(&bytes); + return ones_complement_checksum(bytes, len*4, sum); + } + extern int icmp_checksum(const struct icmp* icmpp, int len); // Returns 'A', 'B', 'C' or 'D' diff --git a/testing/btest/Baseline/core.checksums/bad.out b/testing/btest/Baseline/core.checksums/bad.out new file mode 100644 index 0000000000..cd3c799277 --- /dev/null +++ b/testing/btest/Baseline/core.checksums/bad.out @@ -0,0 +1,9 @@ +1332784981.078396 weird: bad_IP_checksum +1332784885.686428 weird: bad_TCP_checksum +1332784933.501023 weird: bad_UDP_checksum +1332785210.013051 weird: routing0_hdr +1332785210.013051 weird: bad_TCP_checksum +1332782580.798420 weird: routing0_hdr +1332782580.798420 weird: bad_UDP_checksum +1332785250.469132 weird: bad_TCP_checksum +1332781342.923813 weird: bad_UDP_checksum diff --git a/testing/btest/Baseline/core.checksums/good.out b/testing/btest/Baseline/core.checksums/good.out new file mode 100644 index 0000000000..627a330928 --- /dev/null +++ b/testing/btest/Baseline/core.checksums/good.out @@ -0,0 +1,2 @@ +1332785125.596793 weird: routing0_hdr +1332782508.592037 weird: routing0_hdr diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output index a5a0caf7c6..c6ebddc7e1 100644 --- a/testing/btest/Baseline/core.ipv6_ext_headers/output +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -1 +1,3 @@ +weird routing0_hdr from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:78:1:32::2 +[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=53/udp, resp_h=2001:78:1:32::2, resp_p=53/udp] [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/Traces/chksums/ip4-bad-chksum.pcap b/testing/btest/Traces/chksums/ip4-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..6d8b9dd27daeda798a5fa7c56f4b419f10b83ab1 GIT binary patch literal 86 zcmca|c+)~A1{MYwaA0F#U<7hP*BAKP7%?*F0ofq@9}FO>I2c?R7!*Lt90VB{>wy|T QxYWSt1Ov}Xtq33h0Oq<8UH||9 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip4-tcp-bad-chksum.pcap b/testing/btest/Traces/chksums/ip4-tcp-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b9ccd9e6b26cecfe37ce796a8503940e338096dc GIT binary patch literal 94 zcmca|c+)~A1{MYwaA0F#U<7i$t}F15spMiX1F}K*KNvt%aWJ?tFld03Ik457tp{oV S;Zg&J0Ej#TLjaQk*cbr7LlH~> literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip4-tcp-good-chksum.pcap b/testing/btest/Traces/chksums/ip4-tcp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ff3f01188473b75e4c4521c9d4944e54ebff953c GIT binary patch literal 94 zcmca|c+)~A1{MYwaA0F#U<7g|tt;@i;N)g71F}K*KNvt%aWJ?tFld03Ik457tp{oV V;Zg&J0Ej#TLjaQkgG>Sg0|0?W5YYet literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip4-udp-bad-chksum.pcap b/testing/btest/Traces/chksums/ip4-udp-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..f3998c7e1c5a45f744b76e80226f7481916ef424 GIT binary patch literal 86 zcmca|c+)~A1{MYwaA0F#U<7hh*BAK9FJ))Y1F}K*KNvt%aWJ?tFereOISAIAst0NS Q;Zg&m6AU~Ij1fQp00ra`{Qv*} literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip4-udp-good-chksum.pcap b/testing/btest/Traces/chksums/ip4-udp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3aec5073295329666899654a9ff79d613d77eb5b GIT binary patch literal 86 zcmca|c+)~A1{MYwaA0F#U<7gm*BAIRP3K_H1F}K*KNvt%aWJ?tFereOISAIAst0NS Q;Zg&m6AU~nwIYB30Q^W2kpKVy literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-route0-tcp-bad-chksum.pcap b/testing/btest/Traces/chksums/ip6-route0-tcp-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0f5711fe2ed6e8b3620518a98e145e909bc3d811 GIT binary patch literal 154 zcmca|c+)~A1{MYwaA0F#U<7ikHWc{(Hez5X0JIQ6c|~405!8S zJ!t&@FX;b&RQ{}NHWmgZkWvLkh6UVqgFOQoA42 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-route0-tcp-good-chksum.pcap b/testing/btest/Traces/chksums/ip6-route0-tcp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..18f9a366c6b72243ce5cb98e634e25975055b4b6 GIT binary patch literal 154 zcmca|c+)~A1{MYwaA0F#U<7iWt}pPnl;&h80JIQ6c|~405!8S zJ!t&@FX;b&RQ{}NHWmgZkWvLkh683QjX-Q5U_|3Hl^PhGVBpyk5&;ANrB5PK literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-route0-udp-good-chksum.pcap b/testing/btest/Traces/chksums/ip6-route0-udp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..deb1310107c9999ae5c90d11fe4b9ff42c0d68dc GIT binary patch literal 146 zcmca|c+)~A1{MYwaA0F#U<7j3EG_U~%E8Hy1!RNpe=vZkYP*{NVwh+83QjX-Q5U_|3Hl^PhGVBopu5dj1MTPq>R literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-tcp-bad-chksum.pcap b/testing/btest/Traces/chksums/ip6-tcp-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..38d8abf18fc0fa1c61048d80819f854c543f3c98 GIT binary patch literal 114 zcmca|c+)~A1{MYwaA0F#U<7iKHWc{xXs|PQ0ofq@9}FO>+U_QR7$R&A3XCj2fSTEv d9yI>{7xe!>Dt}gXsR2U(L=OW)0FwgPXaH!=9F710 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-tcp-good-chksum.pcap b/testing/btest/Traces/chksums/ip6-tcp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9ab19b0ad86b11cbf3e10406df3c14772959324e GIT binary patch literal 114 zcmca|c+)~A1{MYwaA0F#U<7gsHx&5Kw%}s$0Ed8;06B7gt@!gL?h literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ext_hdr_hbh_routing.trace b/testing/btest/Traces/ipv6-hbh-routing0.trace similarity index 100% rename from testing/btest/Traces/ext_hdr_hbh_routing.trace rename to testing/btest/Traces/ipv6-hbh-routing0.trace diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test index 4bf15cae87..a20bb3bf59 100644 --- a/testing/btest/bifs/routing0_data_to_addrs.test +++ b/testing/btest/bifs/routing0_data_to_addrs.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-routing0.trace %INPUT >output # @TEST-EXEC: btest-diff output event ipv6_ext_headers(c: connection, p: pkt_hdr) diff --git a/testing/btest/core/checksums.test b/testing/btest/core/checksums.test new file mode 100644 index 0000000000..c01ab710af --- /dev/null +++ b/testing/btest/core/checksums.test @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: btest-diff bad.out +# @TEST-EXEC: btest-diff good.out diff --git a/testing/btest/core/ipv6_ext_headers.test b/testing/btest/core/ipv6_ext_headers.test index 170a67bc72..32a0f5d558 100644 --- a/testing/btest/core/ipv6_ext_headers.test +++ b/testing/btest/core/ipv6_ext_headers.test @@ -1,10 +1,22 @@ -# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-routing0.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; } + +# Also check the weird for routing type 0 extensions headers +event flow_weird(name: string, src: addr, dst: addr) + { + print fmt("weird %s from %s to %s", name, src, dst); + } + +# And the connection for routing type 0 packets with non-zero segments left +# should use the last address in that extension header. +event new_connection(c: connection) + { + print c$id; + } From 3a4d03560340a955c625ac1c89b8f6b4ba6e86d9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 29 Mar 2012 14:29:33 -0500 Subject: [PATCH 2/5] Revert "Improve handling of IPv6 Routing Type 0 headers." This reverts commit 256cd592a7d4c0bdbf43c3f2e9c4e1cdb0fe995a. Conflicts: src/IP.cc src/Sessions.cc --- 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 -- ...egleft.trace => ext_hdr_hbh_routing.trace} | Bin .../btest/Traces/ipv6-hbh-rh0-segleft0.trace | Bin 162 -> 0 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, 4 insertions(+), 93 deletions(-) delete mode 100644 testing/btest/Baseline/core.ipv6_rh0/segleft.out delete mode 100644 testing/btest/Baseline/core.ipv6_rh0/segleft0.out rename testing/btest/Traces/{ipv6-hbh-rh0-segleft.trace => ext_hdr_hbh_routing.trace} (100%) delete mode 100644 testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace delete mode 100644 testing/btest/core/ipv6_rh0.test diff --git a/src/IP.cc b/src/IP.cc index 7f616fbbb0..4148c58a33 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -305,24 +305,6 @@ 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 daa508db7f..cb5bcf77c7 100644 --- a/src/IP.h +++ b/src/IP.h @@ -171,20 +171,6 @@ 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. @@ -357,13 +343,6 @@ 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 9ab7d1d1fa..84b57bdc62 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -481,22 +481,6 @@ 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 20714c0931..113c003e37 100644 --- a/src/event.bif +++ b/src/event.bif @@ -478,14 +478,6 @@ 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 58332ca900..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=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=] +[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/Baseline/core.ipv6_rh0/segleft.out b/testing/btest/Baseline/core.ipv6_rh0/segleft.out deleted file mode 100644 index 3c722ee3b4..0000000000 --- a/testing/btest/Baseline/core.ipv6_rh0/segleft.out +++ /dev/null @@ -1,2 +0,0 @@ -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 deleted file mode 100644 index ae57c7cc8d..0000000000 --- a/testing/btest/Baseline/core.ipv6_rh0/segleft0.out +++ /dev/null @@ -1,2 +0,0 @@ -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/ipv6-hbh-rh0-segleft.trace b/testing/btest/Traces/ext_hdr_hbh_routing.trace similarity index 100% rename from testing/btest/Traces/ipv6-hbh-rh0-segleft.trace rename to testing/btest/Traces/ext_hdr_hbh_routing.trace diff --git a/testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace b/testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace deleted file mode 100644 index 35f5b3afe633cc81fc2444b10fa278a29d81783f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/testing/btest/bifs/routing0_data_to_addrs.test b/testing/btest/bifs/routing0_data_to_addrs.test index de10dd80e0..4bf15cae87 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 -b -r $TRACES/ipv6-hbh-rh0-segleft.trace %INPUT >output +# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output # @TEST-EXEC: btest-diff output -event rh0_segleft(p: pkt_hdr) +event ipv6_ext_headers(c: connection, 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 0cf3f2f3fb..170a67bc72 100644 --- a/testing/btest/core/ipv6_ext_headers.test +++ b/testing/btest/core/ipv6_ext_headers.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft0.trace %INPUT >output +# @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 diff --git a/testing/btest/core/ipv6_rh0.test b/testing/btest/core/ipv6_rh0.test deleted file mode 100644 index 18c23ed3b7..0000000000 --- a/testing/btest/core/ipv6_rh0.test +++ /dev/null @@ -1,22 +0,0 @@ -# @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 7d7cadfb562f68f5cd0165818968a11b3d2108c3 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 29 Mar 2012 14:41:44 -0500 Subject: [PATCH 3/5] Revert TCP checksumming to cache common data, like it did before. --- src/TCP_Endpoint.cc | 20 ++++++++++---------- src/TCP_Endpoint.h | 1 + 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/TCP_Endpoint.cc b/src/TCP_Endpoint.cc index d6f5d1bb84..69c08870d9 100644 --- a/src/TCP_Endpoint.cc +++ b/src/TCP_Endpoint.cc @@ -31,6 +31,14 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) tcp_analyzer->Conn()->OrigAddr(); dst_addr = is_orig ? tcp_analyzer->Conn()->OrigAddr() : tcp_analyzer->Conn()->RespAddr(); + + checksum_base = ones_complement_checksum(src_addr, 0); + checksum_base = ones_complement_checksum(dst_addr, checksum_base); + // Note, for IPv6, strictly speaking this field is 32 bits + // rather than 16 bits. But because the upper bits are all zero, + // we get the same checksum either way. The same applies to + // later when we add in the data length in ValidChecksum(). + checksum_base += htons(IPPROTO_TCP); } TCP_Endpoint::~TCP_Endpoint() @@ -100,21 +108,13 @@ void TCP_Endpoint::SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) int TCP_Endpoint::ValidChecksum(const struct tcphdr* tp, int len) const { - uint32 sum; + uint32 sum = checksum_base; int tcp_len = tp->th_off * 4 + len; if ( len % 2 == 1 ) // Add in pad byte. - sum = htons(((const u_char*) tp)[tcp_len - 1] << 8); - else - sum = 0; + sum += htons(((const u_char*) tp)[tcp_len - 1] << 8); - sum = ones_complement_checksum(src_addr, sum); - sum = ones_complement_checksum(dst_addr, sum); - // Note, for IPv6, strictly speaking the protocol and length fields are - // 32 bits rather than 16 bits. But because the upper bits are all zero, - // we get the same checksum either way. - sum += htons(IPPROTO_TCP); sum += htons((unsigned short) tcp_len); // fill out pseudo header sum = ones_complement_checksum((void*) tp, tcp_len, sum); diff --git a/src/TCP_Endpoint.h b/src/TCP_Endpoint.h index 28a114adf3..52a757b256 100644 --- a/src/TCP_Endpoint.h +++ b/src/TCP_Endpoint.h @@ -127,6 +127,7 @@ public: TCP_Reassembler* contents_processor; TCP_Analyzer* tcp_analyzer; BroFile* contents_file; + uint32 checksum_base; double start_time, last_time; IPAddr src_addr; // the other endpoint From 11b15cc2904325421173d956ec60dda4c4b7b89d Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 5 Apr 2012 10:50:35 -0500 Subject: [PATCH 4/5] Refactor IP_Hdr routing header handling, add MobileIPv6 Home Address handling. Packets that use the Home Address Destination option use that option's address as the connection's originator. --- src/IP.cc | 102 +++++++++++++++--- src/IP.h | 100 +++++++++++------ src/PacketFilter.cc | 2 +- src/PacketSort.cc | 2 +- src/Serializer.cc | 2 +- src/Sessions.cc | 6 +- src/UDP.cc | 2 +- src/bro.bif | 4 +- testing/btest/Baseline/core.checksums/bad.out | 2 + .../core.mobile-ipv6-home-addr/output | 2 + .../chksums/ip6-hoa-tcp-bad-chksum.pcap | Bin 0 -> 138 bytes .../chksums/ip6-hoa-tcp-good-chksum.pcap | Bin 0 -> 138 bytes .../chksums/ip6-hoa-udp-bad-chksum.pcap | Bin 0 -> 130 bytes .../chksums/ip6-hoa-udp-good-chksum.pcap | Bin 0 -> 130 bytes testing/btest/Traces/ipv6-mobile-hoa.trace | Bin 0 -> 130 bytes testing/btest/core/checksums.test | 4 + testing/btest/core/mobile-ipv6-home-addr.test | 10 ++ 17 files changed, 185 insertions(+), 53 deletions(-) create mode 100644 testing/btest/Baseline/core.mobile-ipv6-home-addr/output create mode 100644 testing/btest/Traces/chksums/ip6-hoa-tcp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-hoa-tcp-good-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-hoa-udp-bad-chksum.pcap create mode 100644 testing/btest/Traces/chksums/ip6-hoa-udp-good-chksum.pcap create mode 100644 testing/btest/Traces/ipv6-mobile-hoa.trace create mode 100644 testing/btest/core/mobile-ipv6-home-addr.test diff --git a/src/IP.cc b/src/IP.cc index 620b294d40..cce7af152f 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -305,19 +305,12 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) chain.push_back(p); - // Check for routing type 0 header. - if ( current_type == IPPROTO_ROUTING && - ((const struct ip6_rthdr*)hdrs)->ip6r_type == 0 ) - { - if ( ((const struct ip6_rthdr*)hdrs)->ip6r_segleft > 0 ) - // Remember the index for later so we can determine the final - // destination of the packet. - route0_hdr_idx = chain.size() - 1; + // Check for routing headers and remember final destination address. + if ( current_type == IPPROTO_ROUTING ) + ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, len); - // RFC 5095 deprecates routing type 0 headers, so raise weirds - IPAddr src(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); - reporter->Weird(src, FinalDst(), "routing0_hdr"); - } + if ( current_type == IPPROTO_DSTOPTS ) + ProcessDstOpts((const struct ip6_dest*) hdrs, len); hdrs += len; length += len; @@ -326,6 +319,91 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) isIPv6ExtHeader(next_type) ); } +void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len) + { + if ( finalDst ) + { + // RFC 2460 section 4.1 says Routing should occur at most once + reporter->Weird(SrcAddr(), DstAddr(), "multiple_routing_headers"); + return; + } + + // Last 16 bytes of header (for all known types) is the address we want + const in6_addr* addr = (const in6_addr*)(((const u_char*)r) + len - 16); + + switch ( r->ip6r_type ) { + case 0: // Defined by RFC 2460, deprecated by RFC 5095 + { + if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 ) + { + if ( r->ip6r_len % 2 == 0 ) + finalDst = new IPAddr(*addr); + else + reporter->Weird(SrcAddr(), DstAddr(), "odd_routing0_len"); + } + + // Always raise a weird since this type is deprecated + reporter->Weird(SrcAddr(), DstAddr(), "routing0_hdr"); + } + break; + + case 2: // Defined by Mobile IPv6 RFC 6275 + { + if ( r->ip6r_segleft > 0 ) + { + if ( r->ip6r_len == 2 ) + finalDst = new IPAddr(*addr); + else + reporter->Weird(SrcAddr(), DstAddr(), "bad_routing2_len"); + } + } + break; + + default: + reporter->Weird(fmt("unknown_routing_type_%d", r->ip6r_type)); + break; + } + } + +void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16 len) + { + const u_char* data = (const u_char*) d; + len -= 2 * sizeof(uint8); + data += 2* sizeof(uint8); + + while ( len > 0 ) + { + const struct ip6_opt* opt = (const struct ip6_opt*) data; + switch ( opt->ip6o_type ) { + case 201: // Home Address Option, Mobile IPv6 RFC 6275 section 6.3 + { + if ( opt->ip6o_len == 16 ) + if ( homeAddr ) + reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts"); + else + homeAddr = new IPAddr(*((const in6_addr*)(data + 2))); + else + reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len"); + } + break; + + default: + break; + } + + if ( opt->ip6o_type == 0 ) + { + data += sizeof(uint8); + len -= sizeof(uint8); + } + else + { + data += 2 * sizeof(uint8) + opt->ip6o_len; + len -= 2 * sizeof(uint8) + opt->ip6o_len; + } + } + } + VectorVal* IPv6_Hdr_Chain::BuildVal() const { if ( ! ip6_ext_hdr_type ) diff --git a/src/IP.h b/src/IP.h index 7ed0968ef3..4ffb59151a 100644 --- a/src/IP.h +++ b/src/IP.h @@ -117,11 +117,15 @@ public: /** * Initializes the header chain from an IPv6 header structure. */ - IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : route0_hdr_idx(0) + IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : homeAddr(0), finalDst(0) { Init(ip6, false); } ~IPv6_Hdr_Chain() - { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; } + { + for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; + delete homeAddr; + delete finalDst; + } /** * Returns the number of headers in the chain. @@ -173,22 +177,27 @@ public: (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; } /** - * Returns the final destination of the packet this chain belongs to. - * If the chain doesn't contain any routing type 0 header with non-zero - * segments left, this is the destination in the main IP header, else - * it's the last address in the routing header. (If there were to be - * more than one routing type 0 header with non-zero segments left, the - * last one would be the one referenced). + * If the chain contains a Destination Options header with a Home Address + * option as defined by Mobile IPv6 (RFC 6275), then return it, else + * return the source address in the main IPv6 header. */ - IPAddr FinalDst() const + IPAddr SrcAddr() const { - if ( route0_hdr_idx ) - { - const struct in6_addr* a = (const struct in6_addr*) - (chain[route0_hdr_idx]->Data() + - chain[route0_hdr_idx]->Length() - 16); - return IPAddr(*a); - } + if ( homeAddr ) + return IPAddr(*homeAddr); + else + return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); + } + + /** + * If the chain contains a Routing header with non-zero segments left, + * then return the last address of the first such header, else return + * the destination address of the main IPv6 header. + */ + IPAddr DstAddr() const + { + if ( finalDst ) + return IPAddr(*finalDst); else return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst); } @@ -208,11 +217,24 @@ protected: * 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) : route0_hdr_idx(0) + IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) + : homeAddr(0), finalDst(0) { Init(ip6, true, next); } void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0); + /** + * Process a routing header and allocate/remember the final destination + * address if it has segments left and is a valid routing header. + */ + void ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len); + + /** + * Inspect a Destination Option header's options for things we need to + * remember, such as the Home Address option from Mobile IPv6. + */ + void ProcessDstOpts(const struct ip6_dest* d, uint16 len); + vector chain; /** @@ -221,11 +243,15 @@ protected: uint16 length; /** - * Index of routing type 0 header with non-zero segments left in the header - * chain or zero if none exists (it's fine since the main IP header must - * always be at index zero). + * Home Address of the packet's source as defined by Mobile IPv6 (RFC 6275). */ - uint8 route0_hdr_idx; + IPAddr* homeAddr; + + /** + * The final destination address in chain's first Routing header that has + * non-zero segments left. + */ + IPAddr* finalDst; }; class IP_Hdr { @@ -278,20 +304,11 @@ public: const struct ip6_hdr* IP6_Hdr() const { return ip6; } - IPAddr SrcAddr() const - { return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); } - /** - * Returns the final destination address of the header's packet, which - * for IPv6 packets without a routing type 0 extension header and IPv4 - * packets is the destination address in the IP header. For IPv6 packets - * with a routing type 0 extension header and a non-zero number of - * segments left, the final destination is the last address in the routing - * header. If the segments left of a routing type 0 header were zero, - * then the final destination is in the IP header itself. + * Returns the source address held in the IP header. */ - IPAddr FinalDstAddr() const - { return ip4 ? IPAddr(ip4->ip_dst) : ip6_hdrs->FinalDst(); } + IPAddr IPheaderSrcAddr() const + { return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); } /** * Returns the destination address held in the IP header. @@ -299,6 +316,23 @@ public: IPAddr IPHeaderDstAddr() const { return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); } + /** + * For IPv4 or IPv6 headers that don't contain a Home Address option + * (Mobile IPv6, RFC 6275), return source address held in the IP header. + * For IPv6 headers that contain a Home Address option, return that address. + */ + IPAddr SrcAddr() const + { return ip4 ? IPAddr(ip4->ip_src) : ip6_hdrs->SrcAddr(); } + + /** + * For IPv4 or IPv6 headers that don't contain a Routing header with + * non-zero segments left, return destination address held in the IP header. + * For IPv6 headers with a Routing header that has non-zero segments left, + * return the last address in the first such Routing header. + */ + IPAddr DstAddr() const + { return ip4 ? IPAddr(ip4->ip_dst) : ip6_hdrs->DstAddr(); } + /** * Returns a pointer to the payload of the IP packet, usually an * upper-layer protocol. diff --git a/src/PacketFilter.cc b/src/PacketFilter.cc index 412bf14587..4fb3b1c8f7 100644 --- a/src/PacketFilter.cc +++ b/src/PacketFilter.cc @@ -58,7 +58,7 @@ bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen) if ( f ) return MatchFilter(*f, *ip, len, caplen); - f = (Filter*) dst_filter.Lookup(ip->FinalDstAddr(), 128); + f = (Filter*) dst_filter.Lookup(ip->DstAddr(), 128); if ( f ) return MatchFilter(*f, *ip, len, caplen); diff --git a/src/PacketSort.cc b/src/PacketSort.cc index 3fb0e9ccbf..04c525c4d1 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -45,7 +45,7 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, (pkt + tcp_offset); id.src_addr = ip_hdr->SrcAddr(); - id.dst_addr = ip_hdr->FinalDstAddr(); + id.dst_addr = ip_hdr->DstAddr(); id.src_port = tp->th_sport; id.dst_port = tp->th_dport; id.is_one_way = 0; diff --git a/src/Serializer.cc b/src/Serializer.cc index 6aa554cc2b..06bbf73f48 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1105,7 +1105,7 @@ void Packet::Describe(ODesc* d) const const IP_Hdr ip = IP(); d->Add(ip.SrcAddr()); d->Add("->"); - d->Add(ip.FinalDstAddr()); + d->Add(ip.DstAddr()); } bool Packet::Serialize(SerialInfo* info) const diff --git a/src/Sessions.cc b/src/Sessions.cc index 4b5f201db5..84b57bdc62 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -493,7 +493,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, ConnID id; id.src_addr = ip_hdr->SrcAddr(); - id.dst_addr = ip_hdr->FinalDstAddr(); + id.dst_addr = ip_hdr->DstAddr(); Dictionary* d = 0; switch ( proto ) { @@ -667,7 +667,7 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, ListVal* key = new ListVal(TYPE_ANY); key->Append(new AddrVal(ip->SrcAddr())); - key->Append(new AddrVal(ip->FinalDstAddr())); + key->Append(new AddrVal(ip->DstAddr())); key->Append(new Val(frag_id, TYPE_COUNT)); HashKey* h = ch->ComputeHash(key, 1); @@ -1177,7 +1177,7 @@ void NetSessions::Weird(const char* name, void NetSessions::Weird(const char* name, const IP_Hdr* ip) { - reporter->Weird(ip->SrcAddr(), ip->FinalDstAddr(), name); + reporter->Weird(ip->SrcAddr(), ip->DstAddr(), name); } unsigned int NetSessions::ConnectionMemoryUsage() diff --git a/src/UDP.cc b/src/UDP.cc index fc559bf59d..d85cb39edd 100644 --- a/src/UDP.cc +++ b/src/UDP.cc @@ -217,7 +217,7 @@ bool UDP_Analyzer::ValidateChecksum(const IP_Hdr* ip, const udphdr* up, int len) sum = 0; sum = ones_complement_checksum(ip->SrcAddr(), sum); - sum = ones_complement_checksum(ip->FinalDstAddr(), sum); + sum = ones_complement_checksum(ip->DstAddr(), sum); // Note, for IPv6, strictly speaking the protocol and length fields are // 32 bits rather than 16 bits. But because the upper bits are all zero, // we get the same checksum either way. diff --git a/src/bro.bif b/src/bro.bif index 9fbf66699e..49a57274af 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -4693,6 +4693,8 @@ function pcap_error%(%): string ## Installs a filter to drop packets from a given IP source address with ## a certain probability if none of a given set of TCP flags are set. +## Note that for IPv6 packets with a Destination options header that has +## the Home Address option, this filters out against that home address. ## ## ip: The IP address to drop. ## @@ -4795,7 +4797,7 @@ function uninstall_src_net_filter%(snet: subnet%) : bool ## Installs a filter to drop packets destined to a given IP address with ## a certain probability if none of a given set of TCP flags are set. -## Note that for IPv6 packets with a routing type 0 header and non-zero +## Note that for IPv6 packets with a routing type header and non-zero ## segments left, this filters out against the final destination of the ## packet according to the routing extension header. ## diff --git a/testing/btest/Baseline/core.checksums/bad.out b/testing/btest/Baseline/core.checksums/bad.out index cd3c799277..ef83d966a3 100644 --- a/testing/btest/Baseline/core.checksums/bad.out +++ b/testing/btest/Baseline/core.checksums/bad.out @@ -5,5 +5,7 @@ 1332785210.013051 weird: bad_TCP_checksum 1332782580.798420 weird: routing0_hdr 1332782580.798420 weird: bad_UDP_checksum +1333640536.489921 weird: bad_TCP_checksum +1333640468.146461 weird: bad_UDP_checksum 1332785250.469132 weird: bad_TCP_checksum 1332781342.923813 weird: bad_UDP_checksum diff --git a/testing/btest/Baseline/core.mobile-ipv6-home-addr/output b/testing/btest/Baseline/core.mobile-ipv6-home-addr/output new file mode 100644 index 0000000000..f28997ff0b --- /dev/null +++ b/testing/btest/Baseline/core.mobile-ipv6-home-addr/output @@ -0,0 +1,2 @@ +[orig_h=2001:78:1:32::1, orig_p=30000/udp, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=13000/udp] +[ip=, ip6=[class=0, flow=0, len=36, nxt=60, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=60, hopopts=, dstopts=[nxt=17, len=2, options=[[otype=1, len=2, data=\0\0], [otype=201, len=16, data= ^A\0x\0^A\02\0\0\0\0\0\0\0^A]]], routing=, fragment=, ah=, esp=]]], tcp=, udp=[sport=30000/udp, dport=13000/udp, ulen=12], icmp=] diff --git a/testing/btest/Traces/chksums/ip6-hoa-tcp-bad-chksum.pcap b/testing/btest/Traces/chksums/ip6-hoa-tcp-bad-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3aa4bd21fa5a72df37231879d3364577bf4b6c0c GIT binary patch literal 138 zcmca|c+)~A1{MYwaA0F#U<7g^_SX6ztYl|M0oE#rh literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-hoa-tcp-good-chksum.pcap b/testing/btest/Traces/chksums/ip6-hoa-tcp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a6fc9cb0177e3539d6154b9932faa1476fb427f5 GIT binary patch literal 138 zcmca|c+)~A1{MYwaA0F#U<7jP_SX78)#71D0+U_QR7%Dan3XCj2fSTEv u9yI>{7xe!>Dt}hCAQK}K1H(xH1xAJnps_{}{S1ty21X|sco-NXfB*n3fFHmB literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/ip6-hoa-udp-good-chksum.pcap b/testing/btest/Traces/chksums/ip6-hoa-udp-good-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..f3e9d632c3665fbdbfe4a737fe839051d60bb615 GIT binary patch literal 130 zcmca|c+)~A1{MYwaA0F#U<7guch&kwr*bev0ofq@9}FO>+U_QR7%Dan3XCj2fSTEv u9yI>{7xe!>Dt}hCAQK}K1H(xH1xAJnps_{}{S1ty21X|sc%1J=0097LV+U_QR7%Dan3XCj2fSTEv u9yI>{7xe!>Dt}hCAQK}K1H(xH1xAJnps_{}{S1ty21X|sc%1J=0097LV>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-good-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: btest-diff bad.out diff --git a/testing/btest/core/mobile-ipv6-home-addr.test b/testing/btest/core/mobile-ipv6-home-addr.test new file mode 100644 index 0000000000..f113016568 --- /dev/null +++ b/testing/btest/core/mobile-ipv6-home-addr.test @@ -0,0 +1,10 @@ +# @TEST-EXEC: bro -b -r $TRACES/ipv6-mobile-hoa.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# Just check that the orig of the connection is the Home Address, but the +# source in the header is the actual source address. +event new_packet(c: connection, p: pkt_hdr) + { + print c$id; + print p; + } From 91330f1e1c2edcf3ba610190ab03e235e36debde Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 9 Apr 2012 14:39:00 -0500 Subject: [PATCH 5/5] Add support for mobile IPv6 Mobility Header (RFC 6275). - Accessible at script-layer through 'mobile_ipv6_message' event. - All Mobile IPv6 analysis now enabled through --enable-mobile-ipv6 configure-time option, otherwise the mobility header, routing type 2, and Home Address Destination option are ignored. --- config.h.in | 3 + configure | 5 + scripts/base/init-bare.bro | 156 ++++++++++++ src/IP.cc | 155 ++++++++++- src/IP.h | 62 ++++- src/Sessions.cc | 29 +++ src/event.bif | 7 + src/net_util.cc | 26 ++ src/net_util.h | 25 ++ testing/btest/Baseline/core.checksums/bad.out | 2 - .../Baseline/core.disable-mobile-ipv6/output | 1 + testing/btest/Baseline/core.ipv6_esp/output | 240 +++++++++--------- .../Baseline/core.ipv6_ext_headers/output | 2 +- .../core.mobile-ipv6-home-addr/output | 2 +- .../Baseline/core.mobile-ipv6-routing/output | 2 + .../Baseline/core.mobility-checksums/bad.out | 3 + .../Baseline/core.mobility-checksums/good.out | 0 .../btest/Baseline/core.mobility_msg/output | 16 ++ .../Traces/chksums/mip6-bad-mh-chksum.pcap | Bin 0 -> 118 bytes .../Traces/chksums/mip6-good-mh-chksum.pcap | Bin 0 -> 118 bytes .../{ => mobile-ipv6}/ipv6-mobile-hoa.trace | Bin .../mobile-ipv6/ipv6-mobile-routing.trace | Bin 0 -> 130 bytes .../btest/Traces/mobile-ipv6/mip6_back.trace | Bin 0 -> 110 bytes .../btest/Traces/mobile-ipv6/mip6_be.trace | Bin 0 -> 118 bytes .../btest/Traces/mobile-ipv6/mip6_brr.trace | Bin 0 -> 102 bytes .../btest/Traces/mobile-ipv6/mip6_bu.trace | Bin 0 -> 110 bytes .../btest/Traces/mobile-ipv6/mip6_cot.trace | Bin 0 -> 118 bytes .../btest/Traces/mobile-ipv6/mip6_coti.trace | Bin 0 -> 110 bytes .../btest/Traces/mobile-ipv6/mip6_hot.trace | Bin 0 -> 118 bytes .../btest/Traces/mobile-ipv6/mip6_hoti.trace | Bin 0 -> 110 bytes testing/btest/core/checksums.test | 4 - testing/btest/core/disable-mobile-ipv6.test | 12 + testing/btest/core/ipv6_esp.test | 3 +- testing/btest/core/mobile-ipv6-home-addr.test | 3 +- testing/btest/core/mobile-ipv6-routing.test | 11 + testing/btest/core/mobility-checksums.test | 9 + testing/btest/core/mobility_msg.test | 44 ++++ 37 files changed, 688 insertions(+), 134 deletions(-) create mode 100644 testing/btest/Baseline/core.disable-mobile-ipv6/output create mode 100644 testing/btest/Baseline/core.mobile-ipv6-routing/output create mode 100644 testing/btest/Baseline/core.mobility-checksums/bad.out create mode 100644 testing/btest/Baseline/core.mobility-checksums/good.out create mode 100644 testing/btest/Baseline/core.mobility_msg/output create mode 100644 testing/btest/Traces/chksums/mip6-bad-mh-chksum.pcap create mode 100644 testing/btest/Traces/chksums/mip6-good-mh-chksum.pcap rename testing/btest/Traces/{ => mobile-ipv6}/ipv6-mobile-hoa.trace (100%) create mode 100644 testing/btest/Traces/mobile-ipv6/ipv6-mobile-routing.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_back.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_be.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_brr.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_bu.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_cot.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_coti.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_hot.trace create mode 100644 testing/btest/Traces/mobile-ipv6/mip6_hoti.trace create mode 100644 testing/btest/core/disable-mobile-ipv6.test create mode 100644 testing/btest/core/mobile-ipv6-routing.test create mode 100644 testing/btest/core/mobility-checksums.test create mode 100644 testing/btest/core/mobility_msg.test diff --git a/config.h.in b/config.h.in index 0047344c51..6c64fb61bc 100644 --- a/config.h.in +++ b/config.h.in @@ -111,6 +111,9 @@ /* Use Google's perftools */ #cmakedefine USE_PERFTOOLS_DEBUG +/* Analyze Mobile IPv6 traffic */ +#cmakedefine ENABLE_MOBILE_IPV6 + /* Version number of package */ #define VERSION "@VERSION@" diff --git a/configure b/configure index 05aa12815b..3c1cca8c9d 100755 --- a/configure +++ b/configure @@ -27,6 +27,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... Optional Features: --enable-debug compile in debugging mode + --enable-mobile-ipv6 analyze mobile IPv6 features defined by RFC 6275 --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 @@ -98,6 +99,7 @@ append_cache_entry INSTALL_AUX_TOOLS BOOL true append_cache_entry INSTALL_BROCCOLI BOOL true append_cache_entry INSTALL_BROCTL BOOL true append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING +append_cache_entry ENABLE_MOBILE_IPV6 BOOL false # parse arguments while [ $# -ne 0 ]; do @@ -132,6 +134,9 @@ while [ $# -ne 0 ]; do --enable-debug) append_cache_entry ENABLE_DEBUG BOOL true ;; + --enable-mobile-ipv6) + append_cache_entry ENABLE_MOBILE_IPV6 BOOL true + ;; --enable-perftools-debug) append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL true ;; diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index b2237d7af8..a439a0dcb0 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -957,6 +957,7 @@ 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. +const IPPROTO_MOBILITY = 135; ##< IPv6 mobility header. ## Values extracted from an IPv6 extension header's (e.g. hop-by-hop or ## destination option headers) option field. @@ -1059,6 +1060,159 @@ type ip6_esp: record { seq: count; }; +## Values extracted from an IPv6 Mobility Binding Refresh Request message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_brr: record { + ## Reserved. + rsv: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Home Test Init message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_hoti: record { + ## Reserved. + rsv: count; + ## Home Init Cookie. + cookie: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Care-of Test Init message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_coti: record { + ## Reserved. + rsv: count; + ## Care-of Init Cookie. + cookie: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Home Test message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_hot: record { + ## Home Nonce Index. + nonce_idx: count; + ## Home Init Cookie. + cookie: count; + ## Home Keygen Token. + token: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Care-of Test message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_cot: record { + ## Care-of Nonce Index. + nonce_idx: count; + ## Care-of Init Cookie. + cookie: count; + ## Care-of Keygen Token. + token: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Binding Update message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_bu: record { + ## Sequence number. + seq: count; + ## Acknowledge bit. + a: bool; + ## Home Registration bit. + h: bool; + ## Link-Local Address Compatibility bit. + l: bool; + ## Key Management Mobility Capability bit. + k: bool; + ## Lifetime. + life: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Binding Acknowledgement message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_back: record { + ## Status. + status: count; + ## Key Management Mobility Capability. + k: bool; + ## Sequence number. + seq: count; + ## Lifetime. + life: count; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility Binding Error message. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg +type ip6_mobility_be: record { + ## Status. + status: count; + ## Home Address. + hoa: addr; + ## Mobility Options. + options: vector of ip6_option; +}; + +## Values extracted from an IPv6 Mobility header's message data. +## +## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain +type ip6_mobility_msg: record { + ## The type of message from the header's MH Type field. + id: count; + ## Binding Refresh Request. + brr: ip6_mobility_brr &optional; + ## Home Test Init. + hoti: ip6_mobility_hoti &optional; + ## Care-of Test Init. + coti: ip6_mobility_coti &optional; + ## Home Test. + hot: ip6_mobility_hot &optional; + ## Care-of Test. + cot: ip6_mobility_cot &optional; + ## Binding Update. + bu: ip6_mobility_bu &optional; + ## Binding Acknowledgement. + back: ip6_mobility_back &optional; + ## Binding Error. + be: ip6_mobility_be &optional; +}; + +## Values extracted from an IPv6 Mobility header. +## +## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain +type ip6_mobility_hdr: record { + ## 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; + ## Mobility header type used to identify header's the message. + mh_type: count; + ## Reserved field. + rsv: count; + ## Mobility header checksum. + chksum: count; + ## Mobility header message + msg: ip6_mobility_msg; +}; + ## A general container for a more specific IPv6 extension header. ## ## .. bro:see:: pkt_hdr ip4_hdr ip6_hopopts ip6_dstopts ip6_routing ip6_fragment @@ -1079,6 +1233,8 @@ type ip6_ext_hdr: record { ah: ip6_ah &optional; ## Encapsulating security payload header. esp: ip6_esp &optional; + ## Mobility header. + mobility: ip6_mobility_hdr &optional; }; ## Values extracted from an IPv6 header. diff --git a/src/IP.cc b/src/IP.cc index 10de8696f9..27c4b83114 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -15,6 +15,16 @@ 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 RecordType* ip6_mob_type = 0; +static RecordType* ip6_mob_msg_type = 0; +static RecordType* ip6_mob_brr_type = 0; +static RecordType* ip6_mob_hoti_type = 0; +static RecordType* ip6_mob_coti_type = 0; +static RecordType* ip6_mob_hot_type = 0; +static RecordType* ip6_mob_cot_type = 0; +static RecordType* ip6_mob_bu_type = 0; +static RecordType* ip6_mob_back_type = 0; +static RecordType* ip6_mob_be_type = 0; static inline RecordType* hdrType(RecordType*& type, const char* name) { @@ -24,7 +34,7 @@ static inline RecordType* hdrType(RecordType*& type, const char* name) return type; } -static VectorVal* BuildOptionsVal(const u_char* data, uint16 len) +static VectorVal* BuildOptionsVal(const u_char* data, int len) { VectorVal* vv = new VectorVal(new VectorType( hdrType(ip6_option_type, "ip6_option")->Ref())); @@ -154,6 +164,130 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const } break; +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: + { + rv = new RecordVal(hdrType(ip6_mob_type, "ip6_mobility_hdr")); + const struct ip6_mobility* mob = (const struct ip6_mobility*) data; + rv->Assign(0, new Val(mob->ip6mob_payload, TYPE_COUNT)); + rv->Assign(1, new Val(mob->ip6mob_len, TYPE_COUNT)); + rv->Assign(2, new Val(mob->ip6mob_type, TYPE_COUNT)); + rv->Assign(3, new Val(mob->ip6mob_rsv, TYPE_COUNT)); + rv->Assign(4, new Val(ntohs(mob->ip6mob_chksum), TYPE_COUNT)); + + RecordVal* msg = new RecordVal(hdrType(ip6_mob_msg_type, "ip6_mobility_msg")); + msg->Assign(0, new Val(mob->ip6mob_type, TYPE_COUNT)); + + uint16 off = sizeof(ip6_mobility); + const u_char* msg_data = data + off; + + switch ( mob->ip6mob_type ) { + case 0: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_brr")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + off += sizeof(uint16); + m->Assign(1, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(1, m); + } + break; + + case 1: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_hoti")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + m->Assign(1, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16)))), TYPE_COUNT)); + off += sizeof(uint16) + sizeof(uint64); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(2, m); + break; + } + + case 2: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_coti")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + m->Assign(1, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16)))), TYPE_COUNT)); + off += sizeof(uint16) + sizeof(uint64); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(3, m); + break; + } + + case 3: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_hot")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + m->Assign(1, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16)))), TYPE_COUNT)); + m->Assign(2, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16) + sizeof(uint64)))), TYPE_COUNT)); + off += sizeof(uint16) + 2 * sizeof(uint64); + m->Assign(3, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(4, m); + break; + } + + case 4: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_cot")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + m->Assign(1, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16)))), TYPE_COUNT)); + m->Assign(2, new Val(ntohll(*((uint64*)(msg_data + sizeof(uint16) + sizeof(uint64)))), TYPE_COUNT)); + off += sizeof(uint16) + 2 * sizeof(uint64); + m->Assign(3, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(5, m); + break; + } + + case 5: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_bu")); + m->Assign(0, new Val(ntohs(*((uint16*)msg_data)), TYPE_COUNT)); + m->Assign(1, new Val(ntohs(*((uint16*)(msg_data + sizeof(uint16)))) & 0x8000, TYPE_BOOL)); + m->Assign(2, new Val(ntohs(*((uint16*)(msg_data + sizeof(uint16)))) & 0x4000, TYPE_BOOL)); + m->Assign(3, new Val(ntohs(*((uint16*)(msg_data + sizeof(uint16)))) & 0x2000, TYPE_BOOL)); + m->Assign(4, new Val(ntohs(*((uint16*)(msg_data + sizeof(uint16)))) & 0x1000, TYPE_BOOL)); + m->Assign(5, new Val(ntohs(*((uint16*)(msg_data + 2*sizeof(uint16)))), TYPE_COUNT)); + off += 3 * sizeof(uint16); + m->Assign(6, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(6, m); + break; + } + + case 6: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_back")); + m->Assign(0, new Val(*((uint8*)msg_data), TYPE_COUNT)); + m->Assign(1, new Val(*((uint8*)(msg_data + sizeof(uint8))) & 0x80, TYPE_BOOL)); + m->Assign(2, new Val(ntohs(*((uint16*)(msg_data + sizeof(uint16)))), TYPE_COUNT)); + m->Assign(3, new Val(ntohs(*((uint16*)(msg_data + 2*sizeof(uint16)))), TYPE_COUNT)); + off += 3 * sizeof(uint16); + m->Assign(4, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(7, m); + break; + } + + case 7: + { + RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_be")); + m->Assign(0, new Val(*((uint8*)msg_data), TYPE_COUNT)); + const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16)); + m->Assign(1, new AddrVal(IPAddr(*hoa))); + off += sizeof(uint16) + sizeof(in6_addr); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(8, m); + break; + } + + default: + reporter->Weird(fmt("unknown_mobility_type_%d", mob->ip6mob_type)); + break; + } + + rv->Assign(5, msg); + } + break; +#endif //ENABLE_MOBILE_IPV6 + default: break; } @@ -276,6 +410,9 @@ static inline bool isIPv6ExtHeader(uint8 type) case IPPROTO_FRAGMENT: case IPPROTO_AH: case IPPROTO_ESP: +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: +#endif return true; default: return false; @@ -309,13 +446,19 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) if ( current_type == IPPROTO_ROUTING ) ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, len); +#ifdef ENABLE_MOBILE_IPV6 + // Only Mobile IPv6 has a destination option we care about right now if ( current_type == IPPROTO_DSTOPTS ) ProcessDstOpts((const struct ip6_dest*) hdrs, len); +#endif hdrs += len; length += len; } while ( current_type != IPPROTO_FRAGMENT && current_type != IPPROTO_ESP && +#ifdef ENABLE_MOBILE_IPV6 + current_type != IPPROTO_MOBILITY && +#endif isIPv6ExtHeader(next_type) ); } @@ -347,6 +490,7 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len) } break; +#ifdef ENABLE_MOBILE_IPV6 case 2: // Defined by Mobile IPv6 RFC 6275 { if ( r->ip6r_segleft > 0 ) @@ -358,6 +502,7 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len) } } break; +#endif default: reporter->Weird(fmt("unknown_routing_type_%d", r->ip6r_type)); @@ -365,6 +510,7 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len) } } +#ifdef ENABLE_MOBILE_IPV6 void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16 len) { const u_char* data = (const u_char*) d; @@ -403,6 +549,7 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16 len) } } } +#endif VectorVal* IPv6_Hdr_Chain::BuildVal() const { @@ -415,6 +562,7 @@ VectorVal* IPv6_Hdr_Chain::BuildVal() const ip6_fragment_type = internal_type("ip6_fragment")->AsRecordType(); ip6_ah_type = internal_type("ip6_ah")->AsRecordType(); ip6_esp_type = internal_type("ip6_esp")->AsRecordType(); + ip6_mob_type = internal_type("ip6_mobility_hdr")->AsRecordType(); } VectorVal* rval = new VectorVal(new VectorType(ip6_ext_hdr_type->Ref())); @@ -445,6 +593,11 @@ VectorVal* IPv6_Hdr_Chain::BuildVal() const case IPPROTO_ESP: ext_hdr->Assign(6, v); break; +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: + ext_hdr->Assign(7, v); + break; +#endif default: reporter->InternalError("IPv6_Hdr_Chain bad header %d", type); break; diff --git a/src/IP.h b/src/IP.h index 4ffb59151a..8a6ade470d 100644 --- a/src/IP.h +++ b/src/IP.h @@ -14,6 +14,22 @@ #include #include +#ifdef ENABLE_MOBILE_IPV6 + +#ifndef IPPROTO_MOBILITY +#define IPPROTO_MOBILITY 135 +#endif + +struct ip6_mobility { + uint8 ip6mob_payload; + uint8 ip6mob_len; + uint8 ip6mob_type; + uint8 ip6mob_rsv; + uint16 ip6mob_chksum; +}; + +#endif //ENABLE_MOBILE_IPV6 + /** * Base class for IPv6 header/extensions. */ @@ -38,6 +54,9 @@ public: case IPPROTO_ROUTING: case IPPROTO_FRAGMENT: case IPPROTO_AH: +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: +#endif ((ip6_ext*)data)->ip6e_nxt = next_type; break; case IPPROTO_ESP: @@ -62,6 +81,9 @@ public: case IPPROTO_ROUTING: case IPPROTO_FRAGMENT: case IPPROTO_AH: +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: +#endif return ((ip6_ext*)data)->ip6e_nxt; case IPPROTO_ESP: default: @@ -80,6 +102,9 @@ public: case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: +#ifdef ENABLE_MOBILE_IPV6 + case IPPROTO_MOBILITY: +#endif return 8 + 8 * ((ip6_ext*)data)->ip6e_len; case IPPROTO_FRAGMENT: return 8; @@ -117,13 +142,19 @@ public: /** * Initializes the header chain from an IPv6 header structure. */ - IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : homeAddr(0), finalDst(0) + IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : +#ifdef ENABLE_MOBILE_IPV6 + homeAddr(0), +#endif + finalDst(0) { Init(ip6, false); } ~IPv6_Hdr_Chain() { for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; +#ifdef ENABLE_MOBILE_IPV6 delete homeAddr; +#endif delete finalDst; } @@ -183,9 +214,11 @@ public: */ IPAddr SrcAddr() const { +#ifdef ENABLE_MOBILE_IPV6 if ( homeAddr ) return IPAddr(*homeAddr); else +#endif return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); } @@ -217,8 +250,11 @@ protected: * 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) - : homeAddr(0), finalDst(0) + IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) : +#ifdef ENABLE_MOBILE_IPV6 + homeAddr(0), +#endif + finalDst(0) { Init(ip6, true, next); } void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0); @@ -229,11 +265,13 @@ protected: */ void ProcessRoutingHeader(const struct ip6_rthdr* r, uint16 len); +#ifdef ENABLE_MOBILE_IPV6 /** * Inspect a Destination Option header's options for things we need to * remember, such as the Home Address option from Mobile IPv6. */ void ProcessDstOpts(const struct ip6_dest* d, uint16 len); +#endif vector chain; @@ -242,10 +280,12 @@ protected: */ uint16 length; +#ifdef ENABLE_MOBILE_IPV6 /** * Home Address of the packet's source as defined by Mobile IPv6 (RFC 6275). */ IPAddr* homeAddr; +#endif /** * The final destination address in chain's first Routing header that has @@ -345,6 +385,22 @@ public: return ((const u_char*) ip6) + ip6_hdrs->TotalLength(); } +#ifdef ENABLE_MOBILE_IPV6 + /** + * Returns a pointer to the mobility header of the IP packet, if present, + * else a null pointer. + */ + const ip6_mobility* MobilityHeader() const + { + if ( ip4 ) + return 0; + else if ( (*ip6_hdrs)[ip6_hdrs->Size()-1]->Type() != IPPROTO_MOBILITY ) + return 0; + else + return (const ip6_mobility*)(*ip6_hdrs)[ip6_hdrs->Size()-1]->Data(); + } +#endif + /** * 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). diff --git a/src/Sessions.cc b/src/Sessions.cc index 84b57bdc62..eb70e687db 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -481,6 +481,35 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } +#ifdef ENABLE_MOBILE_IPV6 + // We stop building the chain when seeing IPPROTO_MOBILITY so it's always + // last if present + if ( ip_hdr->LastHeader() == IPPROTO_MOBILITY ) + { + dump_this_packet = 1; + + if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff ) + { + Weird("bad_MH_checksum", hdr, pkt); + Remove(f); + return; + } + + if ( mobile_ipv6_message ) + { + val_list* vl = new val_list(); + vl->append(ip_hdr->BuildPktHdrVal()); + mgr.QueueEvent(mobile_ipv6_message, vl); + } + + if ( ip_hdr->NextProto() != IPPROTO_NONE ) + Weird("mobility_piggyback", hdr, pkt); + + Remove(f); + return; + } +#endif + int proto = ip_hdr->NextProto(); if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) ) diff --git a/src/event.bif b/src/event.bif index 113c003e37..0d90a6e88d 100644 --- a/src/event.bif +++ b/src/event.bif @@ -478,6 +478,13 @@ 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 packet using a Mobile IPv6 Mobility Header. +## +## p: Information from the header of the packet that triggered the event. +## +## .. bro:see:: new_packet tcp_packet ipv6_ext_headers +event mobile_ipv6_message%(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/src/net_util.cc b/src/net_util.cc index 578f5f44ad..ecdafdf247 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -12,6 +12,7 @@ #include "Reporter.h" #include "net_util.h" #include "IPAddr.h" +#include "IP.h" // - adapted from tcpdump // Returns the ones-complement checksum of a chunk of b short-aligned bytes. @@ -53,6 +54,31 @@ int icmp_checksum(const struct icmp* icmpp, int len) return sum; } +#ifdef ENABLE_MOBILE_IPV6 +int mobility_header_checksum(const IP_Hdr* ip) + { + const ip6_mobility* mh = ip->MobilityHeader(); + + if ( ! mh ) return 0; + + uint32 sum = 0; + uint8 mh_len = 8 + 8 * mh->ip6mob_len; + + if ( mh_len % 2 == 1 ) + reporter->Weird(ip->SrcAddr(), ip->DstAddr(), "odd_mobility_hdr_len"); + + sum = ones_complement_checksum(ip->SrcAddr(), sum); + sum = ones_complement_checksum(ip->DstAddr(), sum); + // Note, for IPv6, strictly speaking the protocol and length fields are + // 32 bits rather than 16 bits. But because the upper bits are all zero, + // we get the same checksum either way. + sum += htons(IPPROTO_MOBILITY); + sum += htons(mh_len); + sum = ones_complement_checksum(mh, mh_len, sum); + + return sum; + } +#endif #define CLASS_A 0x00000000 #define CLASS_B 0x80000000 diff --git a/src/net_util.h b/src/net_util.h index 4d215b3743..3f8eb01e2a 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -73,6 +73,11 @@ extern int ones_complement_checksum(const IPAddr& a, uint32 sum); extern int icmp_checksum(const struct icmp* icmpp, int len); +#ifdef ENABLE_MOBILE_IPV6 +class IP_Hdr; +extern int mobility_header_checksum(const IP_Hdr* ip); +#endif + // Returns 'A', 'B', 'C' or 'D' extern char addr_to_class(uint32 addr); @@ -93,6 +98,8 @@ extern uint32 extract_uint32(const u_char* data); inline double ntohd(double d) { return d; } inline double htond(double d) { return d; } +inline uint64 ntohll(uint64 i) { return i; } +inline uint64 htonll(uint64 i) { return i; } #else @@ -118,6 +125,24 @@ inline double ntohd(double d) inline double htond(double d) { return ntohd(d); } +inline uint64 ntohll(uint64 i) + { + u_char c; + union { + uint64 i; + u_char c[8]; + } x; + + x.i = i; + c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c; + c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c; + c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c; + c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c; + return x.i; + } + +inline uint64 htonll(uint64 i) { return ntohll(i); } + #endif #endif diff --git a/testing/btest/Baseline/core.checksums/bad.out b/testing/btest/Baseline/core.checksums/bad.out index ef83d966a3..cd3c799277 100644 --- a/testing/btest/Baseline/core.checksums/bad.out +++ b/testing/btest/Baseline/core.checksums/bad.out @@ -5,7 +5,5 @@ 1332785210.013051 weird: bad_TCP_checksum 1332782580.798420 weird: routing0_hdr 1332782580.798420 weird: bad_UDP_checksum -1333640536.489921 weird: bad_TCP_checksum -1333640468.146461 weird: bad_UDP_checksum 1332785250.469132 weird: bad_TCP_checksum 1332781342.923813 weird: bad_UDP_checksum diff --git a/testing/btest/Baseline/core.disable-mobile-ipv6/output b/testing/btest/Baseline/core.disable-mobile-ipv6/output new file mode 100644 index 0000000000..b156353f74 --- /dev/null +++ b/testing/btest/Baseline/core.disable-mobile-ipv6/output @@ -0,0 +1 @@ +1333663011.602839 weird: unknown_protocol_135 diff --git a/testing/btest/Baseline/core.ipv6_esp/output b/testing/btest/Baseline/core.ipv6_esp/output index 97a8434e7b..02fb7e154f 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=[[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=] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] +[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], mobility=]]] diff --git a/testing/btest/Baseline/core.ipv6_ext_headers/output b/testing/btest/Baseline/core.ipv6_ext_headers/output index c6ebddc7e1..b4cd249371 100644 --- a/testing/btest/Baseline/core.ipv6_ext_headers/output +++ b/testing/btest/Baseline/core.ipv6_ext_headers/output @@ -1,3 +1,3 @@ weird routing0_hdr from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:78:1:32::2 [orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=53/udp, resp_h=2001:78:1:32::2, resp_p=53/udp] -[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=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=, mobility=], [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=, mobility=]]], tcp=, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=] diff --git a/testing/btest/Baseline/core.mobile-ipv6-home-addr/output b/testing/btest/Baseline/core.mobile-ipv6-home-addr/output index f28997ff0b..88cbe0cb16 100644 --- a/testing/btest/Baseline/core.mobile-ipv6-home-addr/output +++ b/testing/btest/Baseline/core.mobile-ipv6-home-addr/output @@ -1,2 +1,2 @@ [orig_h=2001:78:1:32::1, orig_p=30000/udp, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=13000/udp] -[ip=, ip6=[class=0, flow=0, len=36, nxt=60, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=60, hopopts=, dstopts=[nxt=17, len=2, options=[[otype=1, len=2, data=\0\0], [otype=201, len=16, data= ^A\0x\0^A\02\0\0\0\0\0\0\0^A]]], routing=, fragment=, ah=, esp=]]], tcp=, udp=[sport=30000/udp, dport=13000/udp, ulen=12], icmp=] +[ip=, ip6=[class=0, flow=0, len=36, nxt=60, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=60, hopopts=, dstopts=[nxt=17, len=2, options=[[otype=1, len=2, data=\0\0], [otype=201, len=16, data= ^A\0x\0^A\02\0\0\0\0\0\0\0^A]]], routing=, fragment=, ah=, esp=, mobility=]]], tcp=, udp=[sport=30000/udp, dport=13000/udp, ulen=12], icmp=] diff --git a/testing/btest/Baseline/core.mobile-ipv6-routing/output b/testing/btest/Baseline/core.mobile-ipv6-routing/output new file mode 100644 index 0000000000..04292caaa7 --- /dev/null +++ b/testing/btest/Baseline/core.mobile-ipv6-routing/output @@ -0,0 +1,2 @@ +[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=30000/udp, resp_h=2001:78:1:32::1, resp_p=13000/udp] +[ip=, ip6=[class=0, flow=0, len=36, nxt=43, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=43, hopopts=, dstopts=, routing=[nxt=17, len=2, rtype=2, segleft=1, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A], fragment=, ah=, esp=, mobility=]]], tcp=, udp=[sport=30000/udp, dport=13000/udp, ulen=12], icmp=] diff --git a/testing/btest/Baseline/core.mobility-checksums/bad.out b/testing/btest/Baseline/core.mobility-checksums/bad.out new file mode 100644 index 0000000000..6ea9955402 --- /dev/null +++ b/testing/btest/Baseline/core.mobility-checksums/bad.out @@ -0,0 +1,3 @@ +1333988844.893456 weird: bad_MH_checksum +1333995733.276730 weird: bad_TCP_checksum +1333995701.656496 weird: bad_UDP_checksum diff --git a/testing/btest/Baseline/core.mobility-checksums/good.out b/testing/btest/Baseline/core.mobility-checksums/good.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/core.mobility_msg/output b/testing/btest/Baseline/core.mobility_msg/output new file mode 100644 index 0000000000..6f8d6a1699 --- /dev/null +++ b/testing/btest/Baseline/core.mobility_msg/output @@ -0,0 +1,16 @@ +Binding ACK: +[class=0, flow=0, len=16, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=1, mh_type=6, rsv=0, chksum=53722, msg=[id=6, brr=, hoti=, coti=, hot=, cot=, bu=, back=[status=0, k=T, seq=42, life=8, options=[[otype=1, len=2, data=\0\0]]], be=]]]]] +Binding Error: +[class=0, flow=0, len=24, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=2, mh_type=7, rsv=0, chksum=45272, msg=[id=7, brr=, hoti=, coti=, hot=, cot=, bu=, back=, be=[status=1, hoa=2001:78:1:32::1, options=[]]]]]]] +Binding Refresh Request: +[class=0, flow=0, len=8, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=0, mh_type=0, rsv=0, chksum=55703, msg=[id=0, brr=[rsv=0, options=[]], hoti=, coti=, hot=, cot=, bu=, back=, be=]]]]] +Binding Update: +[class=0, flow=0, len=16, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=1, mh_type=5, rsv=0, chksum=868, msg=[id=5, brr=, hoti=, coti=, hot=, cot=, bu=[seq=37, a=T, h=T, l=F, k=T, life=3, options=[[otype=1, len=2, data=\0\0]]], back=, be=]]]]] +Care-of Test: +[class=0, flow=0, len=24, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=2, mh_type=4, rsv=0, chksum=54378, msg=[id=4, brr=, hoti=, coti=, hot=, cot=[nonce_idx=13, cookie=15, token=255, options=[]], bu=, back=, be=]]]]] +Care-of Test Init: +[class=0, flow=0, len=16, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=1, mh_type=2, rsv=0, chksum=55181, msg=[id=2, brr=, hoti=, coti=[rsv=0, cookie=1, options=[]], hot=, cot=, bu=, back=, be=]]]]] +Home Test: +[class=0, flow=0, len=24, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=2, mh_type=3, rsv=0, chksum=54634, msg=[id=3, brr=, hoti=, coti=, hot=[nonce_idx=13, cookie=15, token=255, options=[]], cot=, bu=, back=, be=]]]]] +Home Test Init: +[class=0, flow=0, len=16, nxt=135, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=135, hopopts=, dstopts=, routing=, fragment=, ah=, esp=, mobility=[nxt=59, len=1, mh_type=1, rsv=0, chksum=55437, msg=[id=1, brr=, hoti=[rsv=0, cookie=1, options=[]], coti=, hot=, cot=, bu=, back=, be=]]]]] diff --git a/testing/btest/Traces/chksums/mip6-bad-mh-chksum.pcap b/testing/btest/Traces/chksums/mip6-bad-mh-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9a2437baef86be2a73e00c7b59d631b8c07c44fc GIT binary patch literal 118 zcmca|c+)~A1{MYwaA0F#U<7jB@HYDkEaGMG1F}K*KNvt%wcSksF(ld@6c|~405!8S iJ!t&@FX;b&RQ{}NYbJJ}af}QKj0_b(V~rsC85jZZY#hV@ literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/chksums/mip6-good-mh-chksum.pcap b/testing/btest/Traces/chksums/mip6-good-mh-chksum.pcap new file mode 100644 index 0000000000000000000000000000000000000000..6183fd9cb167c878e7245107840dfa503c69ffde GIT binary patch literal 118 zcmca|c+)~A1{MYwaA0F#U<7i0iZ=VV%QG_g0ofq@9}FO>+U_QR7!vIc3XCj2fSTEv j9yI>{7xe!>Dt}hCH4{6-h8v6w3XBXDKx2&{`WYAj4hbGe literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ipv6-mobile-hoa.trace b/testing/btest/Traces/mobile-ipv6/ipv6-mobile-hoa.trace similarity index 100% rename from testing/btest/Traces/ipv6-mobile-hoa.trace rename to testing/btest/Traces/mobile-ipv6/ipv6-mobile-hoa.trace diff --git a/testing/btest/Traces/mobile-ipv6/ipv6-mobile-routing.trace b/testing/btest/Traces/mobile-ipv6/ipv6-mobile-routing.trace new file mode 100644 index 0000000000000000000000000000000000000000..6289f268e3c45d7b7b5209a6464a5c3e956737eb GIT binary patch literal 130 zcmca|c+)~A1{MYwaA0F#U<7iGi8uRCInB-x1!RNpe=vZkYP*{NVyI|4C@`}80BUAu tdeHd)U(o;msQg*kf=o;x!x$7887hFr8iCkAz*uTvbb^8Bo@WFQ004*ZAsGMw literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_back.trace b/testing/btest/Traces/mobile-ipv6/mip6_back.trace new file mode 100644 index 0000000000000000000000000000000000000000..9b97186979a5e95cca0c7b3c1cf47a04fd56aae3 GIT binary patch literal 110 zcmca|c+)~A1{MYwaA0F#U<7iMMeF>p8*wtY0ofq@9}FO>+U_QR7y|7M3XCj2fSTEv g9yI>{7xe!>Dt}hCH6t6t#aj#w3|b5vj7$s+0P(aP$N&HU literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_be.trace b/testing/btest/Traces/mobile-ipv6/mip6_be.trace new file mode 100644 index 0000000000000000000000000000000000000000..19862ee4be183ec0eb9362222bb95e77553d216d GIT binary patch literal 118 zcmca|c+)~A1{MYwaA0F#U<7iCMC<%F3-L1e0ofq@9}FO>+U_QR7!vIc3XCj2fSTEv j9yI>{7xe!>Dt}hCH4{6-h8v6w3XBXDKx2&{`WYAj>8~B< literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_brr.trace b/testing/btest/Traces/mobile-ipv6/mip6_brr.trace new file mode 100644 index 0000000000000000000000000000000000000000..4020ae8b14d02d46325748bd1d3a275deb00b070 GIT binary patch literal 102 zcmca|c+)~A1{MYwaA0F#U<7hRSnB*Gi+LFAfNT){4+aobZFdtu432gO1xA)1K+Wt- X4;ugf3;O>bl|L)n8mR2%bOr_h&yO4* literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_bu.trace b/testing/btest/Traces/mobile-ipv6/mip6_bu.trace new file mode 100644 index 0000000000000000000000000000000000000000..1c8c61e09de7a2d9dd8d944170500e941eb1e4d0 GIT binary patch literal 110 zcmca|c+)~A1{MYwaA0F#U<7hr2-o>9*viP@24sWqe=vZkYP*{NVhFT5C@`}80BUAu gdeHd)U(o;msQg*k){LwS%qa}27Z@0r8JQRu06XFx&;S4c literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_cot.trace b/testing/btest/Traces/mobile-ipv6/mip6_cot.trace new file mode 100644 index 0000000000000000000000000000000000000000..2d8d215a41435f598a3a5241a214cba96e79f142 GIT binary patch literal 118 zcmca|c+)~A1{MYwaA0F#U<7jR3f1{5UE^Tz1F}K*KNvt%wcSksF(ld@6c|~405!8S fJ!t&@FX;b&RQ{}NYbF+kD_IP@5Pb~%Q2IXr5+fdc literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_coti.trace b/testing/btest/Traces/mobile-ipv6/mip6_coti.trace new file mode 100644 index 0000000000000000000000000000000000000000..2a5790cc7c50c182fc5f96d6acfe3b1237634303 GIT binary patch literal 110 zcmca|c+)~A1{MYwaA0F#U<7jh2-f-U_{hcJ24sWqe=vZkYP*{NVhFT5C@`}80BUAu bdeHd)U(o;msQg*k){IOH*LxwlfFvUTV-Oxc literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_hot.trace b/testing/btest/Traces/mobile-ipv6/mip6_hot.trace new file mode 100644 index 0000000000000000000000000000000000000000..0b54c9797d427e460e83256e23ee36c00dd15a4c GIT binary patch literal 118 zcmca|c+)~A1{MYwaA0F#U<7g&3f1{nJ>_EX1F}K*KNvt%wcSksF(ld@6c|~405!8S fJ!t&@FX;b&RQ{}NYbIuft62=Z5Pb~%Q2IXrAn+cl literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mobile-ipv6/mip6_hoti.trace b/testing/btest/Traces/mobile-ipv6/mip6_hoti.trace new file mode 100644 index 0000000000000000000000000000000000000000..3daaeb2905bbb8219e1b6029bf17d256acd56946 GIT binary patch literal 110 zcmca|c+)~A1{MYwaA0F#U<7jR2-f+#N^&u{0ofq@9}FO>+U_QR7y|7M3XCj2fSTEv b9yI>{7xe!>Dt}hCH6tU#jb4Z@Ajt>-?-3l- literal 0 HcmV?d00001 diff --git a/testing/btest/core/checksums.test b/testing/btest/core/checksums.test index 1cf7f9c54f..c01ab710af 100644 --- a/testing/btest/core/checksums.test +++ b/testing/btest/core/checksums.test @@ -3,16 +3,12 @@ # @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-bad-chksum.pcap >>bad.out 2>&1 -# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-bad-chksum.pcap >>bad.out 2>&1 -# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-bad-chksum.pcap >>bad.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-good-chksum.pcap >>good.out 2>&1 -# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-good-chksum.pcap >>good.out 2>&1 -# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-good-chksum.pcap >>good.out 2>&1 # @TEST-EXEC: btest-diff bad.out diff --git a/testing/btest/core/disable-mobile-ipv6.test b/testing/btest/core/disable-mobile-ipv6.test new file mode 100644 index 0000000000..84dc43dae8 --- /dev/null +++ b/testing/btest/core/disable-mobile-ipv6.test @@ -0,0 +1,12 @@ +# @TEST-REQUIRES: grep -q "#undef ENABLE_MOBILE_IPV6" $BUILD/config.h +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_back.trace %INPUT >output 2>&1 +# @TEST-EXEC: btest-diff output + +event mobile_ipv6_message(p: pkt_hdr) + { + if ( ! p?$ip6 ) return; + + for ( i in p$ip6$exts ) + if ( p$ip6$exts[i]$id == IPPROTO_MOBILITY ) + print p$ip6; + } diff --git a/testing/btest/core/ipv6_esp.test b/testing/btest/core/ipv6_esp.test index b606c23400..8744df0036 100644 --- a/testing/btest/core/ipv6_esp.test +++ b/testing/btest/core/ipv6_esp.test @@ -6,5 +6,6 @@ event esp_packet(p: pkt_hdr) { - print p; + if ( p?$ip6 ) + print p$ip6; } diff --git a/testing/btest/core/mobile-ipv6-home-addr.test b/testing/btest/core/mobile-ipv6-home-addr.test index f113016568..536d381f9b 100644 --- a/testing/btest/core/mobile-ipv6-home-addr.test +++ b/testing/btest/core/mobile-ipv6-home-addr.test @@ -1,4 +1,5 @@ -# @TEST-EXEC: bro -b -r $TRACES/ipv6-mobile-hoa.trace %INPUT >output +# @TEST-REQUIRES: grep -q "#define ENABLE_MOBILE_IPV6" $BUILD/config.h +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/ipv6-mobile-hoa.trace %INPUT >output # @TEST-EXEC: btest-diff output # Just check that the orig of the connection is the Home Address, but the diff --git a/testing/btest/core/mobile-ipv6-routing.test b/testing/btest/core/mobile-ipv6-routing.test new file mode 100644 index 0000000000..6ad5be002d --- /dev/null +++ b/testing/btest/core/mobile-ipv6-routing.test @@ -0,0 +1,11 @@ +# @TEST-REQUIRES: grep -q "#define ENABLE_MOBILE_IPV6" $BUILD/config.h +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/ipv6-mobile-routing.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# Just check that the responder of the connection is the final routing +# address, but the destination in the header is the actual destination address. +event new_packet(c: connection, p: pkt_hdr) + { + print c$id; + print p; + } diff --git a/testing/btest/core/mobility-checksums.test b/testing/btest/core/mobility-checksums.test new file mode 100644 index 0000000000..1d41daf543 --- /dev/null +++ b/testing/btest/core/mobility-checksums.test @@ -0,0 +1,9 @@ +# @TEST-REQUIRES: grep -q "#define ENABLE_MOBILE_IPV6" $BUILD/config.h +# @TEST-EXEC: bro -b -r $TRACES/chksums/mip6-bad-mh-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-bad-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/mip6-good-mh-chksum.pcap >>good.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-tcp-good-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-hoa-udp-good-chksum.pcap >>bad.out 2>&1 +# @TEST-EXEC: btest-diff bad.out +# @TEST-EXEC: btest-diff good.out diff --git a/testing/btest/core/mobility_msg.test b/testing/btest/core/mobility_msg.test new file mode 100644 index 0000000000..73461e7944 --- /dev/null +++ b/testing/btest/core/mobility_msg.test @@ -0,0 +1,44 @@ +# @TEST-REQUIRES: grep -q "#define ENABLE_MOBILE_IPV6" $BUILD/config.h +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_back.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_be.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_brr.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_bu.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_cot.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_coti.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_hot.trace %INPUT >>output +# @TEST-EXEC: bro -b -r $TRACES/mobile-ipv6/mip6_hoti.trace %INPUT >>output +# @TEST-EXEC: btest-diff output + +event mobile_ipv6_message(p: pkt_hdr) + { + if ( ! p?$ip6 ) return; + + for ( i in p$ip6$exts ) + { + if ( p$ip6$exts[i]$id == IPPROTO_MOBILITY ) + { + if ( ! p$ip6$exts[i]?$mobility ) + print "ERROR: Mobility extension header uninitialized"; + + if ( p$ip6$exts[i]$mobility$mh_type == 0 ) + print "Binding Refresh Request:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 1 ) + print "Home Test Init:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 2 ) + print "Care-of Test Init:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 3 ) + print "Home Test:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 4 ) + print "Care-of Test:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 5 ) + print "Binding Update:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 6 ) + print "Binding ACK:"; + else if ( p$ip6$exts[i]$mobility$mh_type == 7 ) + print "Binding Error:"; + else + print "Unknown Mobility Header:"; + print p$ip6; + } + } + }