From f4101b52659e19bea11a94c7e51fcfa501e4317c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 27 Mar 2012 16:05:45 -0500 Subject: [PATCH] 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; + }