From 08683175c129812cfaaa62fcf64726c44c8a263c Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sun, 22 Jan 2012 21:27:04 -0800 Subject: [PATCH 01/49] Interface draft for new IP address wrapper class. --- src/IPAddr.h | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/IPAddr.h diff --git a/src/IPAddr.h b/src/IPAddr.h new file mode 100644 index 0000000000..a74c6e3677 --- /dev/null +++ b/src/IPAddr.h @@ -0,0 +1,162 @@ + +#ifndef IPADDR_H +#define IPADDR_H + +/// Class storing both IPv4 and IPv6 addresses. +class IPAddr +{ +public: + /// Address family. + enum { IPv4, IPv6 } Family; + + /// Byte order. + enum { Host, Network } ByteOrder; + + /// Constructs an address instance from an IPv4 address. + /// + /// @param in6 The IPv6 address. + IPAddr(const in4_addr& in4); + + /// Constructs an address instance from an IPv6 address. + /// + /// @param in6 The IPv6 address. + IPAddr(const in6_addr& in6); + + /// Constructs an address instance from a string representation. + /// + /// @param s String containing an IP address as either a dotted IPv4 + /// address or a hex IPv6 address. + IPAddr(const string& s); + + /// Constructs an address instance from a string representation. + /// + /// @param s String containing an IP address as either a dotted IPv4 + /// address or a hex IPv6 address. + IPAddr(const BroString& s); + + /// Constructs an address instance from a raw byte representation. + /// + /// @param family The address family. + /// + /// @param bytes A pointer to the raw byte representation. This must point + /// to 4 bytes if \a family is IPv4, and to 16 bytes if \a family is + /// IPv6. + /// + /// @param order Indicates whether the raw representation pointed to + /// be \a bytes is stored in network or host order. + IPAddr(Family family, const u_char* bytes, ByteOrder order); + + /// Copy constructor. + IPAddr(const IPAddr& other); + + /// Destructor. + ~IPAddr(); + + /// Returns the address' family. + Family family() const; + + /// Returns true if the address represents a loopback device. + bool IsLoopback() const; + + /// Returns true if the address represents a multicast address. + bool IsMulticast() const; + + /// Returs true if the address represents a broadcast address. + bool IsBroadcast() const; + + /// Retrieves the raw byte representation of the address. + /// + /// @param bytes The pointer to which \a bytes points will be set to + /// the address of the raw representation. The return value indicates + /// how many bytes are valid starting at that address. The pointer + /// will be valid as long as the address instance exists. + /// + /// @return The number of bytes the raw representation uses. This + /// will be 4 for an IPv4 address and 32 for an IPv6 address. + int GetBytes(unsigned u_char** bytes); // Returns network-byte order. + + /// Masks out lower bits of the address. + /// + /// @param top_bits_to_keep The number of bits \a not to mask out, + /// counting from the highest order bit. The value is always + /// interpreted relative to the IPv6 bit width, even if the address + /// is IPv4. That means if compute ``192.168.1.2/16``, you need to + /// pass in 112 (i.e., 96 + 16). The value must be in the range from + /// 0 to 128. + void Mask(int top_bits_to_keep); + + /// Assignment operator. + const IPAddr& operator=(const IPAddr& other); + + /// Returns a string representation of the address. IPv4 addresses + /// will be returned in dotted representation, IPv6 addresses in + /// compressed hex. + operator string() const; + +private: + struct in6_addr in6; // This stored IPv6 addresses via the standard v4-to-v6 mapping. +}; + +/// Comparision operator for IP addresss. +extern bool operator==(const IPAddr& addr1, const IPAddr& addr2) const; + +/// Comparision operator IP addresses. This defines a well-defined order for +/// IP addresses. However, the order does not necessarily correspond to their +/// numerical values. +extern bool operator<(const IPAddr& addr1, const IPAddr& addr2) const; + +/// Class storing both IPv4 and IPv6 prefixes (i.e., \c 192.168.1.1/16 and \c FD00::/8. +class IPPrefix +{ +public: + /// Constructs a prefix instance from an IPv4 address and a prefix + /// length. + /// + /// @param addr The IPv4 address. + /// + /// @param length The prefix length in the range from 0 to 32. + IPPrefix(const in4_addr& in4, uint16_t length); + + /// Constructs a prefix instance from an IPv6 address and a prefix + /// length. + /// + /// @param addr The IPv6 address. + /// + /// @param length The prefix length in the range from 0 to 128. + IPPrefix(const in6_addr& in6, uint16_t length); + + /// Copy constructor. + IPPrefix(const IPPrefix& other); + + /// Destructor. + ~IPPrefix(); + + /// Returns the prefix in the form of an IP address. The address will + /// have all bits not part of the prefixed set to zero. + const IPAddr& Prefix() const; + + /// Returns the bit length of the prefix. + uint16_t Length() const; + + /// Assignment operator. + const IPPrefix& operator=(const IPPrefix& other); + + /// Returns a string representation of the prefix. IPv4 addresses + /// will be returned in dotted representation, IPv6 addresses in + /// compressed hex. + operator string() const; + +private: + IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask(). + uint16_t mask; // The bit length. +}; + +/// Comparision operator for IP prefix. +extern bool operator==(const IPPrefix& net1, const IPPrefix& net2) const; + +/// Comparision operator IP prefixes. This defines a well-defined order for +/// IP prefix. However, the order does not necessarily corresponding to their +/// numerical values. +extern bool operator<(const IPPrefix& net1, const IPPrefix& net2) const; + +#endif From 2c439fd0a28fa49e8ecf8915aec9aec8fffe42d4 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 23 Jan 2012 22:00:56 -0800 Subject: [PATCH 02/49] Fixing typo --- src/IPAddr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IPAddr.h b/src/IPAddr.h index a74c6e3677..fda749db9e 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -7,10 +7,10 @@ class IPAddr { public: /// Address family. - enum { IPv4, IPv6 } Family; + enum Family { IPv4, IPv6 }; /// Byte order. - enum { Host, Network } ByteOrder; + enum ByteOrder { Host, Network }; /// Constructs an address instance from an IPv4 address. /// From b3f1f45082ef8ad0e13574f0c0a2702769cf820f Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 3 Feb 2012 16:20:15 -0600 Subject: [PATCH 03/49] Remove --enable-brov6 flag, IPv6 now supported by default. Internally, all BROv6 preprocessor switches were removed and addr/subnet representations wrapped in the new IPAddr/IPPrefix classes. Some script-layer changes of note: - dns_AAAA_reply event signature changed: the string representation of an IPv6 addr is easily derived from the addr value, it doesn't need to be another parameter. This event also now generated directly by the DNS analyzer instead of being "faked" into a dns_A_reply event. - removed addr_to_count BIF. It used to return the host-order count representation of IPv4 addresses only. To make it more generic, we might later add a BIF to return a vector of counts in order to support IPv6. - changed the result of enclosing addr variables in vertical pipes (e.g. |my_addr|) to return the bit-width of the address type which is 128 for IPv6 and 32 for IPv4. It used to function the same way as addr_to_count mentioned above. - remove bro_has_ipv6 BIF --- config.h.in | 3 - configure | 4 - .../base/frameworks/packet-filter/main.bro | 11 +- scripts/base/protocols/dns/main.bro | 9 +- src/Anon.cc | 4 +- src/CMakeLists.txt | 1 + src/CompHash.cc | 86 ++-- src/Conn.cc | 46 +- src/Conn.h | 33 +- src/ConnCompressor.cc | 32 +- src/ConnCompressor.h | 4 +- src/DCE_RPC.cc | 19 +- src/DCE_RPC.h | 11 +- src/DNS.cc | 37 +- src/DNS_Mgr.cc | 46 +- src/DNS_Mgr.h | 1 + src/DPM.cc | 47 +- src/DPM.h | 14 +- src/Expr.cc | 40 +- src/HTTP.cc | 2 +- src/HTTP.h | 3 +- src/ICMP.cc | 4 +- src/IP.h | 69 +-- src/IPAddr.cc | 364 +++++++++++++++ src/IPAddr.h | 133 ++++-- src/LogMgr.cc | 58 +-- src/LogMgr.h | 5 +- src/LogWriterAscii.cc | 6 +- src/OSFinger.cc | 6 +- src/OSFinger.h | 3 +- src/PIA.cc | 12 +- src/PacketFilter.cc | 30 +- src/PacketFilter.h | 8 +- src/PrefixTable.cc | 44 +- src/PrefixTable.h | 7 +- src/Reassem.cc | 2 +- src/Reassem.h | 3 +- src/RemoteSerializer.cc | 31 +- src/RemoteSerializer.h | 4 +- src/Reporter.cc | 19 + src/Reporter.h | 3 + src/RuleMatcher.cc | 18 +- src/SSH.cc | 2 +- src/Serializer.cc | 4 +- src/Sessions.cc | 30 +- src/Sessions.h | 2 +- src/TCP.cc | 12 +- src/TCP.h | 5 +- src/TCP_Endpoint.cc | 13 +- src/TCP_Endpoint.h | 6 +- src/UDP.cc | 2 - src/Val.cc | 379 ++++------------ src/Val.h | 52 ++- src/bif_type.def | 2 +- src/bro.bif | 420 +++++++++--------- src/dhcp-analyzer.pac | 56 +-- src/dns-analyzer.pac | 66 ++- src/event.bif | 38 +- src/net_util.cc | 225 +--------- src/net_util.h | 89 +--- src/patricia.c | 2 +- src/patricia.h | 2 - testing/btest/Baseline/bifs.addr_version/out | 4 + .../Baseline/bifs.net_stats_trace/output | 2 +- testing/btest/Baseline/core.conn-uid/counts | 2 +- testing/btest/Baseline/core.conn-uid/output | 81 ++-- .../btest/Baseline/core.conn-uid/output.cc | 81 ++-- .../btest/Baseline/core.conn-uid/output.cc2 | 81 ++-- .../core.print-bpf-filters-ipv4/output | 32 -- .../core.print-bpf-filters-ipv6/conn.log | 2 - .../core.print-bpf-filters-ipv6/output | 8 - .../conn.log | 0 .../Baseline/core.print-bpf-filters/output | 32 ++ .../language.cross-product-init/output | 6 +- testing/btest/Baseline/language.sizeof/output | 3 +- .../local.log | 44 +- .../remote.log | 3 + .../manager-1.metrics.log | 6 +- .../metrics.log | 6 +- testing/btest/bifs/addr_version.bro | 7 + testing/btest/core/print-bpf-filters-ipv4.bro | 12 - ...filters-ipv6.bro => print-bpf-filters.bro} | 2 - testing/btest/istate/broccoli.bro | 1 - testing/btest/istate/pybroccoli.py | 1 - testing/btest/language/sizeof.bro | 7 +- 85 files changed, 1428 insertions(+), 1684 deletions(-) create mode 100644 src/IPAddr.cc create mode 100644 testing/btest/Baseline/bifs.addr_version/out delete mode 100644 testing/btest/Baseline/core.print-bpf-filters-ipv4/output delete mode 100644 testing/btest/Baseline/core.print-bpf-filters-ipv6/conn.log delete mode 100644 testing/btest/Baseline/core.print-bpf-filters-ipv6/output rename testing/btest/Baseline/{core.print-bpf-filters-ipv4 => core.print-bpf-filters}/conn.log (100%) create mode 100644 testing/btest/Baseline/core.print-bpf-filters/output create mode 100644 testing/btest/bifs/addr_version.bro delete mode 100644 testing/btest/core/print-bpf-filters-ipv4.bro rename testing/btest/core/{print-bpf-filters-ipv6.bro => print-bpf-filters.bro} (89%) diff --git a/config.h.in b/config.h.in index 261cd0ccb9..e744cb7dbd 100644 --- a/config.h.in +++ b/config.h.in @@ -1,6 +1,3 @@ -/* enable IPV6 processing */ -#cmakedefine BROv6 - /* Old libpcap versions (< 0.6.1) need defining pcap_freecode and pcap_compile_nopcap */ #cmakedefine DONT_HAVE_LIBPCAP_PCAP_FREECODE diff --git a/configure b/configure index 0f74674c0f..675447e461 100755 --- a/configure +++ b/configure @@ -92,7 +92,6 @@ append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING /usr/local/bro/share/bro append_cache_entry ENABLE_DEBUG BOOL false -append_cache_entry BROv6 BOOL false append_cache_entry ENABLE_PERFTOOLS BOOL false append_cache_entry BinPAC_SKIP_INSTALL BOOL true append_cache_entry BUILD_SHARED_LIBS BOOL true @@ -134,9 +133,6 @@ while [ $# -ne 0 ]; do --enable-debug) append_cache_entry ENABLE_DEBUG BOOL true ;; - --enable-brov6) - append_cache_entry BROv6 BOOL true - ;; --enable-perftools) append_cache_entry ENABLE_PERFTOOLS BOOL true ;; diff --git a/scripts/base/frameworks/packet-filter/main.bro b/scripts/base/frameworks/packet-filter/main.bro index 16e3ff9789..94a01e04a2 100644 --- a/scripts/base/frameworks/packet-filter/main.bro +++ b/scripts/base/frameworks/packet-filter/main.bro @@ -85,13 +85,8 @@ function build_default_filter(): string return cmd_line_bpf_filter; if ( all_packets ) - { # Return an "always true" filter. - if ( bro_has_ipv6() ) - return "ip or not ip"; - else - return "not ip6"; - } + return "ip or not ip"; # Build filter dynamically. @@ -110,10 +105,6 @@ function build_default_filter(): string if ( unrestricted_filter != "" ) filter = combine_filters(unrestricted_filter, filter, "or"); - # Exclude IPv6 if we don't support it. - if ( ! bro_has_ipv6() ) - filter = combine_filters(filter, "not ip6", "and"); - return filter; } diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index 56107fd02d..f73a947b5f 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -261,10 +261,13 @@ event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string) & event DNS::do_reply(c, msg, ans, str); } -event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr, - astr: string) &priority=5 +event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 + { + event DNS::do_reply(c, msg, ans, fmt("%s", a)); + } + +event dns_A6_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 { - # TODO: What should we do with astr? event DNS::do_reply(c, msg, ans, fmt("%s", a)); } diff --git a/src/Anon.cc b/src/Anon.cc index 440f8600d5..aeaf49feea 100644 --- a/src/Anon.cc +++ b/src/Anon.cc @@ -153,7 +153,9 @@ void AnonymizeIPAddr_A50::init() int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits) { - DEBUG_MSG("%s/%d\n", dotted_addr(input), num_bits); + DEBUG_MSG("%s/%d\n", + string(IPAddr(IPAddr::IPv4, &input, IPAddr::Network)).c_str(), + num_bits); if ( ! before_anonymization ) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47314514f6..ab1332e79a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -330,6 +330,7 @@ set(bro_SRCS IntSet.cc InterConn.cc IOSource.cc + IPAddr.cc IRC.cc List.cc Reporter.cc diff --git a/src/CompHash.cc b/src/CompHash.cc index 148c8384ee..1d13d2f309 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -110,37 +110,27 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, // Use uint32 instead of int, because 'int' is not // guaranteed to be 32-bit. uint32* kp = AlignAndPadType(kp0); -#ifdef BROv6 - const addr_type av = v->AsAddr(); - kp[0] = av[0]; - kp[1] = av[1]; - kp[2] = av[2]; - kp[3] = av[3]; + uint32 bytes[4]; + v->AsAddr()->CopyIPv6(bytes); + kp[0] = bytes[0]; + kp[1] = bytes[1]; + kp[2] = bytes[2]; + kp[3] = bytes[3]; kp1 = reinterpret_cast(kp+4); -#else - *kp = v->AsAddr(); - kp1 = reinterpret_cast(kp+1); -#endif } break; case TYPE_INTERNAL_SUBNET: { uint32* kp = AlignAndPadType(kp0); -#ifdef BROv6 - const subnet_type* sv = v->AsSubNet(); - kp[0] = sv->net[0]; - kp[1] = sv->net[1]; - kp[2] = sv->net[2]; - kp[3] = sv->net[3]; - kp[4] = sv->width; + uint32 bytes[4]; + v->AsSubNet()->Prefix().CopyIPv6(bytes); + kp[0] = bytes[0]; + kp[1] = bytes[1]; + kp[2] = bytes[2]; + kp[3] = bytes[3]; + kp[4] = v->AsSubNet()->Length(); kp1 = reinterpret_cast(kp+5); -#else - const subnet_type* sv = v->AsSubNet(); - kp[0] = sv->net; - kp[1] = sv->width; - kp1 = reinterpret_cast(kp+2); -#endif } break; @@ -283,26 +273,25 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, int type_check) const if ( type_check && v->Type()->InternalType() != singleton_tag ) return 0; - uint32 tmp_addr; switch ( singleton_tag ) { case TYPE_INTERNAL_INT: case TYPE_INTERNAL_UNSIGNED: return new HashKey(v->ForceAsInt()); case TYPE_INTERNAL_ADDR: -#ifdef BROv6 - return new HashKey(v->AsAddr(), 4); -#else - return new HashKey(v->AsAddr()); -#endif + { + uint32 bytes[4]; + v->AsAddr()->CopyIPv6(bytes); + return new HashKey((void*)bytes, 4 * sizeof(uint32)); + } case TYPE_INTERNAL_SUBNET: -#ifdef BROv6 - return new HashKey((const uint32*) v->AsSubNet(), 5); -#else - return new HashKey((const uint32*) v->AsSubNet(), 2); - -#endif + { + uint32 bytes[5]; + v->AsSubNet()->Prefix().CopyIPv6(bytes); + bytes[4] = v->AsSubNet()->Length(); + return new HashKey((void*)bytes, 5 * sizeof(uint32)); + } case TYPE_INTERNAL_DOUBLE: return new HashKey(v->InternalDouble()); @@ -350,22 +339,13 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v, break; case TYPE_INTERNAL_ADDR: -#ifdef BROv6 sz = SizeAlign(sz, sizeof(uint32)); sz += sizeof(uint32) * 3; // to make a total of 4 words -#else - sz = SizeAlign(sz, sizeof(uint32)); -#endif break; case TYPE_INTERNAL_SUBNET: -#ifdef BROv6 sz = SizeAlign(sz, sizeof(uint32)); sz += sizeof(uint32) * 4; // to make a total of 5 words -#else - sz = SizeAlign(sz, sizeof(uint32)); - sz += sizeof(uint32); // make room for width -#endif break; case TYPE_INTERNAL_DOUBLE: @@ -602,16 +582,11 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, case TYPE_INTERNAL_ADDR: { const uint32* const kp = AlignType(kp0); -#ifdef BROv6 - const_addr_type addr_val = kp; kp1 = reinterpret_cast(kp+4); -#else - const_addr_type addr_val = *kp; - kp1 = reinterpret_cast(kp+1); -#endif + IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network); switch ( tag ) { case TYPE_ADDR: - pval = new AddrVal(addr_val); + pval = new AddrVal(addr); break; default: @@ -624,12 +599,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, case TYPE_INTERNAL_SUBNET: { - const subnet_type* const kp = - reinterpret_cast( - AlignType(kp0)); - kp1 = reinterpret_cast(kp+1); - - pval = new SubNetVal(kp->net, kp->width); + const uint32* const kp = AlignType(kp0); + kp1 = reinterpret_cast(kp+5); + pval = new SubNetVal(kp, kp[4]); } break; diff --git a/src/Conn.cc b/src/Conn.cc index df59b1037a..3177d48705 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -24,15 +24,15 @@ HashKey* ConnID::BuildConnKey() const if ( is_one_way || addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) ) { - copy_addr(src_addr, key.ip1); - copy_addr(dst_addr, key.ip2); + key.ip1 = src_addr; + key.ip2 = dst_addr; key.port1 = src_port; key.port2 = dst_port; } else { - copy_addr(dst_addr, key.ip1); - copy_addr(src_addr, key.ip2); + key.ip1 = dst_addr; + key.ip2 = src_addr; key.port1 = dst_port; key.port2 = src_port; } @@ -143,8 +143,8 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id) key = k; start_time = last_time = t; - copy_addr(id->src_addr, orig_addr); - copy_addr(id->dst_addr, resp_addr); + orig_addr = id->src_addr; + resp_addr = id->dst_addr; orig_port = id->src_port; resp_port = id->dst_port; proto = TRANSPORT_UNKNOWN; @@ -521,7 +521,7 @@ Val* Connection::BuildVersionVal(const char* s, int len) return sw; } -int Connection::VersionFoundEvent(const uint32* addr, const char* s, int len, +int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len, Analyzer* analyzer) { if ( ! software_version_found && ! software_parse_error ) @@ -559,7 +559,7 @@ int Connection::VersionFoundEvent(const uint32* addr, const char* s, int len, return 1; } -int Connection::UnparsedVersionFoundEvent(const uint32* addr, +int Connection::UnparsedVersionFoundEvent(const IPAddr& addr, const char* full, int len, Analyzer* analyzer) { // Skip leading white space. @@ -693,10 +693,9 @@ TimerMgr* Connection::GetTimerMgr() const void Connection::FlipRoles() { - uint32 tmp_addr[NUM_ADDR_WORDS]; - copy_addr(resp_addr, tmp_addr); - copy_addr(orig_addr, resp_addr); - copy_addr(tmp_addr, orig_addr); + IPAddr tmp_addr = resp_addr; + orig_addr = resp_addr; + resp_addr = tmp_addr; uint32 tmp_port = resp_port; resp_port = orig_port; @@ -752,14 +751,14 @@ void Connection::Describe(ODesc* d) const } d->SP(); - d->Add(dotted_addr(orig_addr)); + d->Add(string(orig_addr).c_str()); d->Add(":"); d->Add(ntohs(orig_port)); d->SP(); d->AddSP("->"); - d->Add(dotted_addr(resp_addr)); + d->Add(string(resp_addr).c_str()); d->Add(":"); d->Add(ntohs(resp_port)); @@ -782,8 +781,12 @@ bool Connection::DoSerialize(SerialInfo* info) const // First we write the members which are needed to // create the HashKey. - for ( int j = 0; j < NUM_ADDR_WORDS; ++j ) - if ( ! SERIALIZE(orig_addr[j]) || ! SERIALIZE(resp_addr[j]) ) + uint32 orig_a[4]; + uint32 resp_a[4]; + orig_addr.CopyIPv6(orig_a); + resp_addr.CopyIPv6(resp_a); + for ( int j = 0; j < 4; ++j ) + if ( ! SERIALIZE(orig_a[j]) || ! SERIALIZE(resp_a[j]) ) return false; if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) ) @@ -830,14 +833,19 @@ bool Connection::DoUnserialize(UnserialInfo* info) // Build the hash key first. Some of the recursive *::Unserialize() // functions may need it. - for ( int i = 0; i < NUM_ADDR_WORDS; ++i ) - if ( ! UNSERIALIZE(&orig_addr[i]) || ! UNSERIALIZE(&resp_addr[i]) ) + ConnID id; + uint32 orig_a[4]; + uint32 resp_a[4]; + for ( int i = 0; i < 4; ++i ) + if ( ! UNSERIALIZE(&orig_a[i]) || ! UNSERIALIZE(&resp_a[i]) ) goto error; + orig_addr = IPAddr(IPAddr::IPv6, orig_a, IPAddr::Network); + resp_addr = IPAddr(IPAddr::IPv6, resp_a, IPAddr::Network); + if ( ! UNSERIALIZE(&orig_port) || ! UNSERIALIZE(&resp_port) ) goto error; - ConnID id; id.src_addr = orig_addr; id.dst_addr = resp_addr; // This doesn't work for ICMP. But I guess this is not really important. diff --git a/src/Conn.h b/src/Conn.h index 8e90d6a9c3..e7f24e3693 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -12,6 +12,7 @@ #include "PersistenceSerializer.h" #include "RuleMatcher.h" #include "AnalyzerTags.h" +#include "IPAddr.h" class Connection; class ConnectionTimer; @@ -32,8 +33,8 @@ typedef enum { typedef void (Connection::*timer_func)(double t); struct ConnID { - const uint32* src_addr; - const uint32* dst_addr; + IPAddr src_addr; + IPAddr dst_addr; uint32 src_port; uint32 dst_port; bool is_one_way; // if true, don't canonicalize @@ -49,17 +50,20 @@ struct ConnID { // The structure used internally for hashing. struct Key { - uint32 ip1[NUM_ADDR_WORDS]; - uint32 ip2[NUM_ADDR_WORDS]; + IPAddr ip1; + IPAddr ip2; uint16 port1; uint16 port2; }; }; -static inline int addr_port_canon_lt(const uint32* a1, uint32 p1, - const uint32* a2, uint32 p2) +static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1, + const IPAddr& addr2, uint32 p2) { -#ifdef BROv6 + uint32 a1[4]; + uint32 a2[4]; + addr1.CopyIPv6(a1); + addr2.CopyIPv6(a2); // Because it's a canonical ordering, not a strict ordering, // we can choose to give more weight to the least significant // word than to the most significant word. This matters @@ -75,9 +79,6 @@ static inline int addr_port_canon_lt(const uint32* a1, uint32 p1, (a1[0] < a2[0] || (a1[0] == a2[0] && p1 < p2))))))); -#else - return *a1 < *a2 || (*a1 == *a2 && p1 < p2); -#endif } class Analyzer; @@ -119,8 +120,8 @@ public: double LastTime() const { return last_time; } void SetLastTime(double t) { last_time = t; } - const uint32* OrigAddr() const { return orig_addr; } - const uint32* RespAddr() const { return resp_addr; } + const IPAddr& OrigAddr() const { return orig_addr; } + const IPAddr& RespAddr() const { return resp_addr; } uint32 OrigPort() const { return orig_port; } uint32 RespPort() const { return resp_port; } @@ -185,11 +186,11 @@ public: // Raises a software_version_found event based on the // given string (returns false if it's not parseable). - int VersionFoundEvent(const uint32* addr, const char* s, int len, + int VersionFoundEvent(const IPAddr& addr, const char* s, int len, Analyzer* analyzer = 0); // Raises a software_unparsed_version_found event. - int UnparsedVersionFoundEvent(const uint32* addr, + int UnparsedVersionFoundEvent(const IPAddr& addr, const char* full_descr, int len, Analyzer* analyzer); void Event(EventHandlerPtr f, Analyzer* analyzer, const char* name = 0); @@ -325,8 +326,8 @@ protected: TimerMgr::Tag* conn_timer_mgr; timer_list timers; - uint32 orig_addr[NUM_ADDR_WORDS]; // in network order - uint32 resp_addr[NUM_ADDR_WORDS]; // in network order + IPAddr orig_addr; + IPAddr resp_addr; uint32 orig_port, resp_port; // in network order TransportProto proto; double start_time, last_time; diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index 7a04cb4f0b..b745854c66 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -235,7 +235,7 @@ Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip, tc = FirstFromOrig(t, key, ip, tp); } - else if ( addr_eq(ip->SrcAddr(), SrcAddr(pending)) && + else if ( ip->SrcAddr() == SrcAddr(pending) && tp->th_sport == SrcPort(pending) ) // Another packet from originator. tc = NextFromOrig(pending, t, key, ip, tp); @@ -541,7 +541,7 @@ Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending) sessions->BuildHeader(faked_pkt->IP4_Hdr())); // NewConn() may have swapped originator and responder. - int is_orig = addr_eq(conn_id.src_addr, new_conn->OrigAddr()) && + int is_orig = conn_id.src_addr == new_conn->OrigAddr() && conn_id.src_port == new_conn->OrigPort(); // Pass the faked packet to the connection. @@ -607,7 +607,7 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key, memcpy(&c->key, key->Key(), key->Size()); c->hash = key->Hash(); - c->ip1_is_src = addr_eq(c->key.ip1, ip->SrcAddr()) && + c->ip1_is_src = c->key.ip1 == ip->SrcAddr() && c->key.port1 == tp->th_sport; c->time = time; c->window = tp->th_win; @@ -659,14 +659,26 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) // Note, do *not* use copy_addr() here. This is because we're // copying to an IPv4 header, which has room for exactly and // only an IPv4 address. -#ifdef BROv6 - if ( ! is_v4_addr(c->key.ip1) || ! is_v4_addr(c->key.ip2) ) + if ( c->key.ip1.family() == IPAddr::IPv6 || + c->key.ip2.family() == IPAddr::IPv6 ) reporter->InternalError("IPv6 snuck into connection compressor"); -#endif - *(uint32*) &ip->ip_src = - to_v4_addr(c->ip1_is_src ? c->key.ip1 : c->key.ip2); - *(uint32*) &ip->ip_dst = - to_v4_addr(c->ip1_is_src ? c->key.ip2 : c->key.ip1); + else + { + const uint32* src_bytes; + const uint32* dst_bytes; + if ( c->ip1_is_src ) + { + c->key.ip1.GetBytes(&src_bytes); + c->key.ip2.GetBytes(&dst_bytes); + } + else + { + c->key.ip2.GetBytes(&src_bytes); + c->key.ip1.GetBytes(&dst_bytes); + } + memcpy(&ip->ip_src, src_bytes, sizeof(ip->ip_src)); + memcpy(&ip->ip_dst, dst_bytes, sizeof(ip->ip_dst)); + } if ( c->ip1_is_src ) { diff --git a/src/ConnCompressor.h b/src/ConnCompressor.h index 36959b615c..97051e148a 100644 --- a/src/ConnCompressor.h +++ b/src/ConnCompressor.h @@ -105,9 +105,9 @@ public: private: // Helpers to extract addrs/ports from PendingConn. - const uint32* SrcAddr(const PendingConn* c) + const IPAddr& SrcAddr(const PendingConn* c) { return c->ip1_is_src ? c->key.ip1 : c->key.ip2; } - const uint32* DstAddr(const PendingConn* c) + const IPAddr& DstAddr(const PendingConn* c) { return c->ip1_is_src ? c->key.ip2 : c->key.ip1; } uint16 SrcPort(const PendingConn* c) diff --git a/src/DCE_RPC.cc b/src/DCE_RPC.cc index 1d9acaf1fa..2aae4aa76a 100644 --- a/src/DCE_RPC.cc +++ b/src/DCE_RPC.cc @@ -137,12 +137,10 @@ static bool is_mapped_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr) bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto) { -#ifdef BROv6 - if ( ! is_v4_addr(id->dst_addr) ) + if ( id->dst_addr.family() == IPAddr::IPv6 ) return false; -#endif dce_rpc_endpoint_addr addr; - addr.addr = ntohl(to_v4_addr(id->dst_addr)); + addr.addr = id->dst_addr; addr.port = ntohs(id->dst_port); addr.proto = proto; @@ -160,12 +158,7 @@ static void add_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr, // of the dce_rpc_endpoints table. // FIXME: Don't hard-code the timeout. - // Convert the address to a v4/v6 address (depending on how - // Bro was configured). This is all based on the address currently - // being a 32-bit host-order v4 address. - AddrVal a(htonl(addr.addr)); - const addr_type at = a.AsAddr(); - dpm->ExpectConnection(0, at, addr.port, addr.proto, + dpm->ExpectConnection(IPAddr(), addr.addr, addr.port, addr.proto, AnalyzerTag::DCE_RPC, 5 * 60, 0); } @@ -418,8 +411,8 @@ void DCE_RPC_Session::DeliverEpmapperMapResponse( break; case binpac::DCE_RPC_Simple::EPM_PROTOCOL_IP: - mapped.addr.addr = - floor->rhs()->data()->ip(); + uint32 hostip = floor->rhs()->data()->ip(); + mapped.addr.addr = IPAddr(IPAddr::IPv4, &hostip, IPAddr::Host); break; } } @@ -433,7 +426,7 @@ void DCE_RPC_Session::DeliverEpmapperMapResponse( vl->append(analyzer->BuildConnVal()); vl->append(new StringVal(mapped.uuid.to_string())); vl->append(new PortVal(mapped.addr.port, mapped.addr.proto)); - vl->append(new AddrVal(htonl(mapped.addr.addr))); + vl->append(new AddrVal(mapped.addr.addr)); analyzer->ConnectionEvent(epm_map_response, vl); } diff --git a/src/DCE_RPC.h b/src/DCE_RPC.h index 63237a151b..c736928a43 100644 --- a/src/DCE_RPC.h +++ b/src/DCE_RPC.h @@ -8,6 +8,7 @@ #include "NetVar.h" #include "TCP.h" +#include "IPAddr.h" #include "dce_rpc_simple_pac.h" @@ -33,20 +34,20 @@ protected: const char* uuid_to_string(const u_char* uuid_data); struct dce_rpc_endpoint_addr { - // All fields are in host byteorder. - uint32 addr; + // All fields except addr are in host byteorder. + IPAddr addr; u_short port; TransportProto proto; dce_rpc_endpoint_addr() { - addr = 0; + addr = IPAddr(); port = 0; proto = TRANSPORT_UNKNOWN; } bool is_valid_addr() const - { return addr != 0 && port != 0 && proto != TRANSPORT_UNKNOWN; } + { return addr != IPAddr() && port != 0 && proto != TRANSPORT_UNKNOWN; } bool operator<(dce_rpc_endpoint_addr const &e) const { @@ -64,7 +65,7 @@ struct dce_rpc_endpoint_addr { { static char buf[128]; snprintf(buf, sizeof(buf), "%s/%d/%s", - dotted_addr(htonl(addr)), port, + string(addr).c_str(), port, proto == TRANSPORT_TCP ? "tcp" : (proto == TRANSPORT_UDP ? "udp" : "?")); diff --git a/src/DNS.cc b/src/DNS.cc index c93ea6973d..40fe832e34 100644 --- a/src/DNS.cc +++ b/src/DNS.cc @@ -758,17 +758,11 @@ int DNS_Interpreter::ParseRR_A(DNS_MsgInfo* msg, int DNS_Interpreter::ParseRR_AAAA(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength) { - // We need to parse an IPv6 address, high-order byte first. - // ### Currently, we fake an A reply rather than an AAAA reply, - // since for the latter we won't be able to express the full - // address (unless Bro was compiled for IPv6 addresses). We do - // this fake by using just the bottom 4 bytes of the IPv6 address. uint32 addr[4]; - int i; - for ( i = 0; i < 4; ++i ) + for ( int i = 0; i < 4; ++i ) { - addr[i] = ntohl(ExtractLong(data, len)); + addr[i] = htonl(ExtractLong(data, len)); if ( len < 0 ) { @@ -777,23 +771,6 @@ int DNS_Interpreter::ParseRR_AAAA(DNS_MsgInfo* msg, } } - // Currently, dns_AAAA_reply is treated like dns_A_reply, since - // IPv6 addresses are not generally processed. This needs to be - // fixed. ### - if ( dns_A_reply && ! msg->skip_event ) - { - val_list* vl = new val_list; - - vl->append(analyzer->BuildConnVal()); - vl->append(msg->BuildHdrVal()); - vl->append(msg->BuildAnswerVal()); - vl->append(new AddrVal(htonl(addr[3]))); - - analyzer->ConnectionEvent(dns_A_reply, vl); - } - -#if 0 -alternative AAAA code from Chris if ( dns_AAAA_reply && ! msg->skip_event ) { val_list* vl = new val_list; @@ -801,19 +778,9 @@ alternative AAAA code from Chris vl->append(analyzer->BuildConnVal()); vl->append(msg->BuildHdrVal()); vl->append(msg->BuildAnswerVal()); -#ifdef BROv6 - // FIXME: might need to htonl the addr first vl->append(new AddrVal(addr)); -#else - vl->append(new AddrVal((uint32)0x0000)); -#endif - char addrstr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, addr, addrstr, INET6_ADDRSTRLEN); - vl->append(new StringVal(addrstr)); - analyzer->ConnectionEvent(dns_AAAA_reply, vl); } -#endif return 1; } diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 2b9d07a969..b9213c376e 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -95,7 +95,10 @@ public: const char* ReqHost() const { return req_host; } uint32 ReqAddr() const { return req_addr; } const char* ReqStr() const - { return req_host ? req_host : dotted_addr(ReqAddr()); } + { + return req_host ? req_host : + string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(); + } ListVal* Addrs(); TableVal* AddrsSet(); // addresses returned as a set @@ -195,7 +198,13 @@ DNS_Mapping::DNS_Mapping(FILE* f) if ( is_req_host ) req_host = copy_string(req_buf); else - req_addr = dotted_to_addr(req_buf); + { + string s(req_buf); + IPAddr addr(s); + const uint32* bytes; + addr.GetBytes(&bytes); + req_addr = *bytes; //FIXME: IPv6 support + } num_names = 1; names = new char*[num_names]; @@ -217,7 +226,11 @@ DNS_Mapping::DNS_Mapping(FILE* f) if ( newline ) *newline = '\0'; - addrs[i] = dotted_to_addr(buf); + string s(buf); + IPAddr addr(s); + const uint32* bytes; + addr.GetBytes(&bytes); + addrs[i] = *bytes; //FIXME IPv6 support } } else @@ -336,12 +349,14 @@ void DNS_Mapping::Clear() void DNS_Mapping::Save(FILE* f) const { fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0, - req_host ? req_host : dotted_addr(req_addr), + req_host ? req_host : + string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(), failed, (names && names[0]) ? names[0] : "*", num_addrs); for ( int i = 0; i < num_addrs; ++i ) - fprintf(f, "%s\n", dotted_addr(addrs[i])); + fprintf(f, "%s\n", + string(IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)).c_str()); } @@ -491,8 +506,9 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) return d->Host(); else { - reporter->Warning("can't resolve IP address: %s", dotted_addr(addr)); - return new StringVal(dotted_addr(addr)); + string s = IPAddr(IPAddr::IPv4, &addr, IPAddr::Network); + reporter->Warning("can't resolve IP address: %s", s.c_str()); + return new StringVal(s.c_str()); } } } @@ -505,7 +521,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", - dotted_addr(addr)); + string(IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)).c_str()); return 0; case DNS_DEFAULT: @@ -774,17 +790,13 @@ ListVal* DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) for ( int i = 0; i < al1->Length(); ++i ) { - addr_type al1_i = al1->Index(i)->AsAddr(); + const IPAddr* al1_i = al1->Index(i)->AsAddr(); int j; for ( j = 0; j < al2->Length(); ++j ) { - addr_type al2_j = al2->Index(j)->AsAddr(); -#ifdef BROv6 - if ( addr_eq(al1_i, al2_j) ) -#else - if ( al1_i == al2_j ) -#endif + const IPAddr* al2_j = al2->Index(j)->AsAddr(); + if ( *al1_i == *al2_j ) break; } @@ -800,8 +812,8 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al) { for ( int i = 0; i < al->Length(); ++i ) { - addr_type al_i = al->Index(i)->AsAddr(); - fprintf(f, "%s%s", i > 0 ? "," : "", dotted_addr(al_i)); + const IPAddr* al_i = al->Index(i)->AsAddr(); + fprintf(f, "%s%s", i > 0 ? "," : "", string(*al_i).c_str()); } } diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index def608d064..91bcad4084 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -12,6 +12,7 @@ #include "Dict.h" #include "EventHandler.h" #include "IOSource.h" +#include "IPAddr.h" class Val; class ListVal; diff --git a/src/DPM.cc b/src/DPM.cc index 345741dfc8..2700c92933 100644 --- a/src/DPM.cc +++ b/src/DPM.cc @@ -11,48 +11,24 @@ #include "ConnSizeAnalyzer.h" -ExpectedConn::ExpectedConn(const uint32* _orig, const uint32* _resp, +ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp, uint16 _resp_p, uint16 _proto) { - if ( orig ) - copy_addr(_orig, orig); + if ( _orig == IPAddr(string("0.0.0.0")) ) + // don't use the IPv4 mapping, use the literal unspecified address + // to indicate a wildcard + orig[0] = orig[1] = orig[2] = orig[3] = 0; else - { - for ( int i = 0; i < NUM_ADDR_WORDS; ++i ) - orig[i] = 0; - } - - copy_addr(_resp, resp); - - resp_p = _resp_p; - proto = _proto; - } - -ExpectedConn::ExpectedConn(uint32 _orig, uint32 _resp, - uint16 _resp_p, uint16 _proto) - { -#ifdef BROv6 - // Use the IPv4-within-IPv6 convention, as this is what's - // needed when we mix uint32's (like in this construction) - // with addr_type's (for example, when looking up expected - // connections). - - orig[0] = orig[1] = orig[2] = 0; - resp[0] = resp[1] = resp[2] = 0; - orig[3] = _orig; - resp[3] = _resp; -#else - orig[0] = _orig; - resp[0] = _resp; -#endif + _orig.CopyIPv6(orig); + _resp.CopyIPv6(resp); resp_p = _resp_p; proto = _proto; } ExpectedConn::ExpectedConn(const ExpectedConn& c) { - copy_addr(c.orig, orig); - copy_addr(c.resp, resp); + memcpy(orig, c.orig, sizeof(orig)); + memcpy(resp, c.resp, sizeof(resp)); resp_p = c.resp_p; proto = c.proto; } @@ -168,7 +144,7 @@ AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn) if ( ! a ) { // Wildcard for originator. - for ( int i = 0; i < NUM_ADDR_WORDS; ++i ) + for ( int i = 0; i < 4; ++i ) c.orig[i] = 0; HashKey key(&c, sizeof(c.orig) + sizeof(c.resp) + @@ -404,7 +380,8 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn, return true; } -void DPM::ExpectConnection(addr_type orig, addr_type resp, uint16 resp_p, +void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, + uint16 resp_p, TransportProto proto, AnalyzerTag::Tag analyzer, double timeout, void* cookie) { diff --git a/src/DPM.h b/src/DPM.h index 4bacbfbeea..b3e5f8f17f 100644 --- a/src/DPM.h +++ b/src/DPM.h @@ -27,19 +27,13 @@ // Map to assign expected connections to analyzers. class ExpectedConn { public: - // This form can be used for IPv6 as well as IPv4. - ExpectedConn(const uint32* _orig, const uint32* _resp, + ExpectedConn(const IPAddr& _orig, const IPAddr& _resp, uint16 _resp_p, uint16 _proto); - // This form only works for expecting an IPv4 connection. Note - // that we do the right thing whether we're built IPv4-only or - // BROv6. - ExpectedConn(uint32 _orig, uint32 _resp, uint16 _resp_p, uint16 _proto); - ExpectedConn(const ExpectedConn& c); - uint32 orig[NUM_ADDR_WORDS]; - uint32 resp[NUM_ADDR_WORDS]; + uint32 orig[4]; + uint32 resp[4]; uint16 resp_p; uint16 proto; }; @@ -90,7 +84,7 @@ public: // Schedules a particular analyzer for an upcoming connection. // 0 acts as a wildcard for orig. (Cookie is currently unused. // Eventually, we may pass it on to the analyzer). - void ExpectConnection(addr_type orig, addr_type resp, uint16 resp_p, + void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, TransportProto proto, AnalyzerTag::Tag analyzer, double timeout, void* cookie); diff --git a/src/Expr.cc b/src/Expr.cc index c34c44a7d1..e5fe10d790 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -14,6 +14,7 @@ #include "Net.h" #include "Traverse.h" #include "Trigger.h" +#include "IPAddr.h" const char* expr_name(BroExprTag t) { @@ -834,23 +835,15 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const { - addr_type a1 = v1->AsAddr(); - addr_type a2 = v2->AsAddr(); + uint32 a1[4]; + uint32 a2[4]; + v1->AsAddr()->CopyIPv6(a1); + v2->AsAddr()->CopyIPv6(a2); int result = 0; switch ( tag ) { #undef DO_FOLD -#ifdef BROv6 #define DO_FOLD(sense) { result = memcmp(a1, a2, 16) sense 0; break; } -#else -#define DO_FOLD(sense) \ - { \ - a1 = ntohl(a1); \ - a2 = ntohl(a2); \ - result = (a1 < a2 ? -1 : (a1 == a2 ? 0 : 1)) sense 0; \ - break; \ - } -#endif case EXPR_LT: DO_FOLD(<) case EXPR_LE: DO_FOLD(<=) @@ -868,20 +861,13 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const { - subnet_type* n1 = v1->AsSubNet(); - subnet_type* n2 = v2->AsSubNet(); + const IPPrefix* n1 = v1->AsSubNet(); + const IPPrefix* n2 = v2->AsSubNet(); - if ( n1->width != n2->width ) + if ( *n1 == *n2 ) + return new Val(1, TYPE_BOOL); + else return new Val(0, TYPE_BOOL); - -#ifdef BROv6 - if ( memcmp(n1->net, n2->net, 16) ) -#else - if ( n1->net != n2->net ) -#endif - return new Val(0, TYPE_BOOL); - - return new Val(1, TYPE_BOOL); } void BinaryExpr::SwapOps() @@ -1681,15 +1667,13 @@ DivideExpr::DivideExpr(Expr* arg_op1, Expr* arg_op2) Val* DivideExpr::AddrFold(Val* v1, Val* v2) const { - addr_type a1 = v1->AsAddr(); - uint32 mask; if ( v2->Type()->Tag() == TYPE_COUNT ) mask = static_cast(v2->InternalUnsigned()); else mask = static_cast(v2->InternalInt()); - return new SubNetVal(a1, mask); + return new SubNetVal(*v1->AsAddr(), mask); } Expr* DivideExpr::DoSimplify() @@ -4494,7 +4478,7 @@ Val* InExpr::Fold(Val* v1, Val* v2) const if ( v1->Type()->Tag() == TYPE_ADDR && v2->Type()->Tag() == TYPE_SUBNET ) - return new Val(v2->AsSubNetVal()->Contains(v1->AsAddr()), TYPE_BOOL); + return new Val(v2->AsSubNetVal()->Contains(*v1->AsAddr()), TYPE_BOOL); TableVal* vt = v2->AsTableVal(); if ( vt->Lookup(v1, false) ) diff --git a/src/HTTP.cc b/src/HTTP.cc index b41933156d..9d9f01be64 100644 --- a/src/HTTP.cc +++ b/src/HTTP.cc @@ -1543,7 +1543,7 @@ void HTTP_Analyzer::HTTP_Header(int is_orig, MIME_Header* h) } } -void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const uint32* host, +void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, bool user_agent) { int len = ver.length; diff --git a/src/HTTP.h b/src/HTTP.h index 00524da20d..c9d8ae55d1 100644 --- a/src/HTTP.h +++ b/src/HTTP.h @@ -8,6 +8,7 @@ #include "MIME.h" #include "binpac_bro.h" #include "ZIP.h" +#include "IPAddr.h" enum CHUNKED_TRANSFER_STATE { NON_CHUNKED_TRANSFER, @@ -212,7 +213,7 @@ protected: const BroString* UnansweredRequestMethod(); - void ParseVersion(data_chunk_t ver, const uint32* host, bool user_agent); + void ParseVersion(data_chunk_t ver, const IPAddr& host, bool user_agent); int HTTP_ReplyCode(const char* code_str); int ExpectReplyMessageBody(); diff --git a/src/ICMP.cc b/src/ICMP.cc index bc081ace51..279adbd7dd 100644 --- a/src/ICMP.cc +++ b/src/ICMP.cc @@ -243,7 +243,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const d->Add(Conn()->LastTime()); d->AddSP(")"); - d->Add(dotted_addr(Conn()->OrigAddr())); + d->Add(string(Conn()->OrigAddr()).c_str()); d->Add("."); d->Add(type); d->Add("."); @@ -252,7 +252,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const d->SP(); d->AddSP("->"); - d->Add(dotted_addr(Conn()->RespAddr())); + d->Add(string(Conn()->RespAddr()).c_str()); } void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val) diff --git a/src/IP.h b/src/IP.h index 73ac4ee5c7..5733f633a2 100644 --- a/src/IP.h +++ b/src/IP.h @@ -4,63 +4,33 @@ #define ip_h #include "config.h" - +#include "IPAddr.h" #include class IP_Hdr { public: IP_Hdr(struct ip* arg_ip4) + : ip4(arg_ip4), ip6(0), + src_addr(arg_ip4->ip_src), dst_addr(arg_ip4->ip_dst), del(1) { - ip4 = arg_ip4; - ip6 = 0; - del = 1; - -#ifdef BROv6 - src_addr[0] = src_addr[1] = src_addr[2] = 0; - dst_addr[0] = dst_addr[1] = dst_addr[2] = 0; - - src_addr[3] = ip4->ip_src.s_addr; - dst_addr[3] = ip4->ip_dst.s_addr; -#endif } IP_Hdr(const struct ip* arg_ip4) + : ip4(arg_ip4), ip6(0), + src_addr(arg_ip4->ip_src), dst_addr(arg_ip4->ip_dst), del(0) { - ip4 = arg_ip4; - ip6 = 0; - del = 0; - -#ifdef BROv6 - src_addr[0] = src_addr[1] = src_addr[2] = 0; - dst_addr[0] = dst_addr[1] = dst_addr[2] = 0; - - src_addr[3] = ip4->ip_src.s_addr; - dst_addr[3] = ip4->ip_dst.s_addr; -#endif } IP_Hdr(struct ip6_hdr* arg_ip6) + : ip4(0), ip6(arg_ip6), + src_addr(arg_ip6->ip6_src), dst_addr(arg_ip6->ip6_dst), del(1) { - ip4 = 0; - ip6 = arg_ip6; - del = 1; - -#ifdef BROv6 - memcpy(src_addr, ip6->ip6_src.s6_addr, 16); - memcpy(dst_addr, ip6->ip6_dst.s6_addr, 16); -#endif } IP_Hdr(const struct ip6_hdr* arg_ip6) + : ip4(0), ip6(arg_ip6), + src_addr(arg_ip6->ip6_src), dst_addr(arg_ip6->ip6_dst), del(0) { - ip4 = 0; - ip6 = arg_ip6; - del = 0; - -#ifdef BROv6 - memcpy(src_addr, ip6->ip6_src.s6_addr, 16); - memcpy(dst_addr, ip6->ip6_dst.s6_addr, 16); -#endif } ~IP_Hdr() @@ -77,19 +47,10 @@ public: const struct ip* IP4_Hdr() const { return ip4; } const struct ip6_hdr* IP6_Hdr() const { return ip6; } -#ifdef BROv6 - const uint32* SrcAddr() const { return src_addr; } - const uint32* DstAddr() const { return dst_addr; } -#else - const uint32* SrcAddr() const - { return ip4 ? &(ip4->ip_src.s_addr) : 0; } - const uint32* DstAddr() const - { return ip4 ? &(ip4->ip_dst.s_addr) : 0; } -#endif - - uint32 SrcAddr4() const { return ip4->ip_src.s_addr; } - uint32 DstAddr4() const { return ip4->ip_dst.s_addr; } + const IPAddr& SrcAddr() const { return src_addr; } + const IPAddr& DstAddr() const { return dst_addr; } + //TODO: needs adapting/replacement for IPv6 support uint16 ID4() const { return ip4 ? ip4->ip_id : 0; } const u_char* Payload() const @@ -131,10 +92,8 @@ public: private: const struct ip* ip4; const struct ip6_hdr* ip6; -#ifdef BROv6 - uint32 src_addr[NUM_ADDR_WORDS]; - uint32 dst_addr[NUM_ADDR_WORDS]; -#endif + IPAddr src_addr; + IPAddr dst_addr; int del; }; diff --git a/src/IPAddr.cc b/src/IPAddr.cc new file mode 100644 index 0000000000..e3737f41b4 --- /dev/null +++ b/src/IPAddr.cc @@ -0,0 +1,364 @@ +#include "IPAddr.h" +#include "Reporter.h" +#include "modp_numtoa.h" +#include + +const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0xff, 0xff }; + +IPAddr::IPAddr() + { + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } + +IPAddr::IPAddr(const in4_addr& in4) + { + memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr)); + } + +IPAddr::IPAddr(const in6_addr& arg_in6) + : in6(arg_in6) + { + } + +void IPAddr::Init(const std::string& s) + { + if ( s.find(':') == std::string::npos ) //IPv4 + { + memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 ) + { + reporter->Error("Bad IP address: %s", s.c_str()); + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } + } + else + { + if ( inet_pton(AF_INET6, s.c_str(), in6.s6_addr) <=0 ) + { + reporter->Error("Bad IP address: %s", s.c_str()); + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } + } + } + +IPAddr::IPAddr(const std::string& s) + { + Init(s); + } + +IPAddr::IPAddr(const BroString& s) + { + Init(s.CheckString()); + } + +IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order) + { + if ( family == IPv4 ) + { + memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + memcpy(&in6.s6_addr[12], bytes, sizeof(uint32_t)); + if ( order == Host ) + { + uint32_t* p = (uint32_t*) &in6.s6_addr[12]; + *p = htonl(*p); + } + } + else + { + memcpy(in6.s6_addr, bytes, sizeof(in6.s6_addr)); + if ( order == Host ) + { + for ( unsigned int i = 0; i < 4; ++ i) + { + uint32_t* p = (uint32_t*) &in6.s6_addr[i*4]; + *p = htonl(*p); + } + } + } + } + +IPAddr::IPAddr(const IPAddr& other) + { + in6 = other.in6; + } + +IPAddr::~IPAddr() + { + } + +IPAddr::Family IPAddr::family() const + { + if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 ) + return IPv4; + else + return IPv6; + } + +bool IPAddr::IsLoopback() const + { + if ( family() == IPv4 ) + return in6.s6_addr[12] == 127; + else + return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) + && (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0) + && (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) + && (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) + && (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0) + && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) + && (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0) + && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); + } + +bool IPAddr::IsMulticast() const + { + if ( family() == IPv4 ) + return in6.s6_addr[12] == 224; + else + return in6.s6_addr[0] == 0xff; + } + +bool IPAddr::IsBroadcast() const + { + if ( family() == IPv4 ) + return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) + && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); + else + return false; + } + +int IPAddr::GetBytes(uint32_t** bytes) + { + if ( family() == IPv4 ) + { + *bytes = (uint32_t*) &in6.s6_addr[12]; + return 1; + } + else + { + *bytes = (uint32_t*) in6.s6_addr; + return 4; + } + } + +int IPAddr::GetBytes(const uint32_t** bytes) const + { + if ( family() == IPv4 ) + { + *bytes = (uint32_t*) &in6.s6_addr[12]; + return 1; + } + else + { + *bytes = (uint32_t*) in6.s6_addr; + return 4; + } + } + +void IPAddr::CopyIPv6(uint32_t* bytes) const + { + memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr)); + } + +void IPAddr::Mask(int top_bits_to_keep) + { + if ( top_bits_to_keep <=0 || top_bits_to_keep > 128 ) + { + reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep); + return; + } + + uint32_t tmp[4]; + memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + + int word = 3; + int bits_to_chop = 128 - top_bits_to_keep; + while ( bits_to_chop >= 32 ) + { + tmp[word] = 0; + --word; + bits_to_chop -= 32; + } + + uint32_t w = ntohl(tmp[word]); + w >>= bits_to_chop; + w <<= bits_to_chop; + tmp[word] = htonl(w); + memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + } + +void IPAddr::ReverseMask(int top_bits_to_chop) + { + if ( top_bits_to_chop <=0 || top_bits_to_chop > 128 ) + { + reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop); + return; + } + + uint32_t tmp[4]; + memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + + int word = 0; + int bits_to_chop = top_bits_to_chop; + while ( bits_to_chop >= 32 ) + { + tmp[word] = 0; + ++word; + bits_to_chop -= 32; + } + + uint32_t w = ntohl(tmp[word]); + w <<= bits_to_chop; + w >>= bits_to_chop; + tmp[word] = htonl(w); + memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + } + +IPAddr& IPAddr::operator =(const IPAddr& other) + { + // No self-assignment check here because it's correct without it and + // makes the common case faster. + in6 = other.in6; + return *this; + } + +IPAddr::operator std::string() const + { + if ( family() == IPv4 ) + { + char s[INET_ADDRSTRLEN]; + if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) + return " 32 ) + reporter->InternalError("Bad in4_addr IPPrefix length : %d", length); + prefix.Mask(this->length); + } + +IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) + : prefix(in6), length(length) + { + if ( length > 128 ) + reporter->InternalError("Bad in6_addr IPPrefix length : %d", length); + prefix.Mask(this->length); + } + +IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length) + : prefix(addr) + { + if ( prefix.family() == IPAddr::IPv4 ) + { + if ( length > 32 ) + reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d", + length); + this->length = length + 96; + } + else + { + if ( length > 128 ) + reporter->InternalError("Bad IPAddr(v6) IPPrefix length : %d", + length); + this->length = length; + } + prefix.Mask(this->length); + } + +IPPrefix::IPPrefix(const std::string& s, uint8_t length) + : prefix(s), length(length) + { + if ( prefix.family() == IPAddr::IPv4 && length > 32 ) + reporter->InternalError("Bad string IPPrefix length : %d", length); + else if ( prefix.family() == IPAddr::IPv6 && length > 128 ) + reporter->InternalError("Bad string IPPrefix length : %d", length); + prefix.Mask(this->length); + } + +IPPrefix::IPPrefix(const IPPrefix& other) + : prefix(other.prefix), length(other.length) + { + } + +IPPrefix::~IPPrefix() + { + } + +const IPAddr& IPPrefix::Prefix() const + { + return prefix; + } + +uint8_t IPPrefix::Length() const + { + return prefix.family() == IPAddr::IPv4 ? length - 96 : length; + } + +uint8_t IPPrefix::LengthIPv6() const + { + return length; + } + +IPPrefix& IPPrefix::operator =(const IPPrefix& other) + { + // No self-assignment check here because it's correct without it and + // makes the common case faster. + prefix = other.Prefix(); + length = other.Length(); + return *this; + } + +IPPrefix::operator std::string() const + { + char l[16]; + if ( prefix.family() == IPAddr::IPv4 ) + modp_uitoa10(length - 96, l); + else + modp_uitoa10(length, l); + return std::string(prefix).append("/").append(l); + } + +bool operator ==(const IPPrefix& net1, const IPPrefix& net2) + { + return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length(); + } + +bool operator <(const IPPrefix& net1, const IPPrefix& net2) + { + if ( net1.Prefix() < net2.Prefix() ) + return true; + else if ( net1.Prefix() == net2.Prefix() ) + return net1.Length() < net2.Length(); + else + return false; + } diff --git a/src/IPAddr.h b/src/IPAddr.h index fda749db9e..d59e853b1e 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -2,6 +2,14 @@ #ifndef IPADDR_H #define IPADDR_H +#include +#include + +#include "BroString.h" +#include "util.h" + +typedef in_addr in4_addr; + /// Class storing both IPv4 and IPv6 addresses. class IPAddr { @@ -12,6 +20,9 @@ public: /// Byte order. enum ByteOrder { Host, Network }; + /// Constructs the unspecified IPv6 address (all 128 bits zeroed). + IPAddr(); + /// Constructs an address instance from an IPv4 address. /// /// @param in6 The IPv6 address. @@ -26,7 +37,7 @@ public: /// /// @param s String containing an IP address as either a dotted IPv4 /// address or a hex IPv6 address. - IPAddr(const string& s); + IPAddr(const std::string& s); /// Constructs an address instance from a string representation. /// @@ -43,8 +54,8 @@ public: /// IPv6. /// /// @param order Indicates whether the raw representation pointed to - /// be \a bytes is stored in network or host order. - IPAddr(Family family, const u_char* bytes, ByteOrder order); + /// by \a bytes is stored in network or host order. + IPAddr(Family family, const uint32_t* bytes, ByteOrder order); /// Copy constructor. IPAddr(const IPAddr& other); @@ -61,19 +72,29 @@ public: /// Returns true if the address represents a multicast address. bool IsMulticast() const; - /// Returs true if the address represents a broadcast address. + /// Returns true if the address represents a broadcast address. bool IsBroadcast() const; /// Retrieves the raw byte representation of the address. /// /// @param bytes The pointer to which \a bytes points will be set to - /// the address of the raw representation. The return value indicates - /// how many bytes are valid starting at that address. The pointer - /// will be valid as long as the address instance exists. + /// the address of the raw representation in network-byte order. + /// The return value indicates how many 32-bit words are valid starting at + /// that address. The pointer will be valid as long as the address instance + /// exists. /// - /// @return The number of bytes the raw representation uses. This - /// will be 4 for an IPv4 address and 32 for an IPv6 address. - int GetBytes(unsigned u_char** bytes); // Returns network-byte order. + /// @return The number of 32-bit words the raw representation uses. This + /// will be 1 for an IPv4 address and 4 for an IPv6 address. + int GetBytes(uint32_t** bytes); + int GetBytes(const uint32_t** bytes) const; + + /// Retrieves a copy of the IPv6 raw byte representation of the address. + /// If the internal address is IPv4, then the copied bytes use the + /// IPv4 to IPv6 address mapping to return a full 16 bytes. + /// + /// @param bytes The pointer to a memory location in which the + /// raw bytes of the address are to be copied in network byte-order. + void CopyIPv6(uint32_t* bytes) const; /// Masks out lower bits of the address. /// @@ -85,45 +106,80 @@ public: /// 0 to 128. void Mask(int top_bits_to_keep); + /// Masks out top bits of the address. + /// + /// @param top_bits_to_chop The number of bits to mask out, counting + /// from the highest order bit. The value is always interpreted relative + /// to the IPv6 bit width, even if the address is IPv4. So to mask out + /// the first 16 bits of an IPv4 address, pass in 112 (i.e., 96 + 16). + /// The value must be in the range from 0 to 128. + void ReverseMask(int top_bits_to_chop); + /// Assignment operator. - const IPAddr& operator=(const IPAddr& other); + IPAddr& operator=(const IPAddr& other); /// Returns a string representation of the address. IPv4 addresses /// will be returned in dotted representation, IPv6 addresses in /// compressed hex. - operator string() const; + operator std::string() const; + + /// Comparison operator for IP address. + friend bool operator==(const IPAddr& addr1, const IPAddr& addr2); + friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2); + + /// Comparison operator IP addresses. This defines a well-defined order for + /// IP addresses. However, the order does not necessarily correspond to + /// their numerical values. + friend bool operator<(const IPAddr& addr1, const IPAddr& addr2); + + unsigned int MemoryAllocation() const { return padded_sizeof(*this); } private: - struct in6_addr in6; // This stored IPv6 addresses via the standard v4-to-v6 mapping. + in6_addr in6; // IPv6 or v4-to-v6-mapped address + static const uint8_t v4_mapped_prefix[12]; // top 96 bits of v4-mapped-addr + + /// Initializes an address instance from a string representation. + /// + /// @param s String containing an IP address as either a dotted IPv4 + /// address or a hex IPv6 address. + void Init(const std::string& s); }; -/// Comparision operator for IP addresss. -extern bool operator==(const IPAddr& addr1, const IPAddr& addr2) const; - -/// Comparision operator IP addresses. This defines a well-defined order for -/// IP addresses. However, the order does not necessarily correspond to their -/// numerical values. -extern bool operator<(const IPAddr& addr1, const IPAddr& addr2) const; - -/// Class storing both IPv4 and IPv6 prefixes (i.e., \c 192.168.1.1/16 and \c FD00::/8. +/// Class storing both IPv4 and IPv6 prefixes +/// (i.e., \c 192.168.1.1/16 and \c FD00::/8. class IPPrefix { public: /// Constructs a prefix instance from an IPv4 address and a prefix /// length. /// - /// @param addr The IPv4 address. + /// @param in4 The IPv4 address. /// /// @param length The prefix length in the range from 0 to 32. - IPPrefix(const in4_addr& in4, uint16_t length); + IPPrefix(const in4_addr& in4, uint8_t length); /// Constructs a prefix instance from an IPv6 address and a prefix /// length. /// - /// @param addr The IPv6 address. + /// @param in6 The IPv6 address. /// /// @param length The prefix length in the range from 0 to 128. - IPPrefix(const in6_addr& in6, uint16_t length); + IPPrefix(const in6_addr& in6, uint8_t length); + + /// Constructs a prefix instance from an IPAddr object and prefix length. + /// + /// @param addr The IP address. + /// + /// @param length The prefix length in the range from 0 to 128 + IPPrefix(const IPAddr& addr, uint8_t length); + + /// Constructs a prefix instance from IP string representation and length. + /// + /// @param s String containing an IP address as either a dotted IPv4 + /// address or a hex IPv6 address. + /// + /// @param length The prefix length in the range from 0 to 128 + IPPrefix(const std::string& s, uint8_t length); /// Copy constructor. IPPrefix(const IPPrefix& other); @@ -135,28 +191,35 @@ public: /// have all bits not part of the prefixed set to zero. const IPAddr& Prefix() const; - /// Returns the bit length of the prefix. - uint16_t Length() const; + /// Returns the bit length of the prefix, relative to the 32 bits + /// of an IPv4 prefix or relative to the 128 bits of an IPv6 prefix. + uint8_t Length() const; + + /// Returns the bit length of the prefix always relative to a full + /// 128 bits of an IPv6 prefix (or IPv4 mapped to IPv6). + uint8_t LengthIPv6() const; /// Assignment operator. - const IPPrefix& operator=(const IPPrefix& other); + IPPrefix& operator=(const IPPrefix& other); /// Returns a string representation of the prefix. IPv4 addresses /// will be returned in dotted representation, IPv6 addresses in /// compressed hex. - operator string() const; + operator std::string() const; + + unsigned int MemoryAllocation() const { return padded_sizeof(*this); } private: IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask(). - uint16_t mask; // The bit length. + uint8_t length; // The bit length of the prefix relative to full IPv6 addr. }; -/// Comparision operator for IP prefix. -extern bool operator==(const IPPrefix& net1, const IPPrefix& net2) const; +/// Comparison operator for IP prefix. +extern bool operator==(const IPPrefix& net1, const IPPrefix& net2); -/// Comparision operator IP prefixes. This defines a well-defined order for +/// Comparison operator IP prefixes. This defines a well-defined order for /// IP prefix. However, the order does not necessarily corresponding to their /// numerical values. -extern bool operator<(const IPPrefix& net1, const IPPrefix& net2) const; +extern bool operator<(const IPPrefix& net1, const IPPrefix& net2); #endif diff --git a/src/LogMgr.cc b/src/LogMgr.cc index 28e9a2ac1f..ffe8a036fe 100644 --- a/src/LogMgr.cc +++ b/src/LogMgr.cc @@ -101,6 +101,12 @@ LogVal::~LogVal() && present ) delete val.string_val; + if ( type == TYPE_ADDR && present ) + delete val.addr_val; + + if ( type == TYPE_SUBNET && present ) + delete val.subnet_val; + if ( type == TYPE_TABLE && present ) { for ( int i = 0; i < val.set_val.size; i++ ) @@ -193,22 +199,15 @@ bool LogVal::Read(SerializationFormat* fmt) case TYPE_SUBNET: { - uint32 net[4]; + uint32 net[5]; if ( ! (fmt->Read(&net[0], "net0") && fmt->Read(&net[1], "net1") && fmt->Read(&net[2], "net2") && fmt->Read(&net[3], "net3") && - fmt->Read(&val.subnet_val.width, "width")) ) + fmt->Read(&net[4], "width")) ) return false; - -#ifdef BROv6 - val.subnet_val.net[0] = net[0]; - val.subnet_val.net[1] = net[1]; - val.subnet_val.net[2] = net[2]; - val.subnet_val.net[3] = net[3]; -#else - val.subnet_val.net = net[0]; -#endif + val.subnet_val = new IPPrefix(IPAddr(IPAddr::IPv6, net, + IPAddr::Network), net[4]); return true; } @@ -221,12 +220,7 @@ bool LogVal::Read(SerializationFormat* fmt) fmt->Read(&addr[3], "addr3")) ) return false; - val.addr_val[0] = addr[0]; -#ifdef BROv6 - val.addr_val[1] = addr[1]; - val.addr_val[2] = addr[2]; - val.addr_val[3] = addr[3]; -#endif + val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); return true; } @@ -309,33 +303,18 @@ bool LogVal::Write(SerializationFormat* fmt) const case TYPE_SUBNET: { uint32 net[4]; -#ifdef BROv6 - net[0] = val.subnet_val.net[0]; - net[1] = val.subnet_val.net[1]; - net[2] = val.subnet_val.net[2]; - net[3] = val.subnet_val.net[3]; -#else - net[0] = val.subnet_val.net; - net[1] = net[2] = net[3] = 0; -#endif + val.subnet_val->Prefix().CopyIPv6(net); return fmt->Write(net[0], "net0") && fmt->Write(net[1], "net1") && fmt->Write(net[2], "net2") && fmt->Write(net[3], "net3") && - fmt->Write(val.subnet_val.width, "width"); + fmt->Write((uint32)val.subnet_val->Length(), "width"); } case TYPE_ADDR: { uint32 addr[4]; - addr[0] = val.addr_val[0]; -#ifdef BROv6 - addr[1] = val.addr_val[1]; - addr[2] = val.addr_val[2]; - addr[3] = val.addr_val[3]; -#else - addr[1] = addr[2] = addr[3] = 0; -#endif + val.addr_val->CopyIPv6(addr); return fmt->Write(addr[0], "addr0") && fmt->Write(addr[1], "addr1") && fmt->Write(addr[2], "addr2") && @@ -1107,17 +1086,12 @@ LogVal* LogMgr::ValToLogVal(Val* val, BroType* ty) break; case TYPE_SUBNET: - lval->val.subnet_val = *val->AsSubNet(); + lval->val.subnet_val = new IPPrefix(*val->AsSubNet()); break; case TYPE_ADDR: { - addr_type t = val->AsAddr(); -#ifdef BROv6 - copy_addr(t, lval->val.addr_val); -#else - copy_addr(&t, lval->val.addr_val); -#endif + lval->val.addr_val = new IPAddr(*val->AsAddr()); break; } diff --git a/src/LogMgr.h b/src/LogMgr.h index 3eaba360d5..c66f9ed7f8 100644 --- a/src/LogMgr.h +++ b/src/LogMgr.h @@ -8,6 +8,7 @@ #include "Val.h" #include "EventHandler.h" #include "RemoteSerializer.h" +#include "IPAddr.h" class SerializationFormat; @@ -40,8 +41,8 @@ struct LogVal { union _val { bro_int_t int_val; bro_uint_t uint_val; - uint32 addr_val[NUM_ADDR_WORDS]; - subnet_type subnet_val; + IPAddr* addr_val; + IPPrefix* subnet_val; double double_val; string* string_val; set_t set_val; diff --git a/src/LogWriterAscii.cc b/src/LogWriterAscii.cc index d2c1d91370..84fe8a3c31 100644 --- a/src/LogWriterAscii.cc +++ b/src/LogWriterAscii.cc @@ -166,13 +166,11 @@ bool LogWriterAscii::DoWriteOne(ODesc* desc, LogVal* val, const LogField* field) break; case TYPE_SUBNET: - desc->Add(dotted_addr(val->val.subnet_val.net)); - desc->Add("/"); - desc->Add(val->val.subnet_val.width); + desc->Add(string(*val->val.subnet_val).c_str()); break; case TYPE_ADDR: - desc->Add(dotted_addr(val->val.addr_val)); + desc->Add(string(*val->val.addr_val).c_str()); break; case TYPE_TIME: diff --git a/src/OSFinger.cc b/src/OSFinger.cc index f8032d60ee..980d618f6e 100644 --- a/src/OSFinger.cc +++ b/src/OSFinger.cc @@ -63,9 +63,11 @@ OSFingerprint::OSFingerprint(FingerprintMode arg_mode) } } -bool OSFingerprint::CacheMatch(uint32 addr, int id) +bool OSFingerprint::CacheMatch(const IPAddr& addr, int id) { - HashKey key = HashKey(&addr, 1); + uint32 bytes[4]; + addr.CopyIPv6(bytes); + HashKey key = HashKey(bytes, 4); int* pid = new int; *pid=id; int* prev = os_matches.Insert(&key, pid); diff --git a/src/OSFinger.h b/src/OSFinger.h index e5a0829640..0968fb5fd3 100644 --- a/src/OSFinger.h +++ b/src/OSFinger.h @@ -14,6 +14,7 @@ #include "util.h" #include "Dict.h" #include "Reporter.h" +#include "IPAddr.h" // Size limit for size wildcards. #define PACKET_BIG 100 @@ -88,7 +89,7 @@ public: int FindMatch(struct os_type* retval, uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS, uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ECN) const; - bool CacheMatch(uint32 addr, int id); + bool CacheMatch(const IPAddr& addr, int id); int Get_OS_From_SYN(struct os_type* retval, uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS, diff --git a/src/PIA.cc b/src/PIA.cc index 6a00e7e1d0..ed46e84794 100644 --- a/src/PIA.cc +++ b/src/PIA.cc @@ -199,17 +199,21 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) ip4_hdr = new IP_Hdr((const struct ip*) ip4); } + const uint32* obytes; + const uint32* rbytes; + Conn()->OrigAddr().GetBytes(&obytes); + Conn()->RespAddr().GetBytes(&rbytes); if ( is_orig ) { - copy_addr(Conn()->OrigAddr(), &ip4->ip_src.s_addr); - copy_addr(Conn()->RespAddr(), &ip4->ip_dst.s_addr); + memcpy(&ip4->ip_src.s_addr, obytes, sizeof(uint32)); + memcpy(&ip4->ip_dst.s_addr, rbytes, sizeof(uint32)); tcp4->th_sport = htons(Conn()->OrigPort()); tcp4->th_dport = htons(Conn()->RespPort()); } else { - copy_addr(Conn()->RespAddr(), &ip4->ip_src.s_addr); - copy_addr(Conn()->OrigAddr(), &ip4->ip_dst.s_addr); + memcpy(&ip4->ip_src.s_addr, rbytes, sizeof(uint32)); + memcpy(&ip4->ip_dst.s_addr, obytes, sizeof(uint32)); tcp4->th_sport = htons(Conn()->RespPort()); tcp4->th_dport = htons(Conn()->OrigPort()); } diff --git a/src/PacketFilter.cc b/src/PacketFilter.cc index 9b6b881ce5..93a452482f 100644 --- a/src/PacketFilter.cc +++ b/src/PacketFilter.cc @@ -1,11 +1,11 @@ #include "PacketFilter.h" -void PacketFilter::AddSrc(addr_type src, uint32 tcp_flags, double probability) +void PacketFilter::AddSrc(const IPAddr& src, uint32 tcp_flags, double probability) { Filter* f = new Filter; f->tcp_flags = tcp_flags; f->probability = uint32(probability * RAND_MAX); - src_filter.Insert(src, NUM_ADDR_WORDS * 32, f); + src_filter.Insert(src, 128, f); } void PacketFilter::AddSrc(Val* src, uint32 tcp_flags, double probability) @@ -16,12 +16,12 @@ void PacketFilter::AddSrc(Val* src, uint32 tcp_flags, double probability) src_filter.Insert(src, f); } -void PacketFilter::AddDst(addr_type dst, uint32 tcp_flags, double probability) +void PacketFilter::AddDst(const IPAddr& dst, uint32 tcp_flags, double probability) { Filter* f = new Filter; f->tcp_flags = tcp_flags; f->probability = uint32(probability * RAND_MAX); - dst_filter.Insert(dst, NUM_ADDR_WORDS * 32, f); + dst_filter.Insert(dst, 128, f); } void PacketFilter::AddDst(Val* dst, uint32 tcp_flags, double probability) @@ -32,9 +32,9 @@ void PacketFilter::AddDst(Val* dst, uint32 tcp_flags, double probability) dst_filter.Insert(dst, f); } -bool PacketFilter::RemoveSrc(addr_type src) +bool PacketFilter::RemoveSrc(const IPAddr& src) { - return src_filter.Remove(src, NUM_ADDR_WORDS * 32) != 0; + return src_filter.Remove(src, 128) != 0; } bool PacketFilter::RemoveSrc(Val* src) @@ -42,9 +42,9 @@ bool PacketFilter::RemoveSrc(Val* src) return src_filter.Remove(src) != NULL; } -bool PacketFilter::RemoveDst(addr_type dst) +bool PacketFilter::RemoveDst(const IPAddr& dst) { - return dst_filter.Remove(dst, NUM_ADDR_WORDS * 32) != NULL; + return dst_filter.Remove(dst, 128) != NULL; } bool PacketFilter::RemoveDst(Val* dst) @@ -54,21 +54,11 @@ bool PacketFilter::RemoveDst(Val* dst) bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen) { -#ifdef BROv6 - Filter* f = (Filter*) src_filter.Lookup(ip->SrcAddr(), - NUM_ADDR_WORDS * 32); -#else - Filter* f = (Filter*) src_filter.Lookup(*ip->SrcAddr(), - NUM_ADDR_WORDS * 32); -#endif + Filter* f = (Filter*) src_filter.Lookup(ip->SrcAddr(), 128); if ( f ) return MatchFilter(*f, *ip, len, caplen); -#ifdef BROv6 - f = (Filter*) dst_filter.Lookup(ip->DstAddr(), NUM_ADDR_WORDS * 32); -#else - f = (Filter*) dst_filter.Lookup(*ip->DstAddr(), NUM_ADDR_WORDS * 32); -#endif + f = (Filter*) dst_filter.Lookup(ip->DstAddr(), 128); if ( f ) return MatchFilter(*f, *ip, len, caplen); diff --git a/src/PacketFilter.h b/src/PacketFilter.h index ed8000f40f..3d7a3aa3be 100644 --- a/src/PacketFilter.h +++ b/src/PacketFilter.h @@ -14,16 +14,16 @@ public: // Drops all packets from a particular source (which may be given // as an AddrVal or a SubnetVal) which hasn't any of TCP flags set // (TH_*) with the given probability (from 0..MAX_PROB). - void AddSrc(addr_type src, uint32 tcp_flags, double probability); + void AddSrc(const IPAddr& src, uint32 tcp_flags, double probability); void AddSrc(Val* src, uint32 tcp_flags, double probability); - void AddDst(addr_type src, uint32 tcp_flags, double probability); + void AddDst(const IPAddr& src, uint32 tcp_flags, double probability); void AddDst(Val* src, uint32 tcp_flags, double probability); // Removes the filter entry for the given src/dst // Returns false if filter doesn not exist. - bool RemoveSrc(addr_type src); + bool RemoveSrc(const IPAddr& src); bool RemoveSrc(Val* dst); - bool RemoveDst(addr_type dst); + bool RemoveDst(const IPAddr& dst); bool RemoveDst(Val* dst); // Returns true if packet matches a drop filter diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index e04c3f9294..62e6fe5c12 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -1,34 +1,21 @@ #include "PrefixTable.h" #include "Reporter.h" -// IPv4 version. -inline static prefix_t* make_prefix(const uint32 addr, int width) +inline static prefix_t* make_prefix(const IPAddr& addr, int width) { prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); - memcpy(&prefix->add.sin, &addr, sizeof(prefix->add.sin)) ; - prefix->family = AF_INET; - prefix->bitlen = width; - prefix->ref_count = 1; - - return prefix; - } - -#ifdef BROv6 -inline static prefix_t* make_prefix(const uint32* addr, int width) - { - prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); - - memcpy(&prefix->add.sin6, addr, 4 * sizeof(uint32)); + uint32 bytes[4]; + addr.CopyIPv6(bytes); + memcpy(&prefix->add.sin6, bytes, 4 * sizeof(uint32)); prefix->family = AF_INET6; prefix->bitlen = width; prefix->ref_count = 1; return prefix; } -#endif -void* PrefixTable::Insert(const_addr_type addr, int width, void* data) +void* PrefixTable::Insert(const IPAddr& addr, int width, void* data) { prefix_t* prefix = make_prefix(addr, width); patricia_node_t* node = patricia_lookup(tree, prefix); @@ -55,12 +42,12 @@ void* PrefixTable::Insert(const Val* value, void* data) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Insert(value->AsAddr(), NUM_ADDR_WORDS * 32, data); + return Insert(*value->AsAddr(), 128, data); break; case TYPE_SUBNET: - return Insert(value->AsSubNet()->net, - value->AsSubNet()->width, data); + return Insert(value->AsSubNet()->Prefix(), + value->AsSubNet()->LengthIPv6(), data); break; default: @@ -69,7 +56,7 @@ void* PrefixTable::Insert(const Val* value, void* data) } } -void* PrefixTable::Lookup(const_addr_type addr, int width, bool exact) const +void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const { prefix_t* prefix = make_prefix(addr, width); patricia_node_t* node = @@ -89,12 +76,12 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Lookup(value->AsAddr(), NUM_ADDR_WORDS * 32, exact); + return Lookup(*value->AsAddr(), 128, exact); break; case TYPE_SUBNET: - return Lookup(value->AsSubNet()->net, - value->AsSubNet()->width, exact); + return Lookup(value->AsSubNet()->Prefix(), + value->AsSubNet()->LengthIPv6(), exact); break; default: @@ -104,7 +91,7 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const } } -void* PrefixTable::Remove(const_addr_type addr, int width) +void* PrefixTable::Remove(const IPAddr& addr, int width) { prefix_t* prefix = make_prefix(addr, width); patricia_node_t* node = patricia_search_exact(tree, prefix); @@ -128,11 +115,12 @@ void* PrefixTable::Remove(const Val* value) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Remove(value->AsAddr(), NUM_ADDR_WORDS * 32); + return Remove(*value->AsAddr(), 128); break; case TYPE_SUBNET: - return Remove(value->AsSubNet()->net, value->AsSubNet()->width); + return Remove(value->AsSubNet()->Prefix(), + value->AsSubNet()->LengthIPv6()); break; default: diff --git a/src/PrefixTable.h b/src/PrefixTable.h index 78596c7f35..2e5f43a0a8 100644 --- a/src/PrefixTable.h +++ b/src/PrefixTable.h @@ -3,6 +3,7 @@ #include "Val.h" #include "net_util.h" +#include "IPAddr.h" extern "C" { #include "patricia.h" @@ -24,7 +25,7 @@ public: // Addr in network byte order. If data is zero, acts like a set. // Returns ptr to old data if already existing. // For existing items without data, returns non-nil if found. - void* Insert(const_addr_type addr, int width, void* data = 0); + void* Insert(const IPAddr& addr, int width, void* data = 0); // Value may be addr or subnet. void* Insert(const Val* value, void* data = 0); @@ -32,11 +33,11 @@ public: // Returns nil if not found, pointer to data otherwise. // For items without data, returns non-nil if found. // If exact is false, performs exact rather than longest-prefix match. - void* Lookup(const_addr_type addr, int width, bool exact = false) const; + void* Lookup(const IPAddr& addr, int width, bool exact = false) const; void* Lookup(const Val* value, bool exact = false) const; // Returns pointer to data or nil if not found. - void* Remove(const_addr_type addr, int width); + void* Remove(const IPAddr& addr, int width); void* Remove(const Val* value); void Clear() { Clear_Patricia(tree, 0); } diff --git a/src/Reassem.cc b/src/Reassem.cc index 89fe29e7d4..fb445c08f7 100644 --- a/src/Reassem.cc +++ b/src/Reassem.cc @@ -43,7 +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 uint32* ip_addr, +Reassembler::Reassembler(int init_seq, const IPAddr& ip_addr, ReassemblerType arg_type) { blocks = last_block = 0; diff --git a/src/Reassem.h b/src/Reassem.h index 06d1e28f40..c9590ea949 100644 --- a/src/Reassem.h +++ b/src/Reassem.h @@ -4,6 +4,7 @@ #define reassem_h #include "Obj.h" +#include "IPAddr.h" class DataBlock { public: @@ -25,7 +26,7 @@ enum ReassemblerType { REASSEM_IP, REASSEM_TCP }; class Reassembler : public BroObj { public: - Reassembler(int init_seq, const uint32* ip_addr, + Reassembler(int init_seq, const IPAddr& ip_addr, ReassemblerType arg_type); virtual ~Reassembler(); diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index b72a6dcc1a..5dc7a715c7 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -185,6 +185,7 @@ #include "Conn.h" #include "LogMgr.h" #include "Reporter.h" +#include "IPAddr.h" extern "C" { #include "setsignal.h" @@ -670,8 +671,8 @@ void RemoteSerializer::Fork() } } -RemoteSerializer::PeerID RemoteSerializer::Connect(addr_type ip, uint16 port, - const char* our_class, double retry, bool use_ssl) +RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip, + uint16 port, const char* our_class, double retry, bool use_ssl) { if ( ! using_communication ) return true; @@ -679,16 +680,12 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(addr_type ip, uint16 port, if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); -#ifdef BROv6 - if ( ! is_v4_addr(ip) ) + if ( ip.family() == IPAddr::IPv6 ) Error("inter-Bro communication not supported over IPv6"); - uint32 ip4 = to_v4_addr(ip); -#else - uint32 ip4 = ip; -#endif - - ip4 = ntohl(ip4); + const uint32* bytes; + ip.GetBytes(&bytes); + uint32 ip4 = ntohl(*bytes); if ( ! child_pid ) Fork(); @@ -1232,7 +1229,7 @@ bool RemoteSerializer::SendCapabilities(Peer* peer) return caps ? SendToChild(MSG_CAPS, peer, 3, caps, 0, 0) : true; } -bool RemoteSerializer::Listen(addr_type ip, uint16 port, bool expect_ssl) +bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl) { if ( ! using_communication ) return true; @@ -1240,16 +1237,12 @@ bool RemoteSerializer::Listen(addr_type ip, uint16 port, bool expect_ssl) if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); -#ifdef BROv6 - if ( ! is_v4_addr(ip) ) + if ( ip.family() == IPAddr::IPv6 ) Error("inter-Bro communication not supported over IPv6"); - uint32 ip4 = to_v4_addr(ip); -#else - uint32 ip4 = ip; -#endif - - ip4 = ntohl(ip4); + const uint32* bytes; + ip.GetBytes(&bytes); + uint32 ip4 = ntohl(*bytes); if ( ! SendToChild(MSG_LISTEN, 0, 3, ip4, port, expect_ssl) ) return false; diff --git a/src/RemoteSerializer.h b/src/RemoteSerializer.h index b64fdcbe66..3c3e103c75 100644 --- a/src/RemoteSerializer.h +++ b/src/RemoteSerializer.h @@ -32,7 +32,7 @@ public: static const PeerID PEER_NONE = SOURCE_LOCAL; // Connect to host (returns PEER_NONE on error). - PeerID Connect(addr_type ip, uint16 port, const char* our_class, double retry, bool use_ssl); + PeerID Connect(const IPAddr& ip, uint16 port, const char* our_class, double retry, bool use_ssl); // Close connection to host. bool CloseConnection(PeerID peer); @@ -60,7 +60,7 @@ public: bool CompleteHandshake(PeerID peer); // Start to listen. - bool Listen(addr_type ip, uint16 port, bool expect_ssl); + bool Listen(const IPAddr& ip, uint16 port, bool expect_ssl); // Stop it. bool StopListening(); diff --git a/src/Reporter.cc b/src/Reporter.cc index fca9a6a233..2caf3f5dfb 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -169,6 +169,20 @@ void Reporter::WeirdFlowHelper(const uint32* orig, const uint32* resp, const cha delete vl; } +void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...) + { + val_list* vl = new val_list(2); + vl->append(new AddrVal(orig)); + vl->append(new AddrVal(resp)); + + va_list ap; + va_start(ap, fmt_name); + DoLog("weird", flow_weird, stderr, 0, vl, false, false, 0, fmt_name, ap); + va_end(ap); + + delete vl; + } + void Reporter::Weird(const char* name) { WeirdHelper(net_weird, 0, 0, name); @@ -189,6 +203,11 @@ void Reporter::Weird(const uint32* orig, const uint32* resp, const char* name) WeirdFlowHelper(orig, resp, "%s", name); } +void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name) + { + WeirdFlowHelper(orig, resp, "%s", name); + } + void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* postfix, const char* fmt, va_list ap) { static char tmp[512]; diff --git a/src/Reporter.h b/src/Reporter.h index 20d7b17e2c..10bb96306d 100644 --- a/src/Reporter.h +++ b/src/Reporter.h @@ -11,6 +11,7 @@ #include "util.h" #include "net_util.h" #include "EventHandler.h" +#include "IPAddr.h" class Connection; class Location; @@ -75,6 +76,7 @@ public: void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird(). void Weird(Val* conn_val, const char* name, const char* addl = ""); // Raises conn_weird(). void Weird(const uint32* orig, const uint32* resp, const char* name); // Raises flow_weird(). + void Weird(const IPAddr& orig, const IPAddr& resp, const char* name); // Raises flow_weird(). // Syslog a message. This methods does nothing if we're running // offline from a trace. @@ -122,6 +124,7 @@ private: // contain format specifiers void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...); void WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...); + void WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...); int errors; bool via_events; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index ac8f8a867c..63b56aa341 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1067,16 +1067,20 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) break; case TYPE_SUBNET: -#ifdef BROv6 { - uint32* n = v->AsSubNet()->net; - uint32* m = v->AsSubNetVal()->Mask(); + const uint32* n; + uint32 m[4]; + v->AsSubNet()->Prefix().GetBytes(&n); + v->AsSubNetVal()->Mask().CopyIPv6(m); + for ( unsigned int i = 0; i < 4; ++i ) + m[i] = ntohl(m[i]); bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; - if ( is_v4_addr(n) && is_v4_mask ) + if ( v->AsSubNet()->Prefix().family() == IPAddr::IPv4 && + is_v4_mask ) { - mval->val = ntohl(to_v4_addr(n)); + mval->val = ntohl(*n); mval->mask = m[3]; } @@ -1087,10 +1091,6 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) mval->mask = 0; } } -#else - mval->val = ntohl(v->AsSubNet()->net); - mval->mask = v->AsSubNetVal()->Mask(); -#endif break; default: diff --git a/src/SSH.cc b/src/SSH.cc index c07aad3dd1..1f3666da2f 100644 --- a/src/SSH.cc +++ b/src/SSH.cc @@ -66,7 +66,7 @@ void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { if ( length >= i ) { - const uint32* dst; + IPAddr dst; if ( is_orig ) dst = TCP()->Orig()->dst_addr; else diff --git a/src/Serializer.cc b/src/Serializer.cc index b82da0aaf3..ba593b84be 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1103,9 +1103,9 @@ void EventPlayer::Process() void Packet::Describe(ODesc* d) const { const IP_Hdr ip = IP(); - d->Add(dotted_addr(ip.SrcAddr())); + d->Add(string(ip.SrcAddr()).c_str()); d->Add("->"); - d->Add(dotted_addr(ip.DstAddr())); + d->Add(string(ip.DstAddr()).c_str()); } bool Packet::Serialize(SerialInfo* info) const diff --git a/src/Sessions.cc b/src/Sessions.cc index 572e8dea59..6c262619ad 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -284,13 +284,8 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, else { -#ifdef BROv6 IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size)); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); -#else - Weird("non_IPv4_packet", hdr, pkt); - return; -#endif } } @@ -604,7 +599,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, int record_packet = 1; // whether to record the packet at all int record_content = 1; // whether to record its data - int is_orig = addr_eq(id.src_addr, conn->OrigAddr()) && + int is_orig = id.src_addr == conn->OrigAddr() && id.src_port == conn->OrigPort(); if ( new_packet && ip4 ) @@ -731,13 +726,11 @@ Val* NetSessions::BuildHeader(const struct ip* ip) FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip, const u_char* pkt, uint32 frag_field) { - uint32 src_addr = uint32(ip->SrcAddr4()); - uint32 dst_addr = uint32(ip->DstAddr4()); uint32 frag_id = ntohs(ip->ID4()); // we actually could skip conv. ListVal* key = new ListVal(TYPE_ANY); - key->Append(new Val(src_addr, TYPE_COUNT)); - key->Append(new Val(dst_addr, TYPE_COUNT)); + key->Append(new AddrVal(ip->SrcAddr())); + key->Append(new AddrVal(ip->DstAddr())); key->Append(new Val(frag_id, TYPE_COUNT)); HashKey* h = ch->ComputeHash(key, 1); @@ -772,7 +765,7 @@ int NetSessions::Get_OS_From_SYN(struct os_type* retval, quirks, ECN) : 0; } -bool NetSessions::CompareWithPreviousOSMatch(uint32 addr, int id) const +bool NetSessions::CompareWithPreviousOSMatch(const IPAddr& addr, int id) const { return SYN_OS_Fingerprinter ? SYN_OS_Fingerprinter->CacheMatch(addr, id) : 0; @@ -813,21 +806,16 @@ Connection* NetSessions::FindConnection(Val* v) // types, too. } - addr_type orig_addr = (*vl)[orig_h]->AsAddr(); - addr_type resp_addr = (*vl)[resp_h]->AsAddr(); + IPAddr* orig_addr = (*vl)[orig_h]->AsAddr(); + IPAddr* resp_addr = (*vl)[resp_h]->AsAddr(); PortVal* orig_portv = (*vl)[orig_p]->AsPortVal(); PortVal* resp_portv = (*vl)[resp_p]->AsPortVal(); ConnID id; -#ifdef BROv6 - id.src_addr = orig_addr; - id.dst_addr = resp_addr; -#else - id.src_addr = &orig_addr; - id.dst_addr = &resp_addr; -#endif + id.src_addr = *orig_addr; + id.dst_addr = *resp_addr; id.src_port = htons((unsigned short) orig_portv->Port()); id.dst_port = htons((unsigned short) resp_portv->Port()); @@ -1092,7 +1080,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, // an analyzable connection. ConnID flip_id = *id; - const uint32* ta = flip_id.src_addr; + const IPAddr ta = flip_id.src_addr; flip_id.src_addr = flip_id.dst_addr; flip_id.dst_addr = ta; diff --git a/src/Sessions.h b/src/Sessions.h index 452de874db..0a6338899b 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -87,7 +87,7 @@ public: uint32 tstamp, /* uint8 TOS, */ uint32 quirks, uint8 ECN) const; - bool CompareWithPreviousOSMatch(uint32 addr, int id) const; + bool CompareWithPreviousOSMatch(const IPAddr& addr, int id) const; // Looks up the connection referred to by the given Val, // which should be a conn_id record. Returns nil if there's diff --git a/src/TCP.cc b/src/TCP.cc index 0fae07a24d..dc71d13252 100644 --- a/src/TCP.cc +++ b/src/TCP.cc @@ -276,7 +276,7 @@ void TCP_Analyzer::ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, uint32 tcp_hdr_len, int& seq_len, TCP_Endpoint* endpoint, TCP_Endpoint* peer, uint32 base_seq, uint32 ack_seq, - const uint32* orig_addr, + const IPAddr& orig_addr, int is_orig, TCP_Flags flags) { int len = seq_len; @@ -346,7 +346,7 @@ void TCP_Analyzer::ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, // is_orig will be removed once we can do SYN-ACK fingerprinting. if ( OS_version_found && is_orig ) { - Val src_addr_val(orig_addr, TYPE_ADDR); + AddrVal src_addr_val(orig_addr); if ( generate_OS_version_event->Size() == 0 || generate_OS_version_event->Lookup(&src_addr_val) ) { @@ -414,7 +414,7 @@ int TCP_Analyzer::ProcessFlags(double t, uint32 tcp_hdr_len, int len, int& seq_len, TCP_Endpoint* endpoint, TCP_Endpoint* peer, uint32 base_seq, uint32 ack_seq, - const uint32* orig_addr, + const IPAddr& orig_addr, int is_orig, TCP_Flags flags) { if ( flags.SYN() ) @@ -989,8 +989,8 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, if ( ! orig->did_close || ! resp->did_close ) Conn()->SetLastTime(t); - const uint32* orig_addr = Conn()->OrigAddr(); - const uint32* resp_addr = Conn()->RespAddr(); + const IPAddr orig_addr = Conn()->OrigAddr(); + const IPAddr resp_addr = Conn()->RespAddr(); uint32 tcp_hdr_len = data - (const u_char*) tp; @@ -1331,7 +1331,7 @@ RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, tstamp, quirks, uint8(tcp->th_flags & (TH_ECE|TH_CWR))); - if ( sessions->CompareWithPreviousOSMatch(ip->SrcAddr4(), id) ) + if ( sessions->CompareWithPreviousOSMatch(ip->SrcAddr(), id) ) { RecordVal* os = new RecordVal(OS_version); diff --git a/src/TCP.h b/src/TCP.h index 65f437856a..c84202fcf6 100644 --- a/src/TCP.h +++ b/src/TCP.h @@ -6,6 +6,7 @@ #include "Analyzer.h" #include "TCP.h" #include "PacketDumper.h" +#include "IPAddr.h" // We define two classes here: // - TCP_Analyzer is the analyzer for the TCP protocol itself. @@ -128,7 +129,7 @@ protected: uint32 tcp_hdr_len, int& seq_len, TCP_Endpoint* endpoint, TCP_Endpoint* peer, uint32 base_seq, uint32 ack_seq, - const uint32* orig_addr, + const IPAddr& orig_addr, int is_orig, TCP_Flags flags); void ProcessFIN(double t, TCP_Endpoint* endpoint, int& seq_len, @@ -144,7 +145,7 @@ protected: uint32 tcp_hdr_len, int len, int& seq_len, TCP_Endpoint* endpoint, TCP_Endpoint* peer, uint32 base_seq, uint32 ack_seq, - const uint32* orig_addr, + const IPAddr& orig_addr, int is_orig, TCP_Flags flags); void TransitionFromInactive(double t, TCP_Endpoint* endpoint, diff --git a/src/TCP_Endpoint.cc b/src/TCP_Endpoint.cc index 5a65a18d7c..4fe53a4b60 100644 --- a/src/TCP_Endpoint.cc +++ b/src/TCP_Endpoint.cc @@ -32,13 +32,12 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) dst_addr = is_orig ? tcp_analyzer->Conn()->OrigAddr() : tcp_analyzer->Conn()->RespAddr(); -#ifdef BROv6 - checksum_base = ones_complement_checksum((void*) src_addr, 16, 0); - checksum_base = ones_complement_checksum((void*) dst_addr, 16, checksum_base); -#else - checksum_base = ones_complement_checksum((void*) src_addr, 4, 0); - checksum_base = ones_complement_checksum((void*) dst_addr, 4, checksum_base); -#endif + const uint32* src_bytes; + const uint32* dst_bytes; + int n = src_addr.GetBytes(&src_bytes); + dst_addr.GetBytes(&dst_bytes); + checksum_base = ones_complement_checksum((void*) src_bytes, n*4, 0); + checksum_base = ones_complement_checksum((void*) dst_bytes, n*4, 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 diff --git a/src/TCP_Endpoint.h b/src/TCP_Endpoint.h index 758a504ff5..52a757b256 100644 --- a/src/TCP_Endpoint.h +++ b/src/TCP_Endpoint.h @@ -3,6 +3,8 @@ #ifndef tcpendpoint_h #define tcpendpoint_h +#include "IPAddr.h" + typedef enum { TCP_ENDPOINT_INACTIVE, // no SYN (or other packets) seen for this side TCP_ENDPOINT_SYN_SENT, // SYN seen, but no ack @@ -128,8 +130,8 @@ public: uint32 checksum_base; double start_time, last_time; - const uint32* src_addr; // the other endpoint - const uint32* dst_addr; // this endpoint + IPAddr src_addr; // the other endpoint + IPAddr dst_addr; // this endpoint uint32 window; // current congestion window (*scaled*, not pre-scaling) int window_scale; // from the TCP option uint32 window_ack_seq; // at which ack_seq number did we record 'window' diff --git a/src/UDP.cc b/src/UDP.cc index 35e9f58388..c5dfe2c316 100644 --- a/src/UDP.cc +++ b/src/UDP.cc @@ -61,11 +61,9 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, udp_checksum(ip->IP4_Hdr(), up, len) != 0xffff ) bad = true; -#ifdef BROv6 if ( ip->IP6_Hdr() && /* checksum is not optional for IPv6 */ udp6_checksum(ip->IP6_Hdr(), up, len) != 0xffff ) bad = true; -#endif if ( bad ) { diff --git a/src/Val.cc b/src/Val.cc index 1ec54d36cd..7de63534c4 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -25,7 +25,7 @@ #include "PrefixTable.h" #include "Conn.h" #include "Reporter.h" - +#include "IPAddr.h" Val::Val(Func* f) { @@ -205,29 +205,31 @@ bool Val::DoSerialize(SerialInfo* info) const val.string_val->Len()); case TYPE_INTERNAL_ADDR: - return SERIALIZE(NUM_ADDR_WORDS) -#ifdef BROv6 - && SERIALIZE(uint32(ntohl(val.addr_val[0]))) - && SERIALIZE(uint32(ntohl(val.addr_val[1]))) - && SERIALIZE(uint32(ntohl(val.addr_val[2]))) - && SERIALIZE(uint32(ntohl(val.addr_val[3]))); -#else - && SERIALIZE(uint32(ntohl(val.addr_val))); -#endif + { + const uint32* addrp; + int words = val.addr_val->GetBytes(&addrp); + if ( ! SERIALIZE(words) ) + return false; + for ( int i = 0; i < words; ++i ) + if ( ! SERIALIZE(ntohl(addrp[i])) ) + return false; + return true; + } case TYPE_INTERNAL_SUBNET: - return info->s->WriteOpenTag("subnet") - && SERIALIZE(NUM_ADDR_WORDS) -#ifdef BROv6 - && SERIALIZE(uint32(ntohl(val.subnet_val.net[0]))) - && SERIALIZE(uint32(ntohl(val.subnet_val.net[1]))) - && SERIALIZE(uint32(ntohl(val.subnet_val.net[2]))) - && SERIALIZE(uint32(ntohl(val.subnet_val.net[3]))) -#else - && SERIALIZE(uint32(ntohl(val.subnet_val.net))) -#endif - && SERIALIZE(val.subnet_val.width) - && info->s->WriteCloseTag("subnet"); + { + const uint32* addrp; + int words = val.subnet_val->Prefix().GetBytes(&addrp); + if ( ! (info->s->WriteOpenTag("subnet") && SERIALIZE(words)) ) + return false; + for ( int i = 0; i < words; ++i ) + if ( ! SERIALIZE(ntohl(addrp[i])) ) + return false; + if ( ! (SERIALIZE(val.subnet_val->Length()) && + info->s->WriteCloseTag("subnet")) ) + return false; + return true; + } case TYPE_INTERNAL_OTHER: // Derived classes are responsible for this. @@ -314,21 +316,10 @@ bool Val::DoUnserialize(UnserialInfo* info) a[i] = htonl(a[i]); } -#ifndef BROv6 - if ( num_words == 4 ) - { - if ( a[0] || a[1] || a[2] ) - info->s->Warning("received IPv6 address, ignoring"); - ((AddrVal*) this)->Init(a[3]); - } + if ( num_words == 1) + val.addr_val = new IPAddr(IPAddr::IPv4, a, IPAddr::Network); else - ((AddrVal*) this)->Init(a[0]); -#else - if ( num_words == 1 ) - ((AddrVal*) this)->Init(a[0]); - else - ((AddrVal*) this)->Init(a); -#endif + val.addr_val = new IPAddr(IPAddr::IPv6, a, IPAddr::Network); } return true; @@ -358,28 +349,16 @@ bool Val::DoUnserialize(UnserialInfo* info) if ( ! UNSERIALIZE(&width) ) return false; -#ifdef BROv6 if ( num_words == 1 ) { - a[3] = a[0]; - a[0] = a[1] = a[2] = 0; + IPAddr tmp(IPAddr::IPv4, a, IPAddr::Network); + val.subnet_val = new IPPrefix(tmp, width); } - - ((SubNetVal*) this)->Init(a, width); - -#else - if ( num_words == 4 ) + else { - if ( a[0] || a[1] || a[2] ) - info->s->Warning("received IPv6 subnet, ignoring"); - a[0] = a[3]; - - if ( width > 32 ) - width -= 96; + IPAddr tmp(IPAddr::IPv6, a, IPAddr::Network); + val.subnet_val = new IPPrefix(tmp, width); } - - ((SubNetVal*) this)->Init(a[0], width); -#endif } return true; @@ -590,12 +569,10 @@ void Val::ValDescribe(ODesc* d) const case TYPE_INTERNAL_UNSIGNED: d->Add(val.uint_val); break; case TYPE_INTERNAL_DOUBLE: d->Add(val.double_val); break; case TYPE_INTERNAL_STRING: d->AddBytes(val.string_val); break; - case TYPE_INTERNAL_ADDR: d->Add(dotted_addr(val.addr_val)); break; + case TYPE_INTERNAL_ADDR: d->Add(string(*val.addr_val).c_str()); break; case TYPE_INTERNAL_SUBNET: - d->Add(dotted_addr(val.subnet_val.net)); - d->Add("/"); - d->Add(val.subnet_val.width); + d->Add(string(*val.subnet_val).c_str()); break; case TYPE_INTERNAL_ERROR: d->AddCS("error"); break; @@ -706,7 +683,8 @@ ID* MutableVal::Bind() const ip = htonl(0x7f000001); // 127.0.0.1 safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", - dotted_addr(ip), getpid()); + string(IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)).c_str(), + getpid()); #else safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid()); #endif @@ -957,92 +935,41 @@ bool PortVal::DoUnserialize(UnserialInfo* info) AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR) { - const char* colon = strchr(text, ':'); - - if ( colon ) - { -#ifdef BROv6 - Init(dotted_to_addr6(text)); -#else - reporter->Error("bro wasn't compiled with IPv6 support"); - Init(uint32(0)); -#endif - } - - else - Init(dotted_to_addr(text)); + val.addr_val = new IPAddr(string(text)); } AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR) { // ### perhaps do gethostbyaddr here? - Init(addr); + val.addr_val = new IPAddr(IPAddr::IPv4, &addr, IPAddr::Network); } AddrVal::AddrVal(const uint32* addr) : Val(TYPE_ADDR) { - Init(addr); + val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); + } + +AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR) + { + val.addr_val = new IPAddr(addr); } AddrVal::~AddrVal() { -#ifdef BROv6 - delete [] val.addr_val; -#endif - } - -Val* AddrVal::SizeVal() const - { - uint32 addr; - -#ifdef BROv6 - if ( ! is_v4_addr(val.addr_val) ) - { - Error("|addr| for IPv6 addresses not supported"); - return new Val(0, TYPE_COUNT); - } - - addr = to_v4_addr(val.addr_val); -#else - addr = val.addr_val; -#endif - - addr = ntohl(addr); - - return new Val(addr, TYPE_COUNT); - } - -void AddrVal::Init(uint32 addr) - { -#ifdef BROv6 - val.addr_val = new uint32[4]; - val.addr_val[0] = val.addr_val[1] = val.addr_val[2] = 0; - val.addr_val[3] = addr; -#else - val.addr_val = addr; -#endif - } - -void AddrVal::Init(const uint32* addr) - { -#ifdef BROv6 - val.addr_val = new uint32[4]; - val.addr_val[0] = addr[0]; - val.addr_val[1] = addr[1]; - val.addr_val[2] = addr[2]; - val.addr_val[3] = addr[3]; -#else - val.addr_val = addr[0]; -#endif + delete val.addr_val; } unsigned int AddrVal::MemoryAllocation() const { -#ifdef BROv6 - return padded_sizeof(*this) + pad_size(4 * sizeof(uint32)); -#else - return padded_sizeof(*this); -#endif + return padded_sizeof(*this) + val.addr_val->MemoryAllocation(); + } + +Val* AddrVal::SizeVal() const + { + if ( val.addr_val->family() == IPAddr::IPv4 ) + return new Val(32, TYPE_COUNT); + else + return new Val(128, TYPE_COUNT); } IMPLEMENT_SERIAL(AddrVal, SER_ADDR_VAL); @@ -1059,209 +986,105 @@ bool AddrVal::DoUnserialize(UnserialInfo* info) return true; } -static uint32 parse_dotted(const char* text, int& dots) - { - int addr[4]; - uint32 a = 0; - dots = 0; - - if ( sscanf(text, "%d.%d.%d.%d", addr+0, addr+1, addr+2, addr+3) == 4 ) - { - a = (addr[0] << 24) | (addr[1] << 16) | - (addr[2] << 8) | addr[3]; - dots = 3; - } - - else if ( sscanf(text, "%d.%d.%d", addr+0, addr+1, addr+2) == 3 ) - { - a = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8); - dots = 2; - } - - else if ( sscanf(text, "%d.%d", addr+0, addr+1) == 2 ) - { - a = (addr[0] << 24) | (addr[1] << 16); - dots = 1; - } - - else - reporter->InternalError("scanf failed in parse_dotted()"); - - for ( int i = 0; i <= dots; ++i ) - { - if ( addr[i] < 0 || addr[i] > 255 ) - { - reporter->Error("bad dotted address %s", text); - break; - } - } - - return a; - } - SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET) { const char* sep = strchr(text, '/'); if ( ! sep ) Internal("separator missing in SubNetVal::SubNetVal"); - - Init(text, atoi(sep+1)); + val.subnet_val = new IPPrefix(text, atoi(sep+1)); } SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET) { - Init(text, width); + val.subnet_val = new IPPrefix(text, width); } SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET) { - Init(addr, width); + IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); + val.subnet_val = new IPPrefix(a, width); } -#ifdef BROv6 SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET) { - Init(addr, width); - } -#endif - -void SubNetVal::Init(const char* text, int width) - { -#ifdef BROv6 - if ( width <= 0 || width > 128 ) -#else - if ( width <= 0 || width > 32 ) -#endif - Error("bad subnet width"); - - int dots; - uint32 a = parse_dotted(text, dots); - - Init(uint32(htonl(a)), width); + IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); + val.subnet_val = new IPPrefix(a, width); } - -void SubNetVal::Init(uint32 addr, int width) +SubNetVal::SubNetVal(const IPAddr& addr, int width) : Val(TYPE_SUBNET) { -#ifdef BROv6 - Internal("SubNetVal::Init called on 4-byte address w/ BROv6"); -#else - val.subnet_val.net = mask_addr(addr, uint32(width)); - val.subnet_val.width = width; -#endif + val.subnet_val = new IPPrefix(addr, width); } -void SubNetVal::Init(const uint32* addr, int width) +SubNetVal::~SubNetVal() { -#ifdef BROv6 - const uint32* a = mask_addr(addr, uint32(width)); + delete val.subnet_val; + } - val.subnet_val.net[0] = a[0]; - val.subnet_val.net[1] = a[1]; - val.subnet_val.net[2] = a[2]; - val.subnet_val.net[3] = a[3]; - - if ( is_v4_addr(addr) && width <= 32 ) - val.subnet_val.width = width + 96; - else - val.subnet_val.width = width; -#else - Internal("SubNetVal::Init called on 16-byte address w/o BROv6"); -#endif +unsigned int SubNetVal::MemoryAllocation() const + { + return padded_sizeof(*this) + val.subnet_val->MemoryAllocation(); } Val* SubNetVal::SizeVal() const { - int retained; -#ifdef BROv6 - retained = 128 - Width(); -#else - retained = 32 - Width(); -#endif - + int retained = 128 - val.subnet_val->LengthIPv6(); return new Val(pow(2.0, double(retained)), TYPE_DOUBLE); } void SubNetVal::ValDescribe(ODesc* d) const { - d->Add(dotted_addr(val.subnet_val.net, d->Style() == ALTERNATIVE_STYLE)); - d->Add("/"); -#ifdef BROv6 - if ( is_v4_addr(val.subnet_val.net) ) - d->Add(val.subnet_val.width - 96); - else -#endif - d->Add(val.subnet_val.width); + d->Add(string(*val.subnet_val).c_str()); } -addr_type SubNetVal::Mask() const +IPAddr SubNetVal::Mask() const { - if ( val.subnet_val.width == 0 ) + if ( val.subnet_val->Length() == 0 ) { // We need to special-case a mask width of zero, since // the compiler doesn't guarantee that 1 << 32 yields 0. -#ifdef BROv6 - uint32* m = new uint32[4]; - for ( int i = 0; i < 4; ++i ) + uint32 m[4]; + for ( unsigned int i = 0; i < 4; ++i ) m[i] = 0; - - return m; -#else - return 0; -#endif + IPAddr rval(IPAddr::IPv6, m, IPAddr::Host); + return rval; } -#ifdef BROv6 - uint32* m = new uint32[4]; + uint32 m[4]; uint32* mp = m; uint32 w; - for ( w = val.subnet_val.width; w >= 32; w -= 32 ) - *(mp++) = 0xffffffff; + for ( w = val.subnet_val->Length(); w >= 32; w -= 32 ) + *(mp++) = 0xffffffff; *mp = ~((1 << (32 - w)) - 1); while ( ++mp < m + 4 ) - *mp = 0; + *mp = 0; - return m; - -#else - return ~((1 << (32 - val.subnet_val.width)) - 1); -#endif + IPAddr rval(IPAddr::IPv6, m, IPAddr::Host); + return rval; } bool SubNetVal::Contains(const uint32 addr) const { -#ifdef BROv6 - Internal("SubNetVal::Contains called on 4-byte address w/ BROv6"); - return false; -#else - return ntohl(val.subnet_val.net) == (ntohl(addr) & Mask()); -#endif + IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); + a.Mask(val.subnet_val->Length()); + return a == val.subnet_val->Prefix(); } bool SubNetVal::Contains(const uint32* addr) const { -#ifdef BROv6 - const uint32* net = val.subnet_val.net; - const uint32* a = addr; - uint32 m; + IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); + a.Mask(val.subnet_val->Length()); + return a == val.subnet_val->Prefix(); + } - for ( m = val.subnet_val.width; m > 32; m -= 32 ) - { - if ( *net != *a ) - return false; - - ++net; - ++a; - } - - uint32 mask = ~((1 << (32 - m)) - 1); - return ntohl(*net) == (ntohl(*a) & mask); -#else - return Contains(addr[3]); -#endif +bool SubNetVal::Contains(const IPAddr& addr) const + { + IPAddr a(addr); + a.Mask(val.subnet_val->Length()); + return a == val.subnet_val->Prefix(); } IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL); @@ -3476,20 +3299,10 @@ int same_atomic_val(const Val* v1, const Val* v2) return v1->InternalDouble() == v2->InternalDouble(); case TYPE_INTERNAL_STRING: return Bstr_eq(v1->AsString(), v2->AsString()); - case TYPE_INTERNAL_ADDR: - { - const addr_type& a1 = v1->AsAddr(); - const addr_type& a2 = v2->AsAddr(); -#ifdef BROv6 - return addr_eq(a1, a2); -#else - return addr_eq(&a1, &a2); -#endif - } - + return *v1->AsAddr() == *v2->AsAddr(); case TYPE_INTERNAL_SUBNET: - return subnet_eq(v1->AsSubNet(), v2->AsSubNet()); + return *v1->AsSubNet() == *v2->AsSubNet(); default: reporter->InternalError("same_atomic_val called for non-atomic value"); diff --git a/src/Val.h b/src/Val.h index d851be311b..11a11dc6e5 100644 --- a/src/Val.h +++ b/src/Val.h @@ -18,6 +18,7 @@ #include "ID.h" #include "Scope.h" #include "StateAccess.h" +#include "IPAddr.h" class Val; class Func; @@ -53,11 +54,11 @@ typedef union { // Used for count, counter, port, subnet. bro_uint_t uint_val; - // Used for addr, net - addr_type addr_val; + // Used for addr + IPAddr* addr_val; // Used for subnet - subnet_type subnet_val; + IPPrefix* subnet_val; // Used for double, time, interval. double double_val; @@ -226,10 +227,10 @@ public: CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern) CONST_ACCESSOR(TYPE_VECTOR, vector*, vector_val, AsVector) - const subnet_type* AsSubNet() const + const IPPrefix* AsSubNet() const { CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name) - return &val.subnet_val; + return val.subnet_val; } BroType* AsType() const @@ -238,8 +239,7 @@ public: return type; } - // ... in network byte order - const addr_type AsAddr() const + const IPAddr* AsAddr() const { if ( type->Tag() != TYPE_ADDR ) BadTag("Val::AsAddr", type_name(type->Tag())); @@ -261,10 +261,17 @@ public: ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern) ACCESSOR(TYPE_VECTOR, vector*, vector_val, AsVector) - subnet_type* AsSubNet() + IPPrefix* AsSubNet() { CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name) - return &val.subnet_val; + return val.subnet_val; + } + + IPAddr* AsAddr() + { + if ( type->Tag() != TYPE_ADDR ) + BadTag("Val::AsAddr", type_name(type->Tag())); + return val.addr_val; } // Gives fast access to the bits of something that is one of @@ -282,6 +289,7 @@ public: CONVERTER(TYPE_PATTERN, PatternVal*, AsPatternVal) CONVERTER(TYPE_PORT, PortVal*, AsPortVal) CONVERTER(TYPE_SUBNET, SubNetVal*, AsSubNetVal) + CONVERTER(TYPE_ADDR, AddrVal*, AsAddrVal) CONVERTER(TYPE_TABLE, TableVal*, AsTableVal) CONVERTER(TYPE_RECORD, RecordVal*, AsRecordVal) CONVERTER(TYPE_LIST, ListVal*, AsListVal) @@ -299,6 +307,7 @@ public: CONST_CONVERTER(TYPE_PATTERN, PatternVal*, AsPatternVal) CONST_CONVERTER(TYPE_PORT, PortVal*, AsPortVal) CONST_CONVERTER(TYPE_SUBNET, SubNetVal*, AsSubNetVal) + CONST_CONVERTER(TYPE_ADDR, AddrVal*, AsAddrVal) CONST_CONVERTER(TYPE_TABLE, TableVal*, AsTableVal) CONST_CONVERTER(TYPE_RECORD, RecordVal*, AsRecordVal) CONST_CONVERTER(TYPE_LIST, ListVal*, AsListVal) @@ -555,6 +564,7 @@ public: // Constructor for address already in network order. AddrVal(uint32 addr); AddrVal(const uint32* addr); + AddrVal(const IPAddr& addr); unsigned int MemoryAllocation() const; @@ -564,9 +574,6 @@ protected: AddrVal(TypeTag t) : Val(t) { } AddrVal(BroType* t) : Val(t) { } - void Init(uint32 addr); - void Init(const uint32* addr); - DECLARE_SERIAL(AddrVal); }; @@ -574,30 +581,27 @@ class SubNetVal : public Val { public: SubNetVal(const char* text); SubNetVal(const char* text, int width); - SubNetVal(uint32 addr, int width); // for address already massaged - SubNetVal(const uint32* addr, int width); // ditto + SubNetVal(uint32 addr, int width); + SubNetVal(const uint32* addr, int width); + SubNetVal(const IPAddr& addr, int width); + ~SubNetVal(); Val* SizeVal() const; - int Width() const { return val.subnet_val.width; } - addr_type Mask() const; // returns host byte order + const IPAddr& Prefix() const { return val.subnet_val->Prefix(); } + int Width() const { return val.subnet_val->Length(); } + IPAddr Mask() const; bool Contains(const uint32 addr) const; bool Contains(const uint32* addr) const; + bool Contains(const IPAddr& addr) const; - unsigned int MemoryAllocation() const - { - return Val::MemoryAllocation() + padded_sizeof(*this) - padded_sizeof(Val); - } + unsigned int MemoryAllocation() const; protected: friend class Val; SubNetVal() {} - void Init(const char* text, int width); - void Init(uint32 addr, int width); - void Init(const uint32 *addr, int width); - void ValDescribe(ODesc* d) const; DECLARE_SERIAL(SubNetVal); diff --git a/src/bif_type.def b/src/bif_type.def index 4e206ceea2..5d9963ffc9 100644 --- a/src/bif_type.def +++ b/src/bif_type.def @@ -1,6 +1,6 @@ // DEFINE_BIF_TYPE(id, bif_type, bro_type, c_type, accessor, constructor) -DEFINE_BIF_TYPE(TYPE_ADDR, "addr", "addr", "addr_type", "%s->AsAddr()", "new AddrVal(%s)") +DEFINE_BIF_TYPE(TYPE_ADDR, "addr", "addr", "AddrVal*", "%s->AsAddrVal()", "%s") DEFINE_BIF_TYPE(TYPE_ANY, "any", "any", "Val*", "%s", "%s") DEFINE_BIF_TYPE(TYPE_BOOL, "bool", "bool", "int", "%s->AsBool()", "new Val(%s, TYPE_BOOL)") DEFINE_BIF_TYPE(TYPE_CONN_ID, "conn_id", "conn_id", "Val*", "%s", "%s") diff --git a/src/bro.bif b/src/bro.bif index 121f310682..ea09826768 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -14,6 +14,7 @@ #include #include "Reporter.h" +#include "IPAddr.h" using namespace std; @@ -178,35 +179,37 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d) // This makes only a very slight difference, so not // clear it would e worth the hassle. - addr_type u = v->AsAddr(); -#ifdef BROv6 - // We explicitly convert the address to host order - // in a copy, because if we just call ntohl() for - // our invocation on snprintf() below, on some systems - // it turns a 32-bit value (Linux), whereas on - // others it returns a long (FreeBSD); the latter - // gets us in trouble if we have longs > 32 bits, - // because then the format specifier needs to be %lx - // rather than %x ....... what a pain! - // - // Also note that we don't change u in-place because - // that would alter the byte order of the underlying - // value. (Speaking of which, I'm not clear on why - // we're allowed to assign a const addr_type to an - // addr_type above, both g++ allows it.) - uint32 host_order_u[4]; - host_order_u[0] = ntohl(u[0]); - host_order_u[1] = ntohl(u[1]); - host_order_u[2] = ntohl(u[2]); - host_order_u[3] = ntohl(u[3]); + const IPAddr* u = v->AsAddr(); + const uint32* net_order_u; + int len = u->GetBytes(&net_order_u); + if ( len == 4 ) + { + // We explicitly convert the address to host order + // in a copy, because if we just call ntohl() for + // our invocation on snprintf() below, on some systems + // it turns a 32-bit value (Linux), whereas on + // others it returns a long (FreeBSD); the latter + // gets us in trouble if we have longs > 32 bits, + // because then the format specifier needs to be %lx + // rather than %x ....... what a pain! + // + // Also note that we don't change u in-place because + // that would alter the byte order of the underlying + // value. + uint32 host_order_u[4]; + host_order_u[0] = ntohl(net_order_u[0]); + host_order_u[1] = ntohl(net_order_u[1]); + host_order_u[2] = ntohl(net_order_u[2]); + host_order_u[3] = ntohl(net_order_u[3]); - snprintf(out_buf, sizeof(out_buf), "%08x%08x%08x%08x", - host_order_u[0], host_order_u[1], - host_order_u[2], host_order_u[3]); -#else - u = ntohl(u); - snprintf(out_buf, sizeof(out_buf), "%08x", u); -#endif + snprintf(out_buf, sizeof(out_buf), "%08x%08x%08x%08x", + host_order_u[0], host_order_u[1], + host_order_u[2], host_order_u[3]); + } + else + { + snprintf(out_buf, sizeof(out_buf), "%08x", ntohl(net_order_u[0])); + } } else if ( ! check_fmt_type(t, ok_d_fmt) ) @@ -1957,43 +1960,32 @@ function do_profiling%(%) : bool ## Returns: True if *ip* belongs to a local interface. function is_local_interface%(ip: addr%) : bool %{ - static uint32* addrs; - static int len = -1; + if ( ip->AsAddr()->IsLoopback() ) + return new Val(1, TYPE_BOOL); - if ( len < 0 ) - { - char host[MAXHOSTNAMELEN]; + list addrs; - strcpy(host, "localhost"); - gethostname(host, MAXHOSTNAMELEN); - host[MAXHOSTNAMELEN-1] = '\0'; + char host[MAXHOSTNAMELEN]; - struct hostent* ent = gethostbyname(host); + strcpy(host, "localhost"); + gethostname(host, MAXHOSTNAMELEN); + host[MAXHOSTNAMELEN-1] = '\0'; - for ( len = 0; ent->h_addr_list[len]; ++len ) - ; + struct hostent* ent = gethostbyname2(host, AF_INET); + if ( ent ) + for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) + addrs.push_back(IPAddr(IPAddr::IPv4, (uint32*)ent->h_addr_list[len], + IPAddr::Network)); - addrs = new uint32[len + 1]; - for ( int i = 0; i < len; i++ ) - addrs[i] = *(uint32*) ent->h_addr_list[i]; + ent = gethostbyname2(host, AF_INET6); + if ( ent ) + for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) + addrs.push_back(IPAddr(IPAddr::IPv6, (uint32*)ent->h_addr_list[len], + IPAddr::Network)); - addrs[len++] = 0x0100007f; // 127.0.0.1 - } - -#ifdef BROv6 - if ( ! is_v4_addr(ip) ) - { - builtin_error("is_local_interface() only supports IPv4 addresses"); - return new Val(0, TYPE_BOOL); - } - - uint32 ip4 = to_v4_addr(ip); -#else - uint32 ip4 = ip; -#endif - - for ( int i = 0; i < len; i++ ) - if ( addrs[i] == ip4 ) + list::const_iterator it; + for ( it = addrs.begin(); it != addrs.end(); ++it ) + if ( *it == *ip->AsAddr() ) return new Val(1, TYPE_BOOL); return new Val(0, TYPE_BOOL); @@ -2044,6 +2036,32 @@ function gethostname%(%) : string return new StringVal(buffer); %} +## Returns whether an address is IPv4 or not. +## +## a: the address to check. +## +## Returns: true if *a* is an IPv4 address, else false. +function is_v4_addr%(a: addr%): bool + %{ + if ( a->AsAddr()->family() == IPAddr::IPv4 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + +## Returns whether an address is IPv6 or not. +## +## a: the address to check. +## +## Returns: true if *a* is an IPv6 address, else false. +function is_v6_addr%(a: addr%): bool + %{ + if ( a->AsAddr()->family() == IPAddr::IPv6 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + # =========================================================================== # # Conversion @@ -2178,29 +2196,6 @@ function double_to_interval%(d: double%): interval return new Val(d, TYPE_INTERVAL); %} -## Converts a :bro:type:`addr` to a :bro:type:`count`. -## -## a: The :bro:type:`addr` to convert. -## -## Returns: The :bro:type:`addr` *a* as :bro:type:`count`. -## -## .. bro:see:: addr_to_ptr_name -function addr_to_count%(a: addr%): count - %{ -#ifdef BROv6 - if ( ! is_v4_addr(a) ) - { - builtin_error("conversion of non-IPv4 address to count", @ARG@[0]); - return new Val(0, TYPE_COUNT); - } - - uint32 addr = to_v4_addr(a); -#else - uint32 addr = a; -#endif - return new Val(ntohl(addr), TYPE_COUNT); - %} - ## Converts a :bro:type:`port` to a :bro:type:`count`. ## ## p: The :bro:type:`port` to convert. @@ -2331,34 +2326,38 @@ function ptr_name_to_addr%(s: string%): addr ## ## Returns: The reverse pointer representation of *a*. ## -## .. bro:see:: addr_to_count ptr_name_to_addr parse_dotted_addr +## .. bro:see:: ptr_name_to_addr parse_dotted_addr function addr_to_ptr_name%(a: addr%): string %{ - // ## Question: - // uint32 addr = ntohl((*args)[0]->InternalUnsigned()); - uint32 addr; -#ifdef BROv6 - if ( is_v4_addr(a) ) - addr = a[3]; + const uint32* addr; + int len = a->AsAddr()->GetBytes(&addr); + + if ( len == 1 ) + { + char buf[256]; + uint32 a = ntohl(addr[0]); + uint32 a3 = (a >> 24) & 0xff; + uint32 a2 = (a >> 16) & 0xff; + uint32 a1 = (a >> 8) & 0xff; + uint32 a0 = a & 0xff; + sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", a0, a1, a2, a3); + return new StringVal(buf); + } else { - builtin_error("conversion of non-IPv4 address to net", @ARG@[0]); - addr = 0; + static const char hex_digit[] = "0123456789abcdef"; + string ptr_name("ip6.arpa"); + for ( unsigned int i = 0; i < 4; ++i ) + { + uint32 a = ntohl(addr[i]); + for ( unsigned int j = 1; j <=8; ++j ) + { + ptr_name.insert(0, 1, '.'); + ptr_name.insert(0, 1, hex_digit[(a >> (32-j*4)) & 0x0f]); + } + } + return new StringVal(ptr_name.c_str()); } -#else - addr = a; -#endif - - addr = ntohl(addr); - uint32 a3 = (addr >> 24) & 0xff; - uint32 a2 = (addr >> 16) & 0xff; - uint32 a1 = (addr >> 8) & 0xff; - uint32 a0 = addr & 0xff; - - char buf[256]; - sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", a0, a1, a2, a3); - - return new StringVal(buf); %} # Transforms n0.n1.n2.n3 -> addr. @@ -2370,10 +2369,11 @@ function addr_to_ptr_name%(a: addr%): string ## ## Returns: The IP address as type :bro:type:`addr`. ## -## .. bro:see:: addr_to_ptr_name parse_dotted_addr addr_to_count +## .. bro:see:: addr_to_ptr_name parse_dotted_addr function parse_dotted_addr%(s: string%): addr %{ - return new AddrVal(dotted_to_addr(s->CheckString())); + IPAddr a(string(s->CheckString())); + return new AddrVal(a); %} %%{ @@ -2446,7 +2446,11 @@ static Val* parse_eftp(const char* line) line = next_delim + 1; if ( *line != delimiter ) // default of 0 is ok { - addr = dotted_to_addr(line); + string s(line); + IPAddr tmp(s); + uint32* bytes; + tmp.GetBytes(&bytes); + addr = *bytes; if ( addr == 0 ) good = 0; } @@ -2551,20 +2555,23 @@ function parse_ftp_epsv%(str: string%): ftp_port ## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_pasv parse_ftp_epsv function fmt_ftp_port%(a: addr, p: port%): string %{ -#ifdef BROv6 - if ( ! is_v4_addr(a) ) - builtin_error("conversion of non-IPv4 address to net", @ARG@[0]); - - uint32 addr = to_v4_addr(a); -#else - uint32 addr = a; -#endif - addr = ntohl(addr); - uint32 pn = p->Port(); - return new StringVal(fmt("%d,%d,%d,%d,%d,%d", - addr >> 24, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff, - pn >> 8, pn & 0xff)); + const uint32* addr; + int len = a->AsAddr()->GetBytes(&addr); + if ( len == 1 ) + { + uint32 a = ntohl(addr[0]); + uint32 pn = p->Port(); + return new StringVal(fmt("%d,%d,%d,%d,%d,%d", + a >> 24, (a >> 16) & 0xff, + (a >> 8) & 0xff, a & 0xff, + pn >> 8, pn & 0xff)); + } + else + { + builtin_error("conversion of non-IPv4 address in fmt_ftp_port", + @ARG@[0]); + return new StringVal(""); + } %} ## Decode a NetBIOS name. See http://support.microsoft.com/kb/194203. @@ -2877,7 +2884,7 @@ function strftime%(fmt: string, d: time%) : string ## .. bro:see:: remask_addr function mask_addr%(a: addr, top_bits_to_keep: count%): subnet %{ - return new SubNetVal(mask_addr(a, top_bits_to_keep), top_bits_to_keep); + return new SubNetVal(*a->AsAddr(), top_bits_to_keep); %} ## Takes some top bits (e.g., subnet address) from one address and the other @@ -2890,29 +2897,26 @@ function mask_addr%(a: addr, top_bits_to_keep: count%): subnet ## a2: The address to take the remaining bits from. ## ## top_bits_from_a1: The number of top bits to keep in *a1*; must be greater -## than 0 and less than 33. +## than 0 and less than 129. This value is always interpreted +## relative to the IPv6 bit width (v4-mapped addresses start +## at bit number 96). ## ## Returns: The address *a* masked down to *top_bits_to_keep* bits. ## ## .. bro:see:: mask_addr function remask_addr%(a1: addr, a2: addr, top_bits_from_a1: count%): addr %{ -#ifdef BROv6 - if ( ! is_v4_addr(a1) || ! is_v4_addr(a2) ) - { - builtin_error("cannot use remask_addr on IPv6 addresses"); - return new AddrVal(a1); - } - - uint32 x1 = to_v4_addr(a1); - uint32 x2 = to_v4_addr(a2); -#else - uint32 x1 = a1; - uint32 x2 = a2; -#endif - return new AddrVal( - mask_addr(x1, top_bits_from_a1) | - (x2 ^ mask_addr(x2, top_bits_from_a1)) ); + IPAddr addr1(*a1->AsAddr()); + addr1.Mask(top_bits_from_a1); + IPAddr addr2(*a2->AsAddr()); + addr1.ReverseMask(top_bits_from_a1); + uint32 x1[4]; + uint32 x2[4]; + addr1.CopyIPv6(x1); + addr2.CopyIPv6(x2); + for ( unsigned int i = 0; i < 4; ++i ) + x1[i] = x1[i] | x2[i]; + return new AddrVal(x1); %} ## Checks whether a given :bro:type:`port` has TCP as transport protocol. @@ -3085,12 +3089,13 @@ const char* conn_id_string(Val* c) Val* id = (*(c->AsRecord()))[0]; const val_list* vl = id->AsRecord(); - addr_type orig_h = (*vl)[0]->AsAddr(); + const IPAddr* orig_h = (*vl)[0]->AsAddr(); uint32 orig_p = (*vl)[1]->AsPortVal()->Port(); - addr_type resp_h = (*vl)[2]->AsAddr(); + const IPAddr* resp_h = (*vl)[2]->AsAddr(); uint32 resp_p = (*vl)[3]->AsPortVal()->Port(); - return fmt("%s/%u -> %s/%u\n", dotted_addr(orig_h), orig_p, dotted_addr(resp_h), resp_p); + return fmt("%s/%u -> %s/%u\n", string(*orig_h).c_str(), orig_p, + string(*resp_h).c_str(), resp_p); } %%} @@ -3320,8 +3325,7 @@ function lookup_addr%(host: addr%) : string frame->SetDelayed(); trigger->Hold(); -#ifdef BROv6 - if ( ! is_v4_addr(host) ) + if ( host->AsAddr()->family() != IPAddr::IPv4 ) { // FIXME: This is a temporary work-around until we get this // fixed. We warn the user once, and always trigger a timeout. @@ -3337,12 +3341,10 @@ function lookup_addr%(host: addr%) : string return 0; } - dns_mgr->AsyncLookupAddr(to_v4_addr(host), + const uint32* bytes; + host->AsAddr()->GetBytes(&bytes); + dns_mgr->AsyncLookupAddr(*bytes, new LookupHostCallback(trigger, frame->GetCall(), true)); -#else - dns_mgr->AsyncLookupAddr(host, - new LookupHostCallback(trigger, frame->GetCall(), true)); -#endif return 0; %} @@ -3434,8 +3436,6 @@ function lookup_location%(a: addr%) : geo_location else have_city_db = true; -#ifdef BROv6 - #ifdef HAVE_GEOIP_CITY_EDITION_REV0_V6 geoip_v6 = open_geoip_db(GEOIP_CITY_EDITION_REV0_V6); if ( geoip_v6 ) @@ -3448,16 +3448,15 @@ function lookup_location%(a: addr%) : geo_location #endif if ( ! geoip_v6 ) builtin_error("Can't initialize GeoIPv6 City/Country database"); -#endif } -#ifdef BROv6 - #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( geoip_v6 && ! is_v4_addr(a) ) + if ( geoip_v6 && a->AsAddr()->family() == IPAddr::IPv6 ) { + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); geoipv6_t ga; - memcpy(&ga, a, 16); + memcpy(&ga, bytes, 16); if ( have_cityv6_db ) gir = GeoIP_record_by_ipnum_v6(geoip_v6, ga); else @@ -3466,25 +3465,16 @@ function lookup_location%(a: addr%) : geo_location else #endif - if ( geoip && is_v4_addr(a) ) + if ( geoip && a->AsAddr()->family() == IPAddr::IPv4 ) { - uint32 addr = to_v4_addr(a); + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); if ( have_city_db ) - gir = GeoIP_record_by_ipnum(geoip, ntohl(addr)); + gir = GeoIP_record_by_ipnum(geoip, ntohl(*bytes)); else - cc = GeoIP_country_code_by_ipnum(geoip, ntohl(addr)); + cc = GeoIP_country_code_by_ipnum(geoip, ntohl(*bytes)); } -#else // not BROv6 - if ( geoip ) - { - if ( have_city_db ) - gir = GeoIP_record_by_ipnum(geoip, ntohl(a)); - else - cc = GeoIP_country_code_by_ipnum(geoip, ntohl(a)); - } -#endif - if ( gir ) { if ( gir->country_code ) @@ -3556,28 +3546,25 @@ function lookup_asn%(a: addr%) : count if ( geoip_asn ) { -#ifdef BROv6 - // IPv6 support showed up in 1.4.5. #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( ! is_v4_addr(a) ) + if ( a->AsAddr()->family() == IPAddr::IPv6 ) { + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); geoipv6_t ga; - memcpy(&ga, a, 16); + memcpy(&ga, bytes, 16); gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga); } else #endif - if ( is_v4_addr(a) ) + if ( a->AsAddr()->family() == IPAddr::IPv4 ) { - uint32 addr = to_v4_addr(a); - gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(addr)); + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); + gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(*bytes)); } - -#else // not BROv6 - gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(a)); -#endif } if ( gir ) @@ -3859,8 +3846,8 @@ function NFS3::mode2string%(mode: count%): string function expect_connection%(orig: addr, resp: addr, resp_p: port, analyzer: count, tout: interval%) : bool %{ - dpm->ExpectConnection(orig, resp, resp_p->Port(), resp_p->PortType(), - (AnalyzerTag::Tag) analyzer, tout, 0); + dpm->ExpectConnection(*orig->AsAddr(), *resp->AsAddr(), resp_p->Port(), + resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0); return new Val(1, TYPE_BOOL); %} @@ -4633,7 +4620,7 @@ function pcap_error%(%): string ## .. todo:: The return value should be changed to any. function install_src_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool %{ - sessions->GetPacketFilter()->AddSrc(ip, tcp_flags, prob); + sessions->GetPacketFilter()->AddSrc(*ip->AsAddr(), tcp_flags, prob); return new Val(1, TYPE_BOOL); %} @@ -4685,7 +4672,7 @@ function install_src_net_filter%(snet: subnet, tcp_flags: count, prob: double%) ## pcap_error function uninstall_src_addr_filter%(ip: addr%) : bool %{ - return new Val(sessions->GetPacketFilter()->RemoveSrc(ip), TYPE_BOOL); + return new Val(sessions->GetPacketFilter()->RemoveSrc(*ip->AsAddr()), TYPE_BOOL); %} ## Removes a source subnet filter. @@ -4735,7 +4722,7 @@ function uninstall_src_net_filter%(snet: subnet%) : bool ## .. todo:: The return value should be changed to any. function install_dst_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool %{ - sessions->GetPacketFilter()->AddDst(ip, tcp_flags, prob); + sessions->GetPacketFilter()->AddDst(*ip->AsAddr(), tcp_flags, prob); return new Val(1, TYPE_BOOL); %} @@ -4787,7 +4774,7 @@ function install_dst_net_filter%(snet: subnet, tcp_flags: count, prob: double%) ## pcap_error function uninstall_dst_addr_filter%(ip: addr%) : bool %{ - return new Val(sessions->GetPacketFilter()->RemoveDst(ip), TYPE_BOOL); + return new Val(sessions->GetPacketFilter()->RemoveDst(*ip->AsAddr()), TYPE_BOOL); %} ## Removes a destination subnet filter. @@ -4928,7 +4915,7 @@ function capture_state_updates%(filename: string%) : bool ## send_id function connect%(ip: addr, p: port, our_class: string, retry: interval, ssl: bool%) : count %{ - return new Val(uint32(remote_serializer->Connect(ip, p->Port(), + return new Val(uint32(remote_serializer->Connect(*ip->AsAddr(), p->Port(), our_class->CheckString(), retry, ssl)), TYPE_COUNT); %} @@ -5043,7 +5030,7 @@ function set_compression_level%(p: event_peer, level: count%) : bool ## .. bro:see:: connect disconnect function listen%(ip: addr, p: port, ssl: bool %) : bool %{ - return new Val(remote_serializer->Listen(ip, p->Port(), ssl), TYPE_BOOL); + return new Val(remote_serializer->Listen(*ip->AsAddr(), p->Port(), ssl), TYPE_BOOL); %} ## Checks whether the last raised event came from a remote peer. @@ -5299,14 +5286,14 @@ function preserve_prefix%(a: addr, width: count%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { -#ifdef BROv6 - if ( ! is_v4_addr(a) ) + if ( a->AsAddr()->family() == IPAddr::IPv6 ) builtin_error("preserve_prefix() not supported for IPv6 addresses"); else - ip_anon->PreservePrefix(a[3], width); -#else - ip_anon->PreservePrefix(a, width); -#endif + { + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); + ip_anon->PreservePrefix(*bytes, width); + } } @@ -5324,18 +5311,18 @@ function preserve_prefix%(a: addr, width: count%): any ## .. todo:: Currently dysfunctional. function preserve_subnet%(a: subnet%): any %{ - DEBUG_MSG("%s/%d\n", dotted_addr(a->AsAddr()), a->Width()); + DEBUG_MSG("%s/%d\n", string(a->Prefix()).c_str(), a->Width()); AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { -#ifdef BROv6 - if ( ! is_v4_addr(a->AsAddr()) ) + if ( a->AsSubNet()->Prefix().family() == IPAddr::IPv6 ) builtin_error("preserve_subnet() not supported for IPv6 addresses"); else - ip_anon->PreservePrefix(a->AsAddr()[3], a->Width()); -#else - ip_anon->PreservePrefix(a->AsAddr(), a->Width()); -#endif + { + const uint32* bytes; + a->AsSubNet()->Prefix().GetBytes(&bytes); + ip_anon->PreservePrefix(*bytes, a->AsSubNet()->Length()); + } } return 0; @@ -5364,19 +5351,18 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES ) builtin_error("anonymize_addr(): invalid ip addr anonymization class"); -#ifdef BROv6 - if ( ! is_v4_addr(a) ) + if ( a->AsAddr()->family() == IPAddr::IPv6 ) { builtin_error("anonymize_addr() not supported for IPv6 addresses"); return 0; } else - return new AddrVal(anonymize_ip(a[3], + { + const uint32* bytes; + a->AsAddr()->GetBytes(&bytes); + return new AddrVal(anonymize_ip(*bytes, (enum ip_addr_anonymization_class_t) anon_class)); -#else - return new AddrVal(anonymize_ip(a, - (enum ip_addr_anonymization_class_t) anon_class)); -#endif + } %} ## Deprecated. Will be removed. @@ -5448,7 +5434,7 @@ function generate_idmef%(src_ip: addr, src_port: port, newNode(newAddress( newAttribute("category","ipv4-addr"), newSimpleElement("address", - copy_string(dotted_addr(src_ip))), + copy_string(string(*src_ip->AsAddr()).c_str())), NULL), NULL), newService( newSimpleElement("port", @@ -5458,7 +5444,7 @@ function generate_idmef%(src_ip: addr, src_port: port, newNode(newAddress( newAttribute("category","ipv4-addr"), newSimpleElement("address", - copy_string(dotted_addr(dst_ip))), + copy_string(string(*dst_ip->AsAddr()).c_str())), NULL), NULL), newService( newSimpleElement("port", @@ -5473,13 +5459,3 @@ function generate_idmef%(src_ip: addr, src_port: port, return new Val(0, TYPE_BOOL); #endif %} - -## Deprecated. Will be removed. -function bro_has_ipv6%(%) : bool - %{ -#ifdef BROv6 - return new Val(1, TYPE_BOOL); -#else - return new Val(0, TYPE_BOOL); -#endif - %} diff --git a/src/dhcp-analyzer.pac b/src/dhcp-analyzer.pac index a9f1c6bab0..5267075445 100644 --- a/src/dhcp-analyzer.pac +++ b/src/dhcp-analyzer.pac @@ -55,33 +55,18 @@ flow DHCP_Flow(is_orig: bool) { vector::const_iterator ptr; // Requested IP address to the server. -#ifdef BROv6 - ::uint32 req_addr[4], serv_addr[4]; - - req_addr[0] = req_addr[1] = req_addr[2] = req_addr[3] = 0; - serv_addr[0] = serv_addr[1] = serv_addr[2] = serv_addr[3] = 0; -#else - addr_type req_addr = 0, serv_addr = 0; -#endif + ::uint32 req_addr = 0, serv_addr = 0; for ( ptr = options->begin(); ptr != options->end() && ! (*ptr)->last(); ++ptr ) { switch ( (*ptr)->code() ) { case REQ_IP_OPTION: -#ifdef BROv6 - req_addr[3] = htonl((*ptr)->info()->req_addr()); -#else req_addr = htonl((*ptr)->info()->req_addr()); -#endif break; case SERV_ID_OPTION: -#ifdef BROv6 - serv_addr[3] = htonl((*ptr)->info()->serv_addr()); -#else serv_addr = htonl((*ptr)->info()->serv_addr()); -#endif break; } } @@ -91,13 +76,14 @@ flow DHCP_Flow(is_orig: bool) { case DHCPDISCOVER: BifEvent::generate_dhcp_discover(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - dhcp_msg_val_->Ref(), req_addr); + dhcp_msg_val_->Ref(), new AddrVal(req_addr)); break; case DHCPREQUEST: BifEvent::generate_dhcp_request(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - dhcp_msg_val_->Ref(), req_addr, serv_addr); + dhcp_msg_val_->Ref(), new AddrVal(req_addr), + new AddrVal(serv_addr)); break; case DHCPDECLINE: @@ -129,15 +115,7 @@ flow DHCP_Flow(is_orig: bool) { // RFC 1533 allows a list of router addresses. TableVal* router_list = 0; -#ifdef BROv6 - ::uint32 subnet_mask[4], serv_addr[4]; - - subnet_mask[0] = subnet_mask[1] = - subnet_mask[2] = subnet_mask[3] = 0; - serv_addr[0] = serv_addr[1] = serv_addr[2] = serv_addr[3] = 0; -#else - addr_type subnet_mask = 0, serv_addr = 0; -#endif + ::uint32 subnet_mask = 0, serv_addr = 0; uint32 lease = 0; @@ -146,13 +124,7 @@ flow DHCP_Flow(is_orig: bool) { { switch ( (*ptr)->code() ) { case SUBNET_OPTION: -#ifdef BROv6 - subnet_mask[0] = - subnet_mask[1] = subnet_mask[2] = 0; - subnet_mask[3] = htonl((*ptr)->info()->mask()); -#else subnet_mask = htonl((*ptr)->info()->mask()); -#endif break; case ROUTER_OPTION: @@ -170,14 +142,8 @@ flow DHCP_Flow(is_orig: bool) { vector* rlist = (*ptr)->info()->router_list(); uint32 raddr = (*rlist)[i]; -#ifdef BROv6 - ::uint32 tmp_addr[4]; - tmp_addr[0] = tmp_addr[1] = tmp_addr[2] = 0; - tmp_addr[3] = htonl(raddr); -#else ::uint32 tmp_addr; tmp_addr = htonl(raddr); -#endif // index starting from 1 Val* index = new Val(i + 1, TYPE_COUNT); router_list->Assign(index, new AddrVal(tmp_addr)); @@ -191,11 +157,7 @@ flow DHCP_Flow(is_orig: bool) { break; case SERV_ID_OPTION: -#ifdef BROv6 - serv_addr[3] = htonl((*ptr)->info()->serv_addr()); -#else serv_addr = htonl((*ptr)->info()->serv_addr()); -#endif break; } } @@ -204,15 +166,15 @@ flow DHCP_Flow(is_orig: bool) { case DHCPOFFER: BifEvent::generate_dhcp_offer(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - dhcp_msg_val_->Ref(), subnet_mask, - router_list, lease, serv_addr); + dhcp_msg_val_->Ref(), new AddrVal(subnet_mask), + router_list, lease, new AddrVal(serv_addr)); break; case DHCPACK: BifEvent::generate_dhcp_ack(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - dhcp_msg_val_->Ref(), subnet_mask, - router_list, lease, serv_addr); + dhcp_msg_val_->Ref(), new AddrVal(subnet_mask), + router_list, lease, new AddrVal(serv_addr)); break; case DHCPNAK: diff --git a/src/dns-analyzer.pac b/src/dns-analyzer.pac index 0c2dc1b491..e92b6ef709 100644 --- a/src/dns-analyzer.pac +++ b/src/dns-analyzer.pac @@ -216,44 +216,42 @@ flow DNS_Flow switch ( rr->rr_type() ) { case TYPE_A: + if ( dns_A_reply ) + { + ::uint32 addr = rd->type_a(); + BifEvent::generate_dns_A_reply(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + dns_msg_val_->Ref(), build_dns_answer(rr), + new AddrVal(htonl(addr))); + } + break; + case TYPE_A6: - case TYPE_AAAA: - if ( ! dns_A_reply ) - break; - -#ifdef BROv6 - ::uint32 addr[4]; -#else - addr_type addr; -#endif - - if ( rr->rr_type() == TYPE_A ) + if ( dns_A6_reply ) { -#ifdef BROv6 - addr[0] = addr[1] = addr[2] = 0; - addr[3] = htonl(rd->type_a()); -#else - addr = htonl(rd->type_a()); -#endif - } - - else - { -#ifdef BROv6 - for ( int i = 0; i < 4; ++i ) + ::uint32 addr[4]; + for ( unsigned int i = 0; i < 4; ++i ) addr[i] = htonl((*rd->type_aaaa())[i]); -#else - addr = htonl((*rd->type_aaaa())[3]); -#endif - } - // For now, we treat A6 and AAAA as A's. Given the - // above fixes for BROv6, we can probably now introduce - // their own events. (It's not clear A6 is needed - - // do we actually encounter it in practice?) - BifEvent::generate_dns_A_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), build_dns_answer(rr), addr); + BifEvent::generate_dns_A6_reply(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + dns_msg_val_->Ref(), build_dns_answer(rr), + new AddrVal(addr)); + } + break; + + case TYPE_AAAA: + if ( dns_AAAA_reply ) + { + ::uint32 addr[4]; + for ( unsigned int i = 0; i < 4; ++i ) + addr[i] = htonl((*rd->type_aaaa())[i]); + + BifEvent::generate_dns_AAAA_reply(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + dns_msg_val_->Ref(), build_dns_answer(rr), + new AddrVal(addr)); + } break; case TYPE_NS: diff --git a/src/event.bif b/src/event.bif index 001f0b84f1..6a64d2368d 100644 --- a/src/event.bif +++ b/src/event.bif @@ -3732,19 +3732,13 @@ event non_dns_request%(c: connection, msg: string%) &group="dns"; ## ## a: The address returned by the reply. ## -## .. bro:see:: dns_AAAA_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply +## .. bro:see:: dns_AAAA_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply ## dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply ## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request ## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name ## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply ## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout ## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -## -## .. note: This event is currently also raised for ``AAAA`` records. In that -## case, the address *a* will correspond to the lower-order 4 bytes of the -## IPv6 address. This will go away once IPv6 support is improved. -## -## .. todo: IPv6 handling is obviously very broken here ... event dns_A_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; ## Generated for DNS replies of type *AAAA*. For replies with multiple answers, an @@ -3762,18 +3756,38 @@ event dns_A_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &grou ## ## a: The address returned by the reply. ## -## .. bro:see:: dns_A_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply +## .. bro:see:: dns_A_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply ## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl ## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered ## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified ## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request ## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl ## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_AAAA_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; + +## Generated for DNS replies of type *A6*. For replies with multiple answers, an +## individual event of the corresponding type is raised for each. ## -## .. todo: Raising this event is not implemented currently, not even when -## Bro's compiled IPv6 support. ``AAAA`` are currently always turned into -## :bro:id:`dns_A_reply` events. -event dns_AAAA_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr, astr: string%) &group="dns"; +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## a: The address returned by the reply. +## +## .. bro:see:: dns_A_reply dns_AAAA_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_A6_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; ## Generated for DNS replies of type *NS*. For replies with multiple answers, an ## individual event of the corresponding type is raised for each. diff --git a/src/net_util.cc b/src/net_util.cc index c0bacc98b2..14ba475450 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -2,17 +2,16 @@ #include "config.h" -#ifdef BROv6 #include #include #include #include -#endif #include "Reporter.h" #include "net_util.h" +#include "IPAddr.h" // - adapted from tcpdump // Returns the ones-complement checksum of a chunk of b short-aligned bytes. @@ -81,7 +80,6 @@ int udp_checksum(const struct ip* ip, const struct udphdr* up, int len) return sum; } -#ifdef BROv6 int udp6_checksum(const struct ip6_hdr* ip6, const struct udphdr* up, int len) { uint32 sum; @@ -104,7 +102,6 @@ int udp6_checksum(const struct ip6_hdr* ip6, const struct udphdr* up, int len) return sum; } -#endif int icmp_checksum(const struct icmp* icmpp, int len) { @@ -143,225 +140,27 @@ char addr_to_class(uint32 addr) return 'A'; } -uint32 addr_to_net(uint32 addr) +const char* fmt_conn_id(const IPAddr& src_addr, uint32 src_port, + const IPAddr& dst_addr, uint32 dst_port) { - if ( CHECK_CLASS(addr, CLASS_D) ) - ; // class D's are left alone ### - else if ( CHECK_CLASS(addr, CLASS_C) ) - addr = addr & 0xffffff00; - else if ( CHECK_CLASS(addr, CLASS_B) ) - addr = addr & 0xffff0000; - else - addr = addr & 0xff000000; + static char buffer[512]; - return addr; - } + safe_snprintf(buffer, sizeof(buffer), "%s:%d > %s:%d", + string(src_addr).c_str(), src_port, + string(dst_addr).c_str(), dst_port); -const char* dotted_addr(uint32 addr, int alternative) - { - addr = ntohl(addr); - const char* fmt = alternative ? "%d,%d.%d.%d" : "%d.%d.%d.%d"; - - static char buf[32]; - snprintf(buf, sizeof(buf), fmt, - addr >> 24, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); - - return buf; - } - -const char* dotted_addr(const uint32* addr, int alternative) - { -#ifdef BROv6 - if ( is_v4_addr(addr) ) - return dotted_addr(addr[3], alternative); - - static char buf[256]; - - if ( inet_ntop(AF_INET6, addr, buf, sizeof buf) == NULL ) - return ""; - - return buf; - -#else - return dotted_addr(to_v4_addr(addr), alternative); -#endif - } - -const char* dotted_net(uint32 addr) - { - addr = ntohl(addr); - - static char buf[32]; - - if ( CHECK_CLASS(addr, CLASS_D) ) - sprintf(buf, "%d.%d.%d.%d", - addr >> 24, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); - - else if ( CHECK_CLASS(addr, CLASS_C) ) - sprintf(buf, "%d.%d.%d", - addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff); - - else - // Same for class A's and B's. - sprintf(buf, "%d.%d", addr >> 24, (addr >> 16) & 0xff); - - return buf; - } - -#ifdef BROv6 -const char* dotted_net6(const uint32* addr) - { - if ( is_v4_addr(addr) ) - return dotted_net(to_v4_addr(addr)); - else - // ### this isn't right, but net's should go away eventually ... - return dotted_addr(addr); - } -#endif - -uint32 dotted_to_addr(const char* addr_text) - { - int addr[4]; - - if ( sscanf(addr_text, - "%d.%d.%d.%d", addr+0, addr+1, addr+2, addr+3) != 4 ) - { - reporter->Error("bad dotted address: %s", addr_text ); - return 0; - } - - if ( addr[0] < 0 || addr[1] < 0 || addr[2] < 0 || addr[3] < 0 || - addr[0] > 255 || addr[1] > 255 || addr[2] > 255 || addr[3] > 255 ) - { - reporter->Error("bad dotted address: %s", addr_text); - return 0; - } - - uint32 a = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; - - // ### perhaps do gethostbyaddr here? - - return uint32(htonl(a)); - } - -#ifdef BROv6 -uint32* dotted_to_addr6(const char* addr_text) - { - uint32* addr = new uint32[4]; - if ( inet_pton(AF_INET6, addr_text, addr) <= 0 ) - { - reporter->Error("bad IPv6 address: %s", addr_text ); - addr[0] = addr[1] = addr[2] = addr[3] = 0; - } - - return addr; - } - -#endif - -#ifdef BROv6 -int is_v4_addr(const uint32 addr[4]) - { - return addr[0] == 0 && addr[1] == 0 && addr[2] == 0; - } -#endif - -uint32 to_v4_addr(const uint32* addr) - { -#ifdef BROv6 - if ( ! is_v4_addr(addr) ) - reporter->InternalError("conversion of non-IPv4 address to IPv4 address"); - return addr[3]; -#else - return addr[0]; -#endif - } - -uint32 mask_addr(uint32 a, uint32 top_bits_to_keep) - { - if ( top_bits_to_keep > 32 ) - { - reporter->Error("bad address mask value %d", top_bits_to_keep); - return a; - } - - if ( top_bits_to_keep == 0 ) - // The shifts below don't have any effect with 0, i.e., - // 1 << 32 does not yield 0; either due to compiler - // misoptimization or language semantics. - return 0; - - uint32 addr = ntohl(a); - - int shift = 32 - top_bits_to_keep; - addr >>= shift; - addr <<= shift; - - return htonl(addr); - } - -const uint32* mask_addr(const uint32* a, uint32 top_bits_to_keep) - { -#ifdef BROv6 - static uint32 addr[4]; - - addr[0] = a[0]; - addr[1] = a[1]; - addr[2] = a[2]; - addr[3] = a[3]; - - // This is a bit dicey: if it's a v4 address, then we interpret - // the mask as being with respect to 32 bits total, even though - // strictly speaking, the v4 address comprises the least-significant - // bits out of 128, rather than the most significant. However, - // we only do this if the mask itself is consistent for a 32-bit - // address. - uint32 max_bits = (is_v4_addr(a) && top_bits_to_keep <= 32) ? 32 : 128; - - if ( top_bits_to_keep == 0 || top_bits_to_keep > max_bits ) - { - reporter->Error("bad address mask value %s", top_bits_to_keep); - return addr; - } - - int word = 3; // start zeroing out with word #3 - int bits_to_chop = max_bits - top_bits_to_keep; // bits to discard - while ( bits_to_chop >= 32 ) - { // there's an entire word to discard - addr[word] = 0; - --word; // move on to next, more significant word - bits_to_chop -= 32; // we just go rid of 32 bits - } - - // All that's left to work with now is the word pointed to by "word". - uint32 addr32 = ntohl(addr[word]); - addr32 >>= bits_to_chop; - addr32 <<= bits_to_chop; - addr[word] = htonl(addr32); - - return addr; -#else - return a; -#endif + return buffer; } const char* fmt_conn_id(const uint32* src_addr, uint32 src_port, const uint32* dst_addr, uint32 dst_port) { - char addr1[128], addr2[128]; - static char buffer[512]; - - strcpy(addr1, dotted_addr(src_addr)); - strcpy(addr2, dotted_addr(dst_addr)); - - safe_snprintf(buffer, sizeof(buffer), "%s:%d > %s:%d", - addr1, src_port, addr2, dst_port); - - return buffer; + IPAddr src(IPAddr::IPv6, src_addr, IPAddr::Network); + IPAddr dst(IPAddr::IPv6, dst_addr, IPAddr::Network); + return fmt_conn_id(src, src_port, dst, dst_port); } + uint32 extract_uint32(const u_char* data) { uint32 val; diff --git a/src/net_util.h b/src/net_util.h index 28abf4dbcb..a1304fcbe2 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -21,6 +21,7 @@ #include #include "util.h" +#include "IPAddr.h" #ifdef HAVE_NETINET_IP6_H #include @@ -32,30 +33,6 @@ struct ip6_hdr { }; #endif -#include "util.h" - -#ifdef BROv6 -typedef uint32* addr_type; // a pointer to 4 uint32's -typedef const uint32* const_addr_type; -#define NUM_ADDR_WORDS 4 - -typedef struct { - uint32 net[4]; - uint32 width; -} subnet_type; - -#else -typedef uint32 addr_type; -typedef const uint32 const_addr_type; -#define NUM_ADDR_WORDS 1 - -typedef struct { - uint32 net; - uint32 width; -} subnet_type; - -#endif - // For Solaris. #if !defined(TCPOPT_WINDOW) && defined(TCPOPT_WSCALE) #define TCPOPT_WINDOW TCPOPT_WSCALE @@ -86,78 +63,18 @@ extern int ones_complement_checksum(const void* p, int b, 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); -#ifdef BROv6 extern int udp6_checksum(const struct ip6_hdr* ip, const struct udphdr* up, int len); -#endif extern int icmp_checksum(const struct icmp* icmpp, int len); -// Given an address in host order, returns its "classical network prefix", -// also in host order. -extern uint32 addr_to_net(uint32 addr); // Returns 'A', 'B', 'C' or 'D' extern char addr_to_class(uint32 addr); -// Returns a pointer to static storage giving the ASCII dotted representation -// of the given address, which should be passed in network order. -extern const char* dotted_addr(uint32 addr, int alternative=0); -extern const char* dotted_addr(const uint32* addr, int alternative=0); - -// Same, but for the network prefix. -extern const char* dotted_net(uint32 addr); -extern const char* dotted_net6(const uint32* addr); - -// Given an ASCII dotted representation, returns the corresponding address -// in network order. -extern uint32 dotted_to_addr(const char* addr_text); -extern uint32* dotted_to_addr6(const char* addr_text); - -extern int is_v4_addr(const uint32 addr[4]); -extern uint32 to_v4_addr(const uint32* addr); - -extern uint32 mask_addr(uint32 a, uint32 top_bits_to_keep); -extern const uint32* mask_addr(const uint32* a, uint32 top_bits_to_keep); - +extern const char* fmt_conn_id(const IPAddr& src_addr, uint32 src_port, + const IPAddr& dst_addr, uint32 dst_port); extern const char* fmt_conn_id(const uint32* src_addr, uint32 src_port, const uint32* dst_addr, uint32 dst_port); -inline void copy_addr(const uint32* src_a, uint32* dst_a) - { -#ifdef BROv6 - dst_a[0] = src_a[0]; - dst_a[1] = src_a[1]; - dst_a[2] = src_a[2]; - dst_a[3] = src_a[3]; -#else - dst_a[0] = src_a[0]; -#endif - } - -inline int addr_eq(const uint32* a1, const uint32* a2) - { -#ifdef BROv6 - return a1[0] == a2[0] && - a1[1] == a2[1] && - a1[2] == a2[2] && - a1[3] == a2[3]; -#else - return a1[0] == a2[0]; -#endif - } - -inline int subnet_eq(const subnet_type* s1, const subnet_type* s2) - { -#ifdef BROv6 - return s1->net[0] == s2->net[0] && - s1->net[1] == s2->net[1] && - s1->net[2] == s2->net[2] && - s1->net[3] == s2->net[3] && - s1->width == s2->width; -#else - return s1->net == s2->net && s1->width == s2->width; -#endif - } - // Read 4 bytes from data and return in network order. extern uint32 extract_uint32(const u_char* data); diff --git a/src/patricia.c b/src/patricia.c index ef9c008f4b..c2e2016570 100644 --- a/src/patricia.c +++ b/src/patricia.c @@ -259,7 +259,7 @@ New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix) if (family == AF_INET6) { default_bitlen = 128; if (prefix == NULL) { - prefix = calloc(1, sizeof (prefix6_t)); + prefix = calloc(1, sizeof (prefix_t)); dynamic_allocated++; } memcpy (&prefix->add.sin6, dest, 16); diff --git a/src/patricia.h b/src/patricia.h index 4bc2f9b81f..c4d3ce9b08 100644 --- a/src/patricia.h +++ b/src/patricia.h @@ -53,11 +53,9 @@ #include -#ifdef BROv6 #ifndef HAVE_IPV6 #define HAVE_IPV6 #endif -#endif /* typedef unsigned int u_int; */ typedef void (*void_fn_t)(); diff --git a/testing/btest/Baseline/bifs.addr_version/out b/testing/btest/Baseline/bifs.addr_version/out new file mode 100644 index 0000000000..328bff6687 --- /dev/null +++ b/testing/btest/Baseline/bifs.addr_version/out @@ -0,0 +1,4 @@ +T +F +F +T diff --git a/testing/btest/Baseline/bifs.net_stats_trace/output b/testing/btest/Baseline/bifs.net_stats_trace/output index a2e25e03a7..55d6693db5 100644 --- a/testing/btest/Baseline/bifs.net_stats_trace/output +++ b/testing/btest/Baseline/bifs.net_stats_trace/output @@ -1 +1 @@ -[pkts_recvd=131, pkts_dropped=0, pkts_link=0] +[pkts_recvd=136, pkts_dropped=0, pkts_link=0] diff --git a/testing/btest/Baseline/core.conn-uid/counts b/testing/btest/Baseline/core.conn-uid/counts index a8fa06e1be..38b10c1b2b 100644 --- a/testing/btest/Baseline/core.conn-uid/counts +++ b/testing/btest/Baseline/core.conn-uid/counts @@ -1 +1 @@ -62 +68 diff --git a/testing/btest/Baseline/core.conn-uid/output b/testing/btest/Baseline/core.conn-uid/output index 6f58e7c10c..c77eda4f04 100644 --- a/testing/btest/Baseline/core.conn-uid/output +++ b/testing/btest/Baseline/core.conn-uid/output @@ -1,40 +1,43 @@ [orig_h=141.142.220.202, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], UWkUyAuUGXf -[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], arKYeMETxOg -[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], k6kgXLOoSKl -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh -[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 -[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 -[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 -[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], 2cx26uAvUPl -[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], BWaU4aSuwkc -[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], 10XodEwRycf -[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], zno26fFZkrh -[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], v5rgkJBig5l +[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp], arKYeMETxOg +[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], k6kgXLOoSKl +[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], nQcgTWjvg4c +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh +[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal +[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], 5OKnoww6xl4 +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 +[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 +[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], iE6yhOq3SF +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 +[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 +[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], h5DsfNtYzi1 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 +[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq +[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], GvmoxJFXdTa +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb +[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], UfGkYA2HI2g +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], BWaU4aSuwkc +[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], 10XodEwRycf +[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp], zno26fFZkrh +[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], v5rgkJBig5l +[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp], eWZCH7OONC1 +[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], 0Pwk3ntf8O3 +[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], 0HKorjr8Zp7 diff --git a/testing/btest/Baseline/core.conn-uid/output.cc b/testing/btest/Baseline/core.conn-uid/output.cc index 6f58e7c10c..c77eda4f04 100644 --- a/testing/btest/Baseline/core.conn-uid/output.cc +++ b/testing/btest/Baseline/core.conn-uid/output.cc @@ -1,40 +1,43 @@ [orig_h=141.142.220.202, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], UWkUyAuUGXf -[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], arKYeMETxOg -[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], k6kgXLOoSKl -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh -[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 -[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 -[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 -[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], 2cx26uAvUPl -[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], BWaU4aSuwkc -[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], 10XodEwRycf -[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], zno26fFZkrh -[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], v5rgkJBig5l +[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp], arKYeMETxOg +[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], k6kgXLOoSKl +[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], nQcgTWjvg4c +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh +[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal +[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], 5OKnoww6xl4 +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 +[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 +[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], iE6yhOq3SF +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 +[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 +[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], h5DsfNtYzi1 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 +[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq +[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], GvmoxJFXdTa +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb +[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], UfGkYA2HI2g +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], BWaU4aSuwkc +[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], 10XodEwRycf +[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp], zno26fFZkrh +[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], v5rgkJBig5l +[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp], eWZCH7OONC1 +[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], 0Pwk3ntf8O3 +[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], 0HKorjr8Zp7 diff --git a/testing/btest/Baseline/core.conn-uid/output.cc2 b/testing/btest/Baseline/core.conn-uid/output.cc2 index 6f58e7c10c..c77eda4f04 100644 --- a/testing/btest/Baseline/core.conn-uid/output.cc2 +++ b/testing/btest/Baseline/core.conn-uid/output.cc2 @@ -1,40 +1,43 @@ [orig_h=141.142.220.202, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], UWkUyAuUGXf -[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], arKYeMETxOg -[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], k6kgXLOoSKl -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh -[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 -[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 -[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 -[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], UfGkYA2HI2g -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], 2cx26uAvUPl -[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], BWaU4aSuwkc -[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], 10XodEwRycf -[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], zno26fFZkrh -[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], v5rgkJBig5l +[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp], arKYeMETxOg +[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], k6kgXLOoSKl +[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], nQcgTWjvg4c +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif +[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh +[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal +[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], 5OKnoww6xl4 +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 +[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 +[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], iE6yhOq3SF +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 +[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 +[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], h5DsfNtYzi1 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 +[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq +[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], GvmoxJFXdTa +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb +[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], UfGkYA2HI2g +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a +[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 +[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa +[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 +[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a +[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 +[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl +[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], BWaU4aSuwkc +[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], 10XodEwRycf +[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp], zno26fFZkrh +[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], v5rgkJBig5l +[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp], eWZCH7OONC1 +[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], 0Pwk3ntf8O3 +[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], 0HKorjr8Zp7 diff --git a/testing/btest/Baseline/core.print-bpf-filters-ipv4/output b/testing/btest/Baseline/core.print-bpf-filters-ipv4/output deleted file mode 100644 index d7ff523927..0000000000 --- a/testing/btest/Baseline/core.print-bpf-filters-ipv4/output +++ /dev/null @@ -1,32 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path packet_filter -#fields ts node filter init success -#types time string string bool bool -1324314285.981347 - not ip6 T T -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path packet_filter -#fields ts node filter init success -#types time string string bool bool -1324314286.168294 - (((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666)) and (not ip6) T T -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path packet_filter -#fields ts node filter init success -#types time string string bool bool -1324314286.350780 - port 42 T T -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path packet_filter -#fields ts node filter init success -#types time string string bool bool -1324314286.530768 - port 56730 T T diff --git a/testing/btest/Baseline/core.print-bpf-filters-ipv6/conn.log b/testing/btest/Baseline/core.print-bpf-filters-ipv6/conn.log deleted file mode 100644 index e71eff9d57..0000000000 --- a/testing/btest/Baseline/core.print-bpf-filters-ipv6/conn.log +++ /dev/null @@ -1,2 +0,0 @@ -# ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history notice_tags -1128727435.4509 UWkUyAuUGXf 141.42.64.125 56730 125.190.109.199 80 tcp - 1.73330307006836 98 9417 SF - 0 ShADdFaf - diff --git a/testing/btest/Baseline/core.print-bpf-filters-ipv6/output b/testing/btest/Baseline/core.print-bpf-filters-ipv6/output deleted file mode 100644 index 0065fabfd3..0000000000 --- a/testing/btest/Baseline/core.print-bpf-filters-ipv6/output +++ /dev/null @@ -1,8 +0,0 @@ -# ts node filter init success -1308603220.46822 - ip or not ip F T -# ts node filter init success -1308603220.51607 - tcp port 22 F T -# ts node filter init success -1308603220.55432 - port 42 F T -# ts node filter init success -1308603220.59452 - port 56730 T T diff --git a/testing/btest/Baseline/core.print-bpf-filters-ipv4/conn.log b/testing/btest/Baseline/core.print-bpf-filters/conn.log similarity index 100% rename from testing/btest/Baseline/core.print-bpf-filters-ipv4/conn.log rename to testing/btest/Baseline/core.print-bpf-filters/conn.log diff --git a/testing/btest/Baseline/core.print-bpf-filters/output b/testing/btest/Baseline/core.print-bpf-filters/output new file mode 100644 index 0000000000..a2bf430fb4 --- /dev/null +++ b/testing/btest/Baseline/core.print-bpf-filters/output @@ -0,0 +1,32 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path packet_filter +#fields ts node filter init success +#types time string string bool bool +1328294052.330721 - ip or not ip T T +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path packet_filter +#fields ts node filter init success +#types time string string bool bool +1328294052.542418 - ((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666) T T +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path packet_filter +#fields ts node filter init success +#types time string string bool bool +1328294052.748480 - port 42 T T +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path packet_filter +#fields ts node filter init success +#types time string string bool bool +1328294052.952845 - port 56730 T T diff --git a/testing/btest/Baseline/language.cross-product-init/output b/testing/btest/Baseline/language.cross-product-init/output index 95794f9179..fcb5e43e67 100644 --- a/testing/btest/Baseline/language.cross-product-init/output +++ b/testing/btest/Baseline/language.cross-product-init/output @@ -1,6 +1,6 @@ { -[bar, 1.2.0.0/19] , -[foo, 5.6.0.0/21] , +[foo, 1.2.0.0/19] , [bar, 5.6.0.0/21] , -[foo, 1.2.0.0/19] +[foo, 5.6.0.0/21] , +[bar, 1.2.0.0/19] } diff --git a/testing/btest/Baseline/language.sizeof/output b/testing/btest/Baseline/language.sizeof/output index 737a999292..43cb73f763 100644 --- a/testing/btest/Baseline/language.sizeof/output +++ b/testing/btest/Baseline/language.sizeof/output @@ -1,4 +1,5 @@ -Address 1.2.3.4: 16909060 +IPv4 Address 1.2.3.4: 32 +IPv6 Address ::1: 128 Boolean T: 1 Count 10: 10 Double -1.23: 1.230000 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log index e2b3da6efd..340b164f2e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log @@ -5,33 +5,33 @@ #path local #fields ts id.orig_h #types time addr -1300475168.652003 141.142.220.118 1300475168.724007 141.142.220.118 -1300475168.859163 141.142.220.118 -1300475168.902635 141.142.220.118 1300475168.892936 141.142.220.118 +1300475168.895267 141.142.220.118 1300475168.892913 141.142.220.118 +1300475168.652003 141.142.220.118 1300475168.855305 141.142.220.118 1300475168.855330 141.142.220.118 -1300475168.895267 141.142.220.118 -1300475168.853899 141.142.220.118 -1300475168.893988 141.142.220.118 -1300475168.894787 141.142.220.118 -1300475173.117362 141.142.220.226 -1300475173.153679 141.142.220.238 -1300475168.857956 141.142.220.118 -1300475168.854378 141.142.220.118 -1300475168.854837 141.142.220.118 -1300475167.099816 141.142.220.50 -1300475168.891644 141.142.220.118 -1300475168.892037 141.142.220.118 -1300475171.677081 141.142.220.226 +1300475168.859163 141.142.220.118 +1300475168.902635 141.142.220.118 1300475168.894422 141.142.220.118 -1300475167.096535 141.142.220.202 -1300475168.858713 141.142.220.118 -1300475168.902195 141.142.220.118 -1300475169.899438 141.142.220.44 -1300475168.892414 141.142.220.118 -1300475168.858306 141.142.220.118 +1300475168.893988 141.142.220.118 1300475168.901749 141.142.220.118 +1300475168.853899 141.142.220.118 +1300475168.854837 141.142.220.118 +1300475168.857956 141.142.220.118 +1300475168.858713 141.142.220.118 +1300475171.677081 141.142.220.226 +1300475168.854378 141.142.220.118 +1300475173.153679 141.142.220.238 +1300475169.899438 141.142.220.44 +1300475168.892037 141.142.220.118 +1300475168.892414 141.142.220.118 +1300475168.902195 141.142.220.118 +1300475168.891644 141.142.220.118 +1300475168.894787 141.142.220.118 +1300475167.099816 141.142.220.50 1300475170.862384 141.142.220.226 +1300475167.096535 141.142.220.202 +1300475168.858306 141.142.220.118 +1300475173.117362 141.142.220.226 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/remote.log b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/remote.log index 1ac18ff5f7..b396c3fc2d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/remote.log +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/remote.log @@ -6,3 +6,6 @@ #fields ts id.orig_h #types time addr 1300475169.780331 173.192.163.128 +1300475167.097012 fe80::217:f2ff:fed7:cf65 +1300475171.675372 fe80::3074:17d5:2052:c324 +1300475173.116749 fe80::3074:17d5:2052:c324 diff --git a/testing/btest/Baseline/scripts.base.frameworks.metrics.basic-cluster/manager-1.metrics.log b/testing/btest/Baseline/scripts.base.frameworks.metrics.basic-cluster/manager-1.metrics.log index a278bdc56a..a22deb26e4 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.metrics.basic-cluster/manager-1.metrics.log +++ b/testing/btest/Baseline/scripts.base.frameworks.metrics.basic-cluster/manager-1.metrics.log @@ -5,6 +5,6 @@ #path metrics #fields ts metric_id filter_name index.host index.str index.network value #types time enum string addr string subnet count -1324314335.570789 TEST_METRIC foo-bar 6.5.4.3 - - 4 -1324314335.570789 TEST_METRIC foo-bar 1.2.3.4 - - 6 -1324314335.570789 TEST_METRIC foo-bar 7.2.1.5 - - 2 +1328303679.867377 TEST_METRIC foo-bar 6.5.4.3 - - 4 +1328303679.867377 TEST_METRIC foo-bar 7.2.1.5 - - 2 +1328303679.867377 TEST_METRIC foo-bar 1.2.3.4 - - 6 diff --git a/testing/btest/Baseline/scripts.base.frameworks.metrics.basic/metrics.log b/testing/btest/Baseline/scripts.base.frameworks.metrics.basic/metrics.log index 8ee19c255b..4bfb6964ea 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.metrics.basic/metrics.log +++ b/testing/btest/Baseline/scripts.base.frameworks.metrics.basic/metrics.log @@ -5,6 +5,6 @@ #path metrics #fields ts metric_id filter_name index.host index.str index.network value #types time enum string addr string subnet count -1324314344.807073 TEST_METRIC foo-bar 6.5.4.3 - - 2 -1324314344.807073 TEST_METRIC foo-bar 1.2.3.4 - - 3 -1324314344.807073 TEST_METRIC foo-bar 7.2.1.5 - - 1 +1328303763.333948 TEST_METRIC foo-bar 6.5.4.3 - - 2 +1328303763.333948 TEST_METRIC foo-bar 7.2.1.5 - - 1 +1328303763.333948 TEST_METRIC foo-bar 1.2.3.4 - - 3 diff --git a/testing/btest/bifs/addr_version.bro b/testing/btest/bifs/addr_version.bro new file mode 100644 index 0000000000..8d496a9294 --- /dev/null +++ b/testing/btest/bifs/addr_version.bro @@ -0,0 +1,7 @@ +# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: btest-diff out + +print is_v4_addr(1.2.3.4); +print is_v4_addr(::1); +print is_v6_addr(1.2.3.4); +print is_v6_addr(::1); diff --git a/testing/btest/core/print-bpf-filters-ipv4.bro b/testing/btest/core/print-bpf-filters-ipv4.bro deleted file mode 100644 index 5a3b0cf7ce..0000000000 --- a/testing/btest/core/print-bpf-filters-ipv4.bro +++ /dev/null @@ -1,12 +0,0 @@ -# @TEST-REQUIRES: bro -e 'print bro_has_ipv6()' | grep -q F -# -# @TEST-EXEC: bro -r $TRACES/empty.trace -e '' >output -# @TEST-EXEC: cat packet_filter.log >>output -# @TEST-EXEC: bro -r $TRACES/empty.trace PacketFilter::all_packets=F >>output -# @TEST-EXEC: cat packet_filter.log >>output -# @TEST-EXEC: bro -r $TRACES/empty.trace -f "port 42" -e '' >>output -# @TEST-EXEC: cat packet_filter.log >>output -# @TEST-EXEC: bro -r $TRACES/empty.trace -C -f "port 56730" -r $TRACES/mixed-vlan-mpls.trace >>output -# @TEST-EXEC: cat packet_filter.log >>output -# @TEST-EXEC: btest-diff output -# @TEST-EXEC: btest-diff conn.log diff --git a/testing/btest/core/print-bpf-filters-ipv6.bro b/testing/btest/core/print-bpf-filters.bro similarity index 89% rename from testing/btest/core/print-bpf-filters-ipv6.bro rename to testing/btest/core/print-bpf-filters.bro index 824c979d70..6d9cef0220 100644 --- a/testing/btest/core/print-bpf-filters-ipv6.bro +++ b/testing/btest/core/print-bpf-filters.bro @@ -1,5 +1,3 @@ -# @TEST-REQUIRES: bro -e 'print bro_has_ipv6()' | grep -q T -# # @TEST-EXEC: bro -r $TRACES/empty.trace -e '' >output # @TEST-EXEC: cat packet_filter.log >>output # @TEST-EXEC: bro -r $TRACES/empty.trace PacketFilter::all_packets=F >>output diff --git a/testing/btest/istate/broccoli.bro b/testing/btest/istate/broccoli.bro index 7f97f40585..6b88794f73 100644 --- a/testing/btest/istate/broccoli.bro +++ b/testing/btest/istate/broccoli.bro @@ -1,4 +1,3 @@ -# @TEST-REQUIRES: grep -vq '#define BROv6' $BUILD/config.h # @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib # # @TEST-EXEC: btest-bg-run bro bro %INPUT $DIST/aux/broccoli/test/broping-record.bro diff --git a/testing/btest/istate/pybroccoli.py b/testing/btest/istate/pybroccoli.py index b7fb53a955..4e192fcfb6 100644 --- a/testing/btest/istate/pybroccoli.py +++ b/testing/btest/istate/pybroccoli.py @@ -1,4 +1,3 @@ -# @TEST-REQUIRES: grep -vq '#define BROv6' $BUILD/config.h # @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib # @TEST-REQUIRES: test -e $BUILD/aux/broccoli/bindings/broccoli-python/_broccoli_intern.so # diff --git a/testing/btest/language/sizeof.bro b/testing/btest/language/sizeof.bro index 3457f895c9..860c9487ff 100644 --- a/testing/btest/language/sizeof.bro +++ b/testing/btest/language/sizeof.bro @@ -20,6 +20,7 @@ type example_record: record { }; global a: addr = 1.2.3.4; +global a6: addr = ::1; global b: bool = T; global c: count = 10; global d: double = -1.23; @@ -52,8 +53,10 @@ v[4] = "World"; # Print out the sizes of the various vals: #----------------------------------------- -# Size of addr: returns integer representation for IPv4, 0 for IPv6. -print fmt("Address %s: %d", a, |a|); +# Size of addr: returns number of bits required to represent the address +# which is 32 for IPv4 or 128 for IPv6 +print fmt("IPv4 Address %s: %d", a, |a|); +print fmt("IPv6 Address %s: %d", a6, |a6|); # Size of boolean: returns 1 or 0. print fmt("Boolean %s: %d", b, |b|); From fe5d865e640d8d7a19135e22c1ad4e1aa790fbf0 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 3 Feb 2012 18:06:02 -0600 Subject: [PATCH 04/49] Remove --enable-brov6 from configure usage text --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index 675447e461..43afb4ae99 100755 --- a/configure +++ b/configure @@ -27,7 +27,6 @@ Usage: $0 [OPTION]... [VAR=VALUE]... Optional Features: --enable-debug compile in debugging mode - --enable-brov6 enable IPv6 processing --enable-perftools use Google's perftools --disable-broccoli don't build or install the Broccoli library --disable-broctl don't install Broctl From 1f58ac875b03340eb8eec5e6173cca2e1850a227 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 6 Feb 2012 13:05:52 -0600 Subject: [PATCH 05/49] Fix some hashing bugs resulting from adaptation of new IPAddr class. --- src/CompHash.cc | 2 -- src/Conn.cc | 8 ++++---- src/Conn.h | 4 ++-- src/ConnCompressor.cc | 27 ++++++++++++++------------- src/ConnCompressor.h | 4 ++-- src/Sessions.cc | 4 ++-- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/CompHash.cc b/src/CompHash.cc index daaa80bc49..44484ca005 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -107,8 +107,6 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, case TYPE_INTERNAL_ADDR: { - // Use uint32 instead of int, because 'int' is not - // guaranteed to be 32-bit. uint32* kp = AlignAndPadType(kp0); uint32 bytes[4]; v->AsAddr()->CopyIPv6(bytes); diff --git a/src/Conn.cc b/src/Conn.cc index 3177d48705..deb89d50d3 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -24,15 +24,15 @@ HashKey* ConnID::BuildConnKey() const if ( is_one_way || addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) ) { - key.ip1 = src_addr; - key.ip2 = dst_addr; + src_addr.CopyIPv6(key.ip1); + dst_addr.CopyIPv6(key.ip2); key.port1 = src_port; key.port2 = dst_port; } else { - key.ip1 = dst_addr; - key.ip2 = src_addr; + dst_addr.CopyIPv6(key.ip1); + src_addr.CopyIPv6(key.ip2); key.port1 = dst_port; key.port2 = src_port; } diff --git a/src/Conn.h b/src/Conn.h index e7f24e3693..cdd61bd67b 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -50,8 +50,8 @@ struct ConnID { // The structure used internally for hashing. struct Key { - IPAddr ip1; - IPAddr ip2; + uint32 ip1[4]; + uint32 ip2[4]; uint16 port1; uint16 port2; }; diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index b745854c66..b6bcc789b3 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -235,7 +235,8 @@ Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip, tc = FirstFromOrig(t, key, ip, tp); } - else if ( ip->SrcAddr() == SrcAddr(pending) && + else if ( ip->SrcAddr() == + IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network) && tp->th_sport == SrcPort(pending) ) // Another packet from originator. tc = NextFromOrig(pending, t, key, ip, tp); @@ -507,8 +508,8 @@ Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending) { // Instantantiate a Connection. ConnID conn_id; - conn_id.src_addr = SrcAddr(pending); - conn_id.dst_addr = DstAddr(pending); + conn_id.src_addr = IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network); + conn_id.dst_addr = IPAddr(IPAddr::IPv6, DstAddr(pending), IPAddr::Network); conn_id.src_port = SrcPort(pending); conn_id.dst_port = DstPort(pending); @@ -607,7 +608,8 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key, memcpy(&c->key, key->Key(), key->Size()); c->hash = key->Hash(); - c->ip1_is_src = c->key.ip1 == ip->SrcAddr() && + IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network); + c->ip1_is_src = ip1 == ip->SrcAddr() && c->key.port1 == tp->th_sport; c->time = time; c->window = tp->th_win; @@ -656,11 +658,10 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) tp->th_urp = 0; } - // Note, do *not* use copy_addr() here. This is because we're - // copying to an IPv4 header, which has room for exactly and - // only an IPv4 address. - if ( c->key.ip1.family() == IPAddr::IPv6 || - c->key.ip2.family() == IPAddr::IPv6 ) + IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network); + IPAddr ip2(IPAddr::IPv6, c->key.ip2, IPAddr::Network); + if ( ip1.family() == IPAddr::IPv6 || + ip2.family() == IPAddr::IPv6 ) reporter->InternalError("IPv6 snuck into connection compressor"); else { @@ -668,13 +669,13 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) const uint32* dst_bytes; if ( c->ip1_is_src ) { - c->key.ip1.GetBytes(&src_bytes); - c->key.ip2.GetBytes(&dst_bytes); + ip1.GetBytes(&src_bytes); + ip2.GetBytes(&dst_bytes); } else { - c->key.ip2.GetBytes(&src_bytes); - c->key.ip1.GetBytes(&dst_bytes); + ip2.GetBytes(&src_bytes); + ip1.GetBytes(&dst_bytes); } memcpy(&ip->ip_src, src_bytes, sizeof(ip->ip_src)); memcpy(&ip->ip_dst, dst_bytes, sizeof(ip->ip_dst)); diff --git a/src/ConnCompressor.h b/src/ConnCompressor.h index 97051e148a..36959b615c 100644 --- a/src/ConnCompressor.h +++ b/src/ConnCompressor.h @@ -105,9 +105,9 @@ public: private: // Helpers to extract addrs/ports from PendingConn. - const IPAddr& SrcAddr(const PendingConn* c) + const uint32* SrcAddr(const PendingConn* c) { return c->ip1_is_src ? c->key.ip1 : c->key.ip2; } - const IPAddr& DstAddr(const PendingConn* c) + const uint32* DstAddr(const PendingConn* c) { return c->ip1_is_src ? c->key.ip2 : c->key.ip1; } uint16 SrcPort(const PendingConn* c) diff --git a/src/Sessions.cc b/src/Sessions.cc index 6c262619ad..8b84063368 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -71,8 +71,8 @@ void TimerMgrExpireTimer::Dispatch(double t, int is_expire) NetSessions::NetSessions() { TypeList* t = new TypeList(); - t->Append(base_type(TYPE_COUNT)); // source IP address - t->Append(base_type(TYPE_COUNT)); // dest IP address + t->Append(base_type(TYPE_ADDR)); // source IP address + t->Append(base_type(TYPE_ADDR)); // dest IP address t->Append(base_type(TYPE_COUNT)); // source and dest ports ch = new CompositeHash(t); From eca32610779dc6c707fb734e49cc0be379c6cfd5 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Mon, 6 Feb 2012 15:49:03 -0500 Subject: [PATCH 06/49] Protocol field for NULL encapsulation was read big endian. --- src/PktSrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PktSrc.cc b/src/PktSrc.cc index 68b9785e6f..598f13b51c 100644 --- a/src/PktSrc.cc +++ b/src/PktSrc.cc @@ -191,7 +191,7 @@ void PktSrc::Process() switch ( datalink ) { case DLT_NULL: { - protocol = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; + protocol = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; if ( protocol != AF_INET && protocol != AF_INET6 ) { From 4cb6a279f58b775ab464c7a7539a3d1c5896d86a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 7 Feb 2012 11:42:55 -0600 Subject: [PATCH 07/49] Add extra guard against non-IP, non-ARP packets being parsed as IPv6. This would usually manifest in raising truncated_IP weirds, which is misleading because it wasn't actually an IP packet in the first place. Now unknown_packet_type weird is raised instead. --- src/Sessions.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 8b84063368..54a6a85f7b 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -282,11 +282,16 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, else if ( arp_analyzer && arp_analyzer->IsARP(pkt, hdr_size) ) arp_analyzer->NextPacket(t, hdr, pkt, hdr_size); - else + else if ( ip->ip_v == 6 ) { IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size)); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } + else + { + Weird("unknown_packet_type", hdr, pkt); + return; + } } if ( dump_this_packet && ! record_all_packets ) From 5ad0bab9b0013fc27d8a29f8661f15a24dcad9d8 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 7 Feb 2012 14:26:15 -0600 Subject: [PATCH 08/49] Fix a memory leak that perftools now complains about. --- src/DNS_Mgr.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index b9213c376e..e89dbf7d2f 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -1072,9 +1072,6 @@ void DNS_Mgr::Flush() { DoProcess(false); - IterCookie* cookie = addr_mappings.InitForIteration(); - DNS_Mapping* dm; - host_mappings.Clear(); addr_mappings.Clear(); } From 31565d6987e3bd15f2e4fbd3f1365d29deebd9eb Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Tue, 7 Feb 2012 16:15:13 -0600 Subject: [PATCH 09/49] Fix the ptr_name_to_addr BiF to work with IPv6 --- src/bro.bif | 58 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/bro.bif b/src/bro.bif index 01d0e905ba..6a0b935a78 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2322,20 +2322,58 @@ function to_port%(s: string%): port ## .. bro:see:: addr_to_ptr_name parse_dotted_addr function ptr_name_to_addr%(s: string%): addr %{ - int a[4]; - uint32 addr; - - if ( sscanf(s->CheckString(), - "%d.%d.%d.%d.in-addr.arpa", - a, a+1, a+2, a+3) != 4 ) + if ( s->Len() != 72 ) { - builtin_error("bad PTR name", @ARG@[0]); - addr = 0; + int a[4]; + uint32 addr; + char ss[13]; // this will contain "in-addr.arpa" + + if ( sscanf(s->CheckString(), + "%d.%d.%d.%d.%12s", + a, a+1, a+2, a+3, ss) != 5 + || strcmp(ss, "in-addr.arpa") != 0 ) + { + builtin_error("bad PTR name", @ARG@[0]); + addr = 0; + } + else + addr = (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]; + + return new AddrVal(htonl(addr)); } else - addr = (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]; + { + uint32 addr6[4]; + uint32 b[32]; + char ss[9]; // this will contain "ip6.arpa" + if ( sscanf(s->CheckString(), + "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." + "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." + "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." + "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%8s", + b+31, b+30, b+29, b+28, b+27, b+26, b+25, b+24, + b+23, b+22, b+21, b+20, b+19, b+18, b+17, b+16, + b+15, b+14, b+13, b+12, b+11, b+10, b+9, b+8, + b+7, b+6, b+5, b+4, b+3, b+2, b+1, b, ss) != 33 + || strcmp(ss, "ip6.arpa") != 0 ) + { + builtin_error("bad PTR name", @ARG@[0]); + memset(addr6, 0, sizeof addr6); + } + else + { + for ( unsigned int i = 0; i < 4; ++i ) + { + uint32 a = 0; + for ( unsigned int j = 1; j <= 8; ++j ) + a |= b[8*i+j-1] << (32-j*4); - return new AddrVal(htonl(addr)); + addr6[i] = htonl(a); + } + } + + return new AddrVal(addr6); + } %} ## Converts an IP address to a reverse pointer name. For example, From 161ad1a3df2099a2ae12971c6e047eb553c918d5 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 7 Feb 2012 20:57:18 -0500 Subject: [PATCH 10/49] Adding a test and baseline for ptr_name_to_addr BiF. --- testing/btest/Baseline/bifs.ptr_name_to_addr/output | 2 ++ testing/btest/bifs/ptr_name_to_addr.bro | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 testing/btest/Baseline/bifs.ptr_name_to_addr/output create mode 100644 testing/btest/bifs/ptr_name_to_addr.bro diff --git a/testing/btest/Baseline/bifs.ptr_name_to_addr/output b/testing/btest/Baseline/bifs.ptr_name_to_addr/output new file mode 100644 index 0000000000..7c290027aa --- /dev/null +++ b/testing/btest/Baseline/bifs.ptr_name_to_addr/output @@ -0,0 +1,2 @@ +2607:f8b0:4009:802::1012 +74.125.225.52 diff --git a/testing/btest/bifs/ptr_name_to_addr.bro b/testing/btest/bifs/ptr_name_to_addr.bro new file mode 100644 index 0000000000..89679ba57a --- /dev/null +++ b/testing/btest/bifs/ptr_name_to_addr.bro @@ -0,0 +1,8 @@ +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +global v6 = ptr_name_to_addr("2.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.2.0.8.0.9.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa"); +global v4 = ptr_name_to_addr("52.225.125.74.in-addr.arpa"); + +print v6; +print v4; \ No newline at end of file From d3e432e8dd8c7ddda34b96912d0ef103883f998f Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Wed, 8 Feb 2012 11:23:02 -0600 Subject: [PATCH 11/49] Add a test and baseline for addr_to_ptr_name BiF. --- testing/btest/Baseline/bifs.addr_to_ptr_name/output | 2 ++ testing/btest/bifs/addr_to_ptr_name.bro | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 testing/btest/Baseline/bifs.addr_to_ptr_name/output create mode 100644 testing/btest/bifs/addr_to_ptr_name.bro diff --git a/testing/btest/Baseline/bifs.addr_to_ptr_name/output b/testing/btest/Baseline/bifs.addr_to_ptr_name/output new file mode 100644 index 0000000000..8de05d1d8e --- /dev/null +++ b/testing/btest/Baseline/bifs.addr_to_ptr_name/output @@ -0,0 +1,2 @@ +2.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.2.0.8.0.9.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa +52.225.125.74.in-addr.arpa diff --git a/testing/btest/bifs/addr_to_ptr_name.bro b/testing/btest/bifs/addr_to_ptr_name.bro new file mode 100644 index 0000000000..c9b3fb9e16 --- /dev/null +++ b/testing/btest/bifs/addr_to_ptr_name.bro @@ -0,0 +1,6 @@ +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +print addr_to_ptr_name(2607:f8b0:4009:802::1012); +print addr_to_ptr_name(74.125.225.52); + From 3ff0eed3fc3896702a9bc3bacb6cb370f9c485c3 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Wed, 8 Feb 2012 17:30:54 -0600 Subject: [PATCH 12/49] Remove mention of --enable-brov6 in docs --- doc/scripts/builtins.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/scripts/builtins.rst b/doc/scripts/builtins.rst index ef6738a1a6..37edb79904 100644 --- a/doc/scripts/builtins.rst +++ b/doc/scripts/builtins.rst @@ -156,9 +156,7 @@ The Bro scripting language supports the following built-in types. .. bro:type:: addr - A type representing an IP address. Currently, Bro defaults to only - supporting IPv4 addresses unless configured/built with - ``--enable-brov6``, in which case, IPv6 addresses are supported. + A type representing an IP address. IPv4 address constants are written in "dotted quad" format, ``A1.A2.A3.A4``, where Ai all lie between 0 and 255. From 303f02d6f8de9f1865ac736a6ce406500f3d4fdb Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 9 Feb 2012 12:53:37 -0600 Subject: [PATCH 13/49] Inline some IPAddr methods. --- src/IPAddr.cc | 263 +++----------------------------------------------- src/IPAddr.h | 220 +++++++++++++++++++++++++++++++++++------ 2 files changed, 204 insertions(+), 279 deletions(-) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index e3737f41b4..fa8e5567eb 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,167 +1,10 @@ #include "IPAddr.h" #include "Reporter.h" -#include "modp_numtoa.h" -#include const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; -IPAddr::IPAddr() - { - memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); - } - -IPAddr::IPAddr(const in4_addr& in4) - { - memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr)); - } - -IPAddr::IPAddr(const in6_addr& arg_in6) - : in6(arg_in6) - { - } - -void IPAddr::Init(const std::string& s) - { - if ( s.find(':') == std::string::npos ) //IPv4 - { - memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 ) - { - reporter->Error("Bad IP address: %s", s.c_str()); - memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); - } - } - else - { - if ( inet_pton(AF_INET6, s.c_str(), in6.s6_addr) <=0 ) - { - reporter->Error("Bad IP address: %s", s.c_str()); - memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); - } - } - } - -IPAddr::IPAddr(const std::string& s) - { - Init(s); - } - -IPAddr::IPAddr(const BroString& s) - { - Init(s.CheckString()); - } - -IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order) - { - if ( family == IPv4 ) - { - memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - memcpy(&in6.s6_addr[12], bytes, sizeof(uint32_t)); - if ( order == Host ) - { - uint32_t* p = (uint32_t*) &in6.s6_addr[12]; - *p = htonl(*p); - } - } - else - { - memcpy(in6.s6_addr, bytes, sizeof(in6.s6_addr)); - if ( order == Host ) - { - for ( unsigned int i = 0; i < 4; ++ i) - { - uint32_t* p = (uint32_t*) &in6.s6_addr[i*4]; - *p = htonl(*p); - } - } - } - } - -IPAddr::IPAddr(const IPAddr& other) - { - in6 = other.in6; - } - -IPAddr::~IPAddr() - { - } - -IPAddr::Family IPAddr::family() const - { - if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 ) - return IPv4; - else - return IPv6; - } - -bool IPAddr::IsLoopback() const - { - if ( family() == IPv4 ) - return in6.s6_addr[12] == 127; - else - return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) - && (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0) - && (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) - && (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) - && (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0) - && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) - && (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0) - && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); - } - -bool IPAddr::IsMulticast() const - { - if ( family() == IPv4 ) - return in6.s6_addr[12] == 224; - else - return in6.s6_addr[0] == 0xff; - } - -bool IPAddr::IsBroadcast() const - { - if ( family() == IPv4 ) - return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) - && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); - else - return false; - } - -int IPAddr::GetBytes(uint32_t** bytes) - { - if ( family() == IPv4 ) - { - *bytes = (uint32_t*) &in6.s6_addr[12]; - return 1; - } - else - { - *bytes = (uint32_t*) in6.s6_addr; - return 4; - } - } - -int IPAddr::GetBytes(const uint32_t** bytes) const - { - if ( family() == IPv4 ) - { - *bytes = (uint32_t*) &in6.s6_addr[12]; - return 1; - } - else - { - *bytes = (uint32_t*) in6.s6_addr; - return 4; - } - } - -void IPAddr::CopyIPv6(uint32_t* bytes) const - { - memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr)); - } - void IPAddr::Mask(int top_bits_to_keep) { if ( top_bits_to_keep <=0 || top_bits_to_keep > 128 ) @@ -216,49 +59,27 @@ void IPAddr::ReverseMask(int top_bits_to_chop) memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } -IPAddr& IPAddr::operator =(const IPAddr& other) +void IPAddr::Init(const std::string& s) { - // No self-assignment check here because it's correct without it and - // makes the common case faster. - in6 = other.in6; - return *this; - } - -IPAddr::operator std::string() const - { - if ( family() == IPv4 ) + if ( s.find(':') == std::string::npos ) //IPv4 { - char s[INET_ADDRSTRLEN]; - if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) - return "Error("Bad IP address: %s", s.c_str()); + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } } else { - char s[INET6_ADDRSTRLEN]; - if ( inet_ntop(AF_INET6, in6.s6_addr, s, INET6_ADDRSTRLEN) == NULL ) - return "Error("Bad IP address: %s", s.c_str()); + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } } } -bool operator ==(const IPAddr& addr1, const IPAddr& addr2) - { - return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0; - } - -bool operator !=(const IPAddr& addr1, const IPAddr& addr2) - { - return ! (addr1 == addr2); - } - -bool operator <(const IPAddr& addr1, const IPAddr& addr2) - { - return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0; - } - IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length) : prefix(in4), length(96 + length) { @@ -304,61 +125,3 @@ IPPrefix::IPPrefix(const std::string& s, uint8_t length) reporter->InternalError("Bad string IPPrefix length : %d", length); prefix.Mask(this->length); } - -IPPrefix::IPPrefix(const IPPrefix& other) - : prefix(other.prefix), length(other.length) - { - } - -IPPrefix::~IPPrefix() - { - } - -const IPAddr& IPPrefix::Prefix() const - { - return prefix; - } - -uint8_t IPPrefix::Length() const - { - return prefix.family() == IPAddr::IPv4 ? length - 96 : length; - } - -uint8_t IPPrefix::LengthIPv6() const - { - return length; - } - -IPPrefix& IPPrefix::operator =(const IPPrefix& other) - { - // No self-assignment check here because it's correct without it and - // makes the common case faster. - prefix = other.Prefix(); - length = other.Length(); - return *this; - } - -IPPrefix::operator std::string() const - { - char l[16]; - if ( prefix.family() == IPAddr::IPv4 ) - modp_uitoa10(length - 96, l); - else - modp_uitoa10(length, l); - return std::string(prefix).append("/").append(l); - } - -bool operator ==(const IPPrefix& net1, const IPPrefix& net2) - { - return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length(); - } - -bool operator <(const IPPrefix& net1, const IPPrefix& net2) - { - if ( net1.Prefix() < net2.Prefix() ) - return true; - else if ( net1.Prefix() == net2.Prefix() ) - return net1.Length() < net2.Length(); - else - return false; - } diff --git a/src/IPAddr.h b/src/IPAddr.h index d59e853b1e..dbcad95d75 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -3,6 +3,7 @@ #define IPADDR_H #include +#include #include #include "BroString.h" @@ -21,29 +22,42 @@ public: enum ByteOrder { Host, Network }; /// Constructs the unspecified IPv6 address (all 128 bits zeroed). - IPAddr(); + IPAddr() + { + memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + } /// Constructs an address instance from an IPv4 address. /// /// @param in6 The IPv6 address. - IPAddr(const in4_addr& in4); + IPAddr(const in4_addr& in4) + { + memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr)); + } /// Constructs an address instance from an IPv6 address. /// /// @param in6 The IPv6 address. - IPAddr(const in6_addr& in6); + IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { } /// Constructs an address instance from a string representation. /// /// @param s String containing an IP address as either a dotted IPv4 /// address or a hex IPv6 address. - IPAddr(const std::string& s); + IPAddr(const std::string& s) + { + Init(s); + } /// Constructs an address instance from a string representation. /// /// @param s String containing an IP address as either a dotted IPv4 /// address or a hex IPv6 address. - IPAddr(const BroString& s); + IPAddr(const BroString& s) + { + Init(s.CheckString()); + } /// Constructs an address instance from a raw byte representation. /// @@ -55,25 +69,81 @@ public: /// /// @param order Indicates whether the raw representation pointed to /// by \a bytes is stored in network or host order. - IPAddr(Family family, const uint32_t* bytes, ByteOrder order); + IPAddr(Family family, const uint32_t* bytes, ByteOrder order) + { + if ( family == IPv4 ) + { + memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + memcpy(&in6.s6_addr[12], bytes, sizeof(uint32_t)); + if ( order == Host ) + { + uint32_t* p = (uint32_t*) &in6.s6_addr[12]; + *p = htonl(*p); + } + } + else + { + memcpy(in6.s6_addr, bytes, sizeof(in6.s6_addr)); + if ( order == Host ) + { + for ( unsigned int i = 0; i < 4; ++ i) + { + uint32_t* p = (uint32_t*) &in6.s6_addr[i*4]; + *p = htonl(*p); + } + } + } + } /// Copy constructor. - IPAddr(const IPAddr& other); + IPAddr(const IPAddr& other) : in6(other.in6) { }; /// Destructor. - ~IPAddr(); + ~IPAddr() { }; /// Returns the address' family. - Family family() const; + Family family() const + { + if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 ) + return IPv4; + else + return IPv6; + } /// Returns true if the address represents a loopback device. - bool IsLoopback() const; + bool IsLoopback() const + { + if ( family() == IPv4 ) + return in6.s6_addr[12] == 127; + else + return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) + && (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0) + && (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) + && (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) + && (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0) + && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) + && (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0) + && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); + } /// Returns true if the address represents a multicast address. - bool IsMulticast() const; + bool IsMulticast() const + { + if ( family() == IPv4 ) + return in6.s6_addr[12] == 224; + else + return in6.s6_addr[0] == 0xff; + } /// Returns true if the address represents a broadcast address. - bool IsBroadcast() const; + bool IsBroadcast() const + { + if ( family() == IPv4 ) + return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) + && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); + else + return false; + } /// Retrieves the raw byte representation of the address. /// @@ -85,8 +155,33 @@ public: /// /// @return The number of 32-bit words the raw representation uses. This /// will be 1 for an IPv4 address and 4 for an IPv6 address. - int GetBytes(uint32_t** bytes); - int GetBytes(const uint32_t** bytes) const; + int GetBytes(uint32_t** bytes) + { + if ( family() == IPv4 ) + { + *bytes = (uint32_t*) &in6.s6_addr[12]; + return 1; + } + else + { + *bytes = (uint32_t*) in6.s6_addr; + return 4; + } + } + + int GetBytes(const uint32_t** bytes) const + { + if ( family() == IPv4 ) + { + *bytes = (uint32_t*) &in6.s6_addr[12]; + return 1; + } + else + { + *bytes = (uint32_t*) in6.s6_addr; + return 4; + } + } /// Retrieves a copy of the IPv6 raw byte representation of the address. /// If the internal address is IPv4, then the copied bytes use the @@ -94,7 +189,10 @@ public: /// /// @param bytes The pointer to a memory location in which the /// raw bytes of the address are to be copied in network byte-order. - void CopyIPv6(uint32_t* bytes) const; + void CopyIPv6(uint32_t* bytes) const + { + memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr)); + } /// Masks out lower bits of the address. /// @@ -116,21 +214,55 @@ public: void ReverseMask(int top_bits_to_chop); /// Assignment operator. - IPAddr& operator=(const IPAddr& other); + IPAddr& operator=(const IPAddr& other) + { + // No self-assignment check here because it's correct without it and + // makes the common case faster. + in6 = other.in6; + return *this; + } /// Returns a string representation of the address. IPv4 addresses /// will be returned in dotted representation, IPv6 addresses in /// compressed hex. - operator std::string() const; + operator std::string() const + { + if ( family() == IPv4 ) + { + char s[INET_ADDRSTRLEN]; + if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) + return " Date: Thu, 9 Feb 2012 12:55:55 -0600 Subject: [PATCH 14/49] Change HashKey threshold for using H3 to 36 bytes. This is enough to accommodate using H3 instead of HMAC/MD5 for IPv6 Conn::Key's and performs better since a hash happens for every packet. --- src/Hash.h | 2 +- .../local.log | 48 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Hash.h b/src/Hash.h index 3a1b42084c..00db53d075 100644 --- a/src/Hash.h +++ b/src/Hash.h @@ -7,7 +7,7 @@ #include "BroString.h" -#define UHASH_KEY_SIZE 32 +#define UHASH_KEY_SIZE 36 typedef uint64 hash_t; diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log index 340b164f2e..291909b80a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.path-func-column-demote/local.log @@ -5,33 +5,33 @@ #path local #fields ts id.orig_h #types time addr +1300475168.855330 141.142.220.118 +1300475168.652003 141.142.220.118 +1300475168.895267 141.142.220.118 +1300475168.855305 141.142.220.118 +1300475168.859163 141.142.220.118 +1300475168.892913 141.142.220.118 1300475168.724007 141.142.220.118 1300475168.892936 141.142.220.118 -1300475168.895267 141.142.220.118 -1300475168.892913 141.142.220.118 -1300475168.652003 141.142.220.118 -1300475168.855305 141.142.220.118 -1300475168.855330 141.142.220.118 -1300475168.859163 141.142.220.118 1300475168.902635 141.142.220.118 -1300475168.894422 141.142.220.118 -1300475168.893988 141.142.220.118 -1300475168.901749 141.142.220.118 -1300475168.853899 141.142.220.118 -1300475168.854837 141.142.220.118 -1300475168.857956 141.142.220.118 -1300475168.858713 141.142.220.118 -1300475171.677081 141.142.220.226 -1300475168.854378 141.142.220.118 -1300475173.153679 141.142.220.238 -1300475169.899438 141.142.220.44 -1300475168.892037 141.142.220.118 -1300475168.892414 141.142.220.118 -1300475168.902195 141.142.220.118 1300475168.891644 141.142.220.118 -1300475168.894787 141.142.220.118 -1300475167.099816 141.142.220.50 1300475170.862384 141.142.220.226 -1300475167.096535 141.142.220.202 -1300475168.858306 141.142.220.118 +1300475168.853899 141.142.220.118 +1300475168.854378 141.142.220.118 +1300475168.857956 141.142.220.118 1300475173.117362 141.142.220.226 +1300475168.858713 141.142.220.118 +1300475167.096535 141.142.220.202 +1300475167.099816 141.142.220.50 +1300475168.892037 141.142.220.118 +1300475168.893988 141.142.220.118 +1300475168.854837 141.142.220.118 +1300475169.899438 141.142.220.44 +1300475168.858306 141.142.220.118 +1300475168.894422 141.142.220.118 +1300475173.153679 141.142.220.238 +1300475168.892414 141.142.220.118 +1300475171.677081 141.142.220.226 +1300475168.902195 141.142.220.118 +1300475168.894787 141.142.220.118 +1300475168.901749 141.142.220.118 From 086f747bc14a9fbfdbb68e645287a9303b42c4fe Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 9 Feb 2012 15:32:57 -0600 Subject: [PATCH 15/49] Add counts_to_addr and addr_to_counts conversion BIFs. --- src/bro.bif | 50 +++++++++++++++++++ .../bifs.addr_count_conversion/output | 4 ++ testing/btest/bifs/addr_count_conversion.bro | 11 ++++ 3 files changed, 65 insertions(+) create mode 100644 testing/btest/Baseline/bifs.addr_count_conversion/output create mode 100644 testing/btest/bifs/addr_count_conversion.bro diff --git a/src/bro.bif b/src/bro.bif index 6a0b935a78..00d77e510d 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2070,6 +2070,56 @@ function is_v6_addr%(a: addr%): bool # # =========================================================================== +## Converts a :bro:type:`addr` to a :bro:type:`index_vec`. +## +## a: The address to convert into a vector of counts. +## +## Returns: A vector containing the host-order address representation, +## four elements in size for IPv6 addresses, or one element for IPv4. +## +## .. bro:see:: counts_to_addr +function addr_to_counts%(a: addr%): index_vec + %{ + VectorVal* rval = new VectorVal(new VectorType(base_type(TYPE_COUNT))); + const uint32* bytes; + int len = a->AsAddr()->GetBytes(&bytes); + + for ( int i = 0; i < len; ++i ) + rval->Assign(i, new Val(ntohl(bytes[i]), TYPE_COUNT), 0); + + return rval; + %} + +## Converts a :bro:type:`index_vec` to a :bro:type:`addr`. +## +## v: The vector containing host-order address IP address representation, +## one element for IPv4 addresses, four elements for IPv6 addresses. +## +## Returns: An IP address. +## +## .. bro:see:: addr_to_counts +function counts_to_addr%(v: index_vec%): addr + %{ + if ( v->AsVector()->size() == 1 ) + { + return new AddrVal(htonl((*v->AsVector())[0]->AsCount())); + } + else if ( v->AsVector()->size() == 4 ) + { + uint32 bytes[4]; + for ( int i = 0; i < 4; ++i ) + bytes[i] = htonl((*v->AsVector())[i]->AsCount()); + return new AddrVal(bytes); + } + else + { + builtin_error("invalid vector size", @ARG@[0]); + uint32 bytes[4]; + memset(bytes, 0, sizeof(bytes)); + return new AddrVal(bytes); + } + %} + ## Converts a :bro:type:`string` to a :bro:type:`int`. ## ## str: The :bro:type:`string` to convert. diff --git a/testing/btest/Baseline/bifs.addr_count_conversion/output b/testing/btest/Baseline/bifs.addr_count_conversion/output new file mode 100644 index 0000000000..08a74512d3 --- /dev/null +++ b/testing/btest/Baseline/bifs.addr_count_conversion/output @@ -0,0 +1,4 @@ +[536939960, 2242052096, 35374, 57701172] +2001:db8:85a3::8a2e:370:7334 +[16909060] +1.2.3.4 diff --git a/testing/btest/bifs/addr_count_conversion.bro b/testing/btest/bifs/addr_count_conversion.bro new file mode 100644 index 0000000000..2559d39f27 --- /dev/null +++ b/testing/btest/bifs/addr_count_conversion.bro @@ -0,0 +1,11 @@ +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +global v: index_vec; + +v = addr_to_counts(2001:0db8:85a3:0000:0000:8a2e:0370:7334); +print v; +print counts_to_addr(v); +v = addr_to_counts(1.2.3.4); +print v; +print counts_to_addr(v); From 42d6440bb26e331ee3007a6ef189287644ed996a Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Thu, 9 Feb 2012 18:34:41 -0600 Subject: [PATCH 16/49] Fix parsing of FTP EPRT command and EPSV response --- src/bro.bif | 61 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/src/bro.bif b/src/bro.bif index 00d77e510d..2a0cc914d1 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2532,7 +2532,7 @@ static Val* parse_eftp(const char* line) RecordVal* r = new RecordVal(ftp_port); int net_proto = 0; // currently not used - uint32 addr = 0; + IPAddr addr = IPAddr(); // unspecified IPv6 address (all 128 bits zero) int port = 0; int good = 0; @@ -2542,33 +2542,50 @@ static Val* parse_eftp(const char* line) ++line; char delimiter = *line; - good = 1; char* next_delim; - ++line; // cut off delimiter - net_proto = strtol(line, &next_delim, 10); // currently ignored - if ( *next_delim != delimiter ) - good = 0; - - line = next_delim + 1; - if ( *line != delimiter ) // default of 0 is ok + if ( *line ) { - string s(line); - IPAddr tmp(s); - uint32* bytes; - tmp.GetBytes(&bytes); - addr = *bytes; - if ( addr == 0 ) + good = 1; + ++line; // skip delimiter + + net_proto = strtol(line, &next_delim, 10); + if ( *next_delim != delimiter ) good = 0; + + line = next_delim; + if ( *line ) + ++line; + + if ( *line && *line != delimiter ) + { + const char* nptr = strchr(line, delimiter); + if ( nptr == NULL ) + { + nptr = line + strlen(line); + good = 0; + } + + string s(line, nptr-line); // extract IP address + IPAddr tmp(s); + // on error, "tmp" will have all 128 bits zero + if ( tmp == addr ) + good = 0; + + addr = tmp; + } + + line = strchr(line, delimiter); + if ( line != NULL ) + { + ++line; // now the port + port = strtol(line, &next_delim, 10); + if ( *next_delim != delimiter ) + good = 0; + } + } - // FIXME: check for garbage between IP and delimiter. - line = strchr(line, delimiter); - - ++line; // now the port - port = strtol(line, &next_delim, 10); - if ( *next_delim != delimiter ) - good = 0; } r->Assign(0, new AddrVal(addr)); From c0f05f57a756da14a342af815772885606571e67 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Thu, 9 Feb 2012 18:50:21 -0600 Subject: [PATCH 17/49] Fix a minor typo in documentation --- src/bro.bif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bro.bif b/src/bro.bif index 00d77e510d..e5f5a6d6c3 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2092,7 +2092,7 @@ function addr_to_counts%(a: addr%): index_vec ## Converts a :bro:type:`index_vec` to a :bro:type:`addr`. ## -## v: The vector containing host-order address IP address representation, +## v: The vector containing host-order IP address representation, ## one element for IPv4 addresses, four elements for IPv6 addresses. ## ## Returns: An IP address. From 74899e29febcb8f76561ed12b5b5dfaa44c047fc Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 10 Feb 2012 16:55:15 -0600 Subject: [PATCH 18/49] Update FTP EPSV response processing for IPv6 --- scripts/base/protocols/ftp/main.bro | 2 +- src/bro.bif | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index 9e16804a32..e9783e4df7 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -270,7 +270,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior { c$ftp$passive=T; - if ( code == 229 && data$h == 0.0.0.0 ) + if ( code == 229 && data$h == :: ) data$h = id$resp_h; ftp_data_expected[data$h, data$p] = c$ftp; diff --git a/src/bro.bif b/src/bro.bif index 2a0cc914d1..54038f330d 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2613,7 +2613,7 @@ function parse_ftp_port%(s: string%): ftp_port ## The format is ``EPRT``, ## where ```` is a delimiter in the ASCII range 33-126 (usually ``|``). ## -## s: The string of the FTP PORT command, e.g., ``"10,0,0,1,4,31"``. +## s: The string of the FTP EPRT command, e.g., ``"|1|10.0.0.1|1055|"``. ## ## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` ## @@ -2653,7 +2653,7 @@ function parse_ftp_pasv%(str: string%): ftp_port ## The format is `` ()``, where ```` is a ## delimiter in the ASCII range 33-126 (usually ``|``). ## -## str: The string containing the result of the FTP PASV command. +## str: The string containing the result of the FTP EPSV command. ## ## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` ## From 0f207c243c9e4ebfcca227b71add3ac2e8af1cc4 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 13 Feb 2012 15:57:59 -0600 Subject: [PATCH 19/49] Port DNS_Mgr to use new IPAddr class, enable lookups on IPv6 addrs. Host lookups still need to be changed to also do AAAA queries. --- src/DNS_Mgr.cc | 93 ++++++++++++++++++++++---------------------------- src/DNS_Mgr.h | 16 ++++----- src/Hash.cc | 10 ++++++ src/Hash.h | 2 ++ src/bro.bif | 20 +---------- src/nb_dns.c | 4 +-- 6 files changed, 61 insertions(+), 84 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index e89dbf7d2f..2491ff39ff 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -46,13 +46,13 @@ extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); class DNS_Mgr_Request { public: - DNS_Mgr_Request(const char* h) { host = copy_string(h); addr = 0; } - DNS_Mgr_Request(uint32 a) { addr = a; host = 0; } + DNS_Mgr_Request(const char* h) { host = copy_string(h); } + DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 0; } ~DNS_Mgr_Request() { delete [] host; } // Returns nil if this was an address request. const char* ReqHost() const { return host; } - uint32 ReqAddr() const { return addr; } + const IPAddr& ReqAddr() const { return addr; } int MakeRequest(nb_dns_info* nb_dns); int RequestPending() const { return request_pending; } @@ -61,7 +61,7 @@ public: protected: char* host; // if non-nil, this is a host request - uint32 addr; + IPAddr addr; uint32 ttl; int request_pending; }; @@ -77,13 +77,18 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) if ( host ) return nb_dns_host_request(nb_dns, host, (void*) this, err) >= 0; else - return nb_dns_addr_request(nb_dns, addr, (void*) this, err) >= 0; + { + const uint32* bytes; + int len = addr.GetBytes(&bytes); + return nb_dns_addr_request2(nb_dns, (char*) bytes, + len == 1 ? AF_INET : AF_INET6, (void*) this, err) >= 0; + } } class DNS_Mapping { public: DNS_Mapping(const char* host, struct hostent* h, uint32 ttl); - DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl); + DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32 ttl); DNS_Mapping(FILE* f); int NoMapping() const { return no_mapping; } @@ -93,11 +98,10 @@ public: // Returns nil if this was an address request. const char* ReqHost() const { return req_host; } - uint32 ReqAddr() const { return req_addr; } + const IPAddr& ReqAddr() const { return req_addr; } const char* ReqStr() const { - return req_host ? req_host : - string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(); + return req_host ? req_host : string(req_addr).c_str(); } ListVal* Addrs(); @@ -124,7 +128,7 @@ protected: int init_failed; char* req_host; - uint32 req_addr; + IPAddr req_addr; uint32 req_ttl; int num_names; @@ -132,7 +136,7 @@ protected: StringVal* host_val; int num_addrs; - uint32* addrs; + IPAddr* addrs; ListVal* addrs_val; int failed; @@ -157,14 +161,13 @@ DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32 ttl) { Init(h); req_host = copy_string(host); - req_addr = 0; req_ttl = ttl; if ( names && ! names[0] ) names[0] = copy_string(host); } -DNS_Mapping::DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl) +DNS_Mapping::DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32 ttl) { Init(h); req_addr = addr; @@ -178,7 +181,6 @@ DNS_Mapping::DNS_Mapping(FILE* f) init_failed = 1; req_host = 0; - req_addr = 0; char buf[512]; @@ -200,10 +202,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) else { string s(req_buf); - IPAddr addr(s); - const uint32* bytes; - addr.GetBytes(&bytes); - req_addr = *bytes; //FIXME: IPv6 support + req_addr = IPAddr(s); } num_names = 1; @@ -212,7 +211,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) if ( num_addrs > 0 ) { - addrs = new uint32[num_addrs]; + addrs = new IPAddr[num_addrs]; for ( int i = 0; i < num_addrs; ++i ) { @@ -227,10 +226,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) *newline = '\0'; string s(buf); - IPAddr addr(s); - const uint32* bytes; - addr.GetBytes(&bytes); - addrs[i] = *bytes; //FIXME IPv6 support + addrs[i] = IPAddr(s); } } else @@ -293,14 +289,6 @@ StringVal* DNS_Mapping::Host() return host_val; } -// Converts an array of 4 bytes in network order to the corresponding -// 32-bit network long. -static uint32 raw_bytes_to_addr(const unsigned char b[4]) - { - uint32 l = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; - return uint32(htonl(l)); - } - void DNS_Mapping::Init(struct hostent* h) { no_mapping = 0; @@ -309,7 +297,7 @@ void DNS_Mapping::Init(struct hostent* h) host_val = 0; addrs_val = 0; - if ( ! h || h->h_addrtype != AF_INET || h->h_length != 4 ) + if ( ! h ) { Clear(); return; @@ -324,10 +312,14 @@ void DNS_Mapping::Init(struct hostent* h) if ( num_addrs > 0 ) { - addrs = new uint32[num_addrs]; + addrs = new IPAddr[num_addrs]; for ( int i = 0; i < num_addrs; ++i ) - addrs[i] = raw_bytes_to_addr( - (unsigned char*)h->h_addr_list[i]); + if ( h->h_addrtype == AF_INET ) + addrs[i] = IPAddr(IPAddr::IPv4, (uint32*)h->h_addr_list[i], + IPAddr::Network); + else if ( h->h_addrtype == AF_INET6 ) + addrs[i] = IPAddr(IPAddr::IPv6, (uint32*)h->h_addr_list[i], + IPAddr::Network); } else addrs = 0; @@ -349,14 +341,12 @@ void DNS_Mapping::Clear() void DNS_Mapping::Save(FILE* f) const { fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0, - req_host ? req_host : - string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(), + req_host ? req_host : string(req_addr).c_str(), failed, (names && names[0]) ? names[0] : "*", num_addrs); for ( int i = 0; i < num_addrs; ++i ) - fprintf(f, "%s\n", - string(IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)).c_str()); + fprintf(f, "%s\n", string(addrs[i]).c_str()); } @@ -490,14 +480,14 @@ TableVal* DNS_Mgr::LookupHost(const char* name) } } -Val* DNS_Mgr::LookupAddr(uint32 addr) +Val* DNS_Mgr::LookupAddr(const IPAddr& addr) { if ( ! did_init ) Init(); if ( mode != DNS_PRIME ) { - HashKey h(&addr, 1); + HashKey h(addr); DNS_Mapping* d = addr_mappings.Lookup(&h); if ( d ) @@ -506,7 +496,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) return d->Host(); else { - string s = IPAddr(IPAddr::IPv4, &addr, IPAddr::Network); + string s(addr); reporter->Warning("can't resolve IP address: %s", s.c_str()); return new StringVal(s.c_str()); } @@ -521,7 +511,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", - string(IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)).c_str()); + string(addr).c_str()); return 0; case DNS_DEFAULT: @@ -710,14 +700,12 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) else { new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl); - uint32 tmp_addr = dr->ReqAddr(); - HashKey k(&tmp_addr, 1); + HashKey k(dr->ReqAddr()); prev_dm = addr_mappings.Insert(&k, new_dm); if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) { - uint32 tmp_addr = dr->ReqAddr(); - HashKey k2(&tmp_addr, 1); + HashKey k2(dr->ReqAddr()); (void) addr_mappings.Insert(&k2, prev_dm); ++keep_prev; } @@ -829,8 +817,7 @@ void DNS_Mgr::LoadCache(FILE* f) host_mappings.Insert(m->ReqHost(), m); else { - uint32 tmp_addr = m->ReqAddr(); - HashKey h(&tmp_addr, 1); + HashKey h(m->ReqAddr()); addr_mappings.Insert(&h, m); } } @@ -851,9 +838,9 @@ void DNS_Mgr::Save(FILE* f, PDict(DNS_Mapping)& m) dm->Save(f); } -const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr) +const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) { - HashKey h(&addr, 1); + HashKey h(addr); DNS_Mapping* d = dns_mgr->addr_mappings.Lookup(&h); if ( ! d ) @@ -889,7 +876,7 @@ TableVal* DNS_Mgr::LookupNameInCache(string name) return d->AddrsSet(); } -void DNS_Mgr::AsyncLookupAddr(dns_mgr_addr_type host, LookupCallback* callback) +void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) { if ( ! did_init ) Init(); @@ -999,7 +986,7 @@ double DNS_Mgr::NextTimestamp(double* network_time) return asyncs_timeouts.size() ? timer_mgr->Time() : -1.0; } -void DNS_Mgr::CheckAsyncAddrRequest(dns_mgr_addr_type addr, bool timeout) +void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) { // Note that this code is a mirror of that for CheckAsyncHostRequest. diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 91bcad4084..fb55b991cb 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -40,10 +40,6 @@ enum DNS_MgrMode { // Number of seconds we'll wait for a reply. #define DNS_TIMEOUT 5 -// ### For now, we don't support IPv6 lookups. When we do, this -// should become addr_type. -typedef uint32 dns_mgr_addr_type; - class DNS_Mgr : public IOSource { public: DNS_Mgr(DNS_MgrMode mode); @@ -56,7 +52,7 @@ public: // a set of addr. TableVal* LookupHost(const char* host); - Val* LookupAddr(uint32 addr); + Val* LookupAddr(const IPAddr& addr); // Define the directory where to store the data. void SetDir(const char* arg_dir) { dir = copy_string(arg_dir); } @@ -65,7 +61,7 @@ public: void Resolve(); int Save(); - const char* LookupAddrInCache(dns_mgr_addr_type addr); + const char* LookupAddrInCache(const IPAddr& addr); TableVal* LookupNameInCache(string name); // Support for async lookups. @@ -79,7 +75,7 @@ public: virtual void Timeout() = 0; }; - void AsyncLookupAddr(dns_mgr_addr_type host, LookupCallback* callback); + void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback); void AsyncLookupName(string name, LookupCallback* callback); struct Stats { @@ -121,7 +117,7 @@ protected: // Finish the request if we have a result. If not, time it out if // requested. - void CheckAsyncAddrRequest(dns_mgr_addr_type addr, bool timeout); + void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout); void CheckAsyncHostRequest(const char* host, bool timeout); // Process outstanding requests. @@ -164,7 +160,7 @@ protected: struct AsyncRequest { double time; - dns_mgr_addr_type host; + IPAddr host; string name; CallbackList callbacks; @@ -205,7 +201,7 @@ protected: }; - typedef map AsyncRequestAddrMap; + typedef map AsyncRequestAddrMap; AsyncRequestAddrMap asyncs_addrs; typedef map AsyncRequestNameMap; diff --git a/src/Hash.cc b/src/Hash.cc index 7873e398c3..c8e68da429 100644 --- a/src/Hash.cc +++ b/src/Hash.cc @@ -103,6 +103,16 @@ HashKey::HashKey(const BroString* s) is_our_dynamic = 0; } +HashKey::HashKey(const IPAddr& addr) + { + const uint32* bytes; + int len = addr.GetBytes(&bytes); + size = len * sizeof(uint32); + key = CopyKey(bytes, size); + is_our_dynamic = 1; + hash = HashBytes(key, size); + } + HashKey::HashKey(int copy_key, void* arg_key, int arg_size) { size = arg_size; diff --git a/src/Hash.h b/src/Hash.h index 00db53d075..2d24a05b79 100644 --- a/src/Hash.h +++ b/src/Hash.h @@ -6,6 +6,7 @@ #include #include "BroString.h" +#include "IPAddr.h" #define UHASH_KEY_SIZE 36 @@ -28,6 +29,7 @@ public: HashKey(const void* p); HashKey(const char* s); HashKey(const BroString* s); + HashKey(const IPAddr& addr); ~HashKey() { if ( is_our_dynamic ) diff --git a/src/bro.bif b/src/bro.bif index e5f5a6d6c3..bcd50edaf9 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -3432,25 +3432,7 @@ function lookup_addr%(host: addr%) : string frame->SetDelayed(); trigger->Hold(); - if ( host->AsAddr()->family() != IPAddr::IPv4 ) - { - // FIXME: This is a temporary work-around until we get this - // fixed. We warn the user once, and always trigger a timeout. - // Ticket #355 records the problem. - static bool warned = false; - if ( ! warned ) - { - reporter->Warning("lookup_addr() only supports IPv4 addresses currently"); - warned = true; - } - - trigger->Timeout(); - return 0; - } - - const uint32* bytes; - host->AsAddr()->GetBytes(&bytes); - dns_mgr->AsyncLookupAddr(*bytes, + dns_mgr->AsyncLookupAddr(*host->AsAddr(), new LookupHostCallback(trigger, frame->GetCall(), true)); return 0; %} diff --git a/src/nb_dns.c b/src/nb_dns.c index 475ba3b8b0..d3b3c5c4de 100644 --- a/src/nb_dns.c +++ b/src/nb_dns.c @@ -186,7 +186,7 @@ _nb_dns_cmpsockaddr(register struct sockaddr *sa1, #endif static const char serr[] = "answer from wrong nameserver (%d)"; - if (sa1->sa_family != sa1->sa_family) { + if (sa1->sa_family != sa2->sa_family) { snprintf(errstr, NB_DNS_ERRSIZE, serr, 1); return (-1); } @@ -381,7 +381,7 @@ nb_dns_addr_request2(register struct nb_dns_info *nd, char *addrp, size -= i; cp += i; } - snprintf(cp, size, "ip6.int"); + snprintf(cp, size, "ip6.arpa"); break; #endif From 1f8b299aaf37c5d03994c8ed9f6f7acaaba9a98b Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 14 Feb 2012 10:12:09 -0800 Subject: [PATCH 20/49] Shortening file names a bit. --- src/Attr.cc | 2 +- src/CMakeLists.txt | 2 +- src/RemoteSerializer.cc | 2 +- src/logging/Manager.cc | 4 ++-- src/logging/WriterBackend.cc | 2 +- src/logging/WriterFrontend.cc | 2 +- src/logging/writers/Ascii.cc | 4 ++-- src/threading/{SerializationTypes.cc => SerialTypes.cc} | 2 +- src/threading/{SerializationTypes.h => SerialTypes.h} | 0 9 files changed, 10 insertions(+), 10 deletions(-) rename src/threading/{SerializationTypes.cc => SerialTypes.cc} (99%) rename src/threading/{SerializationTypes.h => SerialTypes.h} (100%) diff --git a/src/Attr.cc b/src/Attr.cc index 40c6c1a75c..82d9c9ddc7 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -5,7 +5,7 @@ #include "Attr.h" #include "Expr.h" #include "Serializer.h" -#include "threading/SerializationTypes.h" +#include "threading/SerialTypes.h" const char* attr_name(attr_tag t) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a3cc4babf..67d82c577a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -411,7 +411,7 @@ set(bro_SRCS threading/BasicThread.cc threading/Manager.cc threading/MsgThread.cc - threading/SerializationTypes.cc + threading/SerialTypes.cc logging/Manager.cc logging/WriterBackend.cc diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index ba2598c018..948dfddaff 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -184,7 +184,7 @@ #include "File.h" #include "Conn.h" #include "Reporter.h" -#include "threading/SerializationTypes.h" +#include "threading/SerialTypes.h" #include "logging/Manager.h" extern "C" { diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 5f9f1c4222..6078a1e566 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -7,6 +7,8 @@ #include "../NetVar.h" #include "../Net.h" +#include "threading/SerialTypes.h" + #include "Manager.h" #include "WriterFrontend.h" #include "WriterBackend.h" @@ -14,8 +16,6 @@ #include "writers/Ascii.h" #include "writers/None.h" -#include "threading/SerializationTypes.h" - using namespace logging; using threading::Value; using threading::Field; diff --git a/src/logging/WriterBackend.cc b/src/logging/WriterBackend.cc index 0ffedf073c..f4e48ebaef 100644 --- a/src/logging/WriterBackend.cc +++ b/src/logging/WriterBackend.cc @@ -1,10 +1,10 @@ // See the file "COPYING" in the main distribution directory for copyright. #include "util.h" +#include "threading/SerialTypes.h" #include "WriterBackend.h" #include "WriterFrontend.h" -#include "../threading/SerializationTypes.h" // Messages sent from backend to frontend (i.e., "OutputMessages"). diff --git a/src/logging/WriterFrontend.cc b/src/logging/WriterFrontend.cc index b0e780f27d..02f1a188d8 100644 --- a/src/logging/WriterFrontend.cc +++ b/src/logging/WriterFrontend.cc @@ -1,9 +1,9 @@ #include "Net.h" +#include "threading/SerialTypes.h" #include "WriterFrontend.h" #include "WriterBackend.h" -#include "../threading/SerializationTypes.h" using threading::Value; using threading::Field; diff --git a/src/logging/writers/Ascii.cc b/src/logging/writers/Ascii.cc index c974877175..0a101feb79 100644 --- a/src/logging/writers/Ascii.cc +++ b/src/logging/writers/Ascii.cc @@ -3,10 +3,10 @@ #include #include -#include "../../NetVar.h" +#include "NetVar.h" +#include "threading/SerialTypes.h" #include "Ascii.h" -#include "../../threading/SerializationTypes.h" using namespace logging; using namespace writer; diff --git a/src/threading/SerializationTypes.cc b/src/threading/SerialTypes.cc similarity index 99% rename from src/threading/SerializationTypes.cc rename to src/threading/SerialTypes.cc index f74de6ce57..f35d1fc6b0 100644 --- a/src/threading/SerializationTypes.cc +++ b/src/threading/SerialTypes.cc @@ -1,7 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. -#include "SerializationTypes.h" +#include "SerialTypes.h" #include "../RemoteSerializer.h" diff --git a/src/threading/SerializationTypes.h b/src/threading/SerialTypes.h similarity index 100% rename from src/threading/SerializationTypes.h rename to src/threading/SerialTypes.h From 2ef18e98a2b405285f3fc91cf12b8d58599225aa Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 15 Feb 2012 11:02:18 -0600 Subject: [PATCH 21/49] DNS name lookups performed by Bro now also query AAAA records. DNS_Mgr handles combining the results of the A and AAAA queries for a given hostname such that at the scripting layer, the name resolution can yield a set with both IPv4 and IPv6 addresses. --- src/DNS_Mgr.cc | 166 +++++++++++++++++++++++++++++++++++++++---------- src/DNS_Mgr.h | 5 +- 2 files changed, 138 insertions(+), 33 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 2491ff39ff..06a337613b 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -46,8 +46,8 @@ extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); class DNS_Mgr_Request { public: - DNS_Mgr_Request(const char* h) { host = copy_string(h); } - DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 0; } + DNS_Mgr_Request(const char* h, int af) { host = copy_string(h); fam = af; } + DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 0; fam = 0; } ~DNS_Mgr_Request() { delete [] host; } // Returns nil if this was an address request. @@ -61,8 +61,8 @@ public: protected: char* host; // if non-nil, this is a host request + int fam; //address family query type for host requests IPAddr addr; - uint32 ttl; int request_pending; }; @@ -75,7 +75,7 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) char err[NB_DNS_ERRSIZE]; if ( host ) - return nb_dns_host_request(nb_dns, host, (void*) this, err) >= 0; + return nb_dns_host_request2(nb_dns, host, fam, (void*) this, err) >= 0; else { const uint32* bytes; @@ -116,7 +116,14 @@ public: int Valid() const { return ! failed; } bool Expired() const - { return current_time() > (creation_time + req_ttl); } + { + if ( req_host && num_addrs == 0) + return false; // nothing to expire + + return current_time() > (creation_time + req_ttl); + } + + int Type() const { return map_type; } protected: friend class DNS_Mgr; @@ -141,6 +148,7 @@ protected: int failed; double creation_time; + int map_type; }; void DNS_Mgr_mapping_delete_func(void* v) @@ -193,8 +201,9 @@ DNS_Mapping::DNS_Mapping(FILE* f) char req_buf[512+1], name_buf[512+1]; int is_req_host; - if ( sscanf(buf, "%lf %d %512s %d %512s %d", &creation_time, &is_req_host, - req_buf, &failed, name_buf, &num_addrs) != 6 ) + if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %"PRIu32, &creation_time, + &is_req_host, req_buf, &failed, name_buf, &map_type, &num_addrs, + &req_ttl) != 8 ) return; if ( is_req_host ) @@ -303,6 +312,7 @@ void DNS_Mapping::Init(struct hostent* h) return; } + map_type = h->h_addrtype; num_names = 1; // for now, just use official name names = new char*[num_names]; names[0] = h->h_name ? copy_string(h->h_name) : 0; @@ -335,15 +345,16 @@ void DNS_Mapping::Clear() host_val = 0; addrs_val = 0; no_mapping = 0; + map_type = 0; failed = 1; } void DNS_Mapping::Save(FILE* f) const { - fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0, + fprintf(f, "%.0f %d %s %d %s %d %d %"PRIu32"\n", creation_time, req_host != 0, req_host ? req_host : string(req_addr).c_str(), failed, (names && names[0]) ? names[0] : "*", - num_addrs); + map_type, num_addrs, req_ttl); for ( int i = 0; i < num_addrs; ++i ) fprintf(f, "%s\n", string(addrs[i]).c_str()); @@ -356,7 +367,6 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) mode = arg_mode; - host_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func); addr_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func); char err[NB_DNS_ERRSIZE]; @@ -445,24 +455,34 @@ TableVal* DNS_Mgr::LookupHost(const char* name) if ( mode != DNS_PRIME ) { - DNS_Mapping* d = host_mappings.Lookup(name); + HostMap::iterator it = host_mappings.find(name); - if ( d ) + if ( it != host_mappings.end() ) { - if ( d->Valid() ) - return d->Addrs()->ConvertToSet(); - else + DNS_Mapping* d4 = it->second.first; + DNS_Mapping* d6 = it->second.second; + + if ( (d4 && d4->Failed()) || (d6 && d6->Failed()) ) { reporter->Warning("no such host: %s", name); return empty_addr_set(); } + else if ( d4 && d6 ) + { + TableVal* tv4 = d4->AddrsSet(); + TableVal* tv6 = d6->AddrsSet(); + tv4->AddTo(tv6, false); + Unref(tv4); + return tv6; + } } } // Not found, or priming. switch ( mode ) { case DNS_PRIME: - requests.append(new DNS_Mgr_Request(name)); + requests.append(new DNS_Mgr_Request(name, AF_INET)); + requests.append(new DNS_Mgr_Request(name, AF_INET6)); return empty_addr_set(); case DNS_FORCE: @@ -470,7 +490,8 @@ TableVal* DNS_Mgr::LookupHost(const char* name) return 0; case DNS_DEFAULT: - requests.append(new DNS_Mgr_Request(name)); + requests.append(new DNS_Mgr_Request(name, AF_INET)); + requests.append(new DNS_Mgr_Request(name, AF_INET6)); Resolve(); return LookupHost(name); @@ -687,13 +708,39 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) if ( dr->ReqHost() ) { new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl); - prev_dm = host_mappings.Insert(dr->ReqHost(), new_dm); + + HostMap::iterator it = host_mappings.find(dr->ReqHost()); + if ( it == host_mappings.end() ) + { + host_mappings[dr->ReqHost()].first = + new_dm->Type() == AF_INET ? new_dm : 0; + host_mappings[dr->ReqHost()].second = + new_dm->Type() == AF_INET6 ? new_dm : 0; + prev_dm = 0; + } + else + { + prev_dm = 0; + if ( new_dm->Type() == AF_INET ) + { + prev_dm = it->second.first; + it->second.first = new_dm; + } + else + { + prev_dm = it->second.second; + it->second.second = new_dm; + } + } if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) { // Put previous, valid entry back - CompareMappings // will generate a corresponding warning. - (void) host_mappings.Insert(dr->ReqHost(), prev_dm); + if ( prev_dm->Type() == AF_INET ) + host_mappings[dr->ReqHost()].first = prev_dm; + else + host_mappings[dr->ReqHost()].second = prev_dm; ++keep_prev; } } @@ -814,7 +861,17 @@ void DNS_Mgr::LoadCache(FILE* f) for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) ) { if ( m->ReqHost() ) - host_mappings.Insert(m->ReqHost(), m); + { + if ( host_mappings.find(m->ReqHost()) == host_mappings.end() ) + { + host_mappings[m->ReqHost()].first = 0; + host_mappings[m->ReqHost()].second = 0; + } + if ( m->Type() == AF_INET ) + host_mappings[m->ReqHost()].first = m; + else + host_mappings[m->ReqHost()].second = m; + } else { HashKey h(m->ReqAddr()); @@ -838,6 +895,16 @@ void DNS_Mgr::Save(FILE* f, PDict(DNS_Mapping)& m) dm->Save(f); } +void DNS_Mgr::Save(FILE* f, const HostMap& m) + { + HostMap::const_iterator it; + for ( it = m.begin(); it != m.end(); ++it ) + { + if ( it->second.first ) it->second.first->Save(f); + if ( it->second.second ) it->second.second->Save(f); + } + } + const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) { HashKey h(addr); @@ -860,20 +927,29 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) TableVal* DNS_Mgr::LookupNameInCache(string name) { - DNS_Mapping* d = dns_mgr->host_mappings.Lookup(name.c_str()); - - if ( ! d || ! d->names ) + HostMap::iterator it = dns_mgr->host_mappings.find(name); + if ( it == dns_mgr->host_mappings.end() ) return 0; - if ( d->Expired() ) + DNS_Mapping* d4 = it->second.first; + DNS_Mapping* d6 = it->second.second; + + if ( ! d4 || ! d4->names || ! d6 || ! d6->names ) + return 0; + + if ( d4->Expired() || d6->Expired() ) { - HashKey h(name.c_str()); - dns_mgr->host_mappings.Remove(&h); - delete d; + dns_mgr->host_mappings.erase(it); + delete d4; + delete d6; return 0; } - return d->AddrsSet(); + TableVal* tv4 = d4->AddrsSet(); + TableVal* tv6 = d6->AddrsSet(); + tv4->AddTo(tv6, false); + Unref(tv4); + return tv6; } void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) @@ -955,10 +1031,14 @@ void DNS_Mgr::IssueAsyncRequests() ++num_requests; DNS_Mgr_Request* dr; + DNS_Mgr_Request* dr6 = 0; if ( req->IsAddrReq() ) dr = new DNS_Mgr_Request(req->host); else - dr = new DNS_Mgr_Request(req->name.c_str()); + { + dr = new DNS_Mgr_Request(req->name.c_str(), AF_INET); + dr6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6); + } if ( ! dr->MakeRequest(nb_dns) ) { @@ -968,6 +1048,14 @@ void DNS_Mgr::IssueAsyncRequests() continue; } + if ( dr6 && ! dr6->MakeRequest(nb_dns) ) + { + reporter->Warning("can't issue DNS request"); + ++failed; + req->Timeout(); + continue; + } + req->time = current_time(); asyncs_timeouts.push(req); @@ -1059,7 +1147,13 @@ void DNS_Mgr::Flush() { DoProcess(false); - host_mappings.Clear(); + HostMap::iterator it; + for ( it = host_mappings.begin(); it != host_mappings.end(); ++it ) + { + delete it->second.first; + delete it->second.second; + } + host_mappings.clear(); addr_mappings.Clear(); } @@ -1103,6 +1197,14 @@ void DNS_Mgr::DoProcess(bool flush) else if ( status > 0 ) { DNS_Mgr_Request* dr = (DNS_Mgr_Request*) r.cookie; + + bool do_host_timeout = true; + if ( dr->ReqHost() && + host_mappings.find(dr->ReqHost()) == host_mappings.end() ) + // don't timeout when this is the first result in an expected pair + // (one result each for A and AAAA queries) + do_host_timeout = false; + if ( dr->RequestPending() ) { AddResult(dr, &r); @@ -1112,7 +1214,7 @@ void DNS_Mgr::DoProcess(bool flush) if ( ! dr->ReqHost() ) CheckAsyncAddrRequest(dr->ReqAddr(), true); else - CheckAsyncHostRequest(dr->ReqHost(), true); + CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout); IssueAsyncRequests(); @@ -1163,7 +1265,7 @@ void DNS_Mgr::GetStats(Stats* stats) stats->successful = successful; stats->failed = failed; stats->pending = asyncs_pending; - stats->cached_hosts = host_mappings.Length(); + stats->cached_hosts = host_mappings.size(); stats->cached_addresses = addr_mappings.Length(); } diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index fb55b991cb..b437cda156 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "util.h" #include "BroList.h" @@ -106,6 +107,8 @@ protected: void LoadCache(FILE* f); void Save(FILE* f, PDict(DNS_Mapping)& m); + typedef map > HostMap; + void Save(FILE* f, const HostMap& m); // Selects on the fd to see if there is an answer available (timeout // is secs). Returns 0 on timeout, -1 on EINTR or other error, and 1 @@ -133,7 +136,7 @@ protected: PDict(ListVal) services; - PDict(DNS_Mapping) host_mappings; + HostMap host_mappings; PDict(DNS_Mapping) addr_mappings; DNS_mgr_request_list requests; From 7458ebf38599779380d3282430f481b86483c968 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 15 Feb 2012 13:07:08 -0800 Subject: [PATCH 22/49] Checkpoint after pass. --- CHANGES | 21 +- VERSION | 2 +- doc/scripts/builtins.rst | 28 +- .../base/frameworks/packet-filter/main.bro | 40 +- scripts/base/init-bare.bro | 4 +- .../policy/protocols/http/detect-webapps.bro | 2 +- src/Analyzer.h | 1 - src/Anon.cc | 2 +- src/Brofiler.cc | 2 +- src/CompHash.cc | 2 + src/Conn.cc | 22 +- src/DCE_RPC.cc | 1 + src/DCE_RPC.h | 4 +- src/DNS_Mgr.cc | 19 +- src/Desc.cc | 12 + src/Desc.h | 2 + src/Expr.cc | 14 +- src/ICMP.cc | 4 +- src/IPAddr.cc | 57 +- src/IPAddr.h | 505 ++++++++++-------- src/LogMgr.cc | 45 +- src/LogWriterAscii.cc | 4 +- src/PrefixTable.cc | 18 +- src/Reporter.cc | 19 - src/Reporter.h | 2 - src/RuleMatcher.cc | 8 +- src/SSH.cc | 7 +- src/SerializationFormat.cc | 32 ++ src/SerializationFormat.h | 4 + src/Serializer.cc | 4 +- src/Sessions.cc | 13 +- src/TCP_Endpoint.cc | 4 +- src/Val.cc | 117 +--- src/Val.h | 16 +- src/bro.bif | 81 +-- 35 files changed, 594 insertions(+), 524 deletions(-) diff --git a/CHANGES b/CHANGES index 51147f5306..9286a5409e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,14 +1,23 @@ + +2.0-57 | 2012-02-10 00:02:35 -0800 + + * Fix typos in the documentation. (Daniel Thayer) + + * Fix compiler warning about Brofiler ctor init list order. (Jon Siwek) + + * Fix missing optional field access in webapp signature_match handler. (Jon Siwek) + 2.0-41 | 2012-02-03 04:10:53 -0500 - * Updates to the Software framework to simplify the API. - (Bernhard Amann) + * Updates to the Software framework to simplify the API. (Bernhard + Amann) 2.0-40 | 2012-02-03 01:55:27 -0800 - * Fix typos in documentation. (Daniel Thayer) - - * Fix sorting of lines in Brofiler coverage.log. (Daniel Thayer) - + * Fix typos in documentation. (Daniel Thayer) + + * Fix sorting of lines in Brofiler coverage.log. (Daniel Thayer) + 2.0-38 | 2012-01-31 11:50:53 -0800 * Canonify sorting of lines in Brofiler coverage.log. (Daniel diff --git a/VERSION b/VERSION index 9d6521772a..8dd930b077 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-41 +2.0-57 diff --git a/doc/scripts/builtins.rst b/doc/scripts/builtins.rst index 37edb79904..5da551ed1f 100644 --- a/doc/scripts/builtins.rst +++ b/doc/scripts/builtins.rst @@ -22,7 +22,7 @@ The Bro scripting language supports the following built-in types. is a string of digits preceded by a ``+`` or ``-`` sign, e.g. ``-42`` or ``+5``. When using type inferencing use care so that the intended type is inferred, e.g. ``local size_difference = 0`` will - infer the :bro:type:`count` while ``local size_difference = +0`` + infer :bro:type:`count`, while ``local size_difference = +0`` will infer :bro:type:`int`. .. bro:type:: count @@ -32,7 +32,7 @@ The Bro scripting language supports the following built-in types. .. bro:type:: counter - An alias to :bro:type:`count` + An alias to :bro:type:`count`. .. TODO: is there anything special about this type? @@ -70,7 +70,7 @@ The Bro scripting language supports the following built-in types. A type used to hold character-string values which represent text. String constants are created by enclosing text in double quotes (") - and the backslash character (\) introduces escape sequences. + and the backslash character (\\) introduces escape sequences. Note that Bro represents strings internally as a count and vector of bytes rather than a NUL-terminated byte string (although string @@ -135,7 +135,7 @@ The Bro scripting language supports the following built-in types. type color: enum { Red, White, Blue, }; - The last comma is after ``Blue`` is optional. + The last comma after ``Blue`` is optional. .. bro:type:: timer @@ -150,8 +150,8 @@ The Bro scripting language supports the following built-in types. followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``. Ports can be compared for equality and also for ordering. When - comparing order across transport-level protocols, ``/unknown`` < - ``/tcp`` < ``/udp`` < ``icmp``, for example ``65535/tcp`` is smaller + comparing order across transport-level protocols, ``unknown`` < + ``tcp`` < ``udp`` < ``icmp``, for example ``65535/tcp`` is smaller than ``0/udp``. .. bro:type:: addr @@ -228,7 +228,7 @@ The Bro scripting language supports the following built-in types. global a: table[count] of table[addr, port] of string; - which declared a table indexed by :bro:type:`count` and yielding + which declares a table indexed by :bro:type:`count` and yielding another :bro:type:`table` which is indexed by an :bro:type:`addr` and :bro:type:`port` to yield a :bro:type:`string`. @@ -390,7 +390,7 @@ The Bro scripting language supports the following built-in types. :bro:attr:`&optional` or have a :bro:attr:`&default` attribute must be specified. - To test for existence of field that is :bro:attr:`&optional`, use the + To test for existence of a field that is :bro:attr:`&optional`, use the ``?$`` operator: .. code:: bro @@ -410,7 +410,7 @@ The Bro scripting language supports the following built-in types. print f, "hello, world"; close(f); - Writing to files like this for logging usually isn't recommend, for better + Writing to files like this for logging usually isn't recommended, for better logging support see :doc:`/logging`. .. bro:type:: func @@ -510,22 +510,22 @@ scripting language supports the following built-in attributes. .. bro:attr:: &optional - Allows record field to be missing. For example the type ``record { + Allows a record field to be missing. For example the type ``record { a: int, b: port &optional }`` could be instantiated both as singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``. .. bro:attr:: &default Uses a default value for a record field or container elements. For - example, ``table[int] of string &default="foo" }`` would create - table that returns The :bro:type:`string` ``"foo"`` for any + example, ``table[int] of string &default="foo" }`` would create a + table that returns the :bro:type:`string` ``"foo"`` for any non-existing index. .. bro:attr:: &redef Allows for redefinition of initial object values. This is typically used with constants, for example, ``const clever = T &redef;`` would - allow the constant to be redifined at some later point during script + allow the constant to be redefined at some later point during script execution. .. bro:attr:: &rotate_interval @@ -534,7 +534,7 @@ scripting language supports the following built-in attributes. .. bro:attr:: &rotate_size - Rotates af file after it has reached a given size in bytes. + Rotates a file after it has reached a given size in bytes. .. bro:attr:: &add_func diff --git a/scripts/base/frameworks/packet-filter/main.bro b/scripts/base/frameworks/packet-filter/main.bro index 94a01e04a2..afcb5bd700 100644 --- a/scripts/base/frameworks/packet-filter/main.bro +++ b/scripts/base/frameworks/packet-filter/main.bro @@ -16,7 +16,7 @@ export { redef enum Notice::Type += { ## This notice is generated if a packet filter is unable to be compiled. Compile_Failure, - + ## This notice is generated if a packet filter is fails to install. Install_Failure, }; @@ -26,18 +26,18 @@ export { type Info: record { ## The time at which the packet filter installation attempt was made. ts: time &log; - + ## This is a string representation of the node that applied this ## packet filter. It's mostly useful in the context of dynamically ## changing filters on clusters. node: string &log &optional; - + ## The packet filter that is being set. filter: string &log; - + ## Indicate if this is the filter set during initialization. init: bool &log &default=F; - + ## Indicate if the filter was applied successfully. success: bool &log &default=T; }; @@ -48,16 +48,16 @@ export { ## The latter used to be default for Bro versions < 2.0. That has now ## changed however to enable port-independent protocol analysis. const all_packets = T &redef; - - ## Filter string which is unconditionally or'ed to the beginning of every + + ## Filter string which is unconditionally or'ed to the beginning of every ## dynamically built filter. const unrestricted_filter = "" &redef; - + ## Call this function to build and install a new dynamically built ## packet filter. global install: function(); - - ## This is where the default packet filter is stored and it should not + + ## This is where the default packet filter is stored and it should not ## normally be modified by users. global default_filter = ""; } @@ -89,22 +89,22 @@ function build_default_filter(): string return "ip or not ip"; # Build filter dynamically. - + # First the capture_filter. local cfilter = ""; for ( id in capture_filters ) cfilter = combine_filters(cfilter, capture_filters[id], "or"); - + # Then the restrict_filter. local rfilter = ""; for ( id in restrict_filters ) rfilter = combine_filters(rfilter, restrict_filters[id], "and"); - + # Finally, join them into one filter. local filter = combine_filters(rfilter, cfilter, "and"); if ( unrestricted_filter != "" ) filter = combine_filters(unrestricted_filter, filter, "or"); - + return filter; } @@ -114,32 +114,32 @@ function install() if ( ! precompile_pcap_filter(DefaultPcapFilter, default_filter) ) { - NOTICE([$note=Compile_Failure, + NOTICE([$note=Compile_Failure, $msg=fmt("Compiling packet filter failed"), $sub=default_filter]); Reporter::fatal(fmt("Bad pcap filter '%s'", default_filter)); } - + # Do an audit log for the packet filter. local info: Info; info$ts = network_time(); # If network_time() is 0.0 we're at init time so use the wall clock. - if ( info$ts == 0.0 ) + if ( info$ts == 0.0 ) { info$ts = current_time(); info$init = T; } info$filter = default_filter; - + if ( ! install_pcap_filter(DefaultPcapFilter) ) { # Installing the filter failed for some reason. info$success = F; - NOTICE([$note=Install_Failure, + NOTICE([$note=Install_Failure, $msg=fmt("Installing packet filter failed"), $sub=default_filter]); } - + if ( reading_live_traffic() || reading_traces() ) Log::write(PacketFilter::LOG, info); } diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 200947938d..9f4e0355f0 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -601,10 +601,10 @@ function add_signature_file(sold: string, snew: string): string } ## Signature files to read. Use ``redef signature_files += "foo.sig"`` to -## extend. Signature files will be searched relative to ``BRO_PATH``. +## extend. Signature files will be searched relative to ``BROPATH``. global signature_files = "" &add_func = add_signature_file; -## ``p0f`` fingerprint file to use. Will be searched relative to ``BRO_PATH``. +## ``p0f`` fingerprint file to use. Will be searched relative to ``BROPATH``. const passive_fingerprint_file = "base/misc/p0f.fp" &redef; # todo::testing to see if I can remove these without causing problems. diff --git a/scripts/policy/protocols/http/detect-webapps.bro b/scripts/policy/protocols/http/detect-webapps.bro index afb95074e2..796da5c29a 100644 --- a/scripts/policy/protocols/http/detect-webapps.bro +++ b/scripts/policy/protocols/http/detect-webapps.bro @@ -28,7 +28,7 @@ event signature_match(state: signature_state, msg: string, data: string) &priori local c = state$conn; local si = Software::Info; - si = [$unparsed_version=msg, $host=c$id$resp_h, $host_p=c$id$resp_p, $software_type=WEB_APPLICATION]; + si = [$name=msg, $unparsed_version=msg, $host=c$id$resp_h, $host_p=c$id$resp_p, $software_type=WEB_APPLICATION]; si$url = build_url_http(c$http); if ( c$id$resp_h in Software::tracked && si$name in Software::tracked[c$id$resp_h] ) diff --git a/src/Analyzer.h b/src/Analyzer.h index 7797e215fe..86cfb0266b 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -1,4 +1,3 @@ -// Main analyzer interface. #ifndef ANALYZER_H #define ANALYZER_H diff --git a/src/Anon.cc b/src/Anon.cc index aeaf49feea..ca2a1e6361 100644 --- a/src/Anon.cc +++ b/src/Anon.cc @@ -154,7 +154,7 @@ void AnonymizeIPAddr_A50::init() int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits) { DEBUG_MSG("%s/%d\n", - string(IPAddr(IPAddr::IPv4, &input, IPAddr::Network)).c_str(), + IPAddr(IPAddr::IPv4, &input, IPAddr::Network)->AsString().c_str(), num_bits); if ( ! before_anonymization ) diff --git a/src/Brofiler.cc b/src/Brofiler.cc index 60e57f0964..783d027761 100644 --- a/src/Brofiler.cc +++ b/src/Brofiler.cc @@ -5,7 +5,7 @@ #include "util.h" Brofiler::Brofiler() - : delim('\t'), ignoring(0) + : ignoring(0), delim('\t') { } diff --git a/src/CompHash.cc b/src/CompHash.cc index 44484ca005..77a06976fb 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -727,7 +727,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, { const uint32* const kp = AlignType(kp0); kp1 = reinterpret_cast(kp+4); + IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network); + switch ( tag ) { case TYPE_ADDR: pval = new AddrVal(addr); diff --git a/src/Conn.cc b/src/Conn.cc index deb89d50d3..7f5b936646 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -751,14 +751,14 @@ void Connection::Describe(ODesc* d) const } d->SP(); - d->Add(string(orig_addr).c_str()); + d->Add(orig_addr); d->Add(":"); d->Add(ntohs(orig_port)); d->SP(); d->AddSP("->"); - d->Add(string(resp_addr).c_str()); + d->Add(resp_addr); d->Add(":"); d->Add(ntohs(resp_port)); @@ -781,13 +781,8 @@ bool Connection::DoSerialize(SerialInfo* info) const // First we write the members which are needed to // create the HashKey. - uint32 orig_a[4]; - uint32 resp_a[4]; - orig_addr.CopyIPv6(orig_a); - resp_addr.CopyIPv6(resp_a); - for ( int j = 0; j < 4; ++j ) - if ( ! SERIALIZE(orig_a[j]) || ! SERIALIZE(resp_a[j]) ) - return false; + if ( ! SERIALIZE(orig_addr) || ! SERIALIZE(resp_addr) ) + return false; if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) ) return false; @@ -834,14 +829,9 @@ bool Connection::DoUnserialize(UnserialInfo* info) // Build the hash key first. Some of the recursive *::Unserialize() // functions may need it. ConnID id; - uint32 orig_a[4]; - uint32 resp_a[4]; - for ( int i = 0; i < 4; ++i ) - if ( ! UNSERIALIZE(&orig_a[i]) || ! UNSERIALIZE(&resp_a[i]) ) - goto error; - orig_addr = IPAddr(IPAddr::IPv6, orig_a, IPAddr::Network); - resp_addr = IPAddr(IPAddr::IPv6, resp_a, IPAddr::Network); + if ( ! UNSERIALIZE(&orig_addr) || ! UNSERIALIZE(&resp_addr) ) + goto error; if ( ! UNSERIALIZE(&orig_port) || ! UNSERIALIZE(&resp_port) ) goto error; diff --git a/src/DCE_RPC.cc b/src/DCE_RPC.cc index 2aae4aa76a..a8a81813b7 100644 --- a/src/DCE_RPC.cc +++ b/src/DCE_RPC.cc @@ -139,6 +139,7 @@ bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto) { if ( id->dst_addr.family() == IPAddr::IPv6 ) return false; + dce_rpc_endpoint_addr addr; addr.addr = id->dst_addr; addr.port = ntohs(id->dst_port); diff --git a/src/DCE_RPC.h b/src/DCE_RPC.h index c736928a43..481e7f37a3 100644 --- a/src/DCE_RPC.h +++ b/src/DCE_RPC.h @@ -34,7 +34,7 @@ protected: const char* uuid_to_string(const u_char* uuid_data); struct dce_rpc_endpoint_addr { - // All fields except addr are in host byteorder. + // All fields are in host byteorder. IPAddr addr; u_short port; TransportProto proto; @@ -65,7 +65,7 @@ struct dce_rpc_endpoint_addr { { static char buf[128]; snprintf(buf, sizeof(buf), "%s/%d/%s", - string(addr).c_str(), port, + addr->AsString().c_str(), port, proto == TRANSPORT_TCP ? "tcp" : (proto == TRANSPORT_UDP ? "udp" : "?")); diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index e89dbf7d2f..d0c562da37 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -94,10 +94,9 @@ public: // Returns nil if this was an address request. const char* ReqHost() const { return req_host; } uint32 ReqAddr() const { return req_addr; } - const char* ReqStr() const + string ReqStr() const { - return req_host ? req_host : - string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(); + return req_host ? req_host : IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network); } ListVal* Addrs(); @@ -199,8 +198,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) req_host = copy_string(req_buf); else { - string s(req_buf); - IPAddr addr(s); + IPAddr addr(req_buf); const uint32* bytes; addr.GetBytes(&bytes); req_addr = *bytes; //FIXME: IPv6 support @@ -226,8 +224,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) if ( newline ) *newline = '\0'; - string s(buf); - IPAddr addr(s); + IPAddr addr(buf); const uint32* bytes; addr.GetBytes(&bytes); addrs[i] = *bytes; //FIXME IPv6 support @@ -350,13 +347,13 @@ void DNS_Mapping::Save(FILE* f) const { fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0, req_host ? req_host : - string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(), + IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)->AsString()->c_str(), failed, (names && names[0]) ? names[0] : "*", num_addrs); for ( int i = 0; i < num_addrs; ++i ) fprintf(f, "%s\n", - string(IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)).c_str()); + IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)->AsString().c_str()); } @@ -521,7 +518,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", - string(IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)).c_str()); + IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)->AsString().c_str()); return 0; case DNS_DEFAULT: @@ -813,7 +810,7 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al) for ( int i = 0; i < al->Length(); ++i ) { const IPAddr* al_i = al->Index(i)->AsAddr(); - fprintf(f, "%s%s", i > 0 ? "," : "", string(*al_i).c_str()); + fprintf(f, "%s%s", i > 0 ? "," : "", al_i->AsString().c_str()); } } diff --git a/src/Desc.cc b/src/Desc.cc index 12b4a524eb..df49d84ba2 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -157,6 +157,18 @@ void ODesc::Add(double d) } } +void ODesc::Add(const IPAddr& addr) + { + string s = addr->AsString(); + AddBytes(s.c_str()); + } + +void ODesc::Add(const IPPrefix& prefix) + { + string s = prefix->AsString(); + AddBytes(s.c_str()); + } + void ODesc::AddCS(const char* s) { int n = strlen(s); diff --git a/src/Desc.h b/src/Desc.h index 27cbd4fa01..c633f2d812 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -73,6 +73,8 @@ public: void Add(int64 i); void Add(uint64 u); void Add(double d); + void Add(const IPAddr& addr); + void Add(const IPPrefix& prefix); // Add s as a counted string. void AddCS(const char* s); diff --git a/src/Expr.cc b/src/Expr.cc index 848fe6d351..60e9cdb4ba 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -837,8 +837,8 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const { uint32 a1[4]; uint32 a2[4]; - v1->AsAddr()->CopyIPv6(a1); - v2->AsAddr()->CopyIPv6(a2); + v1->AsAddr().CopyIPv6(a1); + v2->AsAddr().CopyIPv6(a2); int result = 0; switch ( tag ) { @@ -861,10 +861,10 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const { - const IPPrefix* n1 = v1->AsSubNet(); - const IPPrefix* n2 = v2->AsSubNet(); + const IPPrefix& n1 = v1->AsSubNet(); + const IPPrefix& n2 = v2->AsSubNet(); - if ( *n1 == *n2 ) + if ( n1 == n2 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -1673,7 +1673,7 @@ Val* DivideExpr::AddrFold(Val* v1, Val* v2) const else mask = static_cast(v2->InternalInt()); - return new SubNetVal(*v1->AsAddr(), mask); + return new SubNetVal(v1->AsAddr(), mask); } Expr* DivideExpr::DoSimplify() @@ -4493,7 +4493,7 @@ Val* InExpr::Fold(Val* v1, Val* v2) const if ( v1->Type()->Tag() == TYPE_ADDR && v2->Type()->Tag() == TYPE_SUBNET ) - return new Val(v2->AsSubNetVal()->Contains(*v1->AsAddr()), TYPE_BOOL); + return new Val(v2->AsSubNetVal().Contains(v1->AsAddr()), TYPE_BOOL); TableVal* vt = v2->AsTableVal(); if ( vt->Lookup(v1, false) ) diff --git a/src/ICMP.cc b/src/ICMP.cc index 279adbd7dd..5da897b0d5 100644 --- a/src/ICMP.cc +++ b/src/ICMP.cc @@ -243,7 +243,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const d->Add(Conn()->LastTime()); d->AddSP(")"); - d->Add(string(Conn()->OrigAddr()).c_str()); + d->Add(Conn()->OrigAddr()); d->Add("."); d->Add(type); d->Add("."); @@ -252,7 +252,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const d->SP(); d->AddSP("->"); - d->Add(string(Conn()->RespAddr()).c_str()); + d->Add(Conn()->RespAddr()); } void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index fa8e5567eb..7d306e1b2d 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,3 +1,5 @@ +// See the file "COPYING" in the main distribution directory for copyright. + #include "IPAddr.h" #include "Reporter.h" @@ -7,7 +9,7 @@ const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, void IPAddr::Mask(int top_bits_to_keep) { - if ( top_bits_to_keep <=0 || top_bits_to_keep > 128 ) + if ( top_bits_to_keep <= 0 || top_bits_to_keep > 128 ) { reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep); return; @@ -18,6 +20,7 @@ void IPAddr::Mask(int top_bits_to_keep) int word = 3; int bits_to_chop = 128 - top_bits_to_keep; + while ( bits_to_chop >= 32 ) { tmp[word] = 0; @@ -29,12 +32,13 @@ void IPAddr::Mask(int top_bits_to_keep) w >>= bits_to_chop; w <<= bits_to_chop; tmp[word] = htonl(w); + memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } void IPAddr::ReverseMask(int top_bits_to_chop) { - if ( top_bits_to_chop <=0 || top_bits_to_chop > 128 ) + if ( top_bits_to_chop <= 0 || top_bits_to_chop > 128 ) { reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop); return; @@ -45,6 +49,7 @@ void IPAddr::ReverseMask(int top_bits_to_chop) int word = 0; int bits_to_chop = top_bits_to_chop; + while ( bits_to_chop >= 32 ) { tmp[word] = 0; @@ -56,20 +61,23 @@ void IPAddr::ReverseMask(int top_bits_to_chop) w <<= bits_to_chop; w >>= bits_to_chop; tmp[word] = htonl(w); + memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } void IPAddr::Init(const std::string& s) { - if ( s.find(':') == std::string::npos ) //IPv4 + if ( s.find(':') == std::string::npos ) // IPv4. { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); + if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 ) { reporter->Error("Bad IP address: %s", s.c_str()); memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); } } + else { if ( inet_pton(AF_INET6, s.c_str(), in6.s6_addr) <=0 ) @@ -80,11 +88,34 @@ void IPAddr::Init(const std::string& s) } } +string IPAddr::AsString() const + { + if ( family() == IPv4 ) + { + char s[INET_ADDRSTRLEN]; + + if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) + return " 32 ) reporter->InternalError("Bad in4_addr IPPrefix length : %d", length); + prefix.Mask(this->length); } @@ -93,6 +124,7 @@ IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) { if ( length > 128 ) reporter->InternalError("Bad in6_addr IPPrefix length : %d", length); + prefix.Mask(this->length); } @@ -104,15 +136,19 @@ IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length) if ( length > 32 ) reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d", length); + this->length = length + 96; } + else { if ( length > 128 ) reporter->InternalError("Bad IPAddr(v6) IPPrefix length : %d", length); + this->length = length; } + prefix.Mask(this->length); } @@ -121,7 +157,22 @@ IPPrefix::IPPrefix(const std::string& s, uint8_t length) { if ( prefix.family() == IPAddr::IPv4 && length > 32 ) reporter->InternalError("Bad string IPPrefix length : %d", length); + else if ( prefix.family() == IPAddr::IPv6 && length > 128 ) reporter->InternalError("Bad string IPPrefix length : %d", length); + prefix.Mask(this->length); } + +string IPPrefix::AsString() const + { + char l[16]; + + if ( prefix.family() == IPAddr::IPv4 ) + modp_uitoa10(length - 96, l); + else + modp_uitoa10(length, l); + + return prefix->AsString() +"/" + l; + } + diff --git a/src/IPAddr.h b/src/IPAddr.h index dbcad95d75..07891fcee0 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef IPADDR_H #define IPADDR_H @@ -11,97 +12,108 @@ typedef in_addr in4_addr; -/// Class storing both IPv4 and IPv6 addresses. +/** + * Class storing both IPv4 and IPv6 addresses. + */ class IPAddr { public: - /// Address family. + /** + * Address family. + */ enum Family { IPv4, IPv6 }; - /// Byte order. + /** + * Byte order. + */ enum ByteOrder { Host, Network }; - /// Constructs the unspecified IPv6 address (all 128 bits zeroed). + /** + * Constructs the unspecified IPv6 address (all 128 bits zeroed). + */ IPAddr() { memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); } - /// Constructs an address instance from an IPv4 address. - /// - /// @param in6 The IPv6 address. + /** + * Constructs an address instance from an IPv4 address. + * + * @param in6 The IPv6 address. + */ IPAddr(const in4_addr& in4) { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr)); } - /// Constructs an address instance from an IPv6 address. - /// - /// @param in6 The IPv6 address. + /** + * Constructs an address instance from an IPv6 address. + * + * @param in6 The IPv6 address. + */ IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { } - /// Constructs an address instance from a string representation. - /// - /// @param s String containing an IP address as either a dotted IPv4 - /// address or a hex IPv6 address. + /** + * Constructs an address instance from a string representation. + * + * @param s String containing an IP address as either a dotted IPv4 + * address or a hex IPv6 address. + */ IPAddr(const std::string& s) { Init(s); } - /// Constructs an address instance from a string representation. - /// - /// @param s String containing an IP address as either a dotted IPv4 - /// address or a hex IPv6 address. + /** + * Constructs an address instance from a string representation. + * + * @param s ASCIIZ string containing an IP address as either a + * dotted IPv4 address or a hex IPv6 address. + */ + IPAddr(const char* s) + { + Init(s); + } + + /** + * Constructs an address instance from a string representation. + * + * @param s String containing an IP address as either a dotted IPv4 + * address or a hex IPv6 address. + */ IPAddr(const BroString& s) { Init(s.CheckString()); } - /// Constructs an address instance from a raw byte representation. - /// - /// @param family The address family. - /// - /// @param bytes A pointer to the raw byte representation. This must point - /// to 4 bytes if \a family is IPv4, and to 16 bytes if \a family is - /// IPv6. - /// - /// @param order Indicates whether the raw representation pointed to - /// by \a bytes is stored in network or host order. - IPAddr(Family family, const uint32_t* bytes, ByteOrder order) - { - if ( family == IPv4 ) - { - memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - memcpy(&in6.s6_addr[12], bytes, sizeof(uint32_t)); - if ( order == Host ) - { - uint32_t* p = (uint32_t*) &in6.s6_addr[12]; - *p = htonl(*p); - } - } - else - { - memcpy(in6.s6_addr, bytes, sizeof(in6.s6_addr)); - if ( order == Host ) - { - for ( unsigned int i = 0; i < 4; ++ i) - { - uint32_t* p = (uint32_t*) &in6.s6_addr[i*4]; - *p = htonl(*p); - } - } - } - } + /** + * Constructs an address instance from a raw byte representation. + * + * @param family The address family. + * + * @param bytes A pointer to the raw byte representation. This must point + * to 4 bytes if \a family is IPv4, and to 16 bytes if \a family is + * IPv6. + * + * @param order Indicates whether the raw representation pointed to + * by \a bytes is stored in network or host order. + */ + IPAddr(Family family, const uint32_t* bytes, ByteOrder order); - /// Copy constructor. + /** + * Copy constructor. + */ IPAddr(const IPAddr& other) : in6(other.in6) { }; - /// Destructor. + /** + * Destructor. + */ ~IPAddr() { }; - /// Returns the address' family. + /** + * Returns the address' family. + */ Family family() const { if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 ) @@ -110,23 +122,14 @@ public: return IPv6; } - /// Returns true if the address represents a loopback device. - bool IsLoopback() const - { - if ( family() == IPv4 ) - return in6.s6_addr[12] == 127; - else - return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) - && (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0) - && (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) - && (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) - && (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0) - && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) - && (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0) - && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); - } + /** + * Returns true if the address represents a loopback device. + */ + bool IsLoopback() const; - /// Returns true if the address represents a multicast address. + /** + * Returns true if the address represents a multicast address. + */ bool IsMulticast() const { if ( family() == IPv4 ) @@ -135,27 +138,31 @@ public: return in6.s6_addr[0] == 0xff; } - /// Returns true if the address represents a broadcast address. + /** + * Returns true if the address represents a broadcast address. + */ bool IsBroadcast() const { if ( family() == IPv4 ) return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) - && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); + && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); else return false; } - /// Retrieves the raw byte representation of the address. - /// - /// @param bytes The pointer to which \a bytes points will be set to - /// the address of the raw representation in network-byte order. - /// The return value indicates how many 32-bit words are valid starting at - /// that address. The pointer will be valid as long as the address instance - /// exists. - /// - /// @return The number of 32-bit words the raw representation uses. This - /// will be 1 for an IPv4 address and 4 for an IPv6 address. - int GetBytes(uint32_t** bytes) + /** + * Retrieves the raw byte representation of the address. + * + * @param bytes The pointer to which \a bytes points will be set to + * the address of the raw representation in network-byte order. + * The return value indicates how many 32-bit words are valid starting at + * that address. The pointer will be valid as long as the address instance + * exists. + * + * @return The number of 32-bit words the raw representation uses. This + * will be 1 for an IPv4 address and 4 for an IPv6 address. + */ + int GetBytes(const uint32_t* const * bytes) const { if ( family() == IPv4 ) { @@ -169,51 +176,45 @@ public: } } - int GetBytes(const uint32_t** bytes) const - { - if ( family() == IPv4 ) - { - *bytes = (uint32_t*) &in6.s6_addr[12]; - return 1; - } - else - { - *bytes = (uint32_t*) in6.s6_addr; - return 4; - } - } - - /// Retrieves a copy of the IPv6 raw byte representation of the address. - /// If the internal address is IPv4, then the copied bytes use the - /// IPv4 to IPv6 address mapping to return a full 16 bytes. - /// - /// @param bytes The pointer to a memory location in which the - /// raw bytes of the address are to be copied in network byte-order. + /** + * Retrieves a copy of the IPv6 raw byte representation of the address. + * If the internal address is IPv4, then the copied bytes use the + * IPv4 to IPv6 address mapping to return a full 16 bytes. + * + * @param bytes The pointer to a memory location in which the + * raw bytes of the address are to be copied in network byte-order. + */ void CopyIPv6(uint32_t* bytes) const { memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr)); } - /// Masks out lower bits of the address. - /// - /// @param top_bits_to_keep The number of bits \a not to mask out, - /// counting from the highest order bit. The value is always - /// interpreted relative to the IPv6 bit width, even if the address - /// is IPv4. That means if compute ``192.168.1.2/16``, you need to - /// pass in 112 (i.e., 96 + 16). The value must be in the range from - /// 0 to 128. + /** + * Masks out lower bits of the address. + * + * @param top_bits_to_keep The number of bits \a not to mask out, + * counting from the highest order bit. The value is always + * interpreted relative to the IPv6 bit width, even if the address + * is IPv4. That means if compute ``192.168.1.2/16``, you need to + * pass in 112 (i.e., 96 + 16). The value must be in the range from + * 0 to 128. + */ void Mask(int top_bits_to_keep); - /// Masks out top bits of the address. - /// - /// @param top_bits_to_chop The number of bits to mask out, counting - /// from the highest order bit. The value is always interpreted relative - /// to the IPv6 bit width, even if the address is IPv4. So to mask out - /// the first 16 bits of an IPv4 address, pass in 112 (i.e., 96 + 16). - /// The value must be in the range from 0 to 128. + /** + * Masks out top bits of the address. + * + * @param top_bits_to_chop The number of bits to mask out, counting + * from the highest order bit. The value is always interpreted relative + * to the IPv6 bit width, even if the address is IPv4. So to mask out + * the first 16 bits of an IPv4 address, pass in 112 (i.e., 96 + 16). + * The value must be in the range from 0 to 128. + */ void ReverseMask(int top_bits_to_chop); - /// Assignment operator. + /** + * Assignment operator. + */ IPAddr& operator=(const IPAddr& other) { // No self-assignment check here because it's correct without it and @@ -222,30 +223,22 @@ public: return *this; } - /// Returns a string representation of the address. IPv4 addresses - /// will be returned in dotted representation, IPv6 addresses in - /// compressed hex. - operator std::string() const - { - if ( family() == IPv4 ) - { - char s[INET_ADDRSTRLEN]; - if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL ) - return "Read(&net[0], "net0") && - fmt->Read(&net[1], "net1") && - fmt->Read(&net[2], "net2") && - fmt->Read(&net[3], "net3") && - fmt->Read(&net[4], "width")) ) + IPPrefix prefix; + if ( ! fmt->Read(&prefix), "subnet" ) return false; - val.subnet_val = new IPPrefix(IPAddr(IPAddr::IPv6, net, - IPAddr::Network), net[4]); + + val.subnet_val = new IPPrefix(prefix); return true; } case TYPE_ADDR: { - uint32 addr[4]; - if ( ! (fmt->Read(&addr[0], "addr0") && - fmt->Read(&addr[1], "addr1") && - fmt->Read(&addr[2], "addr2") && - fmt->Read(&addr[3], "addr3")) ) + IPAddr addr; + if ( ! fmt->Read(&addr), "net" ) return false; - val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); + val.addr_val = new IPAddr(prefix); return true; } @@ -301,25 +294,11 @@ bool LogVal::Write(SerializationFormat* fmt) const return fmt->Write(val.uint_val, "uint"); case TYPE_SUBNET: - { - uint32 net[4]; - val.subnet_val->Prefix().CopyIPv6(net); - return fmt->Write(net[0], "net0") && - fmt->Write(net[1], "net1") && - fmt->Write(net[2], "net2") && - fmt->Write(net[3], "net3") && - fmt->Write((uint32)val.subnet_val->Length(), "width"); - } + return fmt->Write(*val.subnet_val, "subnet"); + case TYPE_ADDR: - { - uint32 addr[4]; - val.addr_val->CopyIPv6(addr); - return fmt->Write(addr[0], "addr0") && - fmt->Write(addr[1], "addr1") && - fmt->Write(addr[2], "addr2") && - fmt->Write(addr[3], "addr3"); - } + return fmt->Write(*val.addr_val, "addr"); case TYPE_DOUBLE: case TYPE_TIME: @@ -1086,12 +1065,12 @@ LogVal* LogMgr::ValToLogVal(Val* val, BroType* ty) break; case TYPE_SUBNET: - lval->val.subnet_val = new IPPrefix(*val->AsSubNet()); + lval->val.subnet_val = new IPPrefix(val->AsSubNet()); break; case TYPE_ADDR: { - lval->val.addr_val = new IPAddr(*val->AsAddr()); + lval->val.addr_val = new IPAddr(val->AsAddr()); break; } diff --git a/src/LogWriterAscii.cc b/src/LogWriterAscii.cc index 84fe8a3c31..8dd36e1991 100644 --- a/src/LogWriterAscii.cc +++ b/src/LogWriterAscii.cc @@ -166,11 +166,11 @@ bool LogWriterAscii::DoWriteOne(ODesc* desc, LogVal* val, const LogField* field) break; case TYPE_SUBNET: - desc->Add(string(*val->val.subnet_val).c_str()); + desc->Add(*val->val.subnet_val); break; case TYPE_ADDR: - desc->Add(string(*val->val.addr_val).c_str()); + desc->Add(*val->val.addr_val); break; case TYPE_TIME: diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index 62e6fe5c12..bbe391bfcb 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -42,12 +42,12 @@ void* PrefixTable::Insert(const Val* value, void* data) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Insert(*value->AsAddr(), 128, data); + return Insert(value->AsAddr(), 128, data); break; case TYPE_SUBNET: - return Insert(value->AsSubNet()->Prefix(), - value->AsSubNet()->LengthIPv6(), data); + return Insert(value->AsSubNet().Prefix(), + value->AsSubNet().LengthIPv6(), data); break; default: @@ -76,12 +76,12 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Lookup(*value->AsAddr(), 128, exact); + return Lookup(value->AsAddr(), 128, exact); break; case TYPE_SUBNET: - return Lookup(value->AsSubNet()->Prefix(), - value->AsSubNet()->LengthIPv6(), exact); + return Lookup(value->AsSubNet().Prefix(), + value->AsSubNet().LengthIPv6(), exact); break; default: @@ -115,12 +115,12 @@ void* PrefixTable::Remove(const Val* value) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Remove(*value->AsAddr(), 128); + return Remove(value->AsAddr(), 128); break; case TYPE_SUBNET: - return Remove(value->AsSubNet()->Prefix(), - value->AsSubNet()->LengthIPv6()); + return Remove(value->AsSubNet().Prefix(), + value->AsSubNet().LengthIPv6()); break; default: diff --git a/src/Reporter.cc b/src/Reporter.cc index 2caf3f5dfb..37470cd690 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -155,20 +155,6 @@ void Reporter::WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* add delete vl; } -void Reporter::WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...) - { - val_list* vl = new val_list(2); - vl->append(new AddrVal(orig)); - vl->append(new AddrVal(resp)); - - va_list ap; - va_start(ap, fmt_name); - DoLog("weird", flow_weird, stderr, 0, vl, false, false, 0, fmt_name, ap); - va_end(ap); - - delete vl; - } - void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...) { val_list* vl = new val_list(2); @@ -198,11 +184,6 @@ void Reporter::Weird(Val* conn_val, const char* name, const char* addl) WeirdHelper(conn_weird, conn_val, addl, "%s", name); } -void Reporter::Weird(const uint32* orig, const uint32* resp, const char* name) - { - WeirdFlowHelper(orig, resp, "%s", name); - } - void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name) { WeirdFlowHelper(orig, resp, "%s", name); diff --git a/src/Reporter.h b/src/Reporter.h index 10bb96306d..210dd241d2 100644 --- a/src/Reporter.h +++ b/src/Reporter.h @@ -75,7 +75,6 @@ public: void Weird(const char* name); // Raises net_weird(). void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird(). void Weird(Val* conn_val, const char* name, const char* addl = ""); // Raises conn_weird(). - void Weird(const uint32* orig, const uint32* resp, const char* name); // Raises flow_weird(). void Weird(const IPAddr& orig, const IPAddr& resp, const char* name); // Raises flow_weird(). // Syslog a message. This methods does nothing if we're running @@ -123,7 +122,6 @@ private: // The order if addl, name needs to be like that since fmt_name can // contain format specifiers void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...); - void WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...); void WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...); int errors; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 63b56aa341..b7138ee388 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1070,14 +1070,16 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) { const uint32* n; uint32 m[4]; - v->AsSubNet()->Prefix().GetBytes(&n); - v->AsSubNetVal()->Mask().CopyIPv6(m); + v->AsSubNet().Prefix().GetBytes(&n); + v->AsSubNetVal().Mask().CopyIPv6(m); + for ( unsigned int i = 0; i < 4; ++i ) m[i] = ntohl(m[i]); + bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; - if ( v->AsSubNet()->Prefix().family() == IPAddr::IPv4 && + if ( v->AsSubNet().Prefix().family() == IPAddr::IPv4 && is_v4_mask ) { mval->val = ntohl(*n); diff --git a/src/SSH.cc b/src/SSH.cc index 1f3666da2f..3a8f468ae4 100644 --- a/src/SSH.cc +++ b/src/SSH.cc @@ -50,23 +50,24 @@ void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) // SSH-.-\n // // We're interested in the "version" part here. - + if ( length < 4 || memcmp(line, "SSH-", 4) != 0 ) { Weird("malformed_ssh_identification"); ProtocolViolation("malformed ssh identification", line, length); return; } - + int i; for ( i = 4; i < length && line[i] != '-'; ++i ) ; - + if ( TCP() ) { if ( length >= i ) { IPAddr dst; + if ( is_orig ) dst = TCP()->Orig()->dst_addr; else diff --git a/src/SerializationFormat.cc b/src/SerializationFormat.cc index 5e3a68a42e..c88e2979b8 100644 --- a/src/SerializationFormat.cc +++ b/src/SerializationFormat.cc @@ -230,6 +230,28 @@ bool BinarySerializationFormat::Read(string* v, const char* tag) return true; } +bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag) + { + string s; + if ( ! Read(&s, tag) ) + return false; + + *addr = IPAddr(s); + return true; + } + +bool BinarySerializationFormat::Read(IPPrefix* prefix, const char* tag) + { + string s; + int len; + + if ( ! (Read(&s, tag) && Read(&len, tag)) ) + return false; + + *prefix = IPPrefix(IPAddr(s), len); + return true; + } + bool BinarySerializationFormat::Write(char v, const char* tag) { DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag); @@ -299,6 +321,16 @@ bool BinarySerializationFormat::Write(const string& s, const char* tag) return Write(s.data(), s.size(), tag); } +bool BinarySerializationFormat::Write(const IPAddr& addr, const char* tag) + { + return Write(addr.AsString()); + } + +bool BinarySerializationFormat::Write(const IPPrefix& prefix, const char* tag) + { + return Write(addr.AsString(), tag) && Write(prefix->Length(), tag); + } + bool BinarySerializationFormat::WriteOpenTag(const char* tag) { return true; diff --git a/src/SerializationFormat.h b/src/SerializationFormat.h index 2067456bf1..c6dd1e86b0 100644 --- a/src/SerializationFormat.h +++ b/src/SerializationFormat.h @@ -28,6 +28,8 @@ public: virtual bool Read(bool* v, const char* tag) = 0; virtual bool Read(double* d, const char* tag) = 0; virtual bool Read(string* s, const char* tag) = 0; + virtual bool Read(IPAddr* addr, const char* tag) = 0; + virtual bool Read(IPPrefix* prefix, const char* tag) = 0; // Returns number of raw bytes read since last call to StartRead(). int BytesRead() const { return bytes_read; } @@ -50,6 +52,8 @@ public: virtual bool Write(const char* s, const char* tag) = 0; virtual bool Write(const char* buf, int len, const char* tag) = 0; virtual bool Write(const string& s, const char* tag) = 0; + virtual bool Write(const IPAddr& addr, const char* tag) = 0; + virtual bool Write(const IPPrefix& prefix, const char* tag) = 0; virtual bool WriteOpenTag(const char* tag) = 0; virtual bool WriteCloseTag(const char* tag) = 0; diff --git a/src/Serializer.cc b/src/Serializer.cc index ba593b84be..06bbf73f48 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1103,9 +1103,9 @@ void EventPlayer::Process() void Packet::Describe(ODesc* d) const { const IP_Hdr ip = IP(); - d->Add(string(ip.SrcAddr()).c_str()); + d->Add(ip.SrcAddr()); d->Add("->"); - d->Add(string(ip.DstAddr()).c_str()); + d->Add(ip.DstAddr()); } bool Packet::Serialize(SerialInfo* info) const diff --git a/src/Sessions.cc b/src/Sessions.cc index 54a6a85f7b..cec44acb3c 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -287,6 +287,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size)); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } + else { Weird("unknown_packet_type", hdr, pkt); @@ -604,8 +605,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, int record_packet = 1; // whether to record the packet at all int record_content = 1; // whether to record its data - int is_orig = id.src_addr == conn->OrigAddr() && - id.src_port == conn->OrigPort(); + int is_orig = (id.src_addr == conn->OrigAddr()) && + (id.src_port == conn->OrigPort()); if ( new_packet && ip4 ) conn->Event(new_packet, 0, BuildHeader(ip4)); @@ -811,16 +812,16 @@ Connection* NetSessions::FindConnection(Val* v) // types, too. } - IPAddr* orig_addr = (*vl)[orig_h]->AsAddr(); - IPAddr* resp_addr = (*vl)[resp_h]->AsAddr(); + const IPAddr& orig_addr = (*vl)[orig_h]->AsAddr(); + const IPAddr& resp_addr = (*vl)[resp_h]->AsAddr(); PortVal* orig_portv = (*vl)[orig_p]->AsPortVal(); PortVal* resp_portv = (*vl)[resp_p]->AsPortVal(); ConnID id; - id.src_addr = *orig_addr; - id.dst_addr = *resp_addr; + id.src_addr = orig_addr; + id.dst_addr = resp_addr; id.src_port = htons((unsigned short) orig_portv->Port()); id.dst_port = htons((unsigned short) resp_portv->Port()); diff --git a/src/TCP_Endpoint.cc b/src/TCP_Endpoint.cc index 4fe53a4b60..626680966f 100644 --- a/src/TCP_Endpoint.cc +++ b/src/TCP_Endpoint.cc @@ -35,9 +35,9 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) const uint32* src_bytes; const uint32* dst_bytes; int n = src_addr.GetBytes(&src_bytes); - dst_addr.GetBytes(&dst_bytes); + int m = dst_addr.GetBytes(&dst_bytes); checksum_base = ones_complement_checksum((void*) src_bytes, n*4, 0); - checksum_base = ones_complement_checksum((void*) dst_bytes, n*4, checksum_base); + checksum_base = ones_complement_checksum((void*) dst_bytes, m*4, 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 diff --git a/src/Val.cc b/src/Val.cc index 7de63534c4..0e49dca030 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -205,31 +205,10 @@ bool Val::DoSerialize(SerialInfo* info) const val.string_val->Len()); case TYPE_INTERNAL_ADDR: - { - const uint32* addrp; - int words = val.addr_val->GetBytes(&addrp); - if ( ! SERIALIZE(words) ) - return false; - for ( int i = 0; i < words; ++i ) - if ( ! SERIALIZE(ntohl(addrp[i])) ) - return false; - return true; - } + return SERIALIZE(*val.addr_val); case TYPE_INTERNAL_SUBNET: - { - const uint32* addrp; - int words = val.subnet_val->Prefix().GetBytes(&addrp); - if ( ! (info->s->WriteOpenTag("subnet") && SERIALIZE(words)) ) - return false; - for ( int i = 0; i < words; ++i ) - if ( ! SERIALIZE(ntohl(addrp[i])) ) - return false; - if ( ! (SERIALIZE(val.subnet_val->Length()) && - info->s->WriteCloseTag("subnet")) ) - return false; - return true; - } + return SERIALIZE(*val.subnet_val); case TYPE_INTERNAL_OTHER: // Derived classes are responsible for this. @@ -296,71 +275,15 @@ bool Val::DoUnserialize(UnserialInfo* info) case TYPE_INTERNAL_ADDR: { - int num_words; - if ( ! UNSERIALIZE(&num_words) ) - return false; - - if ( num_words != 1 && num_words != 4 ) - { - info->s->Error("bad address type"); - return false; - } - - uint32 a[4]; // big enough to hold either - - for ( int i = 0; i < num_words; ++i ) - { - if ( ! UNSERIALIZE(&a[i]) ) - return false; - - a[i] = htonl(a[i]); - } - - if ( num_words == 1) - val.addr_val = new IPAddr(IPAddr::IPv4, a, IPAddr::Network); - else - val.addr_val = new IPAddr(IPAddr::IPv6, a, IPAddr::Network); + val.addr_val = new IPAddr(); + return UNSERIALIZE(val.addr_val); } - return true; case TYPE_INTERNAL_SUBNET: { - int num_words; - if ( ! UNSERIALIZE(&num_words) ) - return false; - - if ( num_words != 1 && num_words != 4 ) - { - info->s->Error("bad subnet type"); - return false; - } - - uint32 a[4]; // big enough to hold either - - for ( int i = 0; i < num_words; ++i ) - { - if ( ! UNSERIALIZE(&a[i]) ) - return false; - - a[i] = htonl(a[i]); - } - - int width; - if ( ! UNSERIALIZE(&width) ) - return false; - - if ( num_words == 1 ) - { - IPAddr tmp(IPAddr::IPv4, a, IPAddr::Network); - val.subnet_val = new IPPrefix(tmp, width); - } - else - { - IPAddr tmp(IPAddr::IPv6, a, IPAddr::Network); - val.subnet_val = new IPPrefix(tmp, width); - } + val.subnet_val = new IPPrefix(); + return UNSERIALIZE(val.subnet_val); } - return true; case TYPE_INTERNAL_OTHER: // Derived classes are responsible for this. @@ -569,10 +492,10 @@ void Val::ValDescribe(ODesc* d) const case TYPE_INTERNAL_UNSIGNED: d->Add(val.uint_val); break; case TYPE_INTERNAL_DOUBLE: d->Add(val.double_val); break; case TYPE_INTERNAL_STRING: d->AddBytes(val.string_val); break; - case TYPE_INTERNAL_ADDR: d->Add(string(*val.addr_val).c_str()); break; + case TYPE_INTERNAL_ADDR: d->Add(val.addr_val->AsString().c_str()); break; case TYPE_INTERNAL_SUBNET: - d->Add(string(*val.subnet_val).c_str()); + d->Add(val.subnet_val->AsString().c_str()); break; case TYPE_INTERNAL_ERROR: d->AddCS("error"); break; @@ -683,7 +606,7 @@ ID* MutableVal::Bind() const ip = htonl(0x7f000001); // 127.0.0.1 safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", - string(IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)).c_str(), + IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(), getpid()); #else safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid()); @@ -935,9 +858,10 @@ bool PortVal::DoUnserialize(UnserialInfo* info) AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR) { - val.addr_val = new IPAddr(string(text)); + val.addr_val = new IPAddr(text); } +#if 0 AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR) { // ### perhaps do gethostbyaddr here? @@ -948,6 +872,7 @@ AddrVal::AddrVal(const uint32* addr) : Val(TYPE_ADDR) { val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); } +#endif AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR) { @@ -991,6 +916,7 @@ SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET) const char* sep = strchr(text, '/'); if ( ! sep ) Internal("separator missing in SubNetVal::SubNetVal"); + val.subnet_val = new IPPrefix(text, atoi(sep+1)); } @@ -999,6 +925,7 @@ SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET) val.subnet_val = new IPPrefix(text, width); } +#if 0 SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET) { IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); @@ -1010,6 +937,7 @@ SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET) IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); val.subnet_val = new IPPrefix(a, width); } +#endif SubNetVal::SubNetVal(const IPAddr& addr, int width) : Val(TYPE_SUBNET) { @@ -1037,6 +965,7 @@ void SubNetVal::ValDescribe(ODesc* d) const d->Add(string(*val.subnet_val).c_str()); } +#if 0 IPAddr SubNetVal::Mask() const { if ( val.subnet_val->Length() == 0 ) @@ -1069,22 +998,20 @@ IPAddr SubNetVal::Mask() const bool SubNetVal::Contains(const uint32 addr) const { IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); - a.Mask(val.subnet_val->Length()); - return a == val.subnet_val->Prefix(); + return val.subnet_val->Contains(a); } bool SubNetVal::Contains(const uint32* addr) const { IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); - a.Mask(val.subnet_val->Length()); - return a == val.subnet_val->Prefix(); + return val.subnet_val->Contains(a); } +#endif bool SubNetVal::Contains(const IPAddr& addr) const { IPAddr a(addr); - a.Mask(val.subnet_val->Length()); - return a == val.subnet_val->Prefix(); + return val.subnet_val->Contains(a); } IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL); @@ -3300,9 +3227,9 @@ int same_atomic_val(const Val* v1, const Val* v2) case TYPE_INTERNAL_STRING: return Bstr_eq(v1->AsString(), v2->AsString()); case TYPE_INTERNAL_ADDR: - return *v1->AsAddr() == *v2->AsAddr(); + return v1->AsAddr() == v2->AsAddr(); case TYPE_INTERNAL_SUBNET: - return *v1->AsSubNet() == *v2->AsSubNet(); + return v1->AsSubNet() == v2->AsSubNet(); default: reporter->InternalError("same_atomic_val called for non-atomic value"); diff --git a/src/Val.h b/src/Val.h index 11a11dc6e5..e987726601 100644 --- a/src/Val.h +++ b/src/Val.h @@ -227,10 +227,10 @@ public: CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern) CONST_ACCESSOR(TYPE_VECTOR, vector*, vector_val, AsVector) - const IPPrefix* AsSubNet() const + const IPPrefix& AsSubNet() const { CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name) - return val.subnet_val; + return *val.subnet_val; } BroType* AsType() const @@ -239,11 +239,11 @@ public: return type; } - const IPAddr* AsAddr() const + const IPAddr& AsAddr() const { if ( type->Tag() != TYPE_ADDR ) BadTag("Val::AsAddr", type_name(type->Tag())); - return val.addr_val; + return *val.addr_val; } #define ACCESSOR(tag, ctype, accessor, name) \ @@ -562,8 +562,10 @@ public: Val* SizeVal() const; // Constructor for address already in network order. +#if 0 AddrVal(uint32 addr); AddrVal(const uint32* addr); +#endif AddrVal(const IPAddr& addr); unsigned int MemoryAllocation() const; @@ -581,8 +583,10 @@ class SubNetVal : public Val { public: SubNetVal(const char* text); SubNetVal(const char* text, int width); +#if 0 SubNetVal(uint32 addr, int width); SubNetVal(const uint32* addr, int width); +#endif SubNetVal(const IPAddr& addr, int width); ~SubNetVal(); @@ -590,10 +594,12 @@ public: const IPAddr& Prefix() const { return val.subnet_val->Prefix(); } int Width() const { return val.subnet_val->Length(); } +#if 0 IPAddr Mask() const; - bool Contains(const uint32 addr) const; bool Contains(const uint32* addr) const; +#endif + bool Contains(const IPAddr& addr) const; unsigned int MemoryAllocation() const; diff --git a/src/bro.bif b/src/bro.bif index e5f5a6d6c3..cc3c2f335c 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -179,9 +179,10 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d) // This makes only a very slight difference, so not // clear it would e worth the hassle. - const IPAddr* u = v->AsAddr(); + const IPAddr& u = v->AsAddr(); const uint32* net_order_u; int len = u->GetBytes(&net_order_u); + if ( len == 4 ) { // We explicitly convert the address to host order @@ -1974,21 +1975,29 @@ function is_local_interface%(ip: addr%) : bool host[MAXHOSTNAMELEN-1] = '\0'; struct hostent* ent = gethostbyname2(host, AF_INET); + if ( ent ) + { for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) addrs.push_back(IPAddr(IPAddr::IPv4, (uint32*)ent->h_addr_list[len], IPAddr::Network)); + } ent = gethostbyname2(host, AF_INET6); + if ( ent ) + { for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) addrs.push_back(IPAddr(IPAddr::IPv6, (uint32*)ent->h_addr_list[len], IPAddr::Network)); + } list::const_iterator it; for ( it = addrs.begin(); it != addrs.end(); ++it ) - if ( *it == *ip->AsAddr() ) + { + if ( *it == ip->AsAddr() ) return new Val(1, TYPE_BOOL); + } return new Val(0, TYPE_BOOL); %} @@ -2058,7 +2067,7 @@ function is_v4_addr%(a: addr%): bool ## Returns: true if *a* is an IPv6 address, else false. function is_v6_addr%(a: addr%): bool %{ - if ( a->AsAddr()->family() == IPAddr::IPv6 ) + if ( a->AsAddr().Family() == IPAddr::IPv6 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -2479,7 +2488,7 @@ function addr_to_ptr_name%(a: addr%): string ## .. bro:see:: addr_to_ptr_name parse_dotted_addr function parse_dotted_addr%(s: string%): addr %{ - IPAddr a(string(s->CheckString())); + IPAddr a(s->CheckString()); return new AddrVal(a); %} @@ -2991,7 +3000,7 @@ function strftime%(fmt: string, d: time%) : string ## .. bro:see:: remask_addr function mask_addr%(a: addr, top_bits_to_keep: count%): subnet %{ - return new SubNetVal(*a->AsAddr(), top_bits_to_keep); + return new SubNetVal(a->AsAddr(), top_bits_to_keep); %} ## Takes some top bits (e.g., subnet address) from one address and the other @@ -3013,9 +3022,9 @@ function mask_addr%(a: addr, top_bits_to_keep: count%): subnet ## .. bro:see:: mask_addr function remask_addr%(a1: addr, a2: addr, top_bits_from_a1: count%): addr %{ - IPAddr addr1(*a1->AsAddr()); + IPAddr addr1(a1->AsAddr()); addr1.Mask(top_bits_from_a1); - IPAddr addr2(*a2->AsAddr()); + IPAddr addr2(a2->AsAddr()); addr1.ReverseMask(top_bits_from_a1); uint32 x1[4]; uint32 x2[4]; @@ -3196,13 +3205,13 @@ const char* conn_id_string(Val* c) Val* id = (*(c->AsRecord()))[0]; const val_list* vl = id->AsRecord(); - const IPAddr* orig_h = (*vl)[0]->AsAddr(); + const IPAddr& orig_h = (*vl)[0]->AsAddr(); uint32 orig_p = (*vl)[1]->AsPortVal()->Port(); - const IPAddr* resp_h = (*vl)[2]->AsAddr(); + const IPAddr& resp_h = (*vl)[2]->AsAddr(); uint32 resp_p = (*vl)[3]->AsPortVal()->Port(); - return fmt("%s/%u -> %s/%u\n", string(*orig_h).c_str(), orig_p, - string(*resp_h).c_str(), resp_p); + return fmt("%s/%u -> %s/%u\n", orig_h.AsString().c_str(), orig_p, + resp_h.AsString().c_str(), resp_p); } %%} @@ -3432,7 +3441,7 @@ function lookup_addr%(host: addr%) : string frame->SetDelayed(); trigger->Hold(); - if ( host->AsAddr()->family() != IPAddr::IPv4 ) + if ( host->AsAddr().Family() != IPAddr::IPv4 ) { // FIXME: This is a temporary work-around until we get this // fixed. We warn the user once, and always trigger a timeout. @@ -3449,7 +3458,7 @@ function lookup_addr%(host: addr%) : string } const uint32* bytes; - host->AsAddr()->GetBytes(&bytes); + host->AsAddr().GetBytes(&bytes); dns_mgr->AsyncLookupAddr(*bytes, new LookupHostCallback(trigger, frame->GetCall(), true)); return 0; @@ -3558,10 +3567,10 @@ function lookup_location%(a: addr%) : geo_location } #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( geoip_v6 && a->AsAddr()->family() == IPAddr::IPv6 ) + if ( geoip_v6 && a->AsAddr().Family() == IPAddr::IPv6 ) { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); geoipv6_t ga; memcpy(&ga, bytes, 16); if ( have_cityv6_db ) @@ -3572,10 +3581,10 @@ function lookup_location%(a: addr%) : geo_location else #endif - if ( geoip && a->AsAddr()->family() == IPAddr::IPv4 ) + if ( geoip && a->AsAddr().Family() == IPAddr::IPv4 ) { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); if ( have_city_db ) gir = GeoIP_record_by_ipnum(geoip, ntohl(*bytes)); else @@ -3658,7 +3667,7 @@ function lookup_asn%(a: addr%) : count if ( a->AsAddr()->family() == IPAddr::IPv6 ) { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); geoipv6_t ga; memcpy(&ga, bytes, 16); gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga); @@ -3666,10 +3675,10 @@ function lookup_asn%(a: addr%) : count else #endif - if ( a->AsAddr()->family() == IPAddr::IPv4 ) + if ( a->AsAddr().Family() == IPAddr::IPv4 ) { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(*bytes)); } } @@ -3953,7 +3962,7 @@ function file_mode%(mode: count%): string function expect_connection%(orig: addr, resp: addr, resp_p: port, analyzer: count, tout: interval%) : any %{ - dpm->ExpectConnection(*orig->AsAddr(), *resp->AsAddr(), resp_p->Port(), + dpm->ExpectConnection(orig->AsAddr(), resp->AsAddr(), resp_p->Port(), resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0); return new Val(1, TYPE_BOOL); %} @@ -4727,7 +4736,7 @@ function pcap_error%(%): string ## .. todo:: The return value should be changed to any. function install_src_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool %{ - sessions->GetPacketFilter()->AddSrc(*ip->AsAddr(), tcp_flags, prob); + sessions->GetPacketFilter()->AddSrc(ip->AsAddr(), tcp_flags, prob); return new Val(1, TYPE_BOOL); %} @@ -4779,7 +4788,7 @@ function install_src_net_filter%(snet: subnet, tcp_flags: count, prob: double%) ## pcap_error function uninstall_src_addr_filter%(ip: addr%) : bool %{ - return new Val(sessions->GetPacketFilter()->RemoveSrc(*ip->AsAddr()), TYPE_BOOL); + return new Val(sessions->GetPacketFilter()->RemoveSrc(ip->AsAddr()), TYPE_BOOL); %} ## Removes a source subnet filter. @@ -4829,7 +4838,7 @@ function uninstall_src_net_filter%(snet: subnet%) : bool ## .. todo:: The return value should be changed to any. function install_dst_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool %{ - sessions->GetPacketFilter()->AddDst(*ip->AsAddr(), tcp_flags, prob); + sessions->GetPacketFilter()->AddDst(ip->AsAddr(), tcp_flags, prob); return new Val(1, TYPE_BOOL); %} @@ -4881,7 +4890,7 @@ function install_dst_net_filter%(snet: subnet, tcp_flags: count, prob: double%) ## pcap_error function uninstall_dst_addr_filter%(ip: addr%) : bool %{ - return new Val(sessions->GetPacketFilter()->RemoveDst(*ip->AsAddr()), TYPE_BOOL); + return new Val(sessions->GetPacketFilter()->RemoveDst(ip->AsAddr()), TYPE_BOOL); %} ## Removes a destination subnet filter. @@ -5022,7 +5031,7 @@ function capture_state_updates%(filename: string%) : bool ## send_id function connect%(ip: addr, p: port, our_class: string, retry: interval, ssl: bool%) : count %{ - return new Val(uint32(remote_serializer->Connect(*ip->AsAddr(), p->Port(), + return new Val(uint32(remote_serializer->Connect(ip->AsAddr(), p->Port(), our_class->CheckString(), retry, ssl)), TYPE_COUNT); %} @@ -5137,7 +5146,7 @@ function set_compression_level%(p: event_peer, level: count%) : bool ## .. bro:see:: connect disconnect function listen%(ip: addr, p: port, ssl: bool %) : bool %{ - return new Val(remote_serializer->Listen(*ip->AsAddr(), p->Port(), ssl), TYPE_BOOL); + return new Val(remote_serializer->Listen(ip->AsAddr(), p->Port(), ssl), TYPE_BOOL); %} ## Checks whether the last raised event came from a remote peer. @@ -5393,12 +5402,12 @@ function preserve_prefix%(a: addr, width: count%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsAddr()->family() == IPAddr::IPv6 ) + if ( a->AsAddr().Family() == IPAddr::IPv6 ) builtin_error("preserve_prefix() not supported for IPv6 addresses"); else { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); ip_anon->PreservePrefix(*bytes, width); } } @@ -5418,16 +5427,16 @@ function preserve_prefix%(a: addr, width: count%): any ## .. todo:: Currently dysfunctional. function preserve_subnet%(a: subnet%): any %{ - DEBUG_MSG("%s/%d\n", string(a->Prefix()).c_str(), a->Width()); + DEBUG_MSG("%s/%d\n", a->Prefix().AsString().c_str(), a->Width()); AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsSubNet()->Prefix().family() == IPAddr::IPv6 ) + if ( a->AsSubNet()->Prefix().Family() == IPAddr::IPv6 ) builtin_error("preserve_subnet() not supported for IPv6 addresses"); else { const uint32* bytes; - a->AsSubNet()->Prefix().GetBytes(&bytes); + a->AsSubNet().Prefix().GetBytes(&bytes); ip_anon->PreservePrefix(*bytes, a->AsSubNet()->Length()); } } @@ -5458,7 +5467,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES ) builtin_error("anonymize_addr(): invalid ip addr anonymization class"); - if ( a->AsAddr()->family() == IPAddr::IPv6 ) + if ( a->AsAddr().Family() == IPAddr::IPv6 ) { builtin_error("anonymize_addr() not supported for IPv6 addresses"); return 0; @@ -5466,7 +5475,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr else { const uint32* bytes; - a->AsAddr()->GetBytes(&bytes); + a->AsAddr().GetBytes(&bytes); return new AddrVal(anonymize_ip(*bytes, (enum ip_addr_anonymization_class_t) anon_class)); } @@ -5519,7 +5528,7 @@ function generate_idmef%(src_ip: addr, src_port: port, newNode(newAddress( newAttribute("category","ipv4-addr"), newSimpleElement("address", - copy_string(string(*src_ip->AsAddr()).c_str())), + copy_string(src_ip->AsAddr().AsString().c_str())), NULL), NULL), newService( newSimpleElement("port", @@ -5529,7 +5538,7 @@ function generate_idmef%(src_ip: addr, src_port: port, newNode(newAddress( newAttribute("category","ipv4-addr"), newSimpleElement("address", - copy_string(string(*dst_ip->AsAddr()).c_str())), + copy_string(dst_ip->AsAddr().AsString().c_str())), NULL), NULL), newService( newSimpleElement("port", From 93fa1167381f3b450c05426867577ffbe47eb32b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 16 Feb 2012 11:21:12 -0600 Subject: [PATCH 23/49] Various tweaks/refactor of new IPAddr class usages or IPv6 related code. - non-binpac DNS analyzer now also generates dns_a6_reply event - ExpectedConn class refactored to use IPAddr's - BinaryExpr::AddrFold simplified - IP_Hdr src/dst address accessor methods changed to construct IPAddr objects on the fly from ip4/ip6 members. Addresses #770. --- src/DNS.cc | 14 +++++++++--- src/DPM.cc | 64 +++++++++++++++++++++++++++-------------------------- src/DPM.h | 6 +++-- src/Expr.cc | 32 +++++++++++++++++---------- src/IP.h | 20 +++++++---------- 5 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/DNS.cc b/src/DNS.cc index 40fe832e34..a3b0b62ef3 100644 --- a/src/DNS.cc +++ b/src/DNS.cc @@ -766,12 +766,20 @@ int DNS_Interpreter::ParseRR_AAAA(DNS_MsgInfo* msg, if ( len < 0 ) { - analyzer->Weird("DNS_AAAA_neg_length"); + if ( msg->atype == TYPE_AAAA ) + analyzer->Weird("DNS_AAAA_neg_length"); + else + analyzer->Weird("DNS_A6_neg_length"); return 0; } } - if ( dns_AAAA_reply && ! msg->skip_event ) + EventHandlerPtr event; + if ( msg->atype == TYPE_AAAA ) + event = dns_AAAA_reply; + else + event = dns_A6_reply; + if ( event && ! msg->skip_event ) { val_list* vl = new val_list; @@ -779,7 +787,7 @@ int DNS_Interpreter::ParseRR_AAAA(DNS_MsgInfo* msg, vl->append(msg->BuildHdrVal()); vl->append(msg->BuildAnswerVal()); vl->append(new AddrVal(addr)); - analyzer->ConnectionEvent(dns_AAAA_reply, vl); + analyzer->ConnectionEvent(event, vl); } return 1; diff --git a/src/DPM.cc b/src/DPM.cc index 2700c92933..c02db08c2f 100644 --- a/src/DPM.cc +++ b/src/DPM.cc @@ -17,22 +17,37 @@ ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp, if ( _orig == IPAddr(string("0.0.0.0")) ) // don't use the IPv4 mapping, use the literal unspecified address // to indicate a wildcard - orig[0] = orig[1] = orig[2] = orig[3] = 0; + orig = IPAddr(string("::")); else - _orig.CopyIPv6(orig); - _resp.CopyIPv6(resp); + orig = _orig; + resp = _resp; resp_p = _resp_p; proto = _proto; } ExpectedConn::ExpectedConn(const ExpectedConn& c) { - memcpy(orig, c.orig, sizeof(orig)); - memcpy(resp, c.resp, sizeof(resp)); + orig = c.orig; + resp = c.resp; resp_p = c.resp_p; proto = c.proto; } +HashKey* ExpectedConn::GetKey() const + { + struct Key { + uint32 orig[4]; + uint32 resp[4]; + uint16 resp_p; + uint16 proto; + }; + Key k; + orig.CopyIPv6(k.orig); + resp.CopyIPv6(k.resp); + k.resp_p = resp_p; + k.proto = proto; + return new HashKey(&k, sizeof(k)); + } DPM::DPM() : expected_conns_queue(AssignedAnalyzer::compare) @@ -134,23 +149,18 @@ AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn) ExpectedConn c(conn->OrigAddr(), conn->RespAddr(), ntohs(conn->RespPort()), proto); - // Can't use sizeof(c) due to potential alignment issues. - // FIXME: I guess this is still not portable ... - HashKey key(&c, sizeof(c.orig) + sizeof(c.resp) + - sizeof(c.resp_p) + sizeof(c.proto)); - - AssignedAnalyzer* a = expected_conns.Lookup(&key); + HashKey* key = c.GetKey(); + AssignedAnalyzer* a = expected_conns.Lookup(key); + delete key; if ( ! a ) { // Wildcard for originator. - for ( int i = 0; i < 4; ++i ) - c.orig[i] = 0; + c.orig = IPAddr(string("::")); - HashKey key(&c, sizeof(c.orig) + sizeof(c.resp) + - sizeof(c.resp_p) + sizeof(c.proto)); - - a = expected_conns.Lookup(&key); + HashKey* key = c.GetKey(); + a = expected_conns.Lookup(key); + delete key; } if ( ! a ) @@ -393,11 +403,7 @@ void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, { if ( ! a->deleted ) { - HashKey* key = new HashKey(&a->conn, - sizeof(a->conn.orig) + - sizeof(a->conn.resp) + - sizeof(a->conn.resp_p) + - sizeof(a->conn.proto)); + HashKey* key = a->conn.GetKey(); expected_conns.Remove(key); delete key; } @@ -416,10 +422,9 @@ void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, ExpectedConn c(orig, resp, resp_p, proto); - HashKey key(&c, sizeof(c.orig) + sizeof(c.resp) + - sizeof(c.resp_p) + sizeof(c.proto)); + HashKey* key = c.GetKey(); - AssignedAnalyzer* a = expected_conns.Lookup(&key); + AssignedAnalyzer* a = expected_conns.Lookup(key); if ( a ) a->deleted = true; @@ -431,8 +436,9 @@ void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, a->timeout = network_time + timeout; a->deleted = false; - expected_conns.Insert(&key, a); + expected_conns.Insert(key, a); expected_conns_queue.push(a); + delete key; } void DPM::Done() @@ -443,11 +449,7 @@ void DPM::Done() AssignedAnalyzer* a = expected_conns_queue.top(); if ( ! a->deleted ) { - HashKey* key = new HashKey(&a->conn, - sizeof(a->conn.orig) + - sizeof(a->conn.resp) + - sizeof(a->conn.resp_p) + - sizeof(a->conn.proto)); + HashKey* key = a->conn.GetKey(); expected_conns.Remove(key); delete key; } diff --git a/src/DPM.h b/src/DPM.h index b3e5f8f17f..7e9150f3aa 100644 --- a/src/DPM.h +++ b/src/DPM.h @@ -32,8 +32,10 @@ public: ExpectedConn(const ExpectedConn& c); - uint32 orig[4]; - uint32 resp[4]; + HashKey* GetKey() const; + + IPAddr orig; + IPAddr resp; uint16 resp_p; uint16 proto; }; diff --git a/src/Expr.cc b/src/Expr.cc index 848fe6d351..c995ae3d17 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -835,22 +835,30 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const { - uint32 a1[4]; - uint32 a2[4]; - v1->AsAddr()->CopyIPv6(a1); - v2->AsAddr()->CopyIPv6(a2); + IPAddr* a1 = v1->AsAddr(); + IPAddr* a2 = v2->AsAddr(); int result = 0; switch ( tag ) { -#undef DO_FOLD -#define DO_FOLD(sense) { result = memcmp(a1, a2, 16) sense 0; break; } - case EXPR_LT: DO_FOLD(<) - case EXPR_LE: DO_FOLD(<=) - case EXPR_EQ: DO_FOLD(==) - case EXPR_NE: DO_FOLD(!=) - case EXPR_GE: DO_FOLD(>=) - case EXPR_GT: DO_FOLD(>) + case EXPR_LT: + result = *a1 < *a2; + break; + case EXPR_LE: + result = *a1 < *a2 || *a1 == *a2; + break; + case EXPR_EQ: + result = *a1 == *a2; + break; + case EXPR_NE: + result = *a1 != *a2; + break; + case EXPR_GE: + result = ! ( *a1 < *a2 ); + break; + case EXPR_GT: + result = ( ! ( *a1 < *a2 ) ) && ( *a1 != *a2 ); + break; default: BadTag("BinaryExpr::AddrFold", expr_name(tag)); diff --git a/src/IP.h b/src/IP.h index 5733f633a2..ba37fb4c69 100644 --- a/src/IP.h +++ b/src/IP.h @@ -10,26 +10,22 @@ class IP_Hdr { public: IP_Hdr(struct ip* arg_ip4) - : ip4(arg_ip4), ip6(0), - src_addr(arg_ip4->ip_src), dst_addr(arg_ip4->ip_dst), del(1) + : ip4(arg_ip4), ip6(0), del(1) { } IP_Hdr(const struct ip* arg_ip4) - : ip4(arg_ip4), ip6(0), - src_addr(arg_ip4->ip_src), dst_addr(arg_ip4->ip_dst), del(0) + : ip4(arg_ip4), ip6(0), del(0) { } IP_Hdr(struct ip6_hdr* arg_ip6) - : ip4(0), ip6(arg_ip6), - src_addr(arg_ip6->ip6_src), dst_addr(arg_ip6->ip6_dst), del(1) + : ip4(0), ip6(arg_ip6), del(1) { } IP_Hdr(const struct ip6_hdr* arg_ip6) - : ip4(0), ip6(arg_ip6), - src_addr(arg_ip6->ip6_src), dst_addr(arg_ip6->ip6_dst), del(0) + : ip4(0), ip6(arg_ip6), del(0) { } @@ -47,8 +43,10 @@ public: const struct ip* IP4_Hdr() const { return ip4; } const struct ip6_hdr* IP6_Hdr() const { return ip6; } - const IPAddr& SrcAddr() const { return src_addr; } - const IPAddr& DstAddr() const { return dst_addr; } + IPAddr SrcAddr() const + { return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); } + IPAddr DstAddr() const + { return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); } //TODO: needs adapting/replacement for IPv6 support uint16 ID4() const { return ip4 ? ip4->ip_id : 0; } @@ -92,8 +90,6 @@ public: private: const struct ip* ip4; const struct ip6_hdr* ip6; - IPAddr src_addr; - IPAddr dst_addr; int del; }; From 278704f7a366546f915d8638f9fdef5caa8c177f Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Thu, 16 Feb 2012 15:17:55 -0600 Subject: [PATCH 24/49] Add a test for FTP over IPv6 --- .../conn.log | 13 +++++++++++++ .../scripts.base.protocols.ftp.ftp-ipv6/ftp.log | 9 +++++++++ testing/btest/Traces/ipv6-ftp.trace | Bin 0 -> 18679 bytes .../scripts/base/protocols/ftp/ftp-ipv6.bro | 6 ++++++ 4 files changed, 28 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log create mode 100644 testing/btest/Traces/ipv6-ftp.trace create mode 100644 testing/btest/scripts/base/protocols/ftp/ftp-ipv6.bro diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log new file mode 100644 index 0000000000..6bab9332c8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes +#types time string addr port addr port enum string interval count count string bool count string count count count count +1329327783.316897 arKYeMETxOg 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49186 2001:470:4867:99::21 57086 tcp ftp-data 0.219721 0 342 SF - 0 ShAdfFa 5 372 4 642 +1329327786.524332 k6kgXLOoSKl 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49187 2001:470:4867:99::21 57087 tcp ftp-data 0.217501 0 43 SF - 0 ShAdfFa 5 372 4 343 +1329327787.289095 nQcgTWjvg4c 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49188 2001:470:4867:99::21 57088 tcp ftp-data 0.217941 0 77 SF - 0 ShAdfFa 5 372 4 377 +1329327795.571921 j4u32Pc5bif 2001:470:4867:99::21 55785 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49189 tcp ftp-data 0.109813 77 0 SF - 0 ShADFaf 5 449 4 300 +1329327800.017649 TEfuqmmG4bh 2001:470:4867:99::21 55647 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49190 tcp ftp-data 0.109181 342 0 SF - 0 ShADFaf 5 714 4 300 +1329327777.822004 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 tcp ftp 26.658219 310 3448 SF - 0 ShAdDfFa 57 4426 34 5908 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log new file mode 100644 index 0000000000..670855414e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log @@ -0,0 +1,9 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ftp +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type mime_desc file_size reply_code reply_msg tags extraction_file +#types time string addr port addr port string string string string string string count count string table[string] file +1329327787.396984 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://2001:470:4867:99::21/robots.txt - - 77 226 Transfer complete. - - +1329327795.463946 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://2001:470:4867:99::21/robots.txt - - 77 226 Transfer complete. - - diff --git a/testing/btest/Traces/ipv6-ftp.trace b/testing/btest/Traces/ipv6-ftp.trace new file mode 100644 index 0000000000000000000000000000000000000000..81313fac11b5270986b03b04c0aaeb8e7ef6fbd3 GIT binary patch literal 18679 zcmeHPdwdjCmagt}0we?wQ5bdC%Oj9Lclwc#M+2G=fRGqRCiaBmVVjQAqixM zs5?FY-y_QEsQB1*#C7oPPmzf-?u_n?KW7D%aX^^`M;@z-JGv|CWWQ6ltNM{ficS5w z{YxdO>hAm9^PO|g{qE^oy?4*E+s%SSP#*&Wf?&eQ_RnW6{>!G3f*1eO@u9=J;LR6) zWzCrteDcNvYj8!d=G8EhC3^8W!!LeoTj5Wi>@B^7&KI-`+vsULCiYJh&YQaF$E)dN zr+Hvt-YtS)w&Xr+%E>XAOvCftrejU?oW;x$ueFZS5IGjd)ex&P5i)xqoYy}wFZMrE zfVyVq*fB!+A2h@~LIjwJP%UPYiEKOt#AUchM;05IZX4GCwWx1QU!&y^Ah>NW6WSv{ zIsT#`+>H}DGVQwP3t?5BUb~9OuD%IEUH^?7g%DuR%PyCLwZ)^QO;UWWXI^O}*3Ra) zHZxg@t&?J`m|wQx6@KP&I312Mm!pKmB+=hfT9{8=T=xd>e6P~0a z3;j!U)9(fSQKEnM^BffoTHL0S_m-78*=3!Q9B08udmzjrYppEa6O~v`q%+3CVn|}5 z%%Y+!cST};P)^T!wcR#$6fOFgxP`P2rY z&>NMRFA@&p{eg9O1x`9+@JebXF>s4EtVYAs-U1uyNh2y~< z=IM+^(I>Fd92Dbikr?`kSJ-BxW7%yC?X0oc8JniI)XSLYi^Re!Tou+b*D5O$gYA(R z{fTyn_!IJ1l!FtzEag#bUukFP7cSXXrnH2Y2inCI)@am6EyaBJ6&GUxEAvX;NVmdm zdP{a#MXj%)*3+7Tmt`ySNpf2N&G;f-F&MWpKT>tbC(8IYvr~)NVq7ax8cZ?;IBA`C zg%}H2LxHGFU9-v^W$0cW6XQZ95veaZIZ4!k>1 zR#l+|PFhpNt4m85v5w!&o=O$Y1Kv=$3q}TdBH;ko33i6XiYjEx#3QXG#!3+e_BHfe zdP5=6w<1LE!+sbGNAwZ958SO9@S{IU1n?l@o1;TzQhECE0?aZck zmMUimN;^{`GtF^fsY~XKP*1>4Sn7@|W<}bF{gifk=isrpq@-ldoD#MYuA}oLNztH) zK_|uok+93kq9G9+MPpLb%49L@k46Gvgn`gwclO;P01^g!X5tg`#}sX6%62G%WwiA;KAMvgM(=?N_aDHZ8> zq^2UoF&@RN7~=wYL^)Hv?vW%$QlU%o%7Hl4LY#HP<59QW-qqEWqUtDZC=Ym=S(Oe@ z1gQPhB9bkaNQxkz1(jJO9uvcI8zLIo$d9xV3gNHJ16pYhA+$m1k@5?}ws?Lcf)n=g z*_K{Ze?{}+mR8oZxV53Kp7)&pZVpPKEU|C|J&$*w@06AizB0`@@s5DZ#V8qusVOdE z67$7+qVY(3OpJB}e7qGo(iZO$WBfI-NHB=R-bup{O-QW1n;K=c{!kzskYNu2U@mO$ zMDACxitB4zN}#Q%tNeFUBn(;;UC^2ji9JZn%pd6r2P2{%D3KV803+5FfEAJgq+I2# z#3Y+`4P!6Dit&2<5h3gdSqxGGF-Z>iF)snH1ap)Zvq%F-x3b27w?|A&tDa6jU21|Q z9c*C)S>1{mHWm=61u={{nz}(#b~qmEA&@T6)1eTswA53|Iz(t%GEfS6#aMd;-E4;z zkkibb+oKs52)9$yoihC+ivd4VX|R$u#bkw8YmZ41Jr6j*^Y$^DO6^EB2q6TF`ch;e z*a<7uC*Us_shlc~S6_%w;O!)Ji#5fW6b0}wxUwpipN>i5gtsGif(DfrSOnh_U&`em z;sFF8PzQ-{(TAy2Cg;Rs0VpDhNiiA?(z1uriuHPvQOQd-&FvfWW6ytFqb09DtI2Ek zPfVI5&Z5Dm>ek>J@(2YQyz;4Z6wj5OR&LR%X*otLc7TIKc^%2`2insT<)2;7nQUoO z!xgL*D;zg#tYXWMSU{~ip#C#W}_heH|!}X|Z$cGnImGTU4SiD#Gp@5sWCDj?L$FJ%xVN`=W~HO5qPK+iYSmtY#`s;}xg0!~ANd!Jfrnsj0r7lj zpG7OWW{F@uW!^~#|60&=crRL1%DlPbw4!UG%sW76N|~1s<=#9EF_Ue)%z9?F5B{}( z(g!ZvT|nKpb8Mfmu|h*kDf13IL}gw=topkl=K^lyKA=*mt?`$$6HJ-~rKn6OyMUrr zzOpc>f12n1Lc~_xmWEQ$*g(@fVZB^5T(}iv(UHj^O3KU6%%M^$M_eFc@1ux)Em1r~ zgCpIr$~n`)7DuHp1#GRSuAza2C`$b(ZIFsr3QSO85Q=P?-5UtogYq<}D(akPszC|j zJ_PPs(Cs+L8&UE*&mBg*qo485Ed*vBjiga!Q2J-4sTB6U@0+v~m<6n23US zBo1+3UE!>B73K$HUETC!>!vzeEE0(`sB=jQk{nkaWiD3R+0L953`KTFH7gB4dy4H6 zvt7cXonAYy?%6SO&0ADo%GVUOgcL5!_w&YW)P7mE_GdaX+Lz*3IoV=e$`2}I=vIZp zfv%u{;g$W2l~=o*<>i;T)|jMEMHQ5b zem=q&`NI8$h%M<&LmAtIMIMihyhR1V?Et1DlS9atE6<#n6Y}LbMC@Y}u@@v3XJ`-+ zJMyNpkuPn5Aj+kvB9VY0!W+=NArj6L(PIeR6Cm9F!4n!4C#j2svY@FzxDF?DWRQ^i z-=l?vXC~nw4yY|C3qlC~It zf?2tsQA7C>aiK8w@X3+J%*rR!(Q@-fjWHT6Cr>vk6O#vlKE$Zd215=l_iH{lPqnd- z>L$uyVBaQDh7=X65ET%+$R=cC&7ruja zhEg@dPMD$g8{)I4VCMw*Z0`F%Qtcd71(VJtlxr?D2`COLM;11ny4mC? zU~`XJJvVa{D(_)kl3Y9x?9zU-=EN+t7VD;U0%(1WXniV?rpPcipk2-~R$0lZ{1ea& zq4G6Q$w1|TeVFyQj2ZQ)N@ddX?D?@nR1D>0~bNN2Cs%RcPO6B>oz>uq5Q$7~1{q;xGRYfk|_qZnB z5^_;NQ{*DqHFnfct6d)p{Zp0{_>Kd0Imt!uRt+&lE{+~Wa*+_P2I3Hzws5l2A4I6_$j6v`uXWH6F@$95rfW=0YLc7g(oWaJx1HAXOVj$XeM`$%mlWQF5y zHa&k{K*qL$NEiMujkm8)JI^?cd()rxu6HTKY#TZ;T7>$mK}^vjsKWA`I+}=4B6J`H zB?~b+geE7(U#$=Wp~(`HJs}V=ij!X&vXhgxxD{Kl0L`@JfnA28Kxl6NL__&hW$eyn z#*}|@wyJ~c?|;EjfIx%m$mxV8G5I~vhnTmx(4^t=G?=V;Z@y~d7>IX1T%_eAjLBOZ z1$pbYccr7yN1B83R=1cmZb-rCMlfDM`j!=I)KV~hN)#SHm2ZsVd>RfsLfP@g%QX}@ za7+_PBdTsYs+<*0r^``R#dF>L-{u?Ryd!Yl8*tv-f75FIV`wM+xaVNssyB0taUMs3 z^B#Fqb)M}TLK&nu33l~0xyC5YH$dyxMC)dh@Df6PvfFI?Mpc}Ib^vIGjDxR1<=dcg z!SjDqjV$%S$jOAVb8W7$87FjP5${WNi+7F!Du4D-I!b*rc8m48dJ!&8cX_45?QC;8 z-Br#ux39Xo+U>6{cZ*`B&+U@Rq~7vsXH_-!98%Xl8aqsgqg!-jj1^ipU2^6bEwOHT zd+Mf*Gl=f%f2Pqr#ceM2(Yi_LUSca8Z6uLHgg?nxhAn50a;t)(Rels(6qLMnLs1|{_xz`33p^w!C_D0use4*V z)xqWagrks8$Tz2xqr_zOuw+FtgGszym%oxxF&|9UJlm<-=sm4JFVe=}mxs=$v?|h9-tJ{2OWo9|K7Gj8yr#O?*lEqFvsf!PV zrC>8mY(8?IX6JU;X(g1^u91c)(v2JiY;O98bdij?~BF8W|dNN<7@X#SY9U0W8^P=VA&DBBJuZ{N(~YTcXIHgXg=;j8hg z6F3Ur#P%|i*R|zq|ewp!Smty|Pq8Ovuoh4d{#_LkV%&@#H5lS!~oJL%EIpKz)@G?bc7U z$bk&4*+3|<6DC8p16sBqKJTFT?0H2)L44MXN|m8!u^o^)_Z2#4NZ{Uqz}j$HRzeqAR zWLw75cEI!BAB^(#9XW<jY~9YkybuEod72$ue;Njdxkbr-uMW4qvm1M z3`jk?&9zI^ydiE)q6{ha#v}H2QG&kbZ#W7NC~tha3%0nP%r)fm-GnWeRzJH+wPguO zY}=Bh4cJ^oSeLg9)37ouqVk#EZ(smt@Y+_I3?6z&v#7#tUUH4g<-|8I5Y`*O8f(J7 z2OL?j{;0Q9XTeP=!1|F;*VdPgMO&-q(WZ0U^Vx>G;*}le%1xy*3U;{djCJ9=HJmfc z`DbtR4GAtrJG#`HB3qSR+&}p4a!PEY2Uzt_Yy2o; Ii>ZD83rTW1%m4rY literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ftp/ftp-ipv6.bro b/testing/btest/scripts/base/protocols/ftp/ftp-ipv6.bro new file mode 100644 index 0000000000..7ce31808c9 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ftp/ftp-ipv6.bro @@ -0,0 +1,6 @@ +# This tests both active and passive FTP over IPv6. +# +# @TEST-EXEC: bro -r $TRACES/ipv6-ftp.trace +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ftp.log + From 94b9644da78ad724e830b6bef3510fef04e8c88e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 16 Feb 2012 18:23:26 -0800 Subject: [PATCH 25/49] Working on merging the v6-addr branch. This is checkpoint, tests don't pass yet. Changes: - Gave IPAddress/IPPrefix methods AsString() so that one doesn't need to cast to get a string represenation. - Val::AsAddr()/AsSubnet() return references rather than pointers. I find that more intuitive. - ODesc/Serializer/SerializationFormat get methods to support IPAddress/IPPrefix directly. - Reformatted the comments in IPAddr.h from /// to /** style. - Given IPPrefix a Contains() method. - A bit of cleanup. --- src/Analyzer.h | 1 + src/CompHash.cc | 12 +++---- src/ConnCompressor.cc | 4 +-- src/DCE_RPC.cc | 3 +- src/DCE_RPC.h | 2 +- src/DNS_Mgr.cc | 16 ++++----- src/Desc.cc | 12 ------- src/Desc.h | 7 ++-- src/Expr.cc | 2 +- src/IPAddr.cc | 20 +++--------- src/IPAddr.h | 40 +++++++++++++---------- src/LogMgr.cc | 6 ++-- src/RemoteSerializer.cc | 4 +-- src/RuleMatcher.cc | 4 +-- src/SerializationFormat.cc | 66 +++++++++++++++++++++++++++++++++++--- src/SerializationFormat.h | 8 +++++ src/Serializer.h | 4 +++ src/Val.cc | 20 ++---------- src/Val.h | 24 +++++--------- src/bro.bif | 34 ++++++++++---------- 20 files changed, 160 insertions(+), 129 deletions(-) diff --git a/src/Analyzer.h b/src/Analyzer.h index 86cfb0266b..7797e215fe 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -1,3 +1,4 @@ +// Main analyzer interface. #ifndef ANALYZER_H #define ANALYZER_H diff --git a/src/CompHash.cc b/src/CompHash.cc index 77a06976fb..ecd2543050 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -109,7 +109,7 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, { uint32* kp = AlignAndPadType(kp0); uint32 bytes[4]; - v->AsAddr()->CopyIPv6(bytes); + v->AsAddr().CopyIPv6(bytes); kp[0] = bytes[0]; kp[1] = bytes[1]; kp[2] = bytes[2]; @@ -122,12 +122,12 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, { uint32* kp = AlignAndPadType(kp0); uint32 bytes[4]; - v->AsSubNet()->Prefix().CopyIPv6(bytes); + v->AsSubNet().Prefix().CopyIPv6(bytes); kp[0] = bytes[0]; kp[1] = bytes[1]; kp[2] = bytes[2]; kp[3] = bytes[3]; - kp[4] = v->AsSubNet()->Length(); + kp[4] = v->AsSubNet().Length(); kp1 = reinterpret_cast(kp+5); } break; @@ -354,15 +354,15 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, int type_check) const case TYPE_INTERNAL_ADDR: { uint32 bytes[4]; - v->AsAddr()->CopyIPv6(bytes); + v->AsAddr().CopyIPv6(bytes); return new HashKey((void*)bytes, 4 * sizeof(uint32)); } case TYPE_INTERNAL_SUBNET: { uint32 bytes[5]; - v->AsSubNet()->Prefix().CopyIPv6(bytes); - bytes[4] = v->AsSubNet()->Length(); + v->AsSubNet().Prefix().CopyIPv6(bytes); + bytes[4] = v->AsSubNet().Length(); return new HashKey((void*)bytes, 5 * sizeof(uint32)); } diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index b6bcc789b3..ee194c607f 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -660,8 +660,8 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network); IPAddr ip2(IPAddr::IPv6, c->key.ip2, IPAddr::Network); - if ( ip1.family() == IPAddr::IPv6 || - ip2.family() == IPAddr::IPv6 ) + if ( ip1.GetFamily() == IPAddr::IPv6 || + ip2.GetFamily() == IPAddr::IPv6 ) reporter->InternalError("IPv6 snuck into connection compressor"); else { diff --git a/src/DCE_RPC.cc b/src/DCE_RPC.cc index a8a81813b7..88cdb48e80 100644 --- a/src/DCE_RPC.cc +++ b/src/DCE_RPC.cc @@ -137,7 +137,8 @@ static bool is_mapped_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr) bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto) { - if ( id->dst_addr.family() == IPAddr::IPv6 ) + if ( id->dst_addr.GetFamily() == IPAddr::IPv6 ) + // TODO: Does the protocol support v6 addresses? #773 return false; dce_rpc_endpoint_addr addr; diff --git a/src/DCE_RPC.h b/src/DCE_RPC.h index 481e7f37a3..acdbf1637d 100644 --- a/src/DCE_RPC.h +++ b/src/DCE_RPC.h @@ -65,7 +65,7 @@ struct dce_rpc_endpoint_addr { { static char buf[128]; snprintf(buf, sizeof(buf), "%s/%d/%s", - addr->AsString().c_str(), port, + addr.AsString().c_str(), port, proto == TRANSPORT_TCP ? "tcp" : (proto == TRANSPORT_UDP ? "udp" : "?")); diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index d0c562da37..2234ccbb10 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -347,13 +347,13 @@ void DNS_Mapping::Save(FILE* f) const { fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0, req_host ? req_host : - IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)->AsString()->c_str(), + IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network).AsString().c_str(), failed, (names && names[0]) ? names[0] : "*", num_addrs); for ( int i = 0; i < num_addrs; ++i ) fprintf(f, "%s\n", - IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)->AsString().c_str()); + IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network).AsString().c_str()); } @@ -518,7 +518,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr) case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", - IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)->AsString().c_str()); + IPAddr(IPAddr::IPv4, &addr, IPAddr::Network).AsString().c_str()); return 0; case DNS_DEFAULT: @@ -787,13 +787,13 @@ ListVal* DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) for ( int i = 0; i < al1->Length(); ++i ) { - const IPAddr* al1_i = al1->Index(i)->AsAddr(); + const IPAddr& al1_i = al1->Index(i)->AsAddr(); int j; for ( j = 0; j < al2->Length(); ++j ) { - const IPAddr* al2_j = al2->Index(j)->AsAddr(); - if ( *al1_i == *al2_j ) + const IPAddr& al2_j = al2->Index(j)->AsAddr(); + if ( al1_i == al2_j ) break; } @@ -809,8 +809,8 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al) { for ( int i = 0; i < al->Length(); ++i ) { - const IPAddr* al_i = al->Index(i)->AsAddr(); - fprintf(f, "%s%s", i > 0 ? "," : "", al_i->AsString().c_str()); + const IPAddr& al_i = al->Index(i)->AsAddr(); + fprintf(f, "%s%s", i > 0 ? "," : "", al_i.AsString().c_str()); } } diff --git a/src/Desc.cc b/src/Desc.cc index df49d84ba2..12b4a524eb 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -157,18 +157,6 @@ void ODesc::Add(double d) } } -void ODesc::Add(const IPAddr& addr) - { - string s = addr->AsString(); - AddBytes(s.c_str()); - } - -void ODesc::Add(const IPPrefix& prefix) - { - string s = prefix->AsString(); - AddBytes(s.c_str()); - } - void ODesc::AddCS(const char* s) { int n = strlen(s); diff --git a/src/Desc.h b/src/Desc.h index c633f2d812..9f8d7ab109 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -6,7 +6,9 @@ #include #include #include + #include "BroString.h" +#include "IPAddr.h" typedef enum { DESC_READABLE, @@ -68,13 +70,14 @@ public: void Add(const char* s, int do_indent=1); void AddN(const char* s, int len) { AddBytes(s, len); } + void Add(const string& s) { AddBytes(s.data(), s.size()); } void Add(int i); void Add(uint32 u); void Add(int64 i); void Add(uint64 u); void Add(double d); - void Add(const IPAddr& addr); - void Add(const IPPrefix& prefix); + void Add(const IPAddr& addr) { Add(addr.AsString()); } + void Add(const IPPrefix& prefix) { Add(prefix.AsString()); } // Add s as a counted string. void AddCS(const char* s); diff --git a/src/Expr.cc b/src/Expr.cc index 60e9cdb4ba..46590493a8 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4493,7 +4493,7 @@ Val* InExpr::Fold(Val* v1, Val* v2) const if ( v1->Type()->Tag() == TYPE_ADDR && v2->Type()->Tag() == TYPE_SUBNET ) - return new Val(v2->AsSubNetVal().Contains(v1->AsAddr()), TYPE_BOOL); + return new Val(v2->AsSubNetVal()->Contains(v1->AsAddr()), TYPE_BOOL); TableVal* vt = v2->AsTableVal(); if ( vt->Lookup(v1, false) ) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 7d306e1b2d..b378f58473 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -90,7 +90,7 @@ void IPAddr::Init(const std::string& s) string IPAddr::AsString() const { - if ( family() == IPv4 ) + if ( GetFamily() == IPv4 ) { char s[INET_ADDRSTRLEN]; @@ -131,7 +131,7 @@ IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length) : prefix(addr) { - if ( prefix.family() == IPAddr::IPv4 ) + if ( prefix.GetFamily() == IPAddr::IPv4 ) { if ( length > 32 ) reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d", @@ -152,27 +152,15 @@ IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length) prefix.Mask(this->length); } -IPPrefix::IPPrefix(const std::string& s, uint8_t length) - : prefix(s), length(length) - { - if ( prefix.family() == IPAddr::IPv4 && length > 32 ) - reporter->InternalError("Bad string IPPrefix length : %d", length); - - else if ( prefix.family() == IPAddr::IPv6 && length > 128 ) - reporter->InternalError("Bad string IPPrefix length : %d", length); - - prefix.Mask(this->length); - } - string IPPrefix::AsString() const { char l[16]; - if ( prefix.family() == IPAddr::IPv4 ) + if ( prefix.GetFamily() == IPAddr::IPv4 ) modp_uitoa10(length - 96, l); else modp_uitoa10(length, l); - return prefix->AsString() +"/" + l; + return prefix.AsString() +"/" + l; } diff --git a/src/IPAddr.h b/src/IPAddr.h index 07891fcee0..d9774b4ba4 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -114,7 +114,7 @@ public: /** * Returns the address' family. */ - Family family() const + Family GetFamily() const { if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 ) return IPv4; @@ -132,7 +132,7 @@ public: */ bool IsMulticast() const { - if ( family() == IPv4 ) + if ( GetFamily() == IPv4 ) return in6.s6_addr[12] == 224; else return in6.s6_addr[0] == 0xff; @@ -143,7 +143,7 @@ public: */ bool IsBroadcast() const { - if ( family() == IPv4 ) + if ( GetFamily() == IPv4 ) return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) && (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); else @@ -162,9 +162,9 @@ public: * @return The number of 32-bit words the raw representation uses. This * will be 1 for an IPv4 address and 4 for an IPv6 address. */ - int GetBytes(const uint32_t* const * bytes) const + int GetBytes(const uint32_t** bytes) const { - if ( family() == IPv4 ) + if ( GetFamily() == IPv4 ) { *bytes = (uint32_t*) &in6.s6_addr[12]; return 1; @@ -306,7 +306,7 @@ inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order) inline bool IPAddr::IsLoopback() const { - if ( family() == IPv4 ) + if ( GetFamily() == IPv4 ) return in6.s6_addr[12] == 127; else @@ -327,6 +327,12 @@ inline bool IPAddr::IsLoopback() const class IPPrefix { public: + + /** + * Constructs a prefix 0/0. + */ + IPPrefix() : length(0) {} + /** * Constructs a prefix instance from an IPv4 address and a prefix * length. @@ -356,16 +362,6 @@ public: */ IPPrefix(const IPAddr& addr, uint8_t length); - /** - * Constructs a prefix instance from IP string representation and length. - * - * @param s String containing an IP address as either a dotted IPv4 - * address or a hex IPv6 address. - * - * @param length The prefix length in the range from 0 to 128 - */ - IPPrefix(const std::string& s, uint8_t length); - /** * Copy constructor. */ @@ -389,7 +385,7 @@ public: */ uint8_t Length() const { - return prefix.family() == IPAddr::IPv4 ? length - 96 : length; + return prefix.GetFamily() == IPAddr::IPv4 ? length - 96 : length; } /** @@ -398,6 +394,16 @@ public: */ uint8_t LengthIPv6() const { return length; } + /** Returns true if the given address is part of the prefix. + * + * @param addr The address to test. + */ + bool Contains(const IPAddr& addr) const + { + IPAddr p(addr); + p.Mask(length); + return p == prefix; + } /** * Assignment operator. */ diff --git a/src/LogMgr.cc b/src/LogMgr.cc index 9c7f38b55d..9d397325be 100644 --- a/src/LogMgr.cc +++ b/src/LogMgr.cc @@ -200,7 +200,7 @@ bool LogVal::Read(SerializationFormat* fmt) case TYPE_SUBNET: { IPPrefix prefix; - if ( ! fmt->Read(&prefix), "subnet" ) + if ( ! fmt->Read(&prefix, "subnet") ) return false; val.subnet_val = new IPPrefix(prefix); @@ -210,10 +210,10 @@ bool LogVal::Read(SerializationFormat* fmt) case TYPE_ADDR: { IPAddr addr; - if ( ! fmt->Read(&addr), "net" ) + if ( ! fmt->Read(&addr, "net") ) return false; - val.addr_val = new IPAddr(prefix); + val.addr_val = new IPAddr(addr); return true; } diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 5dc7a715c7..d59374ad7c 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -680,7 +680,7 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip, if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); - if ( ip.family() == IPAddr::IPv6 ) + if ( ip.GetFamily() == IPAddr::IPv6 ) Error("inter-Bro communication not supported over IPv6"); const uint32* bytes; @@ -1237,7 +1237,7 @@ bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl) if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); - if ( ip.family() == IPAddr::IPv6 ) + if ( ip.GetFamily() == IPAddr::IPv6 ) Error("inter-Bro communication not supported over IPv6"); const uint32* bytes; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index b7138ee388..685e35bade 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1071,7 +1071,7 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) const uint32* n; uint32 m[4]; v->AsSubNet().Prefix().GetBytes(&n); - v->AsSubNetVal().Mask().CopyIPv6(m); + v->AsSubNetVal()->Mask().CopyIPv6(m); for ( unsigned int i = 0; i < 4; ++i ) m[i] = ntohl(m[i]); @@ -1079,7 +1079,7 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; - if ( v->AsSubNet().Prefix().family() == IPAddr::IPv4 && + if ( v->AsSubNet().Prefix().GetFamily() == IPAddr::IPv4 && is_v4_mask ) { mval->val = ntohl(*n); diff --git a/src/SerializationFormat.cc b/src/SerializationFormat.cc index c88e2979b8..ee1fd8fe44 100644 --- a/src/SerializationFormat.cc +++ b/src/SerializationFormat.cc @@ -232,11 +232,29 @@ bool BinarySerializationFormat::Read(string* v, const char* tag) bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag) { - string s; - if ( ! Read(&s, tag) ) + int n = 0; + if ( ! Read(&n, "addr-len") ) return false; - *addr = IPAddr(s); + if ( n != 1 && n != 4 ) + return false; + + uint32_t raw[4]; + + for ( int i = 0; i < n; ++i ) + { + uint32_t i = 0; + if ( ! Read(&i, "addr-part") ) + return false; + + raw[n] = htonl(i); + } + + if ( n == 1 ) + *addr = IPAddr(IPAddr::IPv4, raw, IPAddr::Network); + else + *addr = IPAddr(IPAddr::IPv6, raw, IPAddr::Network); + return true; } @@ -323,12 +341,26 @@ bool BinarySerializationFormat::Write(const string& s, const char* tag) bool BinarySerializationFormat::Write(const IPAddr& addr, const char* tag) { - return Write(addr.AsString()); + const uint32_t* raw; + int n = addr.GetBytes(&raw); + + assert(n == 1 || n == 4); + + if ( ! Write(n, "addr-len") ) + return false; + + for ( int i = 0; i < n; ++i ) + { + if ( ! Write(ntohl(raw[i]), "addr-part") ) + return false; + } + + return true; } bool BinarySerializationFormat::Write(const IPPrefix& prefix, const char* tag) { - return Write(addr.AsString(), tag) && Write(prefix->Length(), tag); + return Write(prefix.Prefix(), "prefix") && Write(prefix.Length(), "width"); } bool BinarySerializationFormat::WriteOpenTag(const char* tag) @@ -421,6 +453,18 @@ bool XMLSerializationFormat::Read(string* s, const char* tag) return false; } +bool XMLSerializationFormat::Read(IPAddr* addr, const char* tag) + { + reporter->InternalError("no reading of xml"); + return false; + } + +bool XMLSerializationFormat::Read(IPPrefix* prefix, const char* tag) + { + reporter->InternalError("no reading of xml"); + return false; + } + bool XMLSerializationFormat::Write(char v, const char* tag) { return WriteElem(tag, "char", &v, 1); @@ -501,6 +545,18 @@ bool XMLSerializationFormat::Write(const char* buf, int len, const char* tag) return WriteElem(tag, "string", buf, len); } +bool XMLSerializationFormat::Write(const IPAddr& addr, const char* tag) + { + reporter->InternalError("XML output of addresses not implemented"); + return false; + } + +bool XMLSerializationFormat::Write(const IPPrefix& prefix, const char* tag) + { + reporter->InternalError("XML output of prefixes not implemented"); + return false; + } + bool XMLSerializationFormat::WriteEncodedString(const char* s, int len) { while ( len-- ) diff --git a/src/SerializationFormat.h b/src/SerializationFormat.h index c6dd1e86b0..f5eb77c608 100644 --- a/src/SerializationFormat.h +++ b/src/SerializationFormat.h @@ -94,6 +94,8 @@ public: virtual bool Read(double* d, const char* tag); virtual bool Read(char** str, int* len, const char* tag); virtual bool Read(string* s, const char* tag); + virtual bool Read(IPAddr* addr, const char* tag); + virtual bool Read(IPPrefix* prefix, const char* tag); virtual bool Write(int v, const char* tag); virtual bool Write(uint16 v, const char* tag); virtual bool Write(uint32 v, const char* tag); @@ -105,6 +107,8 @@ public: virtual bool Write(const char* s, const char* tag); virtual bool Write(const char* buf, int len, const char* tag); virtual bool Write(const string& s, const char* tag); + virtual bool Write(const IPAddr& addr, const char* tag); + virtual bool Write(const IPPrefix& prefix, const char* tag); virtual bool WriteOpenTag(const char* tag); virtual bool WriteCloseTag(const char* tag); virtual bool WriteSeparator(); @@ -127,6 +131,8 @@ public: virtual bool Write(const char* s, const char* tag); virtual bool Write(const char* buf, int len, const char* tag); virtual bool Write(const string& s, const char* tag); + virtual bool Write(const IPAddr& addr, const char* tag); + virtual bool Write(const IPPrefix& prefix, const char* tag); virtual bool WriteOpenTag(const char* tag); virtual bool WriteCloseTag(const char* tag); virtual bool WriteSeparator(); @@ -142,6 +148,8 @@ public: virtual bool Read(double* d, const char* tag); virtual bool Read(char** str, int* len, const char* tag); virtual bool Read(string* s, const char* tag); + virtual bool Read(IPAddr* addr, const char* tag); + virtual bool Read(IPPrefix* prefix, const char* tag); private: // Encodes non-printable characters. diff --git a/src/Serializer.h b/src/Serializer.h index 93581d83ce..45575f7fa0 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -69,6 +69,8 @@ public: { return format->Read(const_cast(str), len, tag); } bool Read(string* s, const char* tag); + bool Read(IPAddr* a, const char* tag) { return format->Read(a, tag); } + bool Read(IPPrefix* p, const char* tag) { return format->Read(p, tag); } bool Write(const char* s, const char* tag) { return format->Write(s, tag); } @@ -76,6 +78,8 @@ public: { return format->Write(buf, len, tag); } bool Write(const string& s, const char* tag) { return format->Write(s.data(), s.size(), tag); } + bool Write(const IPAddr& a, const char* tag) { return format->Write(a, tag); } + bool Write(const IPPrefix& p, const char* tag) { return format->Write(p, tag); } bool WriteOpenTag(const char* tag) { return format->WriteOpenTag(tag); } diff --git a/src/Val.cc b/src/Val.cc index 0e49dca030..e42dfbd36e 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -861,18 +861,16 @@ AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR) val.addr_val = new IPAddr(text); } -#if 0 AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR) { // ### perhaps do gethostbyaddr here? val.addr_val = new IPAddr(IPAddr::IPv4, &addr, IPAddr::Network); } -AddrVal::AddrVal(const uint32* addr) : Val(TYPE_ADDR) +AddrVal::AddrVal(const uint32 addr[4]) : Val(TYPE_ADDR) { val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); } -#endif AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR) { @@ -891,7 +889,7 @@ unsigned int AddrVal::MemoryAllocation() const Val* AddrVal::SizeVal() const { - if ( val.addr_val->family() == IPAddr::IPv4 ) + if ( val.addr_val->GetFamily() == IPAddr::IPv4 ) return new Val(32, TYPE_COUNT); else return new Val(128, TYPE_COUNT); @@ -965,7 +963,6 @@ void SubNetVal::ValDescribe(ODesc* d) const d->Add(string(*val.subnet_val).c_str()); } -#if 0 IPAddr SubNetVal::Mask() const { if ( val.subnet_val->Length() == 0 ) @@ -995,19 +992,6 @@ IPAddr SubNetVal::Mask() const return rval; } -bool SubNetVal::Contains(const uint32 addr) const - { - IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); - return val.subnet_val->Contains(a); - } - -bool SubNetVal::Contains(const uint32* addr) const - { - IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); - return val.subnet_val->Contains(a); - } -#endif - bool SubNetVal::Contains(const IPAddr& addr) const { IPAddr a(addr); diff --git a/src/Val.h b/src/Val.h index e987726601..415996d97a 100644 --- a/src/Val.h +++ b/src/Val.h @@ -261,17 +261,17 @@ public: ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern) ACCESSOR(TYPE_VECTOR, vector*, vector_val, AsVector) - IPPrefix* AsSubNet() + const IPPrefix& AsSubNet() { CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name) - return val.subnet_val; + return *val.subnet_val; } - IPAddr* AsAddr() + const IPAddr& AsAddr() { if ( type->Tag() != TYPE_ADDR ) BadTag("Val::AsAddr", type_name(type->Tag())); - return val.addr_val; + return *val.addr_val; } // Gives fast access to the bits of something that is one of @@ -562,10 +562,8 @@ public: Val* SizeVal() const; // Constructor for address already in network order. -#if 0 - AddrVal(uint32 addr); - AddrVal(const uint32* addr); -#endif + AddrVal(uint32 addr); // IPv4. + AddrVal(const uint32 addr[4]); // IPv6. AddrVal(const IPAddr& addr); unsigned int MemoryAllocation() const; @@ -583,10 +581,8 @@ class SubNetVal : public Val { public: SubNetVal(const char* text); SubNetVal(const char* text, int width); -#if 0 - SubNetVal(uint32 addr, int width); - SubNetVal(const uint32* addr, int width); -#endif + SubNetVal(uint32 addr, int width); // IPv4. + SubNetVal(const uint32 addr[4], int width); // IPv6. SubNetVal(const IPAddr& addr, int width); ~SubNetVal(); @@ -594,11 +590,7 @@ public: const IPAddr& Prefix() const { return val.subnet_val->Prefix(); } int Width() const { return val.subnet_val->Length(); } -#if 0 IPAddr Mask() const; - bool Contains(const uint32 addr) const; - bool Contains(const uint32* addr) const; -#endif bool Contains(const IPAddr& addr) const; diff --git a/src/bro.bif b/src/bro.bif index cc3c2f335c..1d2f0674ad 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -181,7 +181,7 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d) const IPAddr& u = v->AsAddr(); const uint32* net_order_u; - int len = u->GetBytes(&net_order_u); + int len = u.GetBytes(&net_order_u); if ( len == 4 ) { @@ -1963,7 +1963,7 @@ function do_profiling%(%) : any ## Returns: True if *ip* belongs to a local interface. function is_local_interface%(ip: addr%) : bool %{ - if ( ip->AsAddr()->IsLoopback() ) + if ( ip->AsAddr().IsLoopback() ) return new Val(1, TYPE_BOOL); list addrs; @@ -2054,7 +2054,7 @@ function gethostname%(%) : string ## Returns: true if *a* is an IPv4 address, else false. function is_v4_addr%(a: addr%): bool %{ - if ( a->AsAddr()->family() == IPAddr::IPv4 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv4 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -2067,7 +2067,7 @@ function is_v4_addr%(a: addr%): bool ## Returns: true if *a* is an IPv6 address, else false. function is_v6_addr%(a: addr%): bool %{ - if ( a->AsAddr().Family() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -2091,7 +2091,7 @@ function addr_to_counts%(a: addr%): index_vec %{ VectorVal* rval = new VectorVal(new VectorType(base_type(TYPE_COUNT))); const uint32* bytes; - int len = a->AsAddr()->GetBytes(&bytes); + int len = a->AsAddr().GetBytes(&bytes); for ( int i = 0; i < len; ++i ) rval->Assign(i, new Val(ntohl(bytes[i]), TYPE_COUNT), 0); @@ -2446,7 +2446,7 @@ function ptr_name_to_addr%(s: string%): addr function addr_to_ptr_name%(a: addr%): string %{ const uint32* addr; - int len = a->AsAddr()->GetBytes(&addr); + int len = a->AsAddr().GetBytes(&addr); if ( len == 1 ) { @@ -2564,7 +2564,7 @@ static Val* parse_eftp(const char* line) { string s(line); IPAddr tmp(s); - uint32* bytes; + const uint32* bytes; tmp.GetBytes(&bytes); addr = *bytes; if ( addr == 0 ) @@ -2672,7 +2672,7 @@ function parse_ftp_epsv%(str: string%): ftp_port function fmt_ftp_port%(a: addr, p: port%): string %{ const uint32* addr; - int len = a->AsAddr()->GetBytes(&addr); + int len = a->AsAddr().GetBytes(&addr); if ( len == 1 ) { uint32 a = ntohl(addr[0]); @@ -3441,7 +3441,7 @@ function lookup_addr%(host: addr%) : string frame->SetDelayed(); trigger->Hold(); - if ( host->AsAddr().Family() != IPAddr::IPv4 ) + if ( host->AsAddr().GetFamily() != IPAddr::IPv4 ) { // FIXME: This is a temporary work-around until we get this // fixed. We warn the user once, and always trigger a timeout. @@ -3567,7 +3567,7 @@ function lookup_location%(a: addr%) : geo_location } #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( geoip_v6 && a->AsAddr().Family() == IPAddr::IPv6 ) + if ( geoip_v6 && a->AsAddr().GetFamily() == IPAddr::IPv6 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -3581,7 +3581,7 @@ function lookup_location%(a: addr%) : geo_location else #endif - if ( geoip && a->AsAddr().Family() == IPAddr::IPv4 ) + if ( geoip && a->AsAddr().GetFamily() == IPAddr::IPv4 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -3664,7 +3664,7 @@ function lookup_asn%(a: addr%) : count { // IPv6 support showed up in 1.4.5. #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( a->AsAddr()->family() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -3675,7 +3675,7 @@ function lookup_asn%(a: addr%) : count else #endif - if ( a->AsAddr().Family() == IPAddr::IPv4 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv4 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -5402,7 +5402,7 @@ function preserve_prefix%(a: addr, width: count%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsAddr().Family() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) builtin_error("preserve_prefix() not supported for IPv6 addresses"); else { @@ -5431,13 +5431,13 @@ function preserve_subnet%(a: subnet%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsSubNet()->Prefix().Family() == IPAddr::IPv6 ) + if ( a->AsSubNet().Prefix().GetFamily() == IPAddr::IPv6 ) builtin_error("preserve_subnet() not supported for IPv6 addresses"); else { const uint32* bytes; a->AsSubNet().Prefix().GetBytes(&bytes); - ip_anon->PreservePrefix(*bytes, a->AsSubNet()->Length()); + ip_anon->PreservePrefix(*bytes, a->AsSubNet().Length()); } } @@ -5467,7 +5467,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES ) builtin_error("anonymize_addr(): invalid ip addr anonymization class"); - if ( a->AsAddr().Family() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) { builtin_error("anonymize_addr() not supported for IPv6 addresses"); return 0; From d61fad4f9ebb338129264586bb7330a4d69a2a6c Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 17 Feb 2012 10:55:17 -0600 Subject: [PATCH 26/49] Fix IPv6 URLs --- scripts/base/protocols/ftp/main.bro | 7 ++++++- .../Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index e9783e4df7..db9e030c33 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -165,7 +165,12 @@ function ftp_message(s: Info) local arg = s$cmdarg$arg; if ( s$cmdarg$cmd in file_cmds ) - arg = fmt("ftp://%s%s", s$id$resp_h, build_path_compressed(s$cwd, arg)); + { + if ( is_v4_addr(s$id$resp_h) ) + arg = fmt("ftp://%s%s", s$id$resp_h, build_path_compressed(s$cwd, arg)); + else + arg = fmt("ftp://[%s]%s", s$id$resp_h, build_path_compressed(s$cwd, arg)); + } s$ts=s$cmdarg$ts; s$command=s$cmdarg$cmd; diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log index 670855414e..8bc2ef2cb7 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/ftp.log @@ -5,5 +5,5 @@ #path ftp #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type mime_desc file_size reply_code reply_msg tags extraction_file #types time string addr port addr port string string string string string string count count string table[string] file -1329327787.396984 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://2001:470:4867:99::21/robots.txt - - 77 226 Transfer complete. - - -1329327795.463946 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://2001:470:4867:99::21/robots.txt - - 77 226 Transfer complete. - - +1329327787.396984 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://[2001:470:4867:99::21]/robots.txt - - 77 226 Transfer complete. - - +1329327795.463946 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 anonymous test RETR ftp://[2001:470:4867:99::21]/robots.txt - - 77 226 Transfer complete. - - From c227563baf13a8e1f06fd05a108afa8b9e55b09f Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 17 Feb 2012 12:00:35 -0600 Subject: [PATCH 27/49] Fix compile error. --- src/Anon.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Anon.cc b/src/Anon.cc index ca2a1e6361..4c4146ac3e 100644 --- a/src/Anon.cc +++ b/src/Anon.cc @@ -154,7 +154,7 @@ void AnonymizeIPAddr_A50::init() int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits) { DEBUG_MSG("%s/%d\n", - IPAddr(IPAddr::IPv4, &input, IPAddr::Network)->AsString().c_str(), + IPAddr(IPAddr::IPv4, &input, IPAddr::Network).AsString().c_str(), num_bits); if ( ! before_anonymization ) From 06e59e13980026c78d047cb175439c6d0371ba00 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 17 Feb 2012 12:01:00 -0600 Subject: [PATCH 28/49] Fix IPAddr/IPPrefix serialization bugs. (all unit tests pass) --- src/IPAddr.cc | 2 +- src/IPAddr.h | 4 ++-- src/SerializationFormat.cc | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index b378f58473..09248dadfa 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -104,7 +104,7 @@ string IPAddr::AsString() const char s[INET6_ADDRSTRLEN]; if ( inet_ntop(AF_INET6, in6.s6_addr, s, INET6_ADDRSTRLEN) == NULL ) - return " Date: Fri, 17 Feb 2012 13:24:47 -0800 Subject: [PATCH 29/49] Changing ARP detection to always kick in even if no analyzer is activated. Without that, we get "unknown_protocol" weird for ARP, which doesn't seem right. --- src/ARP.cc | 2 +- src/ARP.h | 7 ++++--- src/Sessions.cc | 9 ++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ARP.cc b/src/ARP.cc index 3606ed66d5..7ffd82764c 100644 --- a/src/ARP.cc +++ b/src/ARP.cc @@ -17,7 +17,7 @@ ARP_Analyzer::~ARP_Analyzer() { } -bool ARP_Analyzer::IsARP(const u_char* pkt, int hdr_size) const +bool ARP_Analyzer::IsARP(const u_char* pkt, int hdr_size) { unsigned short network_protocol = *(unsigned short*) (pkt + hdr_size - 2); diff --git a/src/ARP.h b/src/ARP.h index 37f20ced3c..f4b623c513 100644 --- a/src/ARP.h +++ b/src/ARP.h @@ -31,9 +31,6 @@ public: ARP_Analyzer(); virtual ~ARP_Analyzer(); - // Whether a packet is of interest for ARP analysis. - bool IsARP(const u_char* pkt, int hdr_size) const; - void NextPacket(double t, const struct pcap_pkthdr* hdr, const u_char* const pkt, int hdr_size); @@ -41,6 +38,10 @@ public: void RREvent(EventHandlerPtr e, const u_char* src, const u_char* dst, const char* spa, const char* sha, const char* tpa, const char* tha); + + // Whether a packet is of interest for ARP analysis. + static bool IsARP(const u_char* pkt, int hdr_size); + protected: AddrVal* ConstructAddrVal(const void* addr); StringVal* EthAddrToStr(const u_char* addr); diff --git a/src/Sessions.cc b/src/Sessions.cc index cec44acb3c..8ed223a92e 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -279,15 +279,18 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } - else if ( arp_analyzer && arp_analyzer->IsARP(pkt, hdr_size) ) - arp_analyzer->NextPacket(t, hdr, pkt, hdr_size); - else if ( ip->ip_v == 6 ) { IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size)); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } + else if ( ARP_Analyzer::IsARP(pkt, hdr_size) ) + { + if ( arp_analyzer ) + arp_analyzer->NextPacket(t, hdr, pkt, hdr_size); + } + else { Weird("unknown_packet_type", hdr, pkt); From 7ab36dbf8f3b4d46d2eb4c6c4ddbbf183428f726 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 17 Feb 2012 15:36:12 -0800 Subject: [PATCH 30/49] Updating NEWS. --- NEWS | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1a257ce18f..b89493276b 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,20 @@ Release Notes This document summarizes the most important changes in the current Bro release. For a complete list of changes, see the ``CHANGES`` file. + +Bro 2.1 +------- + +- Bro now supports IPv6 out of the box; the configure switch + --enable-brov6 is gone. + +- DNS name lookups performed by Bro now also query AAAA records. The + results of the A and AAAA queries for a given hostname are combined + such that at the scripting layer, the name resolution can yield a + set with both IPv4 and IPv6 addresses. + +TODO: Extend. + Bro 2.0 ------- @@ -61,4 +75,3 @@ final release are: - From 0e3934b19616653927dbd4558363ee30ee055266 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 17 Feb 2012 15:36:12 -0800 Subject: [PATCH 31/49] Updating NEWS. --- CHANGES | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ NEWS | 15 ++++++++++++++- VERSION | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 9286a5409e..092a5b3740 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,52 @@ +2.0-85 | 2012-02-17 15:36:12 -0800 + + * Changing ARP detection to always kick in even if no analyzer is + activated. (Robin Sommer) + + * DNS name lookups performed by Bro now also query AAAA records. + DNS_Mgr handles combining the results of the A and AAAA queries + for a given hostname such that at the scripting layer, the name + resolution can yield a set with both IPv4 and IPv6 addresses. (Jon + Siwek) + + * Add counts_to_addr and addr_to_counts conversion BIFs. (Jon Siwek) + + * Change HashKey threshold for using H3 to 36 bytes. (Jon Siwek) + + * Remove mention of --enable-brov6 in docs. (Daniel Thayer) + + * Remove --enable-brov6 from configure usage text (Daniel Thayer) + + * Add a test and baseline for addr_to_ptr_name BiF. (Daniel Thayer) + + * Adding a test and baseline for ptr_name_to_addr BiF. (Seth Hall) + + * Fix the ptr_name_to_addr BiF to work with IPv6 (Daniel Thayer) + + * Fix a memory leak that perftools now complains about. (Jon Siwek) + + * Remove --enable-brov6 flag, IPv6 now supported by default. (Jon Siwek) + + Some script-layer changes of note: + + - dns_AAAA_reply event signature changed: the string representation + of an IPv6 addr is easily derived from the addr value, it doesn't + need to be another parameter. This event also now generated directly + by the DNS analyzer instead of being "faked" into a dns_A_reply event. + + - Removed addr_to_count BIF. It used to return the host-order + count representation of IPv4 addresses only. To make it more + generic, we might later add a BIF to return a vector of counts + in order to support IPv6. + + - Changed the result of enclosing addr variables in vertical pipes + (e.g. |my_addr|) to return the bit-width of the address type which + is 128 for IPv6 and 32 for IPv4. It used to function the same + way as addr_to_count mentioned above. + + - Remove bro_has_ipv6 BIF + 2.0-57 | 2012-02-10 00:02:35 -0800 * Fix typos in the documentation. (Daniel Thayer) diff --git a/NEWS b/NEWS index 1a257ce18f..b89493276b 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,20 @@ Release Notes This document summarizes the most important changes in the current Bro release. For a complete list of changes, see the ``CHANGES`` file. + +Bro 2.1 +------- + +- Bro now supports IPv6 out of the box; the configure switch + --enable-brov6 is gone. + +- DNS name lookups performed by Bro now also query AAAA records. The + results of the A and AAAA queries for a given hostname are combined + such that at the scripting layer, the name resolution can yield a + set with both IPv4 and IPv6 addresses. + +TODO: Extend. + Bro 2.0 ------- @@ -61,4 +75,3 @@ final release are: - diff --git a/VERSION b/VERSION index 8dd930b077..0e3b680daa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-57 +2.0-85 From b3333a7da227769b02a9ebeeea04ea13c983f58e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 17 Feb 2012 15:41:06 -0800 Subject: [PATCH 32/49] Reverting loopback change which doesn't seem to fully work. --- CHANGES | 2 +- VERSION | 2 +- src/PktSrc.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 092a5b3740..1285b53cf8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ -2.0-85 | 2012-02-17 15:36:12 -0800 +2.0-86 | 2012-02-17 15:41:06 -0800 * Changing ARP detection to always kick in even if no analyzer is activated. (Robin Sommer) diff --git a/VERSION b/VERSION index 0e3b680daa..2436939ed7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-85 +2.0-86 diff --git a/src/PktSrc.cc b/src/PktSrc.cc index 598f13b51c..68b9785e6f 100644 --- a/src/PktSrc.cc +++ b/src/PktSrc.cc @@ -191,7 +191,7 @@ void PktSrc::Process() switch ( datalink ) { case DLT_NULL: { - protocol = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + protocol = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; if ( protocol != AF_INET && protocol != AF_INET6 ) { From 1f7bfbb83c6b320d52f4ff91b6fdc426cb03b59a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 20 Feb 2012 11:56:21 -0600 Subject: [PATCH 33/49] Fix memory leak in DNS manager (fixes #777). --- src/DNS_Mgr.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 534af15d39..550dfeef6e 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -704,6 +704,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) if ( dr->ReqHost() ) { new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl); + prev_dm = 0; HostMap::iterator it = host_mappings.find(dr->ReqHost()); if ( it == host_mappings.end() ) @@ -711,15 +712,11 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) host_mappings[dr->ReqHost()].first = new_dm->Type() == AF_INET ? new_dm : 0; host_mappings[dr->ReqHost()].second = - new_dm->Type() == AF_INET6 ? new_dm : 0; - - prev_dm = 0; + new_dm->Type() == AF_INET ? 0 : new_dm; } else { - prev_dm = 0; - if ( new_dm->Type() == AF_INET ) { prev_dm = it->second.first; From b66b74e5dc0ce96bb1e58cfec591e1a41240d5e0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 20 Feb 2012 14:28:42 -0600 Subject: [PATCH 34/49] Decrease strictness of parsing IPv4 strings into addrs. (fixes #775) IPv4 strings in dotted-decimal format with decimal parts containing leading zeroes now parse better. --- src/IPAddr.cc | 39 +++++++++++++++++++++- src/IPAddr.h | 8 +++++ testing/btest/Baseline/bifs.to_addr/output | 8 +++++ testing/btest/bifs/to_addr.bro | 18 ++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/bifs.to_addr/output create mode 100644 testing/btest/bifs/to_addr.bro diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 09248dadfa..3dc0025c2d 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,5 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. +#include +#include #include "IPAddr.h" #include "Reporter.h" @@ -65,13 +67,48 @@ void IPAddr::ReverseMask(int top_bits_to_chop) memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } +std::string IPAddr::CanonIPv4(const std::string& input) + { + vector parts; + string output; + size_t start = 0; + size_t end; + + do + { + end = input.find('.', start); + string p; + bool in_leading_zeroes = true; + for ( size_t i = start; i != end && i < input.size(); ++i ) + { + if ( in_leading_zeroes && input[i] == '0' ) continue; + in_leading_zeroes = false; + p.push_back(input[i]); + } + + if ( p.size() == 0 ) + p.push_back('0'); + parts.push_back(p); + start = end + 1; + } while ( end != string::npos ); + + for ( size_t i = 0; i < parts.size(); ++i ) + { + if ( i > 0 ) + output += '.'; + output += parts[i]; + } + + return output; + } + void IPAddr::Init(const std::string& s) { if ( s.find(':') == std::string::npos ) // IPv4. { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 ) + if ( inet_pton(AF_INET, CanonIPv4(s).c_str(), &in6.s6_addr[12]) <=0 ) { reporter->Error("Bad IP address: %s", s.c_str()); memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); diff --git a/src/IPAddr.h b/src/IPAddr.h index c2e57ea7d1..96e70689b4 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -261,6 +261,14 @@ public: unsigned int MemoryAllocation() const { return padded_sizeof(*this); } + /** + * Returns a canonicalized IPv4 dotted-decimal string such that + * leading zeroes of each decimal part are removed. + * + * @param s String containing an IPv4 address in dotted-decimal notation. + */ + static std::string CanonIPv4(const std::string& s); + private: /** * Initializes an address instance from a string representation. diff --git a/testing/btest/Baseline/bifs.to_addr/output b/testing/btest/Baseline/bifs.to_addr/output new file mode 100644 index 0000000000..bcfdd3b6a2 --- /dev/null +++ b/testing/btest/Baseline/bifs.to_addr/output @@ -0,0 +1,8 @@ +to_addr(0.0.0.0) = 0.0.0.0 (SUCCESS) +to_addr(1.2.3.4) = 1.2.3.4 (SUCCESS) +to_addr(01.02.03.04) = 1.2.3.4 (SUCCESS) +to_addr(001.002.003.004) = 1.2.3.4 (SUCCESS) +to_addr(10.20.30.40) = 10.20.30.40 (SUCCESS) +to_addr(100.200.30.40) = 100.200.30.40 (SUCCESS) +to_addr(10.0.0.0) = 10.0.0.0 (SUCCESS) +to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS) diff --git a/testing/btest/bifs/to_addr.bro b/testing/btest/bifs/to_addr.bro new file mode 100644 index 0000000000..67ce79c795 --- /dev/null +++ b/testing/btest/bifs/to_addr.bro @@ -0,0 +1,18 @@ +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +function test_to_addr(ip: string, expect: addr) + { + local result = to_addr(ip); + print fmt("to_addr(%s) = %s (%s)", ip, result, + result == expect ? "SUCCESS" : "FAILURE"); + } + +test_to_addr("0.0.0.0", 0.0.0.0); +test_to_addr("1.2.3.4", 1.2.3.4); +test_to_addr("01.02.03.04", 1.2.3.4); +test_to_addr("001.002.003.004", 1.2.3.4); +test_to_addr("10.20.30.40", 10.20.30.40); +test_to_addr("100.200.30.40", 100.200.30.40); +test_to_addr("10.0.0.0", 10.0.0.0); +test_to_addr("10.00.00.000", 10.0.0.0); From 96df1bac408d150a6269fafa1fbcaf25a60a2839 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Tue, 21 Feb 2012 11:18:43 -0600 Subject: [PATCH 35/49] Add test case for FTP over IPv4 --- .../conn.log | 12 ++++++++++++ .../scripts.base.protocols.ftp.ftp-ipv4/ftp.log | 9 +++++++++ testing/btest/Traces/ftp-ipv4.trace | Bin 0 -> 12078 bytes .../scripts/base/protocols/ftp/ftp-ipv4.bro | 6 ++++++ 4 files changed, 27 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/ftp.log create mode 100644 testing/btest/Traces/ftp-ipv4.trace create mode 100644 testing/btest/scripts/base/protocols/ftp/ftp-ipv4.bro diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log new file mode 100644 index 0000000000..bcb05ef415 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes +#types time string addr port addr port enum string interval count count string bool count string count count count count +1329843175.736107 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 tcp ftp-data 0.112432 0 342 SF - 0 ShAdfFa 4 216 4 562 +1329843179.871641 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 tcp ftp-data 0.111218 0 77 SF - 0 ShAdfFa 4 216 4 297 +1329843194.151526 nQcgTWjvg4c 199.233.217.249 61920 141.142.220.235 33582 tcp ftp-data 0.056211 342 0 SF - 0 ShADaFf 5 614 3 164 +1329843197.783443 j4u32Pc5bif 199.233.217.249 61918 141.142.220.235 37835 tcp ftp-data 0.056005 77 0 SF - 0 ShADaFf 5 349 3 164 +1329843161.968492 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 tcp ftp 38.055625 180 3146 SF - 0 ShAdDfFa 38 2164 25 4458 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/ftp.log new file mode 100644 index 0000000000..debc093771 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/ftp.log @@ -0,0 +1,9 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ftp +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type mime_desc file_size reply_code reply_msg tags extraction_file +#types time string addr port addr port string string string string string string count count string table[string] file +1329843179.926563 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test RETR ftp://199.233.217.249/./robots.txt text/plain ASCII text 77 226 Transfer complete. - - +1329843197.727769 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test RETR ftp://199.233.217.249/./robots.txt text/plain ASCII text, with CRLF line terminators 77 226 Transfer complete. - - diff --git a/testing/btest/Traces/ftp-ipv4.trace b/testing/btest/Traces/ftp-ipv4.trace new file mode 100644 index 0000000000000000000000000000000000000000..02cac6f46457d75fec4ef38d4bfc577be97c8721 GIT binary patch literal 12078 zcmeHNdvp_5dLNlb9D}JL;goIJo=XbY4w5a)wlFRPY-5Up!Njsdh#l})8p{GnBW6a} z26p3wY#t<#Jxk7R357tjZAecxgavQOCT+7N4evY`0)$rrge1E?3#8dRP6+*dcQj+o z$Woza|E!L$r5TNW_xpa|^WK@??)l}`EMc%pebUbmaU$t)+{%WKGH5Fjf$< z1`pXaI4e8H(fZ@rblx#&(9jb=K7OAd%)>Da9aG2W$TI|ChTtB0M+>16x-fc=Z~SiQ zOQ5fNX;hvt0ly|>LUTB>bAaKX83t!L9EAQ2zOTkf8Yyy@dEel2Z?Va}4l{h!na6b-c*yPOoD|e9nFMg(bivW= zt8HXrRF3vU-w>! zr6ufdgr0JM<^zkvuDXxq<~Tx(Nu z^Z4Bz9You*bEcBFlNhIgxN!7M!dx8CNTF@I_W(zHU_eCBw(oTV@u?RGaekH0$22IF zn?vARFWn?i)bPmRfoBFuo=_U z^y4<6p9c+Lq9Hcj6#CZ?j!Sy=@=d~LLj*qTwjFZv!WSfI2bj3EAkS_ukjG^=^+x9{h}rX7!2Pi1-fK8z-mHTkCW9@Ia#x>DmRBP;34fXmHFjp z6u%EG#}zn;D`2>X$sKgbz%Qq9+NlH8MKwu@N*eR^sG1Z}S&bZ3Wkn0cBgU2H`-0l~ znufWx}6I18I`W)tf|XS# z^Gj++2rz!RT?}hZ7CO4Lkx)z}(VS{$Da7lH zwUoNu&dF{!4y;nOxfZ!x`E654C<|5mL}$$3kEeFx*P+r1ujx1zsDi~sg^XCoe^#7K z6^=vgk!Tl`4E4y-5ZDRFqoTJ0*(~w0ATd@1Hz;nS@2o%((ccoG-|4iInts{IA`z)a z(y?qnZ~=Pd+i)0*ERRUZQ1JV%P&6PZ5RzWNnM%Jb;zw}GV#YnwVz{W(rRpFg3D}8B z-5OU*?jZJ)a8^yjtD&&4aN4v&)(X?naX(41u!x`&wU8Y3I9V(rf}@xs#hgqPqk)(l zioy*Hnes^{D3;IKK$J7z;!SEhH$GE?p~QzyQ326v3{KkO^p>T#K$3TvQJ0`mjU!r| z-|KiKhc9f8R{<-4FCq5$k-?Ntk{Fe~E~#A& zX{df0>(sPZWpQy=S65P}L7~Q9V23%m0K{5Ct$xDT0*Oj1azL18UQH3BY6rXkbv=Mk zj6_7LQGb3VV=XzvYss3_S`xmsH_tI@$&%Dsa`8a6P%}v2!(K}Um4EyV)siM#YZ$)O zs3oJ&Q6^eKs(QbU22|Zqxz2Enm7F#H58+ras~%1Vo9NY%E~>p}enVpuo7d1(S5vFA ztN))LmPA!zQ5o!No#29JxI7LAa_N>vKYWDvchD{p>&0yg~TV~XLS@sa+&84Q!*>S^>`D}Owr6@m;e+> z4FyndFkc~RPdlnZ9UQ~S>O<{4VxnC7;sH7}51MqcIWn@f6O~g5iG(0VQF}=YD#cMv z>7hxwKu;$ppt;Cb#5zUvjHI9xX&05C3^9YK@v24b>K;?MP&7!;ag{!(Vkp228l2P* zq6i@#f{G;3_m~dT>-eaWQV=NwZVsn5E=6{Mp3u_x0``KE{E!>oxDc+OiP$0Tv0n7*^q zis)PDYtkj%^p7`ZSR{Nhm4d(dQ)?qB)2eejwY(cfTY`U|r=*-U&#SwKHDP5?$?7ZE z-AG`dr!vu7TGv>*2rH^`GLiKbSM3p-YTL)}mS+)J9cN6{&JtM{L4SpqlZmXiIb!dC zh#>11egkn6EfR9DNVq$fa@pT{85c*)Q^C zjwWwAa8$nSK*)=48GZxX4yW$@$$9m~#{EE__R^?cVLEC{>bAqCmucI9&>shS8YTpx z?4gIb+-GfaPs0ocXkB&9X)>`Fs&K?lfJm!98Y#=mO7FXzTl=b9=N6vx(jP5|W9#cE z%t+Ga-wzkCC&5RG=PcFEk>~86YV({G@SIo3bAI)hjthYA!*lkQl)G6&Op21@RQYP^ z>R5!_CV;k|Dj{EdA(J85vi#!qP_#I#<|8waAl(oo4P~^E@g7%jwLw{8hv^kK&kpW9 zZKi@pNEkx={PJ+&@34VI!={?xSfiaM)%H0J)eOoQ z+f$L76IQyq>Ce?oYfD9zHHOM1Nnt8g{8j2nqyg#@ecxb8CzAdh1G*iQJrk4(=lS(t+^HOKkX(hOWY;bn!o|1|gQ$?S?35+S}Ct zW99CW@(S;iayCn9XPy$~F0Cwav#{z4H&zt|SD15hohE0R6I)igPSC?X=Rj0Uo@}K; zk=tcWEz-JCGRaO?VJFk_*3AtBiy)Al?g(1#)Wo=*MrIBF_C>3m2(jc!5~8&xWh49^ z;oi6{21V9y zd1TouG)2~a9$A&9?AZ0vBkS1%Nr=~Lv2n229ld$5*k)69imao*gT?-^A#I}1!~XIS zE@O|uZ&LK{??rlh1Urd(>DaoBWNcbEzn0bI<`D8BWw>xRPSQx>dG-!J@%+RY8_)Z} z^BziYd)rJ|CpcQSZbK~d76Lo88ugEL;FxB~Q`34JaeS1^Z!he7!0{>Kc;QS_et3#7 zfe_~aF+;+Ce?UfbL@=`LDJ!DhDiH3Y^|={Zg&lpIkBE(rQ{V$k3o~DIS@`I?(N>`Z ztpZ7L98%l~RcYAD8SW=6`vYnBs%+T%;+0b^KdgTnWl=Beb9N;c_N{y9Jlz2xbHZi%6PJ>o`Mg_es~zRP;z-yyGyT7}?;1GNfU z_fV@q@{R|3n&?FKTXu;vvE0Ul3p2b%twR25ro8VE354heq7Mf&Y~1Dvwcg{Lfv|y? zh$Wo?c+T7z7Q_jSwM~tv2K_0Urnq`_gzzZPX`}?zik+v)iPm_mP81snCptk+^qVF6 z6!uLv`J}s>X#G+J=5n@>u~&OM4GCacLP$a*h6OgzzL_Y1rfvga>w>;c`_P za-Gsm^%|LqO8&lQOu3Mlw!YJh+b}NF?5I}BZqJz+Qn3Rfcj0r97F=ODwjFBi*00-F zc({1uAYK|NGPxc96wWK4L^3B=C=9zThO5cH9ZdM3M;QR^#QYttW-v>t)lc_H6i^l(JS z?;+#c>yz&4U9Z+7pmh<|pNUu?Bx)y_`3xa`4#f1;c-M#IIFH?DIF4S8V+#z2UK2GD z$)V4rtHv}_0WxzMAD~L{0q1w+0Q}0F-+ng!i}?K-h?@uhS-Mi$GLJyjVPZJ{F z1S}~lah8;Mu;6uL0bK4ZDJ^l9d36Oojyr@lTuH;0b@GJ9jejJX{-N6DJgY&|HKJ)9 z){+T#B$}Qkn)sA_XBC@K*z=)HosM`oLDgUKa-JGDs;D*1%`QQ@F|2ePIE zq}7Dni*0g02=qQm2hv}f{39J~?<2&Ow+~9Ubj)_F*))lmc;?iAh^QkPLetQm5dVMa zXe?L%luJjl(_^qxHC%y)Ezr?Cl`kis`s$L+r~2NVbm15Z>gR#C%}Cfo{zQoDk`b@d zmo6ORzJ!A6f8A<%Li{-p)9!&ZLMWkAGmJq)*dsn?zcy0(15$JbJuY1o# zq+Xk6?!Ou`xZj}HOaF1u|0@b*|1OiPEReN_v<|KxoT0LBuH~WpwT=E`2K_4&djXKI z8i-u(h3jRs1gB8(X@_#>yqIl1omxtJUOrwxf0D7<*->RWZ$SSLO}$ zb6kGa#z^k?-OC0OBeQ0h@=t*Lvk7r05ZiD-!xr!;wO+^#k82tb5sU;!n1~bc``H6m z_A+d3yGwNqHvGk~{`su_i22_80eR1oSFAiO8w{Q%5l?Fp^U+-3X=3KmPWm0kd_G)G zBSpVj?**=3n@zt-VC*(3?UmRtpu&T>N@>oNwHr<0`|n{lQsqytKiGEeUpq)1s`5j& zrLXdY-UamZ3wuEz1^TP}`h%BGKRNwu1TzGw%2)nJa+Tj%g-LmpC*=1J56`gXJQ62U zbZ)en;x?FKDw*QNWjZxLtRs4o^XUJ5%}H{dgIs3VTU}(J?nCD@2(6=(vbKyg<@6kXpqGVuqs zhL0vp9EFK@q3E95f;KVXqYY$ULcBK_@p>uT#VJJ5eP)kUVL}}9R$3Wh6yI%J#;F6y z*oRtoZp*1u8Cw=*+*kUT5WkEWh>2W06_MFVxvaL^L|jNNNHVV2mV|h{TK7R~tOTKT zf2||OX&}Uf6(cg#x}$H9;{>~HA<}7tNEe=!O*jsP$ij5Bj%HFZQyL$jT6dANVea20 zvC+%fKzd8~040{XYe2m9jS-m^HJ@u`fhI8@W{vlb*m zoT8DkII9!{;^Yq7qm#>e!AUixjrS5=4}Lq>(b^Zl{Z2eONw_D0n}LB(xxD6HPJ)4I z_`}1*Kuv`yFA|e5mk?`ERlmaljTA{Qed{1et2WrI_b`|Ad${Ah-LxK;l!r2B4o zbfg0h&GDOV{Mi&0i%H!1W?gtJwxqmF-$A1XC_Str6qbx@jQ^(McH!Ea?n(xcMWc!SR-JYj*AU!?~8)*x@qtkEp|D*prbJfZ0T literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ftp/ftp-ipv4.bro b/testing/btest/scripts/base/protocols/ftp/ftp-ipv4.bro new file mode 100644 index 0000000000..5cb8b808d5 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ftp/ftp-ipv4.bro @@ -0,0 +1,6 @@ +# This tests both active and passive FTP over IPv4. +# +# @TEST-EXEC: bro -r $TRACES/ftp-ipv4.trace +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ftp.log + From c0839cb945f2daa43a800063319c6ed688f16e74 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 21 Feb 2012 16:13:08 -0500 Subject: [PATCH 36/49] GeoIP installation documentation update. --- doc/quickstart.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/quickstart.rst b/doc/quickstart.rst index 5201420856..cc18956836 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -103,10 +103,16 @@ Optional Dependencies Bro can use libGeoIP for geo-locating IP addresses, and sendmail for sending emails. -* RPM/RedHat-based Linux: +* RedHat Enterprise Linux: .. console:: + sudo yum install geoip-devel sendmail + +* CentOS Linux: + + .. console:: + sudo yum install GeoIP-devel sendmail * DEB/Debian-based Linux: From d7dafe2fe24db31e0a71421d022f75b22e61e28d Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 22 Feb 2012 14:45:44 -0600 Subject: [PATCH 37/49] Refactoring various usages of new IPAddr class. Reducing number of places that internal representation was exposed via GetBytes/CopyIPv6. Also fixed a bug in remask_addr bif. --- src/CompHash.cc | 27 +---- src/Conn.cc | 28 +---- src/Conn.h | 37 +------ src/ConnCompressor.cc | 16 +-- src/ConnCompressor.h | 7 +- src/DNS_Mgr.cc | 47 ++++---- src/DNS_Mgr.h | 6 +- src/DPM.cc | 26 +---- src/DPM.h | 2 - src/Hash.cc | 10 -- src/Hash.h | 2 - src/IPAddr.cc | 103 ++++++++++++++++++ src/IPAddr.h | 79 ++++++++++++++ src/OSFinger.cc | 7 +- src/PIA.cc | 12 +- src/PacketSort.cc | 2 +- src/PrefixTable.cc | 4 +- src/Sessions.cc | 4 +- src/TCP_Endpoint.cc | 8 +- src/bro.bif | 91 ++-------------- src/net_util.cc | 7 ++ src/net_util.h | 1 + .../btest/Baseline/bifs.remask_addr/output | 32 ++++++ testing/btest/bifs/remask_addr.bro | 10 ++ 24 files changed, 301 insertions(+), 267 deletions(-) create mode 100644 testing/btest/Baseline/bifs.remask_addr/output create mode 100644 testing/btest/bifs/remask_addr.bro diff --git a/src/CompHash.cc b/src/CompHash.cc index ecd2543050..ae0e082216 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -108,12 +108,7 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, case TYPE_INTERNAL_ADDR: { uint32* kp = AlignAndPadType(kp0); - uint32 bytes[4]; - v->AsAddr().CopyIPv6(bytes); - kp[0] = bytes[0]; - kp[1] = bytes[1]; - kp[2] = bytes[2]; - kp[3] = bytes[3]; + v->AsAddr().CopyIPv6(kp); kp1 = reinterpret_cast(kp+4); } break; @@ -121,12 +116,7 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, case TYPE_INTERNAL_SUBNET: { uint32* kp = AlignAndPadType(kp0); - uint32 bytes[4]; - v->AsSubNet().Prefix().CopyIPv6(bytes); - kp[0] = bytes[0]; - kp[1] = bytes[1]; - kp[2] = bytes[2]; - kp[3] = bytes[3]; + v->AsSubNet().Prefix().CopyIPv6(kp); kp[4] = v->AsSubNet().Length(); kp1 = reinterpret_cast(kp+5); } @@ -352,19 +342,10 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, int type_check) const return new HashKey(v->ForceAsInt()); case TYPE_INTERNAL_ADDR: - { - uint32 bytes[4]; - v->AsAddr().CopyIPv6(bytes); - return new HashKey((void*)bytes, 4 * sizeof(uint32)); - } + return v->AsAddr().GetHashKey(); case TYPE_INTERNAL_SUBNET: - { - uint32 bytes[5]; - v->AsSubNet().Prefix().CopyIPv6(bytes); - bytes[4] = v->AsSubNet().Length(); - return new HashKey((void*)bytes, 5 * sizeof(uint32)); - } + return v->AsSubNet().GetHashKey(); case TYPE_INTERNAL_DOUBLE: return new HashKey(v->InternalDouble()); diff --git a/src/Conn.cc b/src/Conn.cc index 7f5b936646..acf17fab3a 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -14,32 +14,6 @@ #include "PIA.h" #include "binpac.h" -HashKey* ConnID::BuildConnKey() const - { - Key key; - - // Lookup up connection based on canonical ordering, which is - // the smaller of and - // followed by the other. - if ( is_one_way || - addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) ) - { - src_addr.CopyIPv6(key.ip1); - dst_addr.CopyIPv6(key.ip2); - key.port1 = src_port; - key.port2 = dst_port; - } - else - { - dst_addr.CopyIPv6(key.ip1); - src_addr.CopyIPv6(key.ip2); - key.port1 = dst_port; - key.port2 = src_port; - } - - return new HashKey(&key, sizeof(key)); - } - void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) { @@ -842,7 +816,7 @@ bool Connection::DoUnserialize(UnserialInfo* info) id.src_port = orig_port; id.dst_port = resp_port; id.is_one_way = 0; // ### incorrect for ICMP - key = id.BuildConnKey(); + key = BuildConnIDHashKey(id); int len; if ( ! UNSERIALIZE(&len) ) diff --git a/src/Conn.h b/src/Conn.h index cdd61bd67b..8740ddd7da 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -38,47 +38,12 @@ struct ConnID { uint32 src_port; uint32 dst_port; bool is_one_way; // if true, don't canonicalize - - // Returns a ListVal suitable for looking up a connection in - // a hash table. addr/ports are expected to be in network order. - // Unless is_one_way is true, the lookup sorts src and dst, - // so src_addr/src_port and dst_addr/dst_port just have to - // reflect the two different sides of the connection, - // neither has to be the particular source/destination - // or originator/responder. - HashKey* BuildConnKey() const; - - // The structure used internally for hashing. - struct Key { - uint32 ip1[4]; - uint32 ip2[4]; - uint16 port1; - uint16 port2; - }; }; static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1, const IPAddr& addr2, uint32 p2) { - uint32 a1[4]; - uint32 a2[4]; - addr1.CopyIPv6(a1); - addr2.CopyIPv6(a2); - // Because it's a canonical ordering, not a strict ordering, - // we can choose to give more weight to the least significant - // word than to the most significant word. This matters - // because for the common case of IPv4 addresses embedded in - // a IPv6 address, the top three words are identical, so we can - // save a few cycles by first testing the bottom word. - return a1[3] < a2[3] || - (a1[3] == a2[3] && - (a1[2] < a2[2] || - (a1[2] == a2[2] && - (a1[1] < a2[1] || - (a1[1] == a2[1] && - (a1[0] < a2[0] || - (a1[0] == a2[0] && - p1 < p2))))))); + return addr1 < addr2 || (addr1 == addr2 && p1 < p2); } class Analyzer; diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index ee194c607f..9fa43bd3a8 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -665,20 +665,8 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) reporter->InternalError("IPv6 snuck into connection compressor"); else { - const uint32* src_bytes; - const uint32* dst_bytes; - if ( c->ip1_is_src ) - { - ip1.GetBytes(&src_bytes); - ip2.GetBytes(&dst_bytes); - } - else - { - ip2.GetBytes(&src_bytes); - ip1.GetBytes(&dst_bytes); - } - memcpy(&ip->ip_src, src_bytes, sizeof(ip->ip_src)); - memcpy(&ip->ip_dst, dst_bytes, sizeof(ip->ip_dst)); + ip1.CopyIPv4(c->ip1_is_src ? &ip->ip_src : &ip->ip_dst); + ip2.CopyIPv4(c->ip1_is_src ? &ip->ip_dst : &ip->ip_dst); } if ( c->ip1_is_src ) diff --git a/src/ConnCompressor.h b/src/ConnCompressor.h index 36959b615c..96be7faff3 100644 --- a/src/ConnCompressor.h +++ b/src/ConnCompressor.h @@ -90,7 +90,12 @@ public: unsigned int ACK:1; double time; - ConnID::Key key; + struct Key { + uint32 ip1[4]; + uint32 ip2[4]; + uint16 port1; + uint16 port2; + } key; uint32 seq; uint32 ack; hash_t hash; diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 550dfeef6e..c706f26fa1 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -363,8 +363,6 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) mode = arg_mode; - addr_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func); - char err[NB_DNS_ERRSIZE]; nb_dns = nb_dns_init(err); @@ -504,11 +502,11 @@ Val* DNS_Mgr::LookupAddr(const IPAddr& addr) if ( mode != DNS_PRIME ) { - HashKey h(addr); - DNS_Mapping* d = addr_mappings.Lookup(&h); + AddrMap::iterator it = addr_mappings.find(addr); - if ( d ) + if ( it != addr_mappings.end() ) { + DNS_Mapping* d = it->second; if ( d->Valid() ) return d->Host(); else @@ -744,13 +742,13 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) else { new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl); - HashKey k(dr->ReqAddr()); - prev_dm = addr_mappings.Insert(&k, new_dm); + AddrMap::iterator it = addr_mappings.find(dr->ReqAddr()); + prev_dm = it == addr_mappings.end() ? 0 : it->second; + addr_mappings[dr->ReqAddr()] = new_dm; if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) { - HashKey k2(dr->ReqAddr()); - (void) addr_mappings.Insert(&k2, prev_dm); + addr_mappings[dr->ReqAddr()] = prev_dm; ++keep_prev; } } @@ -871,8 +869,7 @@ void DNS_Mgr::LoadCache(FILE* f) } else { - HashKey h(m->ReqAddr()); - addr_mappings.Insert(&h, m); + addr_mappings[m->ReqAddr()] = m; } } @@ -883,13 +880,12 @@ void DNS_Mgr::LoadCache(FILE* f) fclose(f); } -void DNS_Mgr::Save(FILE* f, PDict(DNS_Mapping)& m) +void DNS_Mgr::Save(FILE* f, const AddrMap& m) { - IterCookie* cookie = m.InitForIteration(); - DNS_Mapping* dm; - - while ( (dm = m.NextEntry(cookie)) ) - dm->Save(f); + AddrMap::const_iterator it; + for ( it = m.begin(); it != m.end(); ++it ) + if ( it->second ) + it->second->Save(f); } void DNS_Mgr::Save(FILE* f, const HostMap& m) @@ -908,15 +904,16 @@ void DNS_Mgr::Save(FILE* f, const HostMap& m) const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) { - HashKey h(addr); - DNS_Mapping* d = dns_mgr->addr_mappings.Lookup(&h); + AddrMap::iterator it = dns_mgr->addr_mappings.find(addr); - if ( ! d ) + if ( it == addr_mappings.end() ) return 0; + DNS_Mapping* d = it->second; + if ( d->Expired() ) { - dns_mgr->addr_mappings.Remove(&h); + dns_mgr->addr_mappings.erase(it); delete d; return 0; } @@ -1156,8 +1153,12 @@ void DNS_Mgr::Flush() delete it->second.second; } + AddrMap::iterator it2; + for ( it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 ) + delete it2->second; + host_mappings.clear(); - addr_mappings.Clear(); + addr_mappings.clear(); } void DNS_Mgr::Process() @@ -1269,6 +1270,6 @@ void DNS_Mgr::GetStats(Stats* stats) stats->failed = failed; stats->pending = asyncs_pending; stats->cached_hosts = host_mappings.size(); - stats->cached_addresses = addr_mappings.Length(); + stats->cached_addresses = addr_mappings.size(); } diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index ca3f5b6ff4..7983a91573 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -29,7 +29,6 @@ struct nb_dns_result; declare(PDict,ListVal); class DNS_Mapping; -declare(PDict,DNS_Mapping); enum DNS_MgrMode { DNS_PRIME, // used to prime the cache @@ -106,8 +105,9 @@ protected: void DumpAddrList(FILE* f, ListVal* al); typedef map > HostMap; + typedef map AddrMap; void LoadCache(FILE* f); - void Save(FILE* f, PDict(DNS_Mapping)& m); + void Save(FILE* f, const AddrMap& m); void Save(FILE* f, const HostMap& m); // Selects on the fd to see if there is an answer available (timeout @@ -137,7 +137,7 @@ protected: PDict(ListVal) services; HostMap host_mappings; - PDict(DNS_Mapping) addr_mappings; + AddrMap addr_mappings; DNS_mgr_request_list requests; diff --git a/src/DPM.cc b/src/DPM.cc index c02db08c2f..595ee42ec8 100644 --- a/src/DPM.cc +++ b/src/DPM.cc @@ -33,22 +33,6 @@ ExpectedConn::ExpectedConn(const ExpectedConn& c) proto = c.proto; } -HashKey* ExpectedConn::GetKey() const - { - struct Key { - uint32 orig[4]; - uint32 resp[4]; - uint16 resp_p; - uint16 proto; - }; - Key k; - orig.CopyIPv6(k.orig); - resp.CopyIPv6(k.resp); - k.resp_p = resp_p; - k.proto = proto; - return new HashKey(&k, sizeof(k)); - } - DPM::DPM() : expected_conns_queue(AssignedAnalyzer::compare) { @@ -149,7 +133,7 @@ AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn) ExpectedConn c(conn->OrigAddr(), conn->RespAddr(), ntohs(conn->RespPort()), proto); - HashKey* key = c.GetKey(); + HashKey* key = BuildExpectedConnHashKey(c); AssignedAnalyzer* a = expected_conns.Lookup(key); delete key; @@ -158,7 +142,7 @@ AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn) // Wildcard for originator. c.orig = IPAddr(string("::")); - HashKey* key = c.GetKey(); + HashKey* key = BuildExpectedConnHashKey(c); a = expected_conns.Lookup(key); delete key; } @@ -403,7 +387,7 @@ void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, { if ( ! a->deleted ) { - HashKey* key = a->conn.GetKey(); + HashKey* key = BuildExpectedConnHashKey(a->conn); expected_conns.Remove(key); delete key; } @@ -422,7 +406,7 @@ void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp, ExpectedConn c(orig, resp, resp_p, proto); - HashKey* key = c.GetKey(); + HashKey* key = BuildExpectedConnHashKey(c); AssignedAnalyzer* a = expected_conns.Lookup(key); @@ -449,7 +433,7 @@ void DPM::Done() AssignedAnalyzer* a = expected_conns_queue.top(); if ( ! a->deleted ) { - HashKey* key = a->conn.GetKey(); + HashKey* key = BuildExpectedConnHashKey(a->conn); expected_conns.Remove(key); delete key; } diff --git a/src/DPM.h b/src/DPM.h index 7e9150f3aa..f59d21dbfc 100644 --- a/src/DPM.h +++ b/src/DPM.h @@ -32,8 +32,6 @@ public: ExpectedConn(const ExpectedConn& c); - HashKey* GetKey() const; - IPAddr orig; IPAddr resp; uint16 resp_p; diff --git a/src/Hash.cc b/src/Hash.cc index c8e68da429..7873e398c3 100644 --- a/src/Hash.cc +++ b/src/Hash.cc @@ -103,16 +103,6 @@ HashKey::HashKey(const BroString* s) is_our_dynamic = 0; } -HashKey::HashKey(const IPAddr& addr) - { - const uint32* bytes; - int len = addr.GetBytes(&bytes); - size = len * sizeof(uint32); - key = CopyKey(bytes, size); - is_our_dynamic = 1; - hash = HashBytes(key, size); - } - HashKey::HashKey(int copy_key, void* arg_key, int arg_size) { size = arg_size; diff --git a/src/Hash.h b/src/Hash.h index 2d24a05b79..00db53d075 100644 --- a/src/Hash.h +++ b/src/Hash.h @@ -6,7 +6,6 @@ #include #include "BroString.h" -#include "IPAddr.h" #define UHASH_KEY_SIZE 36 @@ -29,7 +28,6 @@ public: HashKey(const void* p); HashKey(const char* s); HashKey(const BroString* s); - HashKey(const IPAddr& addr); ~HashKey() { if ( is_our_dynamic ) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 3dc0025c2d..a25e8d1341 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -4,11 +4,62 @@ #include #include "IPAddr.h" #include "Reporter.h" +#include "Conn.h" +#include "DPM.h" const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; +HashKey* BuildConnIDHashKey(const ConnID& id) + { + struct { + in6_addr ip1; + in6_addr ip2; + uint16 port1; + uint16 port2; + } key; + + // Lookup up connection based on canonical ordering, which is + // the smaller of and + // followed by the other. + if ( id.is_one_way || + addr_port_canon_lt(id.src_addr, id.src_port, id.dst_addr, id.dst_port) + ) + { + key.ip1 = id.src_addr.in6; + key.ip2 = id.dst_addr.in6; + key.port1 = id.src_port; + key.port2 = id.dst_port; + } + else + { + key.ip1 = id.dst_addr.in6; + key.ip2 = id.src_addr.in6; + key.port1 = id.dst_port; + key.port2 = id.src_port; + } + + return new HashKey(&key, sizeof(key)); + } + +HashKey* BuildExpectedConnHashKey(const ExpectedConn& c) + { + struct { + in6_addr orig; + in6_addr resp; + uint16 resp_p; + uint16 proto; + } key; + + key.orig = c.orig.in6; + key.resp = c.resp.in6; + key.resp_p = c.resp_p; + key.proto = c.proto; + + return new HashKey(&key, sizeof(key)); + } + void IPAddr::Mask(int top_bits_to_keep) { if ( top_bits_to_keep <= 0 || top_bits_to_keep > 128 ) @@ -147,6 +198,58 @@ string IPAddr::AsString() const } } +string IPAddr::AsHexString() const + { + char buf[33]; + + if ( GetFamily() == IPv4 ) + { + uint32_t* p = (uint32_t*) &in6.s6_addr[12]; + snprintf(buf, sizeof(buf), "%08x", (uint32_t) ntohl(*p)); + } + else + { + uint32_t* p = (uint32_t*) in6.s6_addr; + snprintf(buf, sizeof(buf), "%08x%08x%08x%08x", + (uint32_t) ntohl(p[0]), (uint32_t) ntohl(p[1]), + (uint32_t) ntohl(p[2]), (uint32_t) ntohl(p[3])); + } + + return buf; + } + +string IPAddr::PtrName() const + { + if ( GetFamily() == IPv4 ) + { + char buf[256]; + uint32_t* p = (uint32_t*) &in6.s6_addr[12]; + uint32_t a = ntohl(*p); + uint32_t a3 = (a >> 24) & 0xff; + uint32_t a2 = (a >> 16) & 0xff; + uint32_t a1 = (a >> 8) & 0xff; + uint32_t a0 = a & 0xff; + snprintf(buf, sizeof(buf), "%u.%u.%u.%u.in-addr.arpa", a0, a1, a2, a3); + return buf; + } + else + { + static const char hex_digit[] = "0123456789abcdef"; + string ptr_name("ip6.arpa"); + uint32_t* p = (uint32_t*) in6.s6_addr; + for ( unsigned int i = 0; i < 4; ++i ) + { + uint32 a = ntohl(p[i]); + for ( unsigned int j = 1; j <=8; ++j ) + { + ptr_name.insert(0, 1, '.'); + ptr_name.insert(0, 1, hex_digit[(a >> (32-j*4)) & 0x0f]); + } + } + return ptr_name; + } + } + IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length) : prefix(in4), length(96 + length) { diff --git a/src/IPAddr.h b/src/IPAddr.h index 96e70689b4..4b8cb1e369 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -8,8 +8,12 @@ #include #include "BroString.h" +#include "Hash.h" #include "util.h" +struct ConnID; +class ExpectedConn; + typedef in_addr in4_addr; /** @@ -189,6 +193,36 @@ public: memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr)); } + /** + * Retrieves a copy of the IPv6 raw byte representation of the address. + * @see CopyIPv6(uint32_t) + */ + void CopyIPv6(in6_addr* arg_in6) const + { + memcpy(arg_in6->s6_addr, in6.s6_addr, sizeof(in6.s6_addr)); + } + + /** + * Retrieves a copy of the IPv4 raw byte representation of the address. + * The caller should verify the address is of the IPv4 family type + * beforehand. @see GetFamily(). + * + * @param in4 The pointer to a memory location in which the raw bytes + * of the address are to be copied in network byte-order. + */ + void CopyIPv4(in4_addr* in4) const + { + memcpy(&in4->s_addr, &in6.s6_addr[12], sizeof(in4->s_addr)); + } + + /** + * Returns a key that can be used to lookup the IP Address in a hash table. + */ + HashKey* GetHashKey() const + { + return new HashKey((void*)in6.s6_addr, sizeof(in6.s6_addr)); + } + /** * Masks out lower bits of the address. * @@ -223,6 +257,18 @@ public: return *this; } + /** + * Bitwise OR operator returns the IP address resulting from the bitwise + * OR operation on the raw bytes of this address with another. + */ + IPAddr operator|(const IPAddr& other) + { + in6_addr result; + for ( int i = 0; i < 16; ++i ) + result.s6_addr[i] = this->in6.s6_addr[i] | other.in6.s6_addr[i]; + return IPAddr(result); + } + /** * Returns a string representation of the address. IPv4 addresses * will be returned in dotted representation, IPv6 addresses in @@ -230,12 +276,23 @@ public: */ string AsString() const; + /** + * Returns a host-order, plain hex string representation of the address. + */ + string AsHexString() const; + /** * Returns a string representation of the address. This returns the * same as AsString(). */ operator std::string() const { return AsString(); } + /** + * Returns a reverse pointer name associated with the IP address. + * For example, 192.168.0.1's reverse pointer is 1.0.168.192.in-addr.arpa. + */ + string PtrName() const; + /** * Comparison operator for IP address. */ @@ -259,6 +316,11 @@ public: return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0; } + friend HashKey* BuildConnIDHashKey(const ConnID& id); + friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); + + friend class IPPrefix; + unsigned int MemoryAllocation() const { return padded_sizeof(*this); } /** @@ -328,6 +390,9 @@ inline bool IPAddr::IsLoopback() const && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); } +HashKey* BuildConnIDHashKey(const ConnID& id); +HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); + /** * Class storing both IPv4 and IPv6 prefixes * (i.e., \c 192.168.1.1/16 and \c FD00::/8. @@ -433,6 +498,20 @@ public: operator std::string() const { return AsString(); } + /** + * Returns a key that can be used to lookup the IP Prefix in a hash table. + */ + HashKey* GetHashKey() const + { + struct { + in6_addr ip; + uint32 len; + } key; + key.ip = prefix.in6; + key.len = Length(); + return new HashKey(&key, sizeof(key)); + } + unsigned int MemoryAllocation() const { return padded_sizeof(*this); } /** diff --git a/src/OSFinger.cc b/src/OSFinger.cc index 980d618f6e..3368a8e40c 100644 --- a/src/OSFinger.cc +++ b/src/OSFinger.cc @@ -65,15 +65,14 @@ OSFingerprint::OSFingerprint(FingerprintMode arg_mode) bool OSFingerprint::CacheMatch(const IPAddr& addr, int id) { - uint32 bytes[4]; - addr.CopyIPv6(bytes); - HashKey key = HashKey(bytes, 4); + HashKey* key = addr.GetHashKey(); int* pid = new int; *pid=id; - int* prev = os_matches.Insert(&key, pid); + int* prev = os_matches.Insert(key, pid); bool ret = (prev ? *prev != id : 1); if (prev) delete prev; + delete key; return ret; } diff --git a/src/PIA.cc b/src/PIA.cc index ed46e84794..7417615566 100644 --- a/src/PIA.cc +++ b/src/PIA.cc @@ -199,21 +199,17 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) ip4_hdr = new IP_Hdr((const struct ip*) ip4); } - const uint32* obytes; - const uint32* rbytes; - Conn()->OrigAddr().GetBytes(&obytes); - Conn()->RespAddr().GetBytes(&rbytes); if ( is_orig ) { - memcpy(&ip4->ip_src.s_addr, obytes, sizeof(uint32)); - memcpy(&ip4->ip_dst.s_addr, rbytes, sizeof(uint32)); + Conn()->OrigAddr().CopyIPv4(&ip4->ip_src); + Conn()->RespAddr().CopyIPv4(&ip4->ip_dst); tcp4->th_sport = htons(Conn()->OrigPort()); tcp4->th_dport = htons(Conn()->RespPort()); } else { - memcpy(&ip4->ip_src.s_addr, rbytes, sizeof(uint32)); - memcpy(&ip4->ip_dst.s_addr, obytes, sizeof(uint32)); + Conn()->RespAddr().CopyIPv4(&ip4->ip_src); + Conn()->OrigAddr().CopyIPv4(&ip4->ip_dst); tcp4->th_sport = htons(Conn()->RespPort()); tcp4->th_dport = htons(Conn()->OrigPort()); } diff --git a/src/PacketSort.cc b/src/PacketSort.cc index 0ff08b3280..67a0cf861f 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -65,7 +65,7 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, payload_length = ip_hdr->PayloadLen() - tp->th_off * 4; - key = id.BuildConnKey(); + key = BuildConnIDHashKey(id); is_tcp = 1; } diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index bbe391bfcb..58a488a9f1 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -5,9 +5,7 @@ inline static prefix_t* make_prefix(const IPAddr& addr, int width) { prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); - uint32 bytes[4]; - addr.CopyIPv6(bytes); - memcpy(&prefix->add.sin6, bytes, 4 * sizeof(uint32)); + addr.CopyIPv6(&prefix->add.sin6); prefix->family = AF_INET6; prefix->bitlen = width; prefix->ref_count = 1; diff --git a/src/Sessions.cc b/src/Sessions.cc index 8ed223a92e..d78032a25b 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -555,7 +555,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } - HashKey* h = id.BuildConnKey(); + HashKey* h = BuildConnIDHashKey(id); if ( ! h ) reporter->InternalError("hash computation failed"); @@ -831,7 +831,7 @@ Connection* NetSessions::FindConnection(Val* v) id.is_one_way = 0; // ### incorrect for ICMP connections - HashKey* h = id.BuildConnKey(); + HashKey* h = BuildConnIDHashKey(id); if ( ! h ) reporter->InternalError("hash computation failed"); diff --git a/src/TCP_Endpoint.cc b/src/TCP_Endpoint.cc index 626680966f..69c08870d9 100644 --- a/src/TCP_Endpoint.cc +++ b/src/TCP_Endpoint.cc @@ -32,12 +32,8 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) dst_addr = is_orig ? tcp_analyzer->Conn()->OrigAddr() : tcp_analyzer->Conn()->RespAddr(); - const uint32* src_bytes; - const uint32* dst_bytes; - int n = src_addr.GetBytes(&src_bytes); - int m = dst_addr.GetBytes(&dst_bytes); - checksum_base = ones_complement_checksum((void*) src_bytes, n*4, 0); - checksum_base = ones_complement_checksum((void*) dst_bytes, m*4, checksum_base); + 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 diff --git a/src/bro.bif b/src/bro.bif index bbd31ef8a6..52ac903d0c 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -179,38 +179,8 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d) // This makes only a very slight difference, so not // clear it would e worth the hassle. - const IPAddr& u = v->AsAddr(); - const uint32* net_order_u; - int len = u.GetBytes(&net_order_u); - - if ( len == 4 ) - { - // We explicitly convert the address to host order - // in a copy, because if we just call ntohl() for - // our invocation on snprintf() below, on some systems - // it turns a 32-bit value (Linux), whereas on - // others it returns a long (FreeBSD); the latter - // gets us in trouble if we have longs > 32 bits, - // because then the format specifier needs to be %lx - // rather than %x ....... what a pain! - // - // Also note that we don't change u in-place because - // that would alter the byte order of the underlying - // value. - uint32 host_order_u[4]; - host_order_u[0] = ntohl(net_order_u[0]); - host_order_u[1] = ntohl(net_order_u[1]); - host_order_u[2] = ntohl(net_order_u[2]); - host_order_u[3] = ntohl(net_order_u[3]); - - snprintf(out_buf, sizeof(out_buf), "%08x%08x%08x%08x", - host_order_u[0], host_order_u[1], - host_order_u[2], host_order_u[3]); - } - else - { - snprintf(out_buf, sizeof(out_buf), "%08x", ntohl(net_order_u[0])); - } + snprintf(out_buf, sizeof(out_buf), "%s", + v->AsAddr().AsHexString().c_str()); } else if ( ! check_fmt_type(t, ok_d_fmt) ) @@ -2445,35 +2415,7 @@ function ptr_name_to_addr%(s: string%): addr ## .. bro:see:: ptr_name_to_addr parse_dotted_addr function addr_to_ptr_name%(a: addr%): string %{ - const uint32* addr; - int len = a->AsAddr().GetBytes(&addr); - - if ( len == 1 ) - { - char buf[256]; - uint32 a = ntohl(addr[0]); - uint32 a3 = (a >> 24) & 0xff; - uint32 a2 = (a >> 16) & 0xff; - uint32 a1 = (a >> 8) & 0xff; - uint32 a0 = a & 0xff; - sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", a0, a1, a2, a3); - return new StringVal(buf); - } - else - { - static const char hex_digit[] = "0123456789abcdef"; - string ptr_name("ip6.arpa"); - for ( unsigned int i = 0; i < 4; ++i ) - { - uint32 a = ntohl(addr[i]); - for ( unsigned int j = 1; j <=8; ++j ) - { - ptr_name.insert(0, 1, '.'); - ptr_name.insert(0, 1, hex_digit[(a >> (32-j*4)) & 0x0f]); - } - } - return new StringVal(ptr_name.c_str()); - } + return new StringVal(a->AsAddr().PtrName().c_str()); %} # Transforms n0.n1.n2.n3 -> addr. @@ -2541,7 +2483,7 @@ static Val* parse_eftp(const char* line) RecordVal* r = new RecordVal(ftp_port); int net_proto = 0; // currently not used - uint32 addr = 0; + IPAddr addr; int port = 0; int good = 0; @@ -2563,11 +2505,8 @@ static Val* parse_eftp(const char* line) if ( *line != delimiter ) // default of 0 is ok { string s(line); - IPAddr tmp(s); - const uint32* bytes; - tmp.GetBytes(&bytes); - addr = *bytes; - if ( addr == 0 ) + addr = IPAddr(s); + if ( addr == IPAddr("0.0.0.0") ) good = 0; } @@ -3025,14 +2964,8 @@ function remask_addr%(a1: addr, a2: addr, top_bits_from_a1: count%): addr IPAddr addr1(a1->AsAddr()); addr1.Mask(top_bits_from_a1); IPAddr addr2(a2->AsAddr()); - addr1.ReverseMask(top_bits_from_a1); - uint32 x1[4]; - uint32 x2[4]; - addr1.CopyIPv6(x1); - addr2.CopyIPv6(x2); - for ( unsigned int i = 0; i < 4; ++i ) - x1[i] = x1[i] | x2[i]; - return new AddrVal(x1); + addr2.ReverseMask(top_bits_from_a1); + return new AddrVal(addr1|addr2); %} ## Checks whether a given :bro:type:`port` has TCP as transport protocol. @@ -3551,10 +3484,8 @@ function lookup_location%(a: addr%) : geo_location #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 if ( geoip_v6 && a->AsAddr().GetFamily() == IPAddr::IPv6 ) { - const uint32* bytes; - a->AsAddr().GetBytes(&bytes); geoipv6_t ga; - memcpy(&ga, bytes, 16); + a->AsAddr().CopyIPv6(&ga); if ( have_cityv6_db ) gir = GeoIP_record_by_ipnum_v6(geoip_v6, ga); else @@ -3648,10 +3579,8 @@ function lookup_asn%(a: addr%) : count #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) { - const uint32* bytes; - a->AsAddr().GetBytes(&bytes); geoipv6_t ga; - memcpy(&ga, bytes, 16); + a->AsAddr().CopyIPv6(&ga); gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga); } else diff --git a/src/net_util.cc b/src/net_util.cc index 14ba475450..1a4e9f1a7f 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -31,6 +31,13 @@ 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 diff --git a/src/net_util.h b/src/net_util.h index a1304fcbe2..8787340328 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -60,6 +60,7 @@ 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); diff --git a/testing/btest/Baseline/bifs.remask_addr/output b/testing/btest/Baseline/bifs.remask_addr/output new file mode 100644 index 0000000000..1d276abd4f --- /dev/null +++ b/testing/btest/Baseline/bifs.remask_addr/output @@ -0,0 +1,32 @@ +1: 127.255.0.0 +2: 63.255.0.0 +3: 31.255.0.0 +4: 15.255.0.0 +5: 7.255.0.0 +6: 3.255.0.0 +7: 1.255.0.0 +8: 0.255.0.0 +9: 0.127.0.0 +10: 0.63.0.0 +11: 0.31.0.0 +12: 0.15.0.0 +13: 0.7.0.0 +14: 0.3.0.0 +15: 0.1.0.0 +16: 0.0.0.0 +17: 0.0.128.0 +18: 0.0.192.0 +19: 0.0.224.0 +20: 0.0.240.0 +21: 0.0.248.0 +22: 0.0.252.0 +23: 0.0.254.0 +24: 0.0.255.0 +25: 0.0.255.128 +26: 0.0.255.192 +27: 0.0.255.224 +28: 0.0.255.240 +29: 0.0.255.248 +30: 0.0.255.252 +31: 0.0.255.254 +32: 0.0.255.255 diff --git a/testing/btest/bifs/remask_addr.bro b/testing/btest/bifs/remask_addr.bro new file mode 100644 index 0000000000..d387667b6a --- /dev/null +++ b/testing/btest/bifs/remask_addr.bro @@ -0,0 +1,10 @@ +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +const one_to_32: vector of count = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}; + +for ( i in one_to_32 ) + { + print fmt("%s: %s", one_to_32[i], + remask_addr(0.0.255.255, 255.255.0.0, 96+one_to_32[i])); + } From c84394d07f30aa856ca4283ade98c08d63d37b4b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 22 Feb 2012 15:44:05 -0600 Subject: [PATCH 38/49] Refactor IPAddr v4 initialization from string. (fixes #775) Revived code from old dotted_to_addr function to parse the dotted address string directly instead of canonicalizing and passing to inet_pton. --- src/IPAddr.cc | 47 +++++++++++------------------------------------ src/IPAddr.h | 8 -------- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 3dc0025c2d..f0389a68a6 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -67,52 +67,27 @@ void IPAddr::ReverseMask(int top_bits_to_chop) memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } -std::string IPAddr::CanonIPv4(const std::string& input) - { - vector parts; - string output; - size_t start = 0; - size_t end; - - do - { - end = input.find('.', start); - string p; - bool in_leading_zeroes = true; - for ( size_t i = start; i != end && i < input.size(); ++i ) - { - if ( in_leading_zeroes && input[i] == '0' ) continue; - in_leading_zeroes = false; - p.push_back(input[i]); - } - - if ( p.size() == 0 ) - p.push_back('0'); - parts.push_back(p); - start = end + 1; - } while ( end != string::npos ); - - for ( size_t i = 0; i < parts.size(); ++i ) - { - if ( i > 0 ) - output += '.'; - output += parts[i]; - } - - return output; - } - void IPAddr::Init(const std::string& s) { if ( s.find(':') == std::string::npos ) // IPv4. { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - if ( inet_pton(AF_INET, CanonIPv4(s).c_str(), &in6.s6_addr[12]) <=0 ) + // parse the address directly instead of using inet_pton since + // some platforms have more sensitive implementations than others + // that can't e.g. handle leading zeroes. + int a[4]; + int n = sscanf(s.c_str(), "%d.%d.%d.%d", a+0, a+1, a+2, a+3); + if ( n != 4 || a[0] < 0 || a[1] < 0 || a[2] < 0 || a[3] < 0 || + a[0] > 255 || a[1] > 255 || a[2] > 255 || a[3] > 255 ) { reporter->Error("Bad IP address: %s", s.c_str()); memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + return; } + uint32_t addr = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; + addr = htonl(addr); + memcpy(&in6.s6_addr[12], &addr, sizeof(uint32_t)); } else diff --git a/src/IPAddr.h b/src/IPAddr.h index 96e70689b4..c2e57ea7d1 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -261,14 +261,6 @@ public: unsigned int MemoryAllocation() const { return padded_sizeof(*this); } - /** - * Returns a canonicalized IPv4 dotted-decimal string such that - * leading zeroes of each decimal part are removed. - * - * @param s String containing an IPv4 address in dotted-decimal notation. - */ - static std::string CanonIPv4(const std::string& s); - private: /** * Initializes an address instance from a string representation. From 32aabe843245afa28492450f7fc1f49ceb758d66 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 24 Feb 2012 12:34:29 -0600 Subject: [PATCH 39/49] Add to_subnet bif (fixes #782). Also fix IPAddr::Mask/ReverseMask not allowing argument of 0. And clarified return value of to_addr bif when the input string does not parse into a valid IP address. --- src/IPAddr.cc | 4 +-- src/Val.cc | 17 +++++++---- src/bro.bif | 31 ++++++++++++++++---- testing/btest/Baseline/bifs.to_addr/error | 1 + testing/btest/Baseline/bifs.to_addr/output | 1 + testing/btest/Baseline/bifs.to_subnet/error | 1 + testing/btest/Baseline/bifs.to_subnet/output | 3 ++ testing/btest/bifs/to_addr.bro | 4 ++- testing/btest/bifs/to_subnet.bro | 11 +++++++ 9 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 testing/btest/Baseline/bifs.to_addr/error create mode 100644 testing/btest/Baseline/bifs.to_subnet/error create mode 100644 testing/btest/Baseline/bifs.to_subnet/output create mode 100644 testing/btest/bifs/to_subnet.bro diff --git a/src/IPAddr.cc b/src/IPAddr.cc index f0389a68a6..8a70497fd2 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -11,7 +11,7 @@ const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, void IPAddr::Mask(int top_bits_to_keep) { - if ( top_bits_to_keep <= 0 || top_bits_to_keep > 128 ) + if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) { reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep); return; @@ -40,7 +40,7 @@ void IPAddr::Mask(int top_bits_to_keep) void IPAddr::ReverseMask(int top_bits_to_chop) { - if ( top_bits_to_chop <= 0 || top_bits_to_chop > 128 ) + if ( top_bits_to_chop < 0 || top_bits_to_chop > 128 ) { reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop); return; diff --git a/src/Val.cc b/src/Val.cc index fe7bd44481..8c1254a9eb 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -911,11 +911,18 @@ bool AddrVal::DoUnserialize(UnserialInfo* info) SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET) { - const char* sep = strchr(text, '/'); - if ( ! sep ) - Internal("separator missing in SubNetVal::SubNetVal"); - - val.subnet_val = new IPPrefix(text, atoi(sep+1)); + string s(text); + size_t slash_loc = s.find('/'); + if ( slash_loc == string::npos ) + { + reporter->Error("Bad string in SubNetVal ctor: %s", text); + val.subnet_val = new IPPrefix(); + } + else + { + val.subnet_val = new IPPrefix(s.substr(0, slash_loc), + atoi(s.substr(slash_loc + 1).c_str())); + } } SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET) diff --git a/src/bro.bif b/src/bro.bif index bbd31ef8a6..70548933bc 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2135,7 +2135,7 @@ function counts_to_addr%(v: index_vec%): addr ## ## Returns: The :bro:type:`string` *str* as :bro:type:`int`. ## -## .. bro:see:: to_addr to_port +## .. bro:see:: to_addr to_port to_subnet function to_int%(str: string%): int %{ const char* s = str->CheckString(); @@ -2192,7 +2192,7 @@ function double_to_count%(d: double%): count ## Returns: The :bro:type:`string` *str* as unsigned integer or if in invalid ## format. ## -## .. bro:see:: to_addr to_int to_port +## .. bro:see:: to_addr to_int to_port to_subnet function to_count%(str: string%): count %{ const char* s = str->CheckString(); @@ -2287,9 +2287,11 @@ function count_to_port%(num: count, proto: transport_proto%): port ## ## ip: The :bro:type:`string` to convert. ## -## Returns: The :bro:type:`string` *ip* as :bro:type:`addr`. +## Returns: The :bro:type:`string` *ip* as :bro:type:`addr` or the unspecified +## address ``::`` if the input string does not parse correctly. ## ## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr +## to_subnet function to_addr%(ip: string%): addr %{ char* s = ip->AsString()->Render(); @@ -2298,13 +2300,30 @@ function to_addr%(ip: string%): addr return ret; %} +## Converts a :bro:type:`string` to a :bro:type:`subnet`. +## +## sn: The subnet to convert. +## +## Returns: The *sn* string as a :bro:type:`subnet` or the unspecified subnet +## ``::/0`` if the input string does not parse correctly. +## +## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr +## to_addr +function to_subnet%(sn: string%): subnet + %{ + char* s = sn->AsString()->Render(); + Val* ret = new SubNetVal(s); + delete [] s; + return ret; + %} + ## Converts a :bro:type:`count` to an :bro:type:`addr`. ## ## ip: The :bro:type:`count` to convert. ## ## Returns: The :bro:type:`count` *ip* as :bro:type:`addr`. ## -## .. bro:see:: raw_bytes_to_v4_addr to_addr +## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet function count_to_v4_addr%(ip: count%): addr %{ if ( ip > 4294967295LU ) @@ -2324,7 +2343,7 @@ function count_to_v4_addr%(ip: count%): addr ## ## Returns: The byte :bro:type:`string` *ip* as :bro:type:`addr`. ## -## .. bro:see:: raw_bytes_to_v4_addr to_addr +## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet function raw_bytes_to_v4_addr%(b: string%): addr %{ uint32 a = 0; @@ -2347,7 +2366,7 @@ function raw_bytes_to_v4_addr%(b: string%): addr ## ## Returns: A :bro:type:`port` converted from *s*. ## -## .. bro:see:: to_addr to_count to_int +## .. bro:see:: to_addr to_count to_int to_subnet function to_port%(s: string%): port %{ int port = 0; diff --git a/testing/btest/Baseline/bifs.to_addr/error b/testing/btest/Baseline/bifs.to_addr/error new file mode 100644 index 0000000000..b8ba985f7a --- /dev/null +++ b/testing/btest/Baseline/bifs.to_addr/error @@ -0,0 +1 @@ +error: Bad IP address: not an IP diff --git a/testing/btest/Baseline/bifs.to_addr/output b/testing/btest/Baseline/bifs.to_addr/output index bcfdd3b6a2..ff277498f8 100644 --- a/testing/btest/Baseline/bifs.to_addr/output +++ b/testing/btest/Baseline/bifs.to_addr/output @@ -6,3 +6,4 @@ to_addr(10.20.30.40) = 10.20.30.40 (SUCCESS) to_addr(100.200.30.40) = 100.200.30.40 (SUCCESS) to_addr(10.0.0.0) = 10.0.0.0 (SUCCESS) to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS) +to_addr(not an IP) = :: (SUCCESS) diff --git a/testing/btest/Baseline/bifs.to_subnet/error b/testing/btest/Baseline/bifs.to_subnet/error new file mode 100644 index 0000000000..ee0062cd83 --- /dev/null +++ b/testing/btest/Baseline/bifs.to_subnet/error @@ -0,0 +1 @@ +error: Bad string in SubNetVal ctor: 10.0.0.0 diff --git a/testing/btest/Baseline/bifs.to_subnet/output b/testing/btest/Baseline/bifs.to_subnet/output new file mode 100644 index 0000000000..0775063f89 --- /dev/null +++ b/testing/btest/Baseline/bifs.to_subnet/output @@ -0,0 +1,3 @@ +10.0.0.0/8, T +2607:f8b0::/32, T +::/0, T diff --git a/testing/btest/bifs/to_addr.bro b/testing/btest/bifs/to_addr.bro index 67ce79c795..3b79648b00 100644 --- a/testing/btest/bifs/to_addr.bro +++ b/testing/btest/bifs/to_addr.bro @@ -1,5 +1,6 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output 2>error # @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff error function test_to_addr(ip: string, expect: addr) { @@ -16,3 +17,4 @@ test_to_addr("10.20.30.40", 10.20.30.40); test_to_addr("100.200.30.40", 100.200.30.40); test_to_addr("10.0.0.0", 10.0.0.0); test_to_addr("10.00.00.000", 10.0.0.0); +test_to_addr("not an IP", ::); diff --git a/testing/btest/bifs/to_subnet.bro b/testing/btest/bifs/to_subnet.bro new file mode 100644 index 0000000000..6b1eb54946 --- /dev/null +++ b/testing/btest/bifs/to_subnet.bro @@ -0,0 +1,11 @@ +# @TEST-EXEC: bro -b %INPUT >output 2>error +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff error + +global sn: subnet; +sn = to_subnet("10.0.0.0/8"); +print sn, sn == 10.0.0.0/8; +sn = to_subnet("2607:f8b0::/32"); +print sn, sn == 2607:f8b0::/32; +sn = to_subnet("10.0.0.0"); +print sn, sn == ::/0; From b552979011a7f2d467db1e0ef8557be8df48f66e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 24 Feb 2012 13:14:49 -0600 Subject: [PATCH 40/49] Raise minimum required CMake version to 2.6.3 --- CMakeLists.txt | 2 +- INSTALL | 2 +- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 241a5b29d2..de3138c20c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ project(Bro C CXX) -cmake_minimum_required(VERSION 2.6 FATAL_ERROR) +cmake_minimum_required(VERSION 2.6.3 FATAL_ERROR) include(cmake/CommonCMakeConfig.cmake) ######################################################################## diff --git a/INSTALL b/INSTALL index 73b824b2b7..d4aa93d11f 100644 --- a/INSTALL +++ b/INSTALL @@ -8,7 +8,7 @@ Prerequisites Bro relies on the following libraries and tools, which need to be installed before you begin: - * CMake 2.6 or greater http://www.cmake.org + * CMake 2.6.3 or greater http://www.cmake.org * Libpcap (headers and libraries) http://www.tcpdump.org diff --git a/aux/binpac b/aux/binpac index 43308aab47..3034da8f08 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 43308aab47a3357ca1885e1b6954154a2744d821 +Subproject commit 3034da8f082b61157e234237993ffd7a95be6e62 diff --git a/aux/bro-aux b/aux/bro-aux index 139cc2e1e0..f53bcb2b49 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 139cc2e1e049c4e1cc7e95f20866102be1d3d599 +Subproject commit f53bcb2b492cb0db3dd288384040abc2ab711767 diff --git a/aux/broccoli b/aux/broccoli index 930e7c7822..3b63c3f1e7 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 930e7c78221929849086a578308e2fdc99ac3fb8 +Subproject commit 3b63c3f1e7d915b1bda16862bfa4a8593ffc38f6 diff --git a/aux/broctl b/aux/broctl index e908ba686d..954538514d 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit e908ba686dceb56065bdf569c18dd0f67f662f6b +Subproject commit 954538514d71983e7ef3f0e109960466096e1c1d From c2ee15b09f0ecf3701be68844d58b781bd517216 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 12:48:28 +0100 Subject: [PATCH 41/49] protection from bad frees on unallocated strings --- src/BroDoc.cc | 4 ++-- src/Debug.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BroDoc.cc b/src/BroDoc.cc index b20db727ff..9c617f78b3 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -85,8 +85,8 @@ void BroDoc::AddImport(const std::string& s) if ( ext_pos != std::string::npos ) lname = lname.substr(0, ext_pos); - const char* full_filename = ""; - const char* subpath = ""; + const char* full_filename = NULL; + const char* subpath = NULL; FILE* f = search_for_file(lname.c_str(), "bro", &full_filename, true, &subpath); diff --git a/src/Debug.cc b/src/Debug.cc index 1b849fff7e..ea9c52f77e 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -142,7 +142,7 @@ int TraceState::LogTrace(const char* fmt, ...) if ( ! loc.filename ) { - loc.filename = ""; + loc.filename = copy_string(""); loc.last_line = 0; } @@ -735,7 +735,7 @@ string get_context_description(const Stmt* stmt, const Frame* frame) loc = *stmt->GetLocationInfo(); else { - loc.filename = ""; + loc.filename = copy_string(""); loc.last_line = 0; } From b84fd05912d27f9466e661df777a9a5ed5ade6e0 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 13:01:22 +0100 Subject: [PATCH 42/49] Better use of operators priorities --- src/ConnCompressor.cc | 2 +- src/LogMgr.cc | 2 +- src/StateAccess.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index 9fa43bd3a8..29e24457f5 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -440,7 +440,7 @@ Connection* ConnCompressor::NextFromOrig(PendingConn* pending, double t, else if ( tp->th_flags & TH_SYN ) { - if ( ! tp->th_flags & TH_ACK ) + if ( ! (tp->th_flags & TH_ACK) ) { Weird(pending, t, "SYN_after_partial"); pending->SYN = 1; diff --git a/src/LogMgr.cc b/src/LogMgr.cc index 9d397325be..bebce97352 100644 --- a/src/LogMgr.cc +++ b/src/LogMgr.cc @@ -911,7 +911,7 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns) return false; } - if ( ! v->Type()->Tag() == TYPE_STRING ) + if ( v->Type()->Tag() != TYPE_STRING ) { reporter->Error("path_func did not return string"); Unref(v); diff --git a/src/StateAccess.cc b/src/StateAccess.cc index 136a006c52..7abef72c46 100644 --- a/src/StateAccess.cc +++ b/src/StateAccess.cc @@ -231,7 +231,7 @@ bool StateAccess::CheckOldSet(const char* op, ID* id, Val* index, bool StateAccess::MergeTables(TableVal* dst, Val* src) { - if ( ! src->Type()->Tag() == TYPE_TABLE ) + if ( src->Type()->Tag() != TYPE_TABLE ) { reporter->Error("type mismatch while merging tables"); return false; From 7dfb5657a29c589d9ead3dd5179b7efd3a405676 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 12:58:52 +0100 Subject: [PATCH 43/49] Good overridance with the good qualifier --- src/Trigger.cc | 2 +- src/Trigger.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Trigger.cc b/src/Trigger.cc index 26f80c73d9..164f11b885 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -410,7 +410,7 @@ Val* Trigger::Lookup(const CallExpr* expr) return (i != cache.end()) ? i->second : 0; } -const char* Trigger::Name() +const char* Trigger::Name() const { assert(location); return fmt("%s:%d-%d", location->filename, diff --git a/src/Trigger.h b/src/Trigger.h index ffec50d7ef..8e04fb9189 100644 --- a/src/Trigger.h +++ b/src/Trigger.h @@ -60,7 +60,7 @@ public: virtual void Access(Val* val, const StateAccess& sa) { QueueTrigger(this); } - virtual const char* Name(); + virtual const char* Name() const; static void QueueTrigger(Trigger* trigger); From 1df650eb0d4cffd548d21a2131ac60f4cd14a162 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 13:21:47 +0100 Subject: [PATCH 44/49] A destructor must free the memory allocated by the constructor --- src/Gnutella.cc | 6 ++++++ src/Gnutella.h | 1 + src/NCP.cc | 2 ++ src/Sessions.cc | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/src/Gnutella.cc b/src/Gnutella.cc index 448c8dcb3b..6b5e901bc5 100644 --- a/src/Gnutella.cc +++ b/src/Gnutella.cc @@ -42,6 +42,12 @@ Gnutella_Analyzer::Gnutella_Analyzer(Connection* conn) resp_msg_state = new GnutellaMsgState(); } +Gnutella_Analyzer::~Gnutella_Analyzer() + { + delete orig_msg_state; + delete resp_msg_state; + } + void Gnutella_Analyzer::Done() { TCP_ApplicationAnalyzer::Done(); diff --git a/src/Gnutella.h b/src/Gnutella.h index f06c816c90..455876462d 100644 --- a/src/Gnutella.h +++ b/src/Gnutella.h @@ -35,6 +35,7 @@ public: class Gnutella_Analyzer : public TCP_ApplicationAnalyzer { public: Gnutella_Analyzer(Connection* conn); + ~Gnutella_Analyzer(); virtual void Done (); virtual void DeliverStream(int len, const u_char* data, bool orig); diff --git a/src/NCP.cc b/src/NCP.cc index 83378a09a7..edd882747c 100644 --- a/src/NCP.cc +++ b/src/NCP.cc @@ -225,5 +225,7 @@ NCP_Analyzer::NCP_Analyzer(Connection* conn) NCP_Analyzer::~NCP_Analyzer() { delete session; + delete o_ncp; + delete r_ncp; } diff --git a/src/Sessions.cc b/src/Sessions.cc index d78032a25b..b78fdd67d0 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -135,6 +135,10 @@ NetSessions::~NetSessions() delete SYN_OS_Fingerprinter; delete pkt_profiler; Unref(arp_analyzer); + if (discarder) + delete discarder; + if (stp_manager) + delete stp_manager; } void NetSessions::Done() From a3e419fee052d8ca9fdfcb27cd27b92889605a2a Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 13:26:48 +0100 Subject: [PATCH 45/49] removing dead code --- src/Type.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index 4d80eda6f7..82221303af 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1858,13 +1858,8 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( t1->IsSet() ) return new SetType(tl3, 0); - else if ( tg1 == TYPE_TABLE ) - return new TableType(tl3, y3); else - { - reporter->InternalError("bad tag in merge_types"); - return 0; - } + return new TableType(tl3, y3); } case TYPE_FUNC: From 2e069c9596a1da00ffcdacfae47eda55522cdbc3 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 14:07:15 +0100 Subject: [PATCH 46/49] Fix of some memory leaks --- src/Expr.cc | 1 + src/Net.cc | 1 + src/NetbiosSSN.cc | 3 +++ src/POP3.cc | 2 ++ src/RuleMatcher.cc | 5 +++++ 5 files changed, 12 insertions(+) diff --git a/src/Expr.cc b/src/Expr.cc index a8c2fc32c9..1ab49bcd3b 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4910,6 +4910,7 @@ Val* ListExpr::Eval(Frame* f) const if ( ! ev ) { Error("uninitialized list value"); + delete v; return 0; } diff --git a/src/Net.cc b/src/Net.cc index 2d8ee85353..149cee6e94 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -254,6 +254,7 @@ void net_init(name_list& interfaces, name_list& readfiles, { io_sources.Register(fs); } + delete fs; } } diff --git a/src/NetbiosSSN.cc b/src/NetbiosSSN.cc index 274e76f137..7f7a77933d 100644 --- a/src/NetbiosSSN.cc +++ b/src/NetbiosSSN.cc @@ -131,6 +131,9 @@ int NetbiosSSN_Interpreter::ParseBroadcast(const u_char* data, int len, return 0; } + delete srcname; + delete dstname; + return 0; } diff --git a/src/POP3.cc b/src/POP3.cc index 4ffe67ef48..3075e76507 100644 --- a/src/POP3.cc +++ b/src/POP3.cc @@ -158,6 +158,7 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line) if ( e >= end ) { Weird("pop3_malformed_auth_plain"); + delete decoded; return; } @@ -167,6 +168,7 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line) if ( s >= end ) { Weird("pop3_malformed_auth_plain"); + delete decoded; return; } diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 685e35bade..9be559c5ab 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -73,6 +73,7 @@ RuleHdrTest::RuleHdrTest(RuleHdrTest& h) copied_set->ids = orig_set->ids; loop_over_list(orig_set->patterns, l) copied_set->patterns.append(copy_string(orig_set->patterns[l])); + delete copied_set; } } @@ -1116,7 +1117,11 @@ void id_to_maskedvallist(const char* id, maskedvalue_list* append_to) val_list* vals = v->AsTableVal()->ConvertToPureList()->Vals(); loop_over_list(*vals, i ) if ( ! val_to_maskedval((*vals)[i], append_to) ) + { + delete vals; return; + } + delete vals; } else From d65b2f12c66fab10d1c7f90bba11bfe1df30d1a4 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 14:15:56 +0100 Subject: [PATCH 47/49] Suppression of unused code --- src/Expr.cc | 2 -- src/SMTP.cc | 1 - src/TCP.cc | 1 - 3 files changed, 4 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 1ab49bcd3b..f8d2772feb 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2664,8 +2664,6 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const Error("bad table insertion"); TableVal* tv = aggr->AsTableVal(); - const TableType* tt = tv->Type()->AsTableType(); - const BroType* yt = tv->Type()->YieldType(); Val* index = op1->Eval(f); Val* v = op2->Eval(f); diff --git a/src/SMTP.cc b/src/SMTP.cc index 3af8af3b7b..85a3bc79dc 100644 --- a/src/SMTP.cc +++ b/src/SMTP.cc @@ -353,7 +353,6 @@ void SMTP_Analyzer::ProcessLine(int length, const char* line, bool orig) int ext_len; get_word(end_of_line - line, line, ext_len, ext); - line = skip_whitespace(line + ext_len, end_of_line); ProcessExtension(ext_len, ext); } } diff --git a/src/TCP.cc b/src/TCP.cc index dc71d13252..3315db79f3 100644 --- a/src/TCP.cc +++ b/src/TCP.cc @@ -990,7 +990,6 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, Conn()->SetLastTime(t); const IPAddr orig_addr = Conn()->OrigAddr(); - const IPAddr resp_addr = Conn()->RespAddr(); uint32 tcp_hdr_len = data - (const u_char*) tp; From 900cc8f2ab81d7a2808cdfb6281aff951a9730d6 Mon Sep 17 00:00:00 2001 From: Julien Sentier Date: Thu, 23 Feb 2012 14:17:09 +0100 Subject: [PATCH 48/49] possible use after free forbidden --- src/PktSrc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PktSrc.cc b/src/PktSrc.cc index 68b9785e6f..422ed3b39e 100644 --- a/src/PktSrc.cc +++ b/src/PktSrc.cc @@ -382,6 +382,7 @@ void PktSrc::AddSecondaryTablePrograms() { delete program; Close(); + continue; } SecondaryProgram* sp = new SecondaryProgram(program, se); From d2b21574543ad03b3d675dfe2005d635526ec61e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 24 Feb 2012 15:52:15 -0800 Subject: [PATCH 49/49] Fixing merge relict. --- src/bro.bif | 7 ++++--- .../Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bro.bif b/src/bro.bif index 7ffc4044fb..ff06288940 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2516,10 +2516,11 @@ static Val* parse_eftp(const char* line) if ( *line ) { - string s(line); - addr = IPAddr(s); + good = 1; + ++line; // skip delimiter - if ( addr == IPAddr("0.0.0.0") ) + net_proto = strtol(line, &next_delim, 10); + if ( *next_delim != delimiter ) good = 0; line = next_delim; diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log index 6bab9332c8..c4a515710d 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log @@ -9,5 +9,5 @@ 1329327786.524332 k6kgXLOoSKl 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49187 2001:470:4867:99::21 57087 tcp ftp-data 0.217501 0 43 SF - 0 ShAdfFa 5 372 4 343 1329327787.289095 nQcgTWjvg4c 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49188 2001:470:4867:99::21 57088 tcp ftp-data 0.217941 0 77 SF - 0 ShAdfFa 5 372 4 377 1329327795.571921 j4u32Pc5bif 2001:470:4867:99::21 55785 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49189 tcp ftp-data 0.109813 77 0 SF - 0 ShADFaf 5 449 4 300 -1329327800.017649 TEfuqmmG4bh 2001:470:4867:99::21 55647 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49190 tcp ftp-data 0.109181 342 0 SF - 0 ShADFaf 5 714 4 300 1329327777.822004 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 tcp ftp 26.658219 310 3448 SF - 0 ShAdDfFa 57 4426 34 5908 +1329327800.017649 TEfuqmmG4bh 2001:470:4867:99::21 55647 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49190 tcp ftp-data 0.109181 342 0 SF - 0 ShADFaf 5 714 4 300