Making exchange of addresses between threads thread-safe.

As we can't use the IPAddr class (because it's not thread-safe), this
involved a bit manual address manipulation and also shuffling some
things around a bit.

Not fully working yet, the tests for remote logging still fail.
This commit is contained in:
Robin Sommer 2012-02-28 15:12:35 -08:00
parent 14916b43f6
commit edc9bb14af
24 changed files with 325 additions and 84 deletions

View file

@ -154,7 +154,7 @@ void AnonymizeIPAddr_A50::init()
int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits)
{
DEBUG_MSG("%s/%d\n",
IPAddr(IPAddr::IPv4, &input, IPAddr::Network).AsString().c_str(),
IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(),
num_bits);
if ( ! before_anonymization )

View file

@ -709,7 +709,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
const uint32* const kp = AlignType<uint32>(kp0);
kp1 = reinterpret_cast<const char*>(kp+4);
IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network);
IPAddr addr(IPv6, kp, IPAddr::Network);
switch ( tag ) {
case TYPE_ADDR:

View file

@ -236,7 +236,7 @@ Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip,
}
else if ( ip->SrcAddr() ==
IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network) &&
IPAddr(IPv6, SrcAddr(pending), IPAddr::Network) &&
tp->th_sport == SrcPort(pending) )
// Another packet from originator.
tc = NextFromOrig(pending, t, key, ip, tp);
@ -508,8 +508,8 @@ Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending)
{
// Instantantiate a Connection.
ConnID conn_id;
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_addr = IPAddr(IPv6, SrcAddr(pending), IPAddr::Network);
conn_id.dst_addr = IPAddr(IPv6, DstAddr(pending), IPAddr::Network);
conn_id.src_port = SrcPort(pending);
conn_id.dst_port = DstPort(pending);
@ -608,7 +608,7 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key,
memcpy(&c->key, key->Key(), key->Size());
c->hash = key->Hash();
IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network);
IPAddr ip1(IPv6, c->key.ip1, IPAddr::Network);
c->ip1_is_src = ip1 == ip->SrcAddr() &&
c->key.port1 == tp->th_sport;
c->time = time;
@ -658,10 +658,10 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c)
tp->th_urp = 0;
}
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 )
IPAddr ip1(IPv6, c->key.ip1, IPAddr::Network);
IPAddr ip2(IPv6, c->key.ip2, IPAddr::Network);
if ( ip1.GetFamily() == IPv6 ||
ip2.GetFamily() == IPv6 )
reporter->InternalError("IPv6 snuck into connection compressor");
else
{

View file

@ -137,7 +137,7 @@ static bool is_mapped_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr)
bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto)
{
if ( id->dst_addr.GetFamily() == IPAddr::IPv6 )
if ( id->dst_addr.GetFamily() == IPv6 )
// TODO: Does the protocol support v6 addresses? #773
return false;
@ -414,7 +414,7 @@ void DCE_RPC_Session::DeliverEpmapperMapResponse(
case binpac::DCE_RPC_Simple::EPM_PROTOCOL_IP:
uint32 hostip = floor->rhs()->data()->ip();
mapped.addr.addr = IPAddr(IPAddr::IPv4, &hostip, IPAddr::Host);
mapped.addr.addr = IPAddr(IPv4, &hostip, IPAddr::Host);
break;
}
}

View file

@ -321,10 +321,10 @@ void DNS_Mapping::Init(struct hostent* h)
addrs = new IPAddr[num_addrs];
for ( int i = 0; i < num_addrs; ++i )
if ( h->h_addrtype == AF_INET )
addrs[i] = IPAddr(IPAddr::IPv4, (uint32*)h->h_addr_list[i],
addrs[i] = 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],
addrs[i] = IPAddr(IPv6, (uint32*)h->h_addr_list[i],
IPAddr::Network);
}
else

View file

@ -157,6 +157,16 @@ void ODesc::Add(double d)
}
}
void ODesc::Add(const IPAddr& addr)
{
Add(addr.AsString());
}
void ODesc::Add(const IPPrefix& prefix)
{
Add(prefix.AsString());
}
void ODesc::AddCS(const char* s)
{
int n = strlen(s);

View file

@ -8,7 +8,6 @@
#include <utility>
#include "BroString.h"
#include "IPAddr.h"
typedef enum {
DESC_READABLE,
@ -23,6 +22,8 @@ typedef enum {
} desc_style;
class BroFile;
class IPAddr;
class IPPrefix;
class ODesc {
public:
@ -76,8 +77,8 @@ public:
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()); }
void Add(const IPAddr& addr);
void Add(const IPPrefix& prefix);
// Add s as a counted string.
void AddCS(const char* s);

View file

@ -250,7 +250,7 @@ IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length)
IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length)
: prefix(addr)
{
if ( prefix.GetFamily() == IPAddr::IPv4 )
if ( prefix.GetFamily() == IPv4 )
{
if ( length > 32 )
reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d",
@ -275,7 +275,7 @@ string IPPrefix::AsString() const
{
char l[16];
if ( prefix.GetFamily() == IPAddr::IPv4 )
if ( prefix.GetFamily() == IPv4 )
modp_uitoa10(length - 96, l);
else
modp_uitoa10(length, l);

View file

@ -10,6 +10,8 @@
#include "BroString.h"
#include "Hash.h"
#include "util.h"
#include "Type.h"
#include "threading/SerialTypes.h"
struct ConnID;
class ExpectedConn;
@ -25,7 +27,7 @@ public:
/**
* Address family.
*/
enum Family { IPv4, IPv6 };
typedef IPFamily Family;
/**
* Byte order.
@ -318,14 +320,19 @@ public:
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0;
}
/** Converts the address into the type used internally by the
* inter-thread communication.
*/
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
friend HashKey* BuildConnIDHashKey(const ConnID& id);
friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
friend class IPPrefix;
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
private:
friend class IPPrefix;
/**
* Initializes an address instance from a string representation.
*
@ -384,6 +391,25 @@ inline bool IPAddr::IsLoopback() const
&& (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1));
}
inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
{
v->family = GetFamily();
switch ( v->family ) {
case IPv4:
CopyIPv4(&v->in.in4);
return;
case IPv6:
CopyIPv6(&v->in.in6);
return;
// Can't be reached.
abort();
}
}
/**
* Returns a hash key for a given ConnID. Passes ownership to caller.
*/
@ -459,7 +485,7 @@ public:
*/
uint8_t Length() const
{
return prefix.GetFamily() == IPAddr::IPv4 ? length - 96 : length;
return prefix.GetFamily() == IPv4 ? length - 96 : length;
}
/**
@ -497,6 +523,8 @@ public:
*/
string AsString() const;
/** Converts the address into the type used internally by the inter-thread communicastion.
*/
operator std::string() const { return AsString(); }
/**
@ -516,6 +544,15 @@ public:
return new HashKey(&key, sizeof(key));
}
/** Converts the prefix into the type used internally by the
* inter-thread communication.
*/
void ConvertToThreadingValue(threading::Value::subnet_t* v) const
{
v->length = length;
prefix.ConvertToThreadingValue(&v->prefix);
}
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
/**

View file

@ -681,7 +681,7 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip,
if ( ! initialized )
reporter->InternalError("remote serializer not initialized");
if ( ip.GetFamily() == IPAddr::IPv6 )
if ( ip.GetFamily() == IPv6 )
Error("inter-Bro communication not supported over IPv6");
const uint32* bytes;
@ -1238,7 +1238,7 @@ bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl)
if ( ! initialized )
reporter->InternalError("remote serializer not initialized");
if ( ip.GetFamily() == IPAddr::IPv6 )
if ( ip.GetFamily() == IPv6 )
Error("inter-Bro communication not supported over IPv6");
const uint32* bytes;

View file

@ -1082,7 +1082,7 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to)
bool is_v4_mask = m[0] == 0xffffffff &&
m[1] == m[0] && m[2] == m[0];
if ( v->AsSubNet().Prefix().GetFamily() == IPAddr::IPv4 &&
if ( v->AsSubNet().Prefix().GetFamily() == IPv4 &&
is_v4_mask )
{
mval->val = ntohl(*n);

View file

@ -250,9 +250,9 @@ bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag)
}
if ( n == 1 )
*addr = IPAddr(IPAddr::IPv4, raw, IPAddr::Network);
*addr = IPAddr(IPv4, raw, IPAddr::Network);
else
*addr = IPAddr(IPAddr::IPv6, raw, IPAddr::Network);
*addr = IPAddr(IPv6, raw, IPAddr::Network);
return true;
}
@ -269,6 +269,33 @@ bool BinarySerializationFormat::Read(IPPrefix* prefix, const char* tag)
return true;
}
bool BinarySerializationFormat::Read(struct in_addr* addr, const char* tag)
{
uint32_t* bytes = (uint32_t*) &addr->s_addr;
if ( ! Read(&bytes[0], "addr4") )
return false;
bytes[0] = htonl(bytes[0]);
return true;
}
bool BinarySerializationFormat::Read(struct in6_addr* addr, const char* tag)
{
uint32_t* bytes = (uint32_t*) &addr->s6_addr;
for ( int i = 0; i < 4; ++i )
{
if ( ! Read(&bytes[i], "addr6-part") )
return false;
bytes[i] = htonl(bytes[i]);
}
return true;
}
bool BinarySerializationFormat::Write(char v, const char* tag)
{
DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag);
@ -362,6 +389,31 @@ bool BinarySerializationFormat::Write(const IPPrefix& prefix, const char* tag)
return Write(prefix.Prefix(), "prefix") && Write(prefix.Length(), "width");
}
bool BinarySerializationFormat::Write(struct in_addr& addr, const char* tag)
{
const uint32_t* bytes;
bytes = (uint32_t*) &addr.s_addr;
if ( ! Write(ntohl(bytes[0]), "addr4") )
return false;
return true;
}
bool BinarySerializationFormat::Write(struct in6_addr& addr, const char* tag)
{
const uint32_t* bytes;
bytes = (uint32_t*) &addr.s6_addr;
for ( int i = 0; i < 4; ++i )
{
if ( ! Write(ntohl(bytes[i]), "addr6-part") )
return false;
}
return true;
}
bool BinarySerializationFormat::WriteOpenTag(const char* tag)
{
return true;
@ -464,6 +516,18 @@ bool XMLSerializationFormat::Read(IPPrefix* prefix, const char* tag)
return false;
}
bool XMLSerializationFormat::Read(struct in_addr* addr, const char* tag)
{
reporter->InternalError("no reading of xml");
return false;
}
bool XMLSerializationFormat::Read(struct in6_addr* addr, 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);
@ -556,6 +620,18 @@ bool XMLSerializationFormat::Write(const IPPrefix& prefix, const char* tag)
return false;
}
bool XMLSerializationFormat::Write(struct in_addr& addr, const char* tag)
{
reporter->InternalError("XML output of in_addr not implemented");
return false;
}
bool XMLSerializationFormat::Write(struct in6_addr& addr, const char* tag)
{
reporter->InternalError("XML output of in6_addr not implemented");
return false;
}
bool XMLSerializationFormat::WriteEncodedString(const char* s, int len)
{
while ( len-- )

View file

@ -9,6 +9,9 @@ using namespace std;
#include "util.h"
class IPAddr;
class IPPrefix;
// Abstract base class.
class SerializationFormat {
public:
@ -30,6 +33,8 @@ public:
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;
virtual bool Read(struct in_addr* addr, const char* tag) = 0;
virtual bool Read(struct in6_addr* addr, const char* tag) = 0;
// Returns number of raw bytes read since last call to StartRead().
int BytesRead() const { return bytes_read; }
@ -54,6 +59,8 @@ public:
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 Write(struct in_addr& addr, const char* tag) = 0;
virtual bool Write(struct in6_addr& addr, const char* tag) = 0;
virtual bool WriteOpenTag(const char* tag) = 0;
virtual bool WriteCloseTag(const char* tag) = 0;
@ -96,6 +103,8 @@ public:
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 Read(struct in_addr* addr, const char* tag);
virtual bool Read(struct in6_addr* addr, 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);
@ -109,6 +118,8 @@ public:
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 Write(struct in_addr& addr, const char* tag);
virtual bool Write(struct in6_addr& addr, const char* tag);
virtual bool WriteOpenTag(const char* tag);
virtual bool WriteCloseTag(const char* tag);
virtual bool WriteSeparator();
@ -133,6 +144,8 @@ public:
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 Write(struct in_addr& addr, const char* tag);
virtual bool Write(struct in6_addr& addr, const char* tag);
virtual bool WriteOpenTag(const char* tag);
virtual bool WriteCloseTag(const char* tag);
virtual bool WriteSeparator();
@ -150,6 +163,8 @@ public:
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 Read(struct in_addr* addr, const char* tag);
virtual bool Read(struct in6_addr* addr, const char* tag);
private:
// Encodes non-printable characters.

View file

@ -606,7 +606,7 @@ ID* MutableVal::Bind() const
ip = htonl(0x7f000001); // 127.0.0.1
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(),
IPAddr(IPv4, &ip, IPAddr::Network)->AsString().c_str(),
getpid());
#else
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
@ -864,12 +864,12 @@ AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR)
AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR)
{
// ### perhaps do gethostbyaddr here?
val.addr_val = new IPAddr(IPAddr::IPv4, &addr, IPAddr::Network);
val.addr_val = new IPAddr(IPv4, &addr, IPAddr::Network);
}
AddrVal::AddrVal(const uint32 addr[4]) : Val(TYPE_ADDR)
{
val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network);
val.addr_val = new IPAddr(IPv6, addr, IPAddr::Network);
}
AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR)
@ -889,7 +889,7 @@ unsigned int AddrVal::MemoryAllocation() const
Val* AddrVal::SizeVal() const
{
if ( val.addr_val->GetFamily() == IPAddr::IPv4 )
if ( val.addr_val->GetFamily() == IPv4 )
return new Val(32, TYPE_COUNT);
else
return new Val(128, TYPE_COUNT);
@ -933,13 +933,13 @@ SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET)
SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET)
{
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
IPAddr a(IPv4, &addr, IPAddr::Network);
val.subnet_val = new IPPrefix(a, width);
}
SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET)
{
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
IPAddr a(IPv6, addr, IPAddr::Network);
val.subnet_val = new IPPrefix(a, width);
}
@ -953,6 +953,16 @@ SubNetVal::~SubNetVal()
delete val.subnet_val;
}
const IPAddr& SubNetVal::Prefix() const
{
return val.subnet_val->Prefix();
}
int SubNetVal::Width() const
{
return val.subnet_val->Length();
}
unsigned int SubNetVal::MemoryAllocation() const
{
return padded_sizeof(*this) + val.subnet_val->MemoryAllocation();
@ -978,7 +988,7 @@ IPAddr SubNetVal::Mask() const
uint32 m[4];
for ( unsigned int i = 0; i < 4; ++i )
m[i] = 0;
IPAddr rval(IPAddr::IPv6, m, IPAddr::Host);
IPAddr rval(IPv6, m, IPAddr::Host);
return rval;
}
@ -994,7 +1004,7 @@ IPAddr SubNetVal::Mask() const
while ( ++mp < m + 4 )
*mp = 0;
IPAddr rval(IPAddr::IPv6, m, IPAddr::Host);
IPAddr rval(IPv6, m, IPAddr::Host);
return rval;
}

View file

@ -513,10 +513,6 @@ protected:
#define UDP_PORT_MASK 0x20000
#define ICMP_PORT_MASK 0x30000
typedef enum {
TRANSPORT_UNKNOWN, TRANSPORT_TCP, TRANSPORT_UDP, TRANSPORT_ICMP,
} TransportProto;
class PortVal : public Val {
public:
// Constructors - both take the port number in host order.
@ -588,8 +584,8 @@ public:
Val* SizeVal() const;
const IPAddr& Prefix() const { return val.subnet_val->Prefix(); }
int Width() const { return val.subnet_val->Length(); }
const IPAddr& Prefix() const;
int Width() const;
IPAddr Mask() const;
bool Contains(const IPAddr& addr) const;

View file

@ -1949,7 +1949,7 @@ function is_local_interface%(ip: addr%) : bool
if ( ent )
{
for ( unsigned int len = 0; ent->h_addr_list[len]; ++len )
addrs.push_back(IPAddr(IPAddr::IPv4, (uint32*)ent->h_addr_list[len],
addrs.push_back(IPAddr(IPv4, (uint32*)ent->h_addr_list[len],
IPAddr::Network));
}
@ -1958,7 +1958,7 @@ function is_local_interface%(ip: addr%) : bool
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],
addrs.push_back(IPAddr(IPv6, (uint32*)ent->h_addr_list[len],
IPAddr::Network));
}
@ -2024,7 +2024,7 @@ function gethostname%(%) : string
## Returns: true if *a* is an IPv4 address, else false.
function is_v4_addr%(a: addr%): bool
%{
if ( a->AsAddr().GetFamily() == IPAddr::IPv4 )
if ( a->AsAddr().GetFamily() == IPv4 )
return new Val(1, TYPE_BOOL);
else
return new Val(0, TYPE_BOOL);
@ -2037,7 +2037,7 @@ function is_v4_addr%(a: addr%): bool
## Returns: true if *a* is an IPv6 address, else false.
function is_v6_addr%(a: addr%): bool
%{
if ( a->AsAddr().GetFamily() == IPAddr::IPv6 )
if ( a->AsAddr().GetFamily() == IPv6 )
return new Val(1, TYPE_BOOL);
else
return new Val(0, TYPE_BOOL);
@ -3522,7 +3522,7 @@ function lookup_location%(a: addr%) : geo_location
}
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
if ( geoip_v6 && a->AsAddr().GetFamily() == IPAddr::IPv6 )
if ( geoip_v6 && a->AsAddr().GetFamily() == IPv6 )
{
geoipv6_t ga;
a->AsAddr().CopyIPv6(&ga);
@ -3534,7 +3534,7 @@ function lookup_location%(a: addr%) : geo_location
else
#endif
if ( geoip && a->AsAddr().GetFamily() == IPAddr::IPv4 )
if ( geoip && a->AsAddr().GetFamily() == IPv4 )
{
const uint32* bytes;
a->AsAddr().GetBytes(&bytes);
@ -3617,7 +3617,7 @@ function lookup_asn%(a: addr%) : count
{
// IPv6 support showed up in 1.4.5.
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
if ( a->AsAddr().GetFamily() == IPAddr::IPv6 )
if ( a->AsAddr().GetFamily() == IPv6 )
{
geoipv6_t ga;
a->AsAddr().CopyIPv6(&ga);
@ -3626,7 +3626,7 @@ function lookup_asn%(a: addr%) : count
else
#endif
if ( a->AsAddr().GetFamily() == IPAddr::IPv4 )
if ( a->AsAddr().GetFamily() == IPv4 )
{
const uint32* bytes;
a->AsAddr().GetBytes(&bytes);
@ -5353,7 +5353,7 @@ function preserve_prefix%(a: addr, width: count%): any
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
if ( ip_anon )
{
if ( a->AsAddr().GetFamily() == IPAddr::IPv6 )
if ( a->AsAddr().GetFamily() == IPv6 )
builtin_error("preserve_prefix() not supported for IPv6 addresses");
else
{
@ -5382,7 +5382,7 @@ function preserve_subnet%(a: subnet%): any
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
if ( ip_anon )
{
if ( a->AsSubNet().Prefix().GetFamily() == IPAddr::IPv6 )
if ( a->AsSubNet().Prefix().GetFamily() == IPv6 )
builtin_error("preserve_subnet() not supported for IPv6 addresses");
else
{
@ -5418,7 +5418,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr
if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES )
builtin_error("anonymize_addr(): invalid ip addr anonymization class");
if ( a->AsAddr().GetFamily() == IPAddr::IPv6 )
if ( a->AsAddr().GetFamily() == IPv6 )
{
builtin_error("anonymize_addr() not supported for IPv6 addresses");
return 0;

View file

@ -862,11 +862,11 @@ threading::Value* Manager::ValToLogVal(Val* val, BroType* ty)
break;
case TYPE_SUBNET:
lval->val.subnet_val = new IPPrefix(val->AsSubNet());
val->AsSubNet().ConvertToThreadingValue(&lval->val.subnet_val);
break;
case TYPE_ADDR:
lval->val.addr_val = new IPAddr(val->AsAddr());
val->AsAddr().ConvertToThreadingValue(&lval->val.addr_val);
break;
case TYPE_DOUBLE:

View file

@ -242,4 +242,40 @@ bool WriterBackend::DoHeartbeat(double network_time, double current_time)
return true;
}
string WriterBackend::Render(const threading::Value::addr_t& addr) const
{
if ( addr.family == IPv4 )
{
char s[INET_ADDRSTRLEN];
if ( inet_ntop(AF_INET, &addr.in.in4, s, INET_ADDRSTRLEN) == NULL )
return "<bad IPv4 address conversion>";
else
return s;
}
else
{
char s[INET6_ADDRSTRLEN];
if ( inet_ntop(AF_INET6, &addr.in.in6, s, INET6_ADDRSTRLEN) == NULL )
return "<bad IPv6 address conversion>";
else
return s;
}
}
string WriterBackend::Render(const threading::Value::subnet_t& subnet) const
{
char l[16];
if ( subnet.prefix.family == IPv4 )
modp_uitoa10(subnet.length - 96, l);
else
modp_uitoa10(subnet.length, l);
string s = Render(subnet.prefix) + "/" + l;
return s;
}

View file

@ -158,6 +158,21 @@ public:
bool FinishedRotation(string new_name, string old_name,
double open, double close, bool terminating);
/** Helper method to render an IP address as a string.
*
* @param addr The address.
*
* @return An ASCII representation of the address.
*/
string Render(const threading::Value::addr_t& addr) const;
/** Helper method to render an subnet value as a string.
*
* @param addr The address.
*
* @return An ASCII representation of the address.
*/
string Render(const threading::Value::subnet_t& subnet) const;
protected:
/**

View file

@ -177,11 +177,11 @@ bool Ascii::DoWriteOne(ODesc* desc, Value* val, const Field* field)
break;
case TYPE_SUBNET:
desc->Add(*val->val.subnet_val);
desc->Add(Render(val->val.subnet_val));
break;
case TYPE_ADDR:
desc->Add(*val->val.addr_val);
desc->Add(Render(val->val.addr_val));
break;
case TYPE_TIME:

View file

@ -162,8 +162,8 @@ const char* fmt_conn_id(const IPAddr& src_addr, uint32 src_port,
const char* fmt_conn_id(const uint32* src_addr, uint32 src_port,
const uint32* dst_addr, uint32 dst_port)
{
IPAddr src(IPAddr::IPv6, src_addr, IPAddr::Network);
IPAddr dst(IPAddr::IPv6, dst_addr, IPAddr::Network);
IPAddr src(IPv6, src_addr, IPAddr::Network);
IPAddr dst(IPv6, dst_addr, IPAddr::Network);
return fmt_conn_id(src, src_port, dst, dst_port);
}

View file

@ -5,6 +5,13 @@
#include "config.h"
// Define first.
typedef enum {
TRANSPORT_UNKNOWN, TRANSPORT_TCP, TRANSPORT_UDP, TRANSPORT_ICMP,
} TransportProto;
typedef enum { IPv4, IPv6 } IPFamily;
#include <assert.h>
#include <sys/types.h>
@ -21,7 +28,6 @@
#include <netinet/ip_icmp.h>
#include "util.h"
#include "IPAddr.h"
#ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h>
@ -58,6 +64,8 @@ inline int seq_delta(uint32 a, uint32 b)
return int(a-b);
}
class IPAddr;
// 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);

View file

@ -30,12 +30,6 @@ Value::~Value()
&& present )
delete val.string_val;
if ( type == TYPE_ADDR && present )
delete val.addr_val;
if ( type == TYPE_SUBNET && present )
delete val.subnet_val;
if ( type == TYPE_TABLE && present )
{
for ( int i = 0; i < val.set_val.size; i++ )
@ -130,8 +124,8 @@ bool Value::Read(SerializationFormat* fmt)
if ( ! (fmt->Read(&val.port_val.port, "port") && fmt->Read(&proto, "proto") ) ) {
return false;
}
switch (proto) {
switch ( proto ) {
case 0:
val.port_val.proto = TRANSPORT_UNKNOWN;
break;
@ -147,20 +141,35 @@ bool Value::Read(SerializationFormat* fmt)
default:
return false;
}
return true;
}
case TYPE_SUBNET:
{
val.subnet_val = new IPPrefix;
return fmt->Read(val.subnet_val, "subnet");
}
case TYPE_ADDR:
{
val.addr_val = new IPAddr;
return fmt->Read(val.addr_val, "addr");
int family;
if ( ! fmt->Read(&family, "addr-family") )
return false;
switch ( family ) {
case 4:
val.addr_val.family = IPv4;
return fmt->Read(&val.addr_val.in.in4, "addr-in4");
case 6:
val.addr_val.family = IPv6;
return fmt->Read(&val.addr_val.in.in6, "addr-in6");
}
// Can't be reached.
abort();
}
case TYPE_SUBNET:
{
// FIXME.
}
case TYPE_DOUBLE:
@ -239,13 +248,27 @@ bool Value::Write(SerializationFormat* fmt) const
return fmt->Write(val.uint_val, "uint");
case TYPE_PORT:
return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto");
return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto");
case TYPE_SUBNET:
return fmt->Write(*val.subnet_val, "subnet");
return false; // FIXME.
case TYPE_ADDR:
return fmt->Write(*val.addr_val, "addr");
{
switch ( val.addr_val.family ) {
case IPv4:
return fmt->Write((int)4, "addr-family")
&& fmt->Write(val.addr_val.in.in4, "addr-in4");
case IPv6:
return fmt->Write((int)6, "addr-family")
&& fmt->Write(val.addr_val.in.in6, "addr-in6");
break;
}
// Can't be reached.
abort();
}
case TYPE_DOUBLE:
case TYPE_TIME:

View file

@ -2,10 +2,13 @@
#ifndef THREADING_SERIALIZATIONTYPES_H
#define THREADING_SERIALIZATIONTYPES_H
#include "../RemoteSerializer.h"
using namespace std;
#include "Type.h"
#include "net_util.h"
class SerializationFormat;
namespace threading {
/**
@ -62,6 +65,16 @@ struct Value {
typedef set_t vec_t;
struct port_t { bro_uint_t port; TransportProto proto; };
struct addr_t {
IPFamily family;
union {
struct in_addr in4;
struct in6_addr in6;
} in;
};
struct subnet_t { addr_t prefix; uint8_t length; };
/**
* This union is a subset of BroValUnion, including only the types we
* can log directly. See IsCompatibleType().
@ -73,8 +86,8 @@ struct Value {
double double_val;
set_t set_val;
vec_t vector_val;
IPAddr* addr_val;
IPPrefix* subnet_val;
addr_t addr_val;
subnet_t subnet_val;
string* string_val;
} val;
@ -120,6 +133,7 @@ struct Value {
static bool IsCompatibleType(BroType* t, bool atomic_only=false);
private:
friend class ::IPAddr;
Value(const Value& other) { } // Disabled.
};