diff --git a/CHANGES b/CHANGES index 1285b53cf8..2d528beefb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,52 @@ +2.0-121 | 2012-02-24 16:34:17 -0800 + + * A number of smaller memory fixes and code cleanups. (Julien + Sentier) + + * Add to_subnet bif. Fixes #782). (Jon Siwek) + + * Fix IPAddr::Mask/ReverseMask not allowing argument of 0. (Jon + Siwek) + + * Refactor IPAddr v4 initialization from string. Fixes #775. (Jon Siwek) + + * Parse the dotted address string directly instead of canonicalizing + and passing to inet_pton. (Jon Siwek) + + +2.0-108 | 2012-02-24 15:21:07 -0800 + + * Refactoring a number of usages of new IPAddr class. (Jon Siwek) + + * Fixed a bug in remask_addr bif. (Jon Siwek) + +2.0-106 | 2012-02-24 15:02:20 -0800 + + * Raise minimum required CMake version to 2.6.3. (Jon Siwek) + +2.0-104 | 2012-02-24 14:59:12 -0800 + + * Add test case for FTP over IPv4. (Daniel Thayer) + + * Fix IPv6 URLs in ftp.log. (Daniel Thayer) + + * Add a test for FTP over IPv6 (Daniel Thayer) + + * Fix parsing of FTP EPRT command and EPSV response. (Daniel Thayer) + +2.0-95 | 2012-02-22 05:27:34 -0800 + + * GeoIP installation documentation update. (Seth Hall) + + * Decrease strictness of parsing IPv4 strings into addrs. Fixes #775. (Jon Siwek) + + * Fix memory leak in DNS manager. Fixes #777. (Jon Siwek) + + * Fix IPAddr/IPPrefix serialization bugs. (Jon Siwek) + + * Fix compile error. (Jon Siwek) + 2.0-86 | 2012-02-17 15:41:06 -0800 * Changing ARP detection to always kick in even if no analyzer is 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/NEWS b/NEWS index b89493276b..045ba62a7a 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,10 @@ release. For a complete list of changes, see the ``CHANGES`` file. Bro 2.1 ------- +- Dependencies: + + * Bro now requires CMake >= 2.6.3. + - Bro now supports IPv6 out of the box; the configure switch --enable-brov6 is gone. diff --git a/VERSION b/VERSION index 2436939ed7..2027efd988 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-86 +2.0-121 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 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: diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index 9e16804a32..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; @@ -270,7 +275,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/BroDoc.cc b/src/BroDoc.cc index b20db727ff..1e2d7d52ea 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -85,12 +85,13 @@ 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); - if ( f ) + if ( f && full_filename && subpath ) { fclose(f); @@ -126,12 +127,14 @@ void BroDoc::AddImport(const std::string& s) } delete [] tmp; - delete [] full_filename; - delete [] subpath; } + else fprintf(stderr, "Failed to document '@load %s' in file: %s\n", s.c_str(), reST_filename.c_str()); + + delete [] full_filename; + delete [] subpath; } void BroDoc::SetPacketFilter(const std::string& s) 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..a5ed560bde 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -37,48 +37,13 @@ struct ConnID { IPAddr dst_addr; 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; - }; + bool is_one_way; // if true, don't canonicalize order }; 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..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; @@ -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 534af15d39..a80de42704 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 @@ -704,6 +702,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 +710,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; @@ -747,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; } } @@ -874,8 +869,7 @@ void DNS_Mgr::LoadCache(FILE* f) } else { - HashKey h(m->ReqAddr()); - addr_mappings.Insert(&h, m); + addr_mappings[m->ReqAddr()] = m; } } @@ -886,13 +880,13 @@ 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); + for ( AddrMap::const_iterator it = m.begin(); it != m.end(); ++it ) + { + if ( it->second ) + it->second->Save(f); + } } void DNS_Mgr::Save(FILE* f, const HostMap& m) @@ -911,15 +905,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; } @@ -1159,8 +1154,11 @@ void DNS_Mgr::Flush() delete it->second.second; } + for ( AddrMap::iterator 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() @@ -1272,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 431401dd17..fdd7d81222 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; } @@ -365,7 +349,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; } @@ -384,7 +368,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); @@ -411,7 +395,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/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; } diff --git a/src/Expr.cc b/src/Expr.cc index a8c2fc32c9..45f363a559 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); @@ -4910,6 +4908,7 @@ Val* ListExpr::Eval(Frame* f) const if ( ! ev ) { Error("uninitialized list value"); + Unref(v); return 0; } 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/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 09248dadfa..ff124025f9 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,15 +1,68 @@ // See the file "COPYING" in the main distribution directory for copyright. +#include +#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 ) + if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) { reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep); return; @@ -38,7 +91,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; @@ -71,11 +124,23 @@ void IPAddr::Init(const std::string& s) { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - if ( inet_pton(AF_INET, 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 @@ -110,6 +175,60 @@ 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 c2e57ea7d1..f0c0ac12c8 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,37 @@ 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. Passes ownership to caller. + */ + HashKey* GetHashKey() const + { + return new HashKey((void*)in6.s6_addr, sizeof(in6.s6_addr)); + } + /** * Masks out lower bits of the address. * @@ -223,6 +258,19 @@ 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 +278,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 +318,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); } private: @@ -320,6 +384,16 @@ inline bool IPAddr::IsLoopback() const && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); } +/** + * Returns a hash key for a given ConnID. Passes ownership to caller. + */ +HashKey* BuildConnIDHashKey(const ConnID& id); + +/** + * Returns a hash key for a given ExpectedConn instance. Passes ownership to caller. + */ +HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); + /** * Class storing both IPv4 and IPv6 prefixes * (i.e., \c 192.168.1.1/16 and \c FD00::/8. @@ -425,6 +499,23 @@ public: operator std::string() const { return AsString(); } + /** + * Returns a key that can be used to lookup the IP Prefix in a hash + * table. Passes ownership to caller. + */ + 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/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/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/Net.cc b/src/Net.cc index 2d8ee85353..c92545cb87 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -143,7 +143,7 @@ RETSIGTYPE watchdog(int /* signo */) return RETSIGVAL; } -void net_init(name_list& interfaces, name_list& readfiles, +void net_init(name_list& interfaces, name_list& readfiles, name_list& netflows, name_list& flowfiles, const char* writefile, const char* filter, const char* secondary_filter, int do_watchdog) @@ -248,12 +248,14 @@ void net_init(name_list& interfaces, name_list& readfiles, FlowSocketSrc* fs = new FlowSocketSrc(netflows[i]); if ( ! fs->IsOpen() ) + { reporter->Error("%s: problem with netflow socket %s - %s\n", prog, netflows[i], fs->ErrorMsg()); - else - { - io_sources.Register(fs); + delete fs; } + + else + io_sources.Register(fs); } } diff --git a/src/NetbiosSSN.cc b/src/NetbiosSSN.cc index 274e76f137..362d974956 100644 --- a/src/NetbiosSSN.cc +++ b/src/NetbiosSSN.cc @@ -110,7 +110,7 @@ int NetbiosSSN_Interpreter::ParseDatagram(const u_char* data, int len, return 0; } - + int NetbiosSSN_Interpreter::ParseBroadcast(const u_char* data, int len, int is_query) { @@ -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/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/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/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/PktSrc.cc b/src/PktSrc.cc index 68b9785e6f..615815b41b 100644 --- a/src/PktSrc.cc +++ b/src/PktSrc.cc @@ -382,6 +382,7 @@ void PktSrc::AddSecondaryTablePrograms() { delete program; Close(); + return; } SecondaryProgram* sp = new SecondaryProgram(program, se); 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/RuleMatcher.cc b/src/RuleMatcher.cc index 685e35bade..a90bc83293 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -73,6 +73,9 @@ 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; + // TODO: Why do we create copied_set only to then + // never use it? } } @@ -1116,7 +1119,12 @@ 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(vals); return; + } + + delete_vals(vals); } else diff --git a/src/SMTP.cc b/src/SMTP.cc index 3af8af3b7b..0a6e217e3e 100644 --- a/src/SMTP.cc +++ b/src/SMTP.cc @@ -352,8 +352,8 @@ void SMTP_Analyzer::ProcessLine(int length, const char* line, bool orig) const char* ext; int ext_len; - get_word(end_of_line - line, line, ext_len, ext); line = skip_whitespace(line + ext_len, end_of_line); + get_word(end_of_line - line, line, ext_len, ext); ProcessExtension(ext_len, ext); } } diff --git a/src/Sessions.cc b/src/Sessions.cc index ef17c8059a..1cd667cf95 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -135,12 +135,12 @@ NetSessions::~NetSessions() delete SYN_OS_Fingerprinter; delete pkt_profiler; Unref(arp_analyzer); + delete discarder; + delete stp_manager; } void NetSessions::Done() { - delete stp_manager; - delete discarder; } namespace // private namespace @@ -575,7 +575,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"); @@ -869,7 +869,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/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; 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; 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/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); 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: diff --git a/src/Val.cc b/src/Val.cc index 2b68997f45..e19fffa379 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -910,11 +910,19 @@ 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"); + string s(text); + size_t slash_loc = s.find('/'); - val.subnet_val = new IPPrefix(text, atoi(sep+1)); + 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..ff06288940 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) ) @@ -2135,7 +2105,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 +2162,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 +2257,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 +2270,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 +2313,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 +2336,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; @@ -2445,35 +2434,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 +2502,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; // unspecified IPv6 address (all 128 bits zero) int port = 0; int good = 0; @@ -2551,33 +2512,51 @@ 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); - const 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)); @@ -2605,7 +2584,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]`` ## @@ -2645,7 +2624,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]`` ## @@ -3025,14 +3004,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 +3524,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 +3619,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 d57e4fa301..d66e56711f 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 afd89ee6ce..17ca2b9cc1 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/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 new file mode 100644 index 0000000000..ff277498f8 --- /dev/null +++ b/testing/btest/Baseline/bifs.to_addr/output @@ -0,0 +1,9 @@ +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) +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/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/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..c4a515710d --- /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 +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 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..8bc2ef2cb7 --- /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/ftp-ipv4.trace b/testing/btest/Traces/ftp-ipv4.trace new file mode 100644 index 0000000000..02cac6f464 Binary files /dev/null and b/testing/btest/Traces/ftp-ipv4.trace differ diff --git a/testing/btest/Traces/ipv6-ftp.trace b/testing/btest/Traces/ipv6-ftp.trace new file mode 100644 index 0000000000..81313fac11 Binary files /dev/null and b/testing/btest/Traces/ipv6-ftp.trace differ 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])); + } diff --git a/testing/btest/bifs/to_addr.bro b/testing/btest/bifs/to_addr.bro new file mode 100644 index 0000000000..3b79648b00 --- /dev/null +++ b/testing/btest/bifs/to_addr.bro @@ -0,0 +1,20 @@ +# @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) + { + 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); +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; 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 + 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 +