mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge branch 'topic/bernhard/log-threads' into topic/bernhard/input-threads
Seems to work -- all test pass. But there are thread-safety issues at the moment, because the constructors of IPAddr and IPPrefix are not thread-safe, but needed by workers. Conflicts: src/logging/Manager.cc
This commit is contained in:
commit
417542f283
148 changed files with 2635 additions and 2186 deletions
96
CHANGES
96
CHANGES
|
@ -1,4 +1,100 @@
|
|||
|
||||
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
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
########################################################################
|
||||
|
|
2
INSTALL
2
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
|
||||
|
||||
|
|
19
NEWS
19
NEWS
|
@ -5,6 +5,24 @@ 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
|
||||
-------
|
||||
|
||||
- Dependencies:
|
||||
|
||||
* Bro now requires CMake >= 2.6.3.
|
||||
|
||||
- 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 +79,3 @@ final release are:
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.0-57
|
||||
2.0-121
|
||||
|
|
|
@ -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
|
||||
|
|
5
configure
vendored
5
configure
vendored
|
@ -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
|
||||
|
@ -92,7 +91,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 +132,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
|
||||
;;
|
||||
|
|
|
@ -103,7 +103,13 @@ 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::
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
# 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,12 @@ function ftp_message(s: Info)
|
|||
|
||||
local arg = s$cmdarg$arg;
|
||||
if ( s$cmdarg$cmd in file_cmds )
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
IPAddr(IPAddr::IPv4, &input, IPAddr::Network).AsString().c_str(),
|
||||
num_bits);
|
||||
|
||||
if ( ! before_anonymization )
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 = "<error>";
|
||||
const char* subpath = "<error>";
|
||||
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)
|
||||
|
|
|
@ -334,6 +334,7 @@ set(bro_SRCS
|
|||
IntSet.cc
|
||||
InterConn.cc
|
||||
IOSource.cc
|
||||
IPAddr.cc
|
||||
IRC.cc
|
||||
List.cc
|
||||
Reporter.cc
|
||||
|
@ -412,7 +413,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
|
||||
|
|
|
@ -107,40 +107,18 @@ 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<uint32>(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];
|
||||
v->AsAddr().CopyIPv6(kp);
|
||||
kp1 = reinterpret_cast<char*>(kp+4);
|
||||
#else
|
||||
*kp = v->AsAddr();
|
||||
kp1 = reinterpret_cast<char*>(kp+1);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_INTERNAL_SUBNET:
|
||||
{
|
||||
uint32* kp = AlignAndPadType<uint32>(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;
|
||||
v->AsSubNet().Prefix().CopyIPv6(kp);
|
||||
kp[4] = v->AsSubNet().Length();
|
||||
kp1 = reinterpret_cast<char*>(kp+5);
|
||||
#else
|
||||
const subnet_type* sv = v->AsSubNet();
|
||||
kp[0] = sv->net;
|
||||
kp[1] = sv->width;
|
||||
kp1 = reinterpret_cast<char*>(kp+2);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -358,26 +336,16 @@ 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
|
||||
return v->AsAddr().GetHashKey();
|
||||
|
||||
case TYPE_INTERNAL_SUBNET:
|
||||
#ifdef BROv6
|
||||
return new HashKey((const uint32*) v->AsSubNet(), 5);
|
||||
#else
|
||||
return new HashKey((const uint32*) v->AsSubNet(), 2);
|
||||
|
||||
#endif
|
||||
return v->AsSubNet().GetHashKey();
|
||||
|
||||
case TYPE_INTERNAL_DOUBLE:
|
||||
return new HashKey(v->InternalDouble());
|
||||
|
@ -425,22 +393,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:
|
||||
|
@ -748,16 +707,13 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
|||
case TYPE_INTERNAL_ADDR:
|
||||
{
|
||||
const uint32* const kp = AlignType<uint32>(kp0);
|
||||
#ifdef BROv6
|
||||
const_addr_type addr_val = kp;
|
||||
kp1 = reinterpret_cast<const char*>(kp+4);
|
||||
#else
|
||||
const_addr_type addr_val = *kp;
|
||||
kp1 = reinterpret_cast<const char*>(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:
|
||||
|
@ -770,12 +726,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
|||
|
||||
case TYPE_INTERNAL_SUBNET:
|
||||
{
|
||||
const subnet_type* const kp =
|
||||
reinterpret_cast<const subnet_type*>(
|
||||
AlignType<uint32>(kp0));
|
||||
kp1 = reinterpret_cast<const char*>(kp+1);
|
||||
|
||||
pval = new SubNetVal(kp->net, kp->width);
|
||||
const uint32* const kp = AlignType<uint32>(kp0);
|
||||
kp1 = reinterpret_cast<const char*>(kp+5);
|
||||
pval = new SubNetVal(kp, kp[4]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
56
src/Conn.cc
56
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 <src addr, src port> and <dst addr, dst port>
|
||||
// followed by the other.
|
||||
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.port1 = src_port;
|
||||
key.port2 = dst_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_addr(dst_addr, key.ip1);
|
||||
copy_addr(src_addr, 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)
|
||||
{
|
||||
|
@ -143,8 +117,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 +495,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 +533,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 +667,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 +725,14 @@ void Connection::Describe(ODesc* d) const
|
|||
}
|
||||
|
||||
d->SP();
|
||||
d->Add(dotted_addr(orig_addr));
|
||||
d->Add(orig_addr);
|
||||
d->Add(":");
|
||||
d->Add(ntohs(orig_port));
|
||||
|
||||
d->SP();
|
||||
d->AddSP("->");
|
||||
|
||||
d->Add(dotted_addr(resp_addr));
|
||||
d->Add(resp_addr);
|
||||
d->Add(":");
|
||||
d->Add(ntohs(resp_port));
|
||||
|
||||
|
@ -782,8 +755,7 @@ 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]) )
|
||||
if ( ! SERIALIZE(orig_addr) || ! SERIALIZE(resp_addr) )
|
||||
return false;
|
||||
|
||||
if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) )
|
||||
|
@ -830,21 +802,21 @@ 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;
|
||||
|
||||
if ( ! UNSERIALIZE(&orig_addr) || ! UNSERIALIZE(&resp_addr) )
|
||||
goto error;
|
||||
|
||||
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.
|
||||
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) )
|
||||
|
|
60
src/Conn.h
60
src/Conn.h
|
@ -12,6 +12,7 @@
|
|||
#include "PersistenceSerializer.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "AnalyzerTags.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
class Connection;
|
||||
class ConnectionTimer;
|
||||
|
@ -32,52 +33,17 @@ 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
|
||||
|
||||
// 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[NUM_ADDR_WORDS];
|
||||
uint32 ip2[NUM_ADDR_WORDS];
|
||||
uint16 port1;
|
||||
uint16 port2;
|
||||
};
|
||||
bool is_one_way; // if true, don't canonicalize order
|
||||
};
|
||||
|
||||
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
|
||||
// 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)))))));
|
||||
#else
|
||||
return *a1 < *a2 || (*a1 == *a2 && p1 < p2);
|
||||
#endif
|
||||
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
|
||||
}
|
||||
|
||||
class Analyzer;
|
||||
|
@ -119,8 +85,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 +151,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 +291,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;
|
||||
|
|
|
@ -235,7 +235,8 @@ 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() ==
|
||||
IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network) &&
|
||||
tp->th_sport == SrcPort(pending) )
|
||||
// Another packet from originator.
|
||||
tc = NextFromOrig(pending, t, key, ip, tp);
|
||||
|
@ -439,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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -541,7 +542,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 +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 = addr_eq(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,17 +658,16 @@ 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.
|
||||
#ifdef BROv6
|
||||
if ( ! is_v4_addr(c->key.ip1) || ! is_v4_addr(c->key.ip2) )
|
||||
IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network);
|
||||
IPAddr ip2(IPAddr::IPv6, c->key.ip2, IPAddr::Network);
|
||||
if ( ip1.GetFamily() == IPAddr::IPv6 ||
|
||||
ip2.GetFamily() == 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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -137,12 +137,12 @@ 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.GetFamily() == IPAddr::IPv6 )
|
||||
// TODO: Does the protocol support v6 addresses? #773
|
||||
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 +160,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 +413,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 +428,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);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "NetVar.h"
|
||||
#include "TCP.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
#include "dce_rpc_simple_pac.h"
|
||||
|
||||
|
@ -34,19 +35,19 @@ const char* uuid_to_string(const u_char* uuid_data);
|
|||
|
||||
struct dce_rpc_endpoint_addr {
|
||||
// All fields are in host byteorder.
|
||||
uint32 addr;
|
||||
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,
|
||||
addr.AsString().c_str(), port,
|
||||
proto == TRANSPORT_TCP ? "tcp" :
|
||||
(proto == TRANSPORT_UDP ? "udp" : "?"));
|
||||
|
||||
|
|
49
src/DNS.cc
49
src/DNS.cc
|
@ -758,62 +758,37 @@ 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 )
|
||||
{
|
||||
if ( msg->atype == TYPE_AAAA )
|
||||
analyzer->Weird("DNS_AAAA_neg_length");
|
||||
else
|
||||
analyzer->Weird("DNS_A6_neg_length");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 )
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
analyzer->ConnectionEvent(event, vl);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
310
src/DNS_Mgr.cc
310
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, 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.
|
||||
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,8 +61,8 @@ public:
|
|||
|
||||
protected:
|
||||
char* host; // if non-nil, this is a host request
|
||||
uint32 addr;
|
||||
uint32 ttl;
|
||||
int fam; // address family query type for host requests
|
||||
IPAddr addr;
|
||||
int request_pending;
|
||||
};
|
||||
|
||||
|
@ -75,15 +75,20 @@ 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
|
||||
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,9 +98,11 @@ 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
|
||||
{ return req_host ? req_host : dotted_addr(ReqAddr()); }
|
||||
IPAddr ReqAddr() const { return req_addr; }
|
||||
string ReqStr() const
|
||||
{
|
||||
return req_host ? req_host : req_addr;
|
||||
}
|
||||
|
||||
ListVal* Addrs();
|
||||
TableVal* AddrsSet(); // addresses returned as a set
|
||||
|
@ -109,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;
|
||||
|
@ -121,7 +135,7 @@ protected:
|
|||
int init_failed;
|
||||
|
||||
char* req_host;
|
||||
uint32 req_addr;
|
||||
IPAddr req_addr;
|
||||
uint32 req_ttl;
|
||||
|
||||
int num_names;
|
||||
|
@ -129,11 +143,12 @@ protected:
|
|||
StringVal* host_val;
|
||||
|
||||
int num_addrs;
|
||||
uint32* addrs;
|
||||
IPAddr* addrs;
|
||||
ListVal* addrs_val;
|
||||
|
||||
int failed;
|
||||
double creation_time;
|
||||
int map_type;
|
||||
};
|
||||
|
||||
void DNS_Mgr_mapping_delete_func(void* v)
|
||||
|
@ -154,14 +169,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;
|
||||
|
@ -175,7 +189,6 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
|||
init_failed = 1;
|
||||
|
||||
req_host = 0;
|
||||
req_addr = 0;
|
||||
|
||||
char buf[512];
|
||||
|
||||
|
@ -188,14 +201,15 @@ 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 )
|
||||
req_host = copy_string(req_buf);
|
||||
else
|
||||
req_addr = dotted_to_addr(req_buf);
|
||||
req_addr = IPAddr(req_buf);
|
||||
|
||||
num_names = 1;
|
||||
names = new char*[num_names];
|
||||
|
@ -203,7 +217,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 )
|
||||
{
|
||||
|
@ -217,7 +231,7 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
|||
if ( newline )
|
||||
*newline = '\0';
|
||||
|
||||
addrs[i] = dotted_to_addr(buf);
|
||||
addrs[i] = IPAddr(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -280,14 +294,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;
|
||||
|
@ -296,12 +302,13 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -311,10 +318,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;
|
||||
|
@ -330,18 +341,19 @@ 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,
|
||||
req_host ? req_host : dotted_addr(req_addr),
|
||||
fprintf(f, "%.0f %d %s %d %s %d %d %"PRIu32"\n", creation_time, req_host != 0,
|
||||
req_host ? req_host : req_addr.AsString().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", dotted_addr(addrs[i]));
|
||||
fprintf(f, "%s\n", addrs[i].AsString().c_str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -351,9 +363,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];
|
||||
nb_dns = nb_dns_init(err);
|
||||
|
||||
|
@ -440,24 +449,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:
|
||||
|
@ -465,7 +484,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);
|
||||
|
||||
|
@ -475,24 +495,25 @@ 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);
|
||||
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
|
||||
{
|
||||
reporter->Warning("can't resolve IP address: %s", dotted_addr(addr));
|
||||
return new StringVal(dotted_addr(addr));
|
||||
string s(addr);
|
||||
reporter->Warning("can't resolve IP address: %s", s.c_str());
|
||||
return new StringVal(s.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,7 +526,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr)
|
|||
|
||||
case DNS_FORCE:
|
||||
reporter->FatalError("can't find DNS entry for %s in cache",
|
||||
dotted_addr(addr));
|
||||
addr.AsString().c_str());
|
||||
return 0;
|
||||
|
||||
case DNS_DEFAULT:
|
||||
|
@ -681,28 +702,53 @@ 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);
|
||||
prev_dm = 0;
|
||||
|
||||
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_INET ? 0 : new_dm;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl);
|
||||
uint32 tmp_addr = dr->ReqAddr();
|
||||
HashKey k(&tmp_addr, 1);
|
||||
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() )
|
||||
{
|
||||
uint32 tmp_addr = dr->ReqAddr();
|
||||
HashKey k2(&tmp_addr, 1);
|
||||
(void) addr_mappings.Insert(&k2, prev_dm);
|
||||
addr_mappings[dr->ReqAddr()] = prev_dm;
|
||||
++keep_prev;
|
||||
}
|
||||
}
|
||||
|
@ -774,17 +820,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
|
||||
const IPAddr& al2_j = al2->Index(j)->AsAddr();
|
||||
if ( al1_i == al2_j )
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -800,8 +842,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 ? "," : "", al_i.AsString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,12 +856,20 @@ 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
|
||||
{
|
||||
uint32 tmp_addr = m->ReqAddr();
|
||||
HashKey h(&tmp_addr, 1);
|
||||
addr_mappings.Insert(&h, m);
|
||||
addr_mappings[m->ReqAddr()] = m;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,26 +880,41 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr)
|
||||
void DNS_Mgr::Save(FILE* f, const HostMap& m)
|
||||
{
|
||||
HashKey h(&addr, 1);
|
||||
DNS_Mapping* d = dns_mgr->addr_mappings.Lookup(&h);
|
||||
HostMap::const_iterator it;
|
||||
|
||||
if ( ! d )
|
||||
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)
|
||||
{
|
||||
AddrMap::iterator it = dns_mgr->addr_mappings.find(addr);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -861,23 +926,32 @@ const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type 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(dns_mgr_addr_type host, LookupCallback* callback)
|
||||
void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
||||
{
|
||||
if ( ! did_init )
|
||||
Init();
|
||||
|
@ -956,10 +1030,15 @@ 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) )
|
||||
{
|
||||
|
@ -969,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);
|
||||
|
||||
|
@ -987,7 +1074,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.
|
||||
|
||||
|
@ -1060,11 +1147,18 @@ void DNS_Mgr::Flush()
|
|||
{
|
||||
DoProcess(false);
|
||||
|
||||
IterCookie* cookie = addr_mappings.InitForIteration();
|
||||
DNS_Mapping* dm;
|
||||
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();
|
||||
for ( AddrMap::iterator it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 )
|
||||
delete it2->second;
|
||||
|
||||
host_mappings.clear();
|
||||
addr_mappings.clear();
|
||||
}
|
||||
|
||||
void DNS_Mgr::Process()
|
||||
|
@ -1107,6 +1201,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);
|
||||
|
@ -1116,7 +1218,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();
|
||||
|
||||
|
@ -1167,7 +1269,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_addresses = addr_mappings.Length();
|
||||
stats->cached_hosts = host_mappings.size();
|
||||
stats->cached_addresses = addr_mappings.size();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
|
||||
#include "util.h"
|
||||
#include "BroList.h"
|
||||
#include "Dict.h"
|
||||
#include "EventHandler.h"
|
||||
#include "IOSource.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
class Val;
|
||||
class ListVal;
|
||||
|
@ -27,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
|
||||
|
@ -39,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);
|
||||
|
@ -55,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); }
|
||||
|
@ -64,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.
|
||||
|
@ -78,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 {
|
||||
|
@ -107,8 +104,11 @@ protected:
|
|||
ListVal* AddrListDelta(ListVal* al1, ListVal* al2);
|
||||
void DumpAddrList(FILE* f, ListVal* al);
|
||||
|
||||
typedef map<string, pair<DNS_Mapping*, DNS_Mapping*> > HostMap;
|
||||
typedef map<IPAddr, DNS_Mapping*> 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
|
||||
// is secs). Returns 0 on timeout, -1 on EINTR or other error, and 1
|
||||
|
@ -120,7 +120,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.
|
||||
|
@ -136,8 +136,8 @@ protected:
|
|||
|
||||
PDict(ListVal) services;
|
||||
|
||||
PDict(DNS_Mapping) host_mappings;
|
||||
PDict(DNS_Mapping) addr_mappings;
|
||||
HostMap host_mappings;
|
||||
AddrMap addr_mappings;
|
||||
|
||||
DNS_mgr_request_list requests;
|
||||
|
||||
|
@ -163,7 +163,7 @@ protected:
|
|||
|
||||
struct AsyncRequest {
|
||||
double time;
|
||||
dns_mgr_addr_type host;
|
||||
IPAddr host;
|
||||
string name;
|
||||
CallbackList callbacks;
|
||||
|
||||
|
@ -204,7 +204,7 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
typedef map<dns_mgr_addr_type, AsyncRequest*> AsyncRequestAddrMap;
|
||||
typedef map<IPAddr, AsyncRequest*> AsyncRequestAddrMap;
|
||||
AsyncRequestAddrMap asyncs_addrs;
|
||||
|
||||
typedef map<string, AsyncRequest*> AsyncRequestNameMap;
|
||||
|
|
85
src/DPM.cc
85
src/DPM.cc
|
@ -11,53 +11,28 @@
|
|||
#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 = IPAddr(string("::"));
|
||||
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 = _orig;
|
||||
resp = _resp;
|
||||
resp_p = _resp_p;
|
||||
proto = _proto;
|
||||
}
|
||||
|
||||
ExpectedConn::ExpectedConn(const ExpectedConn& c)
|
||||
{
|
||||
copy_addr(c.orig, orig);
|
||||
copy_addr(c.resp, resp);
|
||||
orig = c.orig;
|
||||
resp = c.resp;
|
||||
resp_p = c.resp_p;
|
||||
proto = c.proto;
|
||||
}
|
||||
|
||||
|
||||
DPM::DPM()
|
||||
: expected_conns_queue(AssignedAnalyzer::compare)
|
||||
{
|
||||
|
@ -158,23 +133,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 = BuildExpectedConnHashKey(c);
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
|
||||
if ( ! a )
|
||||
{
|
||||
// Wildcard for originator.
|
||||
for ( int i = 0; i < NUM_ADDR_WORDS; ++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 = BuildExpectedConnHashKey(c);
|
||||
a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
if ( ! a )
|
||||
|
@ -404,7 +374,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)
|
||||
{
|
||||
|
@ -416,11 +387,7 @@ void DPM::ExpectConnection(addr_type orig, addr_type resp, uint16 resp_p,
|
|||
{
|
||||
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 = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
@ -439,10 +406,9 @@ void DPM::ExpectConnection(addr_type orig, addr_type resp, uint16 resp_p,
|
|||
|
||||
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 = BuildExpectedConnHashKey(c);
|
||||
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(&key);
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
|
||||
if ( a )
|
||||
a->deleted = true;
|
||||
|
@ -454,8 +420,9 @@ void DPM::ExpectConnection(addr_type orig, addr_type resp, uint16 resp_p,
|
|||
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()
|
||||
|
@ -466,11 +433,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 = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
|
14
src/DPM.h
14
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];
|
||||
IPAddr orig;
|
||||
IPAddr resp;
|
||||
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);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ int TraceState::LogTrace(const char* fmt, ...)
|
|||
|
||||
if ( ! loc.filename )
|
||||
{
|
||||
loc.filename = "<no filename>";
|
||||
loc.filename = copy_string("<no filename>");
|
||||
loc.last_line = 0;
|
||||
}
|
||||
|
||||
|
@ -735,7 +735,7 @@ string get_context_description(const Stmt* stmt, const Frame* frame)
|
|||
loc = *stmt->GetLocationInfo();
|
||||
else
|
||||
{
|
||||
loc.filename = "<no filename>";
|
||||
loc.filename = copy_string("<no filename>");
|
||||
loc.last_line = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include <stdio.h>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#include "BroString.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
typedef enum {
|
||||
DESC_READABLE,
|
||||
|
@ -68,11 +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) { Add(addr.AsString()); }
|
||||
void Add(const IPPrefix& prefix) { Add(prefix.AsString()); }
|
||||
|
||||
// Add s as a counted string.
|
||||
void AddCS(const char* s);
|
||||
|
|
65
src/Expr.cc
65
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,30 +835,30 @@ 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();
|
||||
IPAddr a1 = v1->AsAddr();
|
||||
IPAddr a2 = v2->AsAddr();
|
||||
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(<=)
|
||||
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));
|
||||
|
@ -868,20 +869,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();
|
||||
|
||||
if ( n1->width != n2->width )
|
||||
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);
|
||||
const IPPrefix& n1 = v1->AsSubNet();
|
||||
const IPPrefix& n2 = v2->AsSubNet();
|
||||
|
||||
if ( n1 == n2 )
|
||||
return new Val(1, TYPE_BOOL);
|
||||
else
|
||||
return new Val(0, TYPE_BOOL);
|
||||
}
|
||||
|
||||
void BinaryExpr::SwapOps()
|
||||
|
@ -1681,15 +1675,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<uint32>(v2->InternalUnsigned());
|
||||
else
|
||||
mask = static_cast<uint32>(v2->InternalInt());
|
||||
|
||||
return new SubNetVal(a1, mask);
|
||||
return new SubNetVal(v1->AsAddr(), mask);
|
||||
}
|
||||
|
||||
Expr* DivideExpr::DoSimplify()
|
||||
|
@ -2672,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);
|
||||
|
@ -4918,6 +4908,7 @@ Val* ListExpr::Eval(Frame* f) const
|
|||
if ( ! ev )
|
||||
{
|
||||
Error("uninitialized list value");
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "BroString.h"
|
||||
|
||||
#define UHASH_KEY_SIZE 32
|
||||
#define UHASH_KEY_SIZE 36
|
||||
|
||||
typedef uint64 hash_t;
|
||||
|
||||
|
|
|
@ -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(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(dotted_addr(Conn()->RespAddr()));
|
||||
d->Add(Conn()->RespAddr());
|
||||
}
|
||||
|
||||
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
|
||||
|
|
65
src/IP.h
65
src/IP.h
|
@ -4,63 +4,29 @@
|
|||
#define ip_h
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "IPAddr.h"
|
||||
#include <net_util.h>
|
||||
|
||||
class IP_Hdr {
|
||||
public:
|
||||
IP_Hdr(struct ip* arg_ip4)
|
||||
: ip4(arg_ip4), ip6(0), 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), 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), 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), 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 +43,12 @@ 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; }
|
||||
IPAddr SrcAddr() const
|
||||
{ return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src); }
|
||||
IPAddr DstAddr() const
|
||||
{ return ip4 ? IPAddr(ip4->ip_dst) : IPAddr(ip6->ip6_dst); }
|
||||
|
||||
//TODO: needs adapting/replacement for IPv6 support
|
||||
uint16 ID4() const { return ip4 ? ip4->ip_id : 0; }
|
||||
|
||||
const u_char* Payload() const
|
||||
|
@ -131,10 +90,6 @@ 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
|
||||
int del;
|
||||
};
|
||||
|
||||
|
|
285
src/IPAddr.cc
Normal file
285
src/IPAddr.cc
Normal file
|
@ -0,0 +1,285 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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 <src addr, src port> and <dst addr, dst port>
|
||||
// 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 )
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
// 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
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string IPAddr::AsString() const
|
||||
{
|
||||
if ( GetFamily() == IPv4 )
|
||||
{
|
||||
char s[INET_ADDRSTRLEN];
|
||||
|
||||
if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL )
|
||||
return "<bad IPv4 address conversion";
|
||||
else
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
|
||||
if ( inet_ntop(AF_INET6, in6.s6_addr, s, INET6_ADDRSTRLEN) == NULL )
|
||||
return "<bad IPv6 address conversion";
|
||||
else
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if ( length > 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.GetFamily() == 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);
|
||||
}
|
||||
|
||||
string IPPrefix::AsString() const
|
||||
{
|
||||
char l[16];
|
||||
|
||||
if ( prefix.GetFamily() == IPAddr::IPv4 )
|
||||
modp_uitoa10(length - 96, l);
|
||||
else
|
||||
modp_uitoa10(length, l);
|
||||
|
||||
return prefix.AsString() +"/" + l;
|
||||
}
|
||||
|
551
src/IPAddr.h
Normal file
551
src/IPAddr.h
Normal file
|
@ -0,0 +1,551 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef IPADDR_H
|
||||
#define IPADDR_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string>
|
||||
|
||||
#include "BroString.h"
|
||||
#include "Hash.h"
|
||||
#include "util.h"
|
||||
|
||||
struct ConnID;
|
||||
class ExpectedConn;
|
||||
|
||||
typedef in_addr in4_addr;
|
||||
|
||||
/**
|
||||
* Class storing both IPv4 and IPv6 addresses.
|
||||
*/
|
||||
class IPAddr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Address family.
|
||||
*/
|
||||
enum Family { IPv4, IPv6 };
|
||||
|
||||
/**
|
||||
* Byte order.
|
||||
*/
|
||||
enum ByteOrder { Host, Network };
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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& 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)
|
||||
{
|
||||
Init(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
IPAddr(const IPAddr& other) : in6(other.in6) { };
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~IPAddr() { };
|
||||
|
||||
/**
|
||||
* Returns the address' family.
|
||||
*/
|
||||
Family GetFamily() 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;
|
||||
|
||||
/**
|
||||
* Returns true if the address represents a multicast address.
|
||||
*/
|
||||
bool IsMulticast() const
|
||||
{
|
||||
if ( GetFamily() == 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
|
||||
{
|
||||
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
|
||||
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(const uint32_t** bytes) const
|
||||
{
|
||||
if ( GetFamily() == 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.
|
||||
*/
|
||||
void CopyIPv6(uint32_t* bytes) const
|
||||
{
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
void ReverseMask(int top_bits_to_chop);
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* compressed hex.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
friend bool operator==(const IPAddr& addr1, const IPAddr& addr2)
|
||||
{
|
||||
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0;
|
||||
}
|
||||
|
||||
friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2)
|
||||
{
|
||||
return ! (addr1 == 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)
|
||||
{
|
||||
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:
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
inline 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IPAddr::IsLoopback() const
|
||||
{
|
||||
if ( GetFamily() == 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 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.
|
||||
*/
|
||||
class IPPrefix
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructs a prefix 0/0.
|
||||
*/
|
||||
IPPrefix() : length(0) {}
|
||||
|
||||
/**
|
||||
* Constructs a prefix instance from an IPv4 address and a prefix
|
||||
* length.
|
||||
*
|
||||
* @param in4 The IPv4 address.
|
||||
*
|
||||
* @param length The prefix length in the range from 0 to 32.
|
||||
*/
|
||||
IPPrefix(const in4_addr& in4, uint8_t length);
|
||||
|
||||
/**
|
||||
* Constructs a prefix instance from an IPv6 address and a prefix
|
||||
* length.
|
||||
*
|
||||
* @param in6 The IPv6 address.
|
||||
*
|
||||
* @param length The prefix length in the range from 0 to 128.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
IPPrefix(const IPPrefix& other)
|
||||
: prefix(other.prefix), length(other.length) { }
|
||||
|
||||
/**
|
||||
* 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 { return prefix; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
return prefix.GetFamily() == IPAddr::IPv4 ? length - 96 : length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 { 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the prefix. IPv4 addresses
|
||||
* will be returned in dotted representation, IPv6 addresses in
|
||||
* compressed hex.
|
||||
*/
|
||||
string AsString() const;
|
||||
|
||||
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); }
|
||||
|
||||
/**
|
||||
* Comparison operator for IP prefix.
|
||||
*/
|
||||
friend bool operator==(const IPPrefix& net1, const IPPrefix& net2)
|
||||
{
|
||||
return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison operator IP prefixes. This defines a well-defined order for
|
||||
* IP prefix. However, the order does not necessarily corresponding to their
|
||||
* numerical values.
|
||||
*/
|
||||
friend 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;
|
||||
}
|
||||
|
||||
private:
|
||||
IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask().
|
||||
uint8_t length; // The bit length of the prefix relative to full IPv6 addr.
|
||||
};
|
||||
|
||||
#endif
|
|
@ -225,5 +225,7 @@ NCP_Analyzer::NCP_Analyzer(Connection* conn)
|
|||
NCP_Analyzer::~NCP_Analyzer()
|
||||
{
|
||||
delete session;
|
||||
delete o_ncp;
|
||||
delete r_ncp;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -131,6 +131,9 @@ int NetbiosSSN_Interpreter::ParseBroadcast(const u_char* data, int len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
delete srcname;
|
||||
delete dstname;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,15 +63,16 @@ 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -201,15 +201,15 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip)
|
|||
|
||||
if ( is_orig )
|
||||
{
|
||||
copy_addr(Conn()->OrigAddr(), &ip4->ip_src.s_addr);
|
||||
copy_addr(Conn()->RespAddr(), &ip4->ip_dst.s_addr);
|
||||
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
|
||||
{
|
||||
copy_addr(Conn()->RespAddr(), &ip4->ip_src.s_addr);
|
||||
copy_addr(Conn()->OrigAddr(), &ip4->ip_dst.s_addr);
|
||||
Conn()->RespAddr().CopyIPv4(&ip4->ip_src);
|
||||
Conn()->OrigAddr().CopyIPv4(&ip4->ip_dst);
|
||||
tcp4->th_sport = htons(Conn()->RespPort());
|
||||
tcp4->th_dport = htons(Conn()->OrigPort());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -382,6 +382,7 @@ void PktSrc::AddSecondaryTablePrograms()
|
|||
{
|
||||
delete program;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
SecondaryProgram* sp = new SecondaryProgram(program, se);
|
||||
|
|
|
@ -1,34 +1,19 @@
|
|||
#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));
|
||||
addr.CopyIPv6(&prefix->add.sin6);
|
||||
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 +40,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 +54,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 +74,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 +89,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 +113,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:
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -184,8 +184,9 @@
|
|||
#include "File.h"
|
||||
#include "Conn.h"
|
||||
#include "Reporter.h"
|
||||
#include "threading/SerializationTypes.h"
|
||||
#include "threading/SerialTypes.h"
|
||||
#include "logging/Manager.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
extern "C" {
|
||||
#include "setsignal.h"
|
||||
|
@ -671,8 +672,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;
|
||||
|
@ -680,16 +681,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.GetFamily() == 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();
|
||||
|
@ -1233,7 +1230,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;
|
||||
|
@ -1241,16 +1238,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.GetFamily() == 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;
|
||||
|
|
|
@ -35,7 +35,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);
|
||||
|
@ -63,7 +63,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();
|
||||
|
|
|
@ -155,7 +155,7 @@ 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, ...)
|
||||
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));
|
||||
|
@ -184,7 +184,7 @@ 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)
|
||||
void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
|
||||
{
|
||||
WeirdFlowHelper(orig, resp, "%s", name);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "util.h"
|
||||
#include "net_util.h"
|
||||
#include "EventHandler.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
class Connection;
|
||||
class Location;
|
||||
|
@ -74,7 +75,7 @@ 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
|
||||
// offline from a trace.
|
||||
|
@ -121,7 +122,7 @@ 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;
|
||||
bool via_events;
|
||||
|
|
|
@ -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?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1067,16 +1070,22 @@ 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().GetFamily() == IPAddr::IPv4 &&
|
||||
is_v4_mask )
|
||||
{
|
||||
mval->val = ntohl(to_v4_addr(n));
|
||||
mval->val = ntohl(*n);
|
||||
mval->mask = m[3];
|
||||
}
|
||||
|
||||
|
@ -1087,10 +1096,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:
|
||||
|
@ -1114,9 +1119,14 @@ 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
|
||||
val_to_maskedval(v, append_to);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,8 @@ 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
|
||||
|
|
|
@ -230,6 +230,45 @@ bool BinarySerializationFormat::Read(string* v, const char* tag)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag)
|
||||
{
|
||||
int n = 0;
|
||||
if ( ! Read(&n, "addr-len") )
|
||||
return false;
|
||||
|
||||
if ( n != 1 && n != 4 )
|
||||
return false;
|
||||
|
||||
uint32_t raw[4];
|
||||
|
||||
for ( int i = 0; i < n; ++i )
|
||||
{
|
||||
if ( ! Read(&raw[i], "addr-part") )
|
||||
return false;
|
||||
|
||||
raw[i] = htonl(raw[i]);
|
||||
}
|
||||
|
||||
if ( n == 1 )
|
||||
*addr = IPAddr(IPAddr::IPv4, raw, IPAddr::Network);
|
||||
else
|
||||
*addr = IPAddr(IPAddr::IPv6, raw, IPAddr::Network);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BinarySerializationFormat::Read(IPPrefix* prefix, const char* tag)
|
||||
{
|
||||
IPAddr addr;
|
||||
int len;
|
||||
|
||||
if ( ! (Read(&addr, "prefix") && Read(&len, "width")) )
|
||||
return false;
|
||||
|
||||
*prefix = IPPrefix(addr, 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 +338,30 @@ 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)
|
||||
{
|
||||
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(prefix.Prefix(), "prefix") && Write(prefix.Length(), "width");
|
||||
}
|
||||
|
||||
bool BinarySerializationFormat::WriteOpenTag(const char* tag)
|
||||
{
|
||||
return true;
|
||||
|
@ -389,6 +452,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);
|
||||
|
@ -469,6 +544,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-- )
|
||||
|
|
|
@ -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;
|
||||
|
@ -90,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);
|
||||
|
@ -101,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();
|
||||
|
@ -123,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();
|
||||
|
@ -138,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.
|
||||
|
|
|
@ -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(ip.SrcAddr());
|
||||
d->Add("->");
|
||||
d->Add(dotted_addr(ip.DstAddr()));
|
||||
d->Add(ip.DstAddr());
|
||||
}
|
||||
|
||||
bool Packet::Serialize(SerialInfo* info) const
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
{ return format->Read(const_cast<char**>(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); }
|
||||
|
|
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -279,18 +279,22 @@ 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) )
|
||||
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
|
||||
{
|
||||
#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);
|
||||
Weird("unknown_packet_type", hdr, pkt);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,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");
|
||||
|
||||
|
@ -604,8 +608,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 = addr_eq(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));
|
||||
|
@ -731,13 +735,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 +774,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,28 +815,23 @@ Connection* NetSessions::FindConnection(Val* v)
|
|||
// types, too.
|
||||
}
|
||||
|
||||
addr_type orig_addr = (*vl)[orig_h]->AsAddr();
|
||||
addr_type 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;
|
||||
|
||||
#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_port = htons((unsigned short) orig_portv->Port());
|
||||
id.dst_port = htons((unsigned short) resp_portv->Port());
|
||||
|
||||
id.is_one_way = 0; // ### incorrect for ICMP connections
|
||||
|
||||
HashKey* h = id.BuildConnKey();
|
||||
HashKey* h = BuildConnIDHashKey(id);
|
||||
if ( ! h )
|
||||
reporter->InternalError("hash computation failed");
|
||||
|
||||
|
@ -1092,7 +1089,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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
11
src/TCP.cc
11
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,7 @@ 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();
|
||||
|
||||
uint32 tcp_hdr_len = data - (const u_char*) tp;
|
||||
|
||||
|
@ -1331,7 +1330,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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -32,13 +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();
|
||||
|
||||
#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
|
||||
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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
417
src/Val.cc
417
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,10 @@ 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
|
||||
return SERIALIZE(*val.addr_val);
|
||||
|
||||
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");
|
||||
return SERIALIZE(*val.subnet_val);
|
||||
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
// Derived classes are responsible for this.
|
||||
|
@ -294,95 +275,16 @@ 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;
|
||||
val.addr_val = new IPAddr();
|
||||
return UNSERIALIZE(val.addr_val);
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
#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]);
|
||||
}
|
||||
else
|
||||
((AddrVal*) this)->Init(a[0]);
|
||||
#else
|
||||
if ( num_words == 1 )
|
||||
((AddrVal*) this)->Init(a[0]);
|
||||
else
|
||||
((AddrVal*) this)->Init(a);
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
val.subnet_val = new IPPrefix();
|
||||
return UNSERIALIZE(val.subnet_val);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#ifdef BROv6
|
||||
if ( num_words == 1 )
|
||||
{
|
||||
a[3] = a[0];
|
||||
a[0] = a[1] = a[2] = 0;
|
||||
}
|
||||
|
||||
((SubNetVal*) this)->Init(a, width);
|
||||
|
||||
#else
|
||||
if ( num_words == 4 )
|
||||
{
|
||||
if ( a[0] || a[1] || a[2] )
|
||||
info->s->Warning("received IPv6 subnet, ignoring");
|
||||
a[0] = a[3];
|
||||
|
||||
if ( width > 32 )
|
||||
width -= 96;
|
||||
}
|
||||
|
||||
((SubNetVal*) this)->Init(a[0], width);
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
// Derived classes are responsible for this.
|
||||
// Exception: Functions and files. There aren't any derived
|
||||
|
@ -590,12 +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(dotted_addr(val.addr_val)); break;
|
||||
case TYPE_INTERNAL_ADDR: d->Add(val.addr_val->AsString().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(val.subnet_val->AsString().c_str());
|
||||
break;
|
||||
|
||||
case TYPE_INTERNAL_ERROR: d->AddCS("error"); break;
|
||||
|
@ -706,7 +606,8 @@ ID* MutableVal::Bind() const
|
|||
ip = htonl(0x7f000001); // 127.0.0.1
|
||||
|
||||
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
|
||||
dotted_addr(ip), getpid());
|
||||
IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(),
|
||||
getpid());
|
||||
#else
|
||||
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
|
||||
#endif
|
||||
|
@ -957,92 +858,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(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)
|
||||
AddrVal::AddrVal(const uint32 addr[4]) : 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->GetFamily() == IPAddr::IPv4 )
|
||||
return new Val(32, TYPE_COUNT);
|
||||
else
|
||||
return new Val(128, TYPE_COUNT);
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(AddrVal, SER_ADDR_VAL);
|
||||
|
@ -1059,164 +909,89 @@ 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");
|
||||
string s(text);
|
||||
size_t slash_loc = s.find('/');
|
||||
|
||||
Init(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)
|
||||
{
|
||||
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(const IPPrefix& prefix) : Val(TYPE_SUBNET)
|
||||
{
|
||||
#ifdef BROv6
|
||||
const uint32* a = mask_addr(addr, uint32(width));
|
||||
val.subnet_val = new IPPrefix(prefix);
|
||||
}
|
||||
|
||||
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];
|
||||
SubNetVal::~SubNetVal()
|
||||
{
|
||||
delete val.subnet_val;
|
||||
}
|
||||
|
||||
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 )
|
||||
for ( w = val.subnet_val->Length(); w >= 32; w -= 32 )
|
||||
*(mp++) = 0xffffffff;
|
||||
|
||||
*mp = ~((1 << (32 - w)) - 1);
|
||||
|
@ -1224,44 +999,14 @@ addr_type SubNetVal::Mask() const
|
|||
while ( ++mp < m + 4 )
|
||||
*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
|
||||
bool SubNetVal::Contains(const IPAddr& 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
|
||||
}
|
||||
|
||||
bool SubNetVal::Contains(const uint32* addr) const
|
||||
{
|
||||
#ifdef BROv6
|
||||
const uint32* net = val.subnet_val.net;
|
||||
const uint32* a = addr;
|
||||
uint32 m;
|
||||
|
||||
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
|
||||
IPAddr a(addr);
|
||||
return val.subnet_val->Contains(a);
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL);
|
||||
|
@ -3476,20 +3221,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");
|
||||
|
|
61
src/Val.h
61
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<Val*>*, 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,12 +239,11 @@ 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()));
|
||||
return val.addr_val;
|
||||
return *val.addr_val;
|
||||
}
|
||||
|
||||
#define ACCESSOR(tag, ctype, accessor, name) \
|
||||
|
@ -261,10 +261,17 @@ public:
|
|||
ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
|
||||
ACCESSOR(TYPE_VECTOR, vector<Val*>*, vector_val, AsVector)
|
||||
|
||||
subnet_type* AsSubNet()
|
||||
const IPPrefix& AsSubNet()
|
||||
{
|
||||
CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name)
|
||||
return &val.subnet_val;
|
||||
return *val.subnet_val;
|
||||
}
|
||||
|
||||
const 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)
|
||||
|
@ -553,8 +562,9 @@ public:
|
|||
Val* SizeVal() const;
|
||||
|
||||
// Constructor for address already in network order.
|
||||
AddrVal(uint32 addr);
|
||||
AddrVal(const uint32* addr);
|
||||
AddrVal(uint32 addr); // IPv4.
|
||||
AddrVal(const uint32 addr[4]); // IPv6.
|
||||
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,26 @@ 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); // IPv4.
|
||||
SubNetVal(const uint32 addr[4], int width); // IPv6.
|
||||
SubNetVal(const IPAddr& addr, int width);
|
||||
SubNetVal(const IPPrefix& prefix);
|
||||
~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);
|
||||
|
|
|
@ -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")
|
||||
|
|
526
src/bro.bif
526
src/bro.bif
|
@ -14,6 +14,7 @@
|
|||
#include <cstdio>
|
||||
|
||||
#include "Reporter.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -178,35 +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.
|
||||
|
||||
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]);
|
||||
|
||||
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), "%s",
|
||||
v->AsAddr().AsHexString().c_str());
|
||||
}
|
||||
|
||||
else if ( ! check_fmt_type(t, ok_d_fmt) )
|
||||
|
@ -1959,44 +1933,41 @@ function do_profiling%(%) : any
|
|||
## 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);
|
||||
|
||||
list<IPAddr> addrs;
|
||||
|
||||
if ( len < 0 )
|
||||
{
|
||||
char host[MAXHOSTNAMELEN];
|
||||
|
||||
strcpy(host, "localhost");
|
||||
gethostname(host, MAXHOSTNAMELEN);
|
||||
host[MAXHOSTNAMELEN-1] = '\0';
|
||||
|
||||
struct hostent* ent = gethostbyname(host);
|
||||
struct hostent* ent = gethostbyname2(host, AF_INET);
|
||||
|
||||
for ( len = 0; ent->h_addr_list[len]; ++len )
|
||||
;
|
||||
|
||||
addrs = new uint32[len + 1];
|
||||
for ( int i = 0; i < len; i++ )
|
||||
addrs[i] = *(uint32*) ent->h_addr_list[i];
|
||||
|
||||
addrs[len++] = 0x0100007f; // 127.0.0.1
|
||||
}
|
||||
|
||||
#ifdef BROv6
|
||||
if ( ! is_v4_addr(ip) )
|
||||
if ( ent )
|
||||
{
|
||||
builtin_error("is_local_interface() only supports IPv4 addresses");
|
||||
return new Val(0, TYPE_BOOL);
|
||||
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));
|
||||
}
|
||||
|
||||
uint32 ip4 = to_v4_addr(ip);
|
||||
#else
|
||||
uint32 ip4 = ip;
|
||||
#endif
|
||||
ent = gethostbyname2(host, AF_INET6);
|
||||
|
||||
for ( int i = 0; i < len; i++ )
|
||||
if ( addrs[i] == ip4 )
|
||||
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<IPAddr>::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);
|
||||
%}
|
||||
|
@ -2046,19 +2017,95 @@ 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().GetFamily() == 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().GetFamily() == IPAddr::IPv6 )
|
||||
return new Val(1, TYPE_BOOL);
|
||||
else
|
||||
return new Val(0, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
# ===========================================================================
|
||||
#
|
||||
# Conversion
|
||||
#
|
||||
# ===========================================================================
|
||||
|
||||
## 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 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.
|
||||
##
|
||||
## 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();
|
||||
|
@ -2115,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();
|
||||
|
@ -2180,29 +2227,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.
|
||||
|
@ -2233,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();
|
||||
|
@ -2244,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 )
|
||||
|
@ -2270,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;
|
||||
|
@ -2293,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;
|
||||
|
@ -2327,12 +2370,16 @@ function to_port%(s: string%): port
|
|||
## .. bro:see:: addr_to_ptr_name parse_dotted_addr
|
||||
function ptr_name_to_addr%(s: string%): addr
|
||||
%{
|
||||
if ( s->Len() != 72 )
|
||||
{
|
||||
int a[4];
|
||||
uint32 addr;
|
||||
char ss[13]; // this will contain "in-addr.arpa"
|
||||
|
||||
if ( sscanf(s->CheckString(),
|
||||
"%d.%d.%d.%d.in-addr.arpa",
|
||||
a, a+1, a+2, a+3) != 4 )
|
||||
"%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;
|
||||
|
@ -2341,6 +2388,40 @@ function ptr_name_to_addr%(s: string%): addr
|
|||
addr = (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
|
||||
|
||||
return new AddrVal(htonl(addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
addr6[i] = htonl(a);
|
||||
}
|
||||
}
|
||||
|
||||
return new AddrVal(addr6);
|
||||
}
|
||||
%}
|
||||
|
||||
## Converts an IP address to a reverse pointer name. For example,
|
||||
|
@ -2350,34 +2431,10 @@ 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];
|
||||
else
|
||||
{
|
||||
builtin_error("conversion of non-IPv4 address to net", @ARG@[0]);
|
||||
addr = 0;
|
||||
}
|
||||
#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);
|
||||
return new StringVal(a->AsAddr().PtrName().c_str());
|
||||
%}
|
||||
|
||||
# Transforms n0.n1.n2.n3 -> addr.
|
||||
|
@ -2389,10 +2446,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(s->CheckString());
|
||||
return new AddrVal(a);
|
||||
%}
|
||||
|
||||
%%{
|
||||
|
@ -2444,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;
|
||||
|
||||
|
@ -2454,31 +2512,53 @@ 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 ( *line )
|
||||
{
|
||||
good = 1;
|
||||
++line; // skip delimiter
|
||||
|
||||
net_proto = strtol(line, &next_delim, 10);
|
||||
if ( *next_delim != delimiter )
|
||||
good = 0;
|
||||
|
||||
line = next_delim + 1;
|
||||
if ( *line != delimiter ) // default of 0 is ok
|
||||
line = next_delim;
|
||||
if ( *line )
|
||||
++line;
|
||||
|
||||
if ( *line && *line != delimiter )
|
||||
{
|
||||
addr = dotted_to_addr(line);
|
||||
if ( addr == 0 )
|
||||
const char* nptr = strchr(line, delimiter);
|
||||
if ( nptr == NULL )
|
||||
{
|
||||
nptr = line + strlen(line);
|
||||
good = 0;
|
||||
}
|
||||
|
||||
// FIXME: check for garbage between IP and delimiter.
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
r->Assign(0, new AddrVal(addr));
|
||||
r->Assign(1, new PortVal(port, TRANSPORT_TCP));
|
||||
r->Assign(2, new Val(good, TYPE_BOOL));
|
||||
|
@ -2504,7 +2584,7 @@ function parse_ftp_port%(s: string%): ftp_port
|
|||
## The format is ``EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>``,
|
||||
## where ``<d>`` 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]``
|
||||
##
|
||||
|
@ -2544,7 +2624,7 @@ function parse_ftp_pasv%(str: string%): ftp_port
|
|||
## The format is ``<text> (<d><d><d><tcp-port><d>)``, where ``<d>`` 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]``
|
||||
##
|
||||
|
@ -2570,20 +2650,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);
|
||||
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",
|
||||
addr >> 24, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff,
|
||||
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.
|
||||
|
@ -2896,7 +2979,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
|
||||
|
@ -2909,29 +2992,20 @@ 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());
|
||||
addr2.ReverseMask(top_bits_from_a1);
|
||||
return new AddrVal(addr1|addr2);
|
||||
%}
|
||||
|
||||
## Checks whether a given :bro:type:`port` has TCP as transport protocol.
|
||||
|
@ -3104,12 +3178,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", orig_h.AsString().c_str(), orig_p,
|
||||
resp_h.AsString().c_str(), resp_p);
|
||||
}
|
||||
%%}
|
||||
|
||||
|
@ -3339,29 +3414,8 @@ function lookup_addr%(host: addr%) : string
|
|||
frame->SetDelayed();
|
||||
trigger->Hold();
|
||||
|
||||
#ifdef BROv6
|
||||
if ( ! is_v4_addr(host) )
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
dns_mgr->AsyncLookupAddr(to_v4_addr(host),
|
||||
dns_mgr->AsyncLookupAddr(host->AsAddr(),
|
||||
new LookupHostCallback(trigger, frame->GetCall(), true));
|
||||
#else
|
||||
dns_mgr->AsyncLookupAddr(host,
|
||||
new LookupHostCallback(trigger, frame->GetCall(), true));
|
||||
#endif
|
||||
return 0;
|
||||
%}
|
||||
|
||||
|
@ -3453,8 +3507,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 )
|
||||
|
@ -3467,16 +3519,13 @@ 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().GetFamily() == IPAddr::IPv6 )
|
||||
{
|
||||
geoipv6_t ga;
|
||||
memcpy(&ga, a, 16);
|
||||
a->AsAddr().CopyIPv6(&ga);
|
||||
if ( have_cityv6_db )
|
||||
gir = GeoIP_record_by_ipnum_v6(geoip_v6, ga);
|
||||
else
|
||||
|
@ -3485,25 +3534,16 @@ function lookup_location%(a: addr%) : geo_location
|
|||
else
|
||||
#endif
|
||||
|
||||
if ( geoip && is_v4_addr(a) )
|
||||
if ( geoip && a->AsAddr().GetFamily() == 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 )
|
||||
|
@ -3575,28 +3615,23 @@ 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().GetFamily() == IPAddr::IPv6 )
|
||||
{
|
||||
geoipv6_t ga;
|
||||
memcpy(&ga, a, 16);
|
||||
a->AsAddr().CopyIPv6(&ga);
|
||||
gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if ( is_v4_addr(a) )
|
||||
if ( a->AsAddr().GetFamily() == 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 )
|
||||
|
@ -3878,9 +3913,9 @@ function file_mode%(mode: count%): string
|
|||
function expect_connection%(orig: addr, resp: addr, resp_p: port,
|
||||
analyzer: count, tout: interval%) : any
|
||||
%{
|
||||
dpm->ExpectConnection(orig, resp, resp_p->Port(), resp_p->PortType(),
|
||||
(AnalyzerTag::Tag) analyzer, tout, 0);
|
||||
return 0;
|
||||
dpm->ExpectConnection(orig->AsAddr(), resp->AsAddr(), resp_p->Port(),
|
||||
resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0);
|
||||
return new Val(1, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
## Disables the analyzer which raised the current event (if the analyzer
|
||||
|
@ -4652,7 +4687,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);
|
||||
%}
|
||||
|
||||
|
@ -4704,7 +4739,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.
|
||||
|
@ -4754,7 +4789,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);
|
||||
%}
|
||||
|
||||
|
@ -4806,7 +4841,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.
|
||||
|
@ -4947,7 +4982,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);
|
||||
%}
|
||||
|
@ -5062,7 +5097,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.
|
||||
|
@ -5318,14 +5353,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().GetFamily() == 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -5343,18 +5378,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", a->Prefix().AsString().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().GetFamily() == 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;
|
||||
|
@ -5383,19 +5418,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().GetFamily() == 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.
|
||||
|
@ -5445,7 +5479,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(src_ip->AsAddr().AsString().c_str())),
|
||||
NULL), NULL),
|
||||
newService(
|
||||
newSimpleElement("port",
|
||||
|
@ -5455,7 +5489,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(dst_ip->AsAddr().AsString().c_str())),
|
||||
NULL), NULL),
|
||||
newService(
|
||||
newSimpleElement("port",
|
||||
|
@ -5470,13 +5504,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
|
||||
%}
|
||||
|
|
|
@ -55,33 +55,18 @@ flow DHCP_Flow(is_orig: bool) {
|
|||
vector<DHCP_Option*>::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<uint32>* 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:
|
||||
|
|
|
@ -216,44 +216,42 @@ flow DNS_Flow
|
|||
|
||||
switch ( rr->rr_type() ) {
|
||||
case TYPE_A:
|
||||
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_A_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 )
|
||||
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?)
|
||||
::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), addr);
|
||||
dns_msg_val_->Ref(), build_dns_answer(rr),
|
||||
new AddrVal(htonl(addr)));
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_A6:
|
||||
if ( dns_A6_reply )
|
||||
{
|
||||
::uint32 addr[4];
|
||||
for ( unsigned int i = 0; i < 4; ++i )
|
||||
addr[i] = htonl((*rd->type_aaaa())[i]);
|
||||
|
||||
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:
|
||||
|
|
|
@ -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 <http://en.wikipedia.org/wiki/Domain_Name_System>`__ 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.
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "CompHash.h"
|
||||
|
||||
#include "../threading/SerializationTypes.h"
|
||||
#include "../threading/SerialTypes.h"
|
||||
|
||||
using namespace input;
|
||||
using threading::Value;
|
||||
|
@ -1427,12 +1427,35 @@ int Manager::GetValueLength(const Value* val) {
|
|||
}
|
||||
|
||||
case TYPE_ADDR:
|
||||
length += NUM_ADDR_WORDS*sizeof(uint32_t);
|
||||
{
|
||||
switch ( val->val.addr_val->GetFamily() ) {
|
||||
case IPAddr::IPv4:
|
||||
length += 1*sizeof(uint32_t);
|
||||
break;
|
||||
case IPAddr::IPv6:
|
||||
length += 4*sizeof(uint32_t);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_SUBNET:
|
||||
length += sizeof(val->val.subnet_val.width);
|
||||
length += sizeof(val->val.subnet_val.net);
|
||||
{
|
||||
switch ( val->val.addr_val->GetFamily() ) {
|
||||
case IPAddr::IPv4:
|
||||
length += 1*sizeof(uint32_t)+sizeof(uint8_t);
|
||||
break;
|
||||
case IPAddr::IPv6:
|
||||
length += 4*sizeof(uint32_t)+sizeof(uint8_t);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_TABLE: {
|
||||
|
@ -1503,17 +1526,22 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) {
|
|||
}
|
||||
|
||||
case TYPE_ADDR:
|
||||
memcpy(data+startpos, val->val.addr_val, NUM_ADDR_WORDS*sizeof(uint32_t));
|
||||
return NUM_ADDR_WORDS*sizeof(uint32_t);
|
||||
{
|
||||
const uint32_t* bytes;
|
||||
int len = val->val.addr_val->GetBytes(&bytes) * sizeof(uint32_t);
|
||||
memcpy(data+startpos, (const char*) bytes, len);
|
||||
return len;
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_SUBNET: {
|
||||
int length = 0;
|
||||
memcpy(data+startpos,(const char*) &(val->val.subnet_val.width), sizeof(val->val.subnet_val.width) );
|
||||
length += sizeof(val->val.subnet_val.width);
|
||||
memcpy(data+startpos+length, (const char*) &(val->val.subnet_val.net), sizeof(val->val.subnet_val.net) );
|
||||
length += sizeof(val->val.subnet_val.net);
|
||||
return length;
|
||||
const uint32_t* bytes;
|
||||
int len = val->val.subnet_val->Prefix().GetBytes(&bytes) * sizeof(uint32_t);
|
||||
memcpy(data+startpos, (const char*) bytes, len);
|
||||
uint8_t prefixlen = val->val.subnet_val->Length();
|
||||
memcpy(data+startpos+len, (const char*) &(prefixlen), sizeof(uint8_t) );
|
||||
len += sizeof(uint8_t);
|
||||
return len;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1620,11 +1648,11 @@ Val* Manager::ValueToVal(const Value* val, BroType* request_type) {
|
|||
break;
|
||||
|
||||
case TYPE_ADDR:
|
||||
return new AddrVal(val->val.addr_val);
|
||||
return new AddrVal(*(val->val.addr_val));
|
||||
break;
|
||||
|
||||
case TYPE_SUBNET:
|
||||
return new SubNetVal(val->val.subnet_val.net, val->val.subnet_val.width);
|
||||
return new SubNetVal(*(val->val.subnet_val));
|
||||
break;
|
||||
|
||||
case TYPE_TABLE: {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#define INPUT_READERBACKEND_H
|
||||
|
||||
#include "BroString.h"
|
||||
#include "../threading/SerializationTypes.h"
|
||||
#include "../threading/SerialTypes.h"
|
||||
#include "threading/MsgThread.h"
|
||||
|
||||
namespace input {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#define INPUT_READERFRONTEND_H
|
||||
|
||||
#include "../threading/MsgThread.h"
|
||||
#include "../threading/SerializationTypes.h"
|
||||
#include "../threading/SerialTypes.h"
|
||||
|
||||
namespace input {
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "../../threading/SerializationTypes.h"
|
||||
#include "../../threading/SerialTypes.h"
|
||||
|
||||
#define MANUAL 0
|
||||
#define REREAD 1
|
||||
|
@ -310,51 +310,17 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) {
|
|||
|
||||
case TYPE_SUBNET: {
|
||||
int pos = s.find("/");
|
||||
string width = s.substr(pos+1);
|
||||
val->val.subnet_val.width = atoi(width.c_str());
|
||||
int width = atoi(s.substr(pos+1).c_str());
|
||||
string addr = s.substr(0, pos);
|
||||
s = addr;
|
||||
#ifdef BROv6
|
||||
if ( s.find(':') != s.npos ) {
|
||||
uint32* addr = new uint32[4];
|
||||
if ( inet_pton(AF_INET6, s.c_str(), addr) <= 0 ) {
|
||||
Error(Fmt("Bad IPv6 address: %s", s.c_str()));
|
||||
val->val.subnet_val.net[0] = val->val.subnet_val.net[1] = val->val.subnet_val.net[2] = val->val.subnet_val.net[3] = 0;
|
||||
}
|
||||
copy_addr(val->val.subnet_val.net, addr);
|
||||
delete addr;
|
||||
} else {
|
||||
val->val.subnet_val.net[0] = val->val.subnet_val.net[1] = val->val.subnet_val.net[2] = 0;
|
||||
if ( inet_aton(s.c_str(), &(val->val.subnet_val.net[3])) <= 0 ) {
|
||||
Error(Fmt("Bad addres: %s", s.c_str()));
|
||||
val->val.subnet_val.net[3] = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( inet_aton(s.c_str(), (in_addr*) &(val->val.subnet_val.net)) <= 0 ) {
|
||||
Error(Fmt("Bad addres: %s", s.c_str()));
|
||||
val->val.subnet_val.net = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
IPAddr a(addr);
|
||||
val->val.subnet_val = new IPPrefix(a, width);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
case TYPE_ADDR: {
|
||||
// NOTE: dottet_to_addr BREAKS THREAD SAFETY! it uses reporter.
|
||||
// Solve this some other time....
|
||||
#ifdef BROv6
|
||||
if ( s.find(':') != s.npos ) {
|
||||
uint32* addr = dotted_to_addr6(s.c_str());
|
||||
copy_addr(val->val.addr_val, addr);
|
||||
delete addr;
|
||||
} else {
|
||||
val->val.addr_val[0] = val->val.addr_val[1] = val->val.addr_val[2] = 0;
|
||||
val->val.addr_val[3] = dotted_to_addr(s.c_str());
|
||||
}
|
||||
#else
|
||||
uint32 t = dotted_to_addr(s.c_str());
|
||||
copy_addr(&t, val->val.addr_val);
|
||||
#endif
|
||||
val->val.addr_val = new IPAddr(s);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "../../threading/SerializationTypes.h"
|
||||
#include "../../threading/SerialTypes.h"
|
||||
|
||||
#define MANUAL 0
|
||||
#define REREAD 1
|
||||
|
|
|
@ -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;
|
||||
|
@ -144,7 +144,7 @@ WriterBackend* Manager::CreateBackend(WriterFrontend* frontend, bro_int_t type)
|
|||
|
||||
if ( ld->type != type )
|
||||
{
|
||||
// no, didn't find the right one...
|
||||
// Not the right one.
|
||||
++ld;
|
||||
continue;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ WriterBackend* Manager::CreateBackend(WriterFrontend* frontend, bro_int_t type)
|
|||
// Oops, we can't instantiate this guy.
|
||||
return 0;
|
||||
|
||||
// all done. break.
|
||||
// All done.
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -862,19 +862,12 @@ threading::Value* Manager::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;
|
||||
}
|
||||
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_TIME:
|
||||
|
|
|
@ -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").
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
#include <string>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../../NetVar.h"
|
||||
#include "NetVar.h"
|
||||
#include "threading/SerialTypes.h"
|
||||
|
||||
#include "Ascii.h"
|
||||
#include "../../threading/SerializationTypes.h"
|
||||
|
||||
using namespace logging;
|
||||
using namespace writer;
|
||||
|
@ -177,34 +177,12 @@ bool Ascii::DoWriteOne(ODesc* desc, Value* val, const Field* field)
|
|||
break;
|
||||
|
||||
case TYPE_SUBNET:
|
||||
{
|
||||
// FIXME: This will be replaced with string(addr) once the
|
||||
// IPV6 branch is merged in.
|
||||
uint32_t addr = ntohl(val->val.subnet_val.net);
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
|
||||
addr >> 24, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff);
|
||||
|
||||
desc->Add(buf);
|
||||
desc->Add("/");
|
||||
desc->Add(val->val.subnet_val.width);
|
||||
desc->Add(*val->val.subnet_val);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_ADDR:
|
||||
{
|
||||
// FIXME: This will be replaced with string(addr) once the
|
||||
// IPV6 branch is merged in.
|
||||
uint32_t addr = ntohl(*val->val.addr_val);
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
|
||||
addr >> 24, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff);
|
||||
|
||||
desc->Add(buf);
|
||||
desc->Add(*val->val.addr_val);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
231
src/net_util.cc
231
src/net_util.cc
|
@ -2,17 +2,16 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef BROv6
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#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.
|
||||
|
@ -32,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
|
||||
|
@ -81,7 +87,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 +109,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 +147,6 @@ char addr_to_class(uint32 addr)
|
|||
return 'A';
|
||||
}
|
||||
|
||||
uint32 addr_to_net(uint32 addr)
|
||||
{
|
||||
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;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
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 "<bad IPv6 address conversion>";
|
||||
|
||||
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 %u", 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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 extract_uint32(const u_char* data)
|
||||
{
|
||||
uint32 val;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <netinet/ip_icmp.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IP6_H
|
||||
#include <netinet/ip6.h>
|
||||
|
@ -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
|
||||
|
@ -83,81 +60,22 @@ 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);
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -53,11 +53,9 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
|
||||
#ifdef BROv6
|
||||
#ifndef HAVE_IPV6
|
||||
#define HAVE_IPV6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* typedef unsigned int u_int; */
|
||||
typedef void (*void_fn_t)();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue