mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Checkpoint after pass.
This commit is contained in:
parent
c0f05f57a7
commit
7458ebf385
35 changed files with 594 additions and 524 deletions
21
CHANGES
21
CHANGES
|
@ -1,14 +1,23 @@
|
||||||
|
|
||||||
|
2.0-57 | 2012-02-10 00:02:35 -0800
|
||||||
|
|
||||||
|
* Fix typos in the documentation. (Daniel Thayer)
|
||||||
|
|
||||||
|
* Fix compiler warning about Brofiler ctor init list order. (Jon Siwek)
|
||||||
|
|
||||||
|
* Fix missing optional field access in webapp signature_match handler. (Jon Siwek)
|
||||||
|
|
||||||
2.0-41 | 2012-02-03 04:10:53 -0500
|
2.0-41 | 2012-02-03 04:10:53 -0500
|
||||||
|
|
||||||
* Updates to the Software framework to simplify the API.
|
* Updates to the Software framework to simplify the API. (Bernhard
|
||||||
(Bernhard Amann)
|
Amann)
|
||||||
|
|
||||||
2.0-40 | 2012-02-03 01:55:27 -0800
|
2.0-40 | 2012-02-03 01:55:27 -0800
|
||||||
|
|
||||||
* Fix typos in documentation. (Daniel Thayer)
|
* Fix typos in documentation. (Daniel Thayer)
|
||||||
|
|
||||||
* Fix sorting of lines in Brofiler coverage.log. (Daniel Thayer)
|
* Fix sorting of lines in Brofiler coverage.log. (Daniel Thayer)
|
||||||
|
|
||||||
2.0-38 | 2012-01-31 11:50:53 -0800
|
2.0-38 | 2012-01-31 11:50:53 -0800
|
||||||
|
|
||||||
* Canonify sorting of lines in Brofiler coverage.log. (Daniel
|
* Canonify sorting of lines in Brofiler coverage.log. (Daniel
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.0-41
|
2.0-57
|
||||||
|
|
|
@ -22,7 +22,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
is a string of digits preceded by a ``+`` or ``-`` sign, e.g.
|
is a string of digits preceded by a ``+`` or ``-`` sign, e.g.
|
||||||
``-42`` or ``+5``. When using type inferencing use care so that the
|
``-42`` or ``+5``. When using type inferencing use care so that the
|
||||||
intended type is inferred, e.g. ``local size_difference = 0`` will
|
intended type is inferred, e.g. ``local size_difference = 0`` will
|
||||||
infer the :bro:type:`count` while ``local size_difference = +0``
|
infer :bro:type:`count`, while ``local size_difference = +0``
|
||||||
will infer :bro:type:`int`.
|
will infer :bro:type:`int`.
|
||||||
|
|
||||||
.. bro:type:: count
|
.. bro:type:: count
|
||||||
|
@ -32,7 +32,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
.. bro:type:: counter
|
.. bro:type:: counter
|
||||||
|
|
||||||
An alias to :bro:type:`count`
|
An alias to :bro:type:`count`.
|
||||||
|
|
||||||
.. TODO: is there anything special about this type?
|
.. TODO: is there anything special about this type?
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
A type used to hold character-string values which represent text.
|
A type used to hold character-string values which represent text.
|
||||||
String constants are created by enclosing text in double quotes (")
|
String constants are created by enclosing text in double quotes (")
|
||||||
and the backslash character (\) introduces escape sequences.
|
and the backslash character (\\) introduces escape sequences.
|
||||||
|
|
||||||
Note that Bro represents strings internally as a count and vector of
|
Note that Bro represents strings internally as a count and vector of
|
||||||
bytes rather than a NUL-terminated byte string (although string
|
bytes rather than a NUL-terminated byte string (although string
|
||||||
|
@ -135,7 +135,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
type color: enum { Red, White, Blue, };
|
type color: enum { Red, White, Blue, };
|
||||||
|
|
||||||
The last comma is after ``Blue`` is optional.
|
The last comma after ``Blue`` is optional.
|
||||||
|
|
||||||
.. bro:type:: timer
|
.. bro:type:: timer
|
||||||
|
|
||||||
|
@ -150,8 +150,8 @@ The Bro scripting language supports the following built-in types.
|
||||||
followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``.
|
followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``.
|
||||||
|
|
||||||
Ports can be compared for equality and also for ordering. When
|
Ports can be compared for equality and also for ordering. When
|
||||||
comparing order across transport-level protocols, ``/unknown`` <
|
comparing order across transport-level protocols, ``unknown`` <
|
||||||
``/tcp`` < ``/udp`` < ``icmp``, for example ``65535/tcp`` is smaller
|
``tcp`` < ``udp`` < ``icmp``, for example ``65535/tcp`` is smaller
|
||||||
than ``0/udp``.
|
than ``0/udp``.
|
||||||
|
|
||||||
.. bro:type:: addr
|
.. bro:type:: addr
|
||||||
|
@ -228,7 +228,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
global a: table[count] of table[addr, port] of string;
|
global a: table[count] of table[addr, port] of string;
|
||||||
|
|
||||||
which declared a table indexed by :bro:type:`count` and yielding
|
which declares a table indexed by :bro:type:`count` and yielding
|
||||||
another :bro:type:`table` which is indexed by an :bro:type:`addr`
|
another :bro:type:`table` which is indexed by an :bro:type:`addr`
|
||||||
and :bro:type:`port` to yield a :bro:type:`string`.
|
and :bro:type:`port` to yield a :bro:type:`string`.
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
||||||
be specified.
|
be specified.
|
||||||
|
|
||||||
To test for existence of field that is :bro:attr:`&optional`, use the
|
To test for existence of a field that is :bro:attr:`&optional`, use the
|
||||||
``?$`` operator:
|
``?$`` operator:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
@ -410,7 +410,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
print f, "hello, world";
|
print f, "hello, world";
|
||||||
close(f);
|
close(f);
|
||||||
|
|
||||||
Writing to files like this for logging usually isn't recommend, for better
|
Writing to files like this for logging usually isn't recommended, for better
|
||||||
logging support see :doc:`/logging`.
|
logging support see :doc:`/logging`.
|
||||||
|
|
||||||
.. bro:type:: func
|
.. bro:type:: func
|
||||||
|
@ -510,22 +510,22 @@ scripting language supports the following built-in attributes.
|
||||||
|
|
||||||
.. bro:attr:: &optional
|
.. bro:attr:: &optional
|
||||||
|
|
||||||
Allows record field to be missing. For example the type ``record {
|
Allows a record field to be missing. For example the type ``record {
|
||||||
a: int, b: port &optional }`` could be instantiated both as
|
a: int, b: port &optional }`` could be instantiated both as
|
||||||
singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``.
|
singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``.
|
||||||
|
|
||||||
.. bro:attr:: &default
|
.. bro:attr:: &default
|
||||||
|
|
||||||
Uses a default value for a record field or container elements. For
|
Uses a default value for a record field or container elements. For
|
||||||
example, ``table[int] of string &default="foo" }`` would create
|
example, ``table[int] of string &default="foo" }`` would create a
|
||||||
table that returns The :bro:type:`string` ``"foo"`` for any
|
table that returns the :bro:type:`string` ``"foo"`` for any
|
||||||
non-existing index.
|
non-existing index.
|
||||||
|
|
||||||
.. bro:attr:: &redef
|
.. bro:attr:: &redef
|
||||||
|
|
||||||
Allows for redefinition of initial object values. This is typically
|
Allows for redefinition of initial object values. This is typically
|
||||||
used with constants, for example, ``const clever = T &redef;`` would
|
used with constants, for example, ``const clever = T &redef;`` would
|
||||||
allow the constant to be redifined at some later point during script
|
allow the constant to be redefined at some later point during script
|
||||||
execution.
|
execution.
|
||||||
|
|
||||||
.. bro:attr:: &rotate_interval
|
.. bro:attr:: &rotate_interval
|
||||||
|
@ -534,7 +534,7 @@ scripting language supports the following built-in attributes.
|
||||||
|
|
||||||
.. bro:attr:: &rotate_size
|
.. bro:attr:: &rotate_size
|
||||||
|
|
||||||
Rotates af file after it has reached a given size in bytes.
|
Rotates a file after it has reached a given size in bytes.
|
||||||
|
|
||||||
.. bro:attr:: &add_func
|
.. bro:attr:: &add_func
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ export {
|
||||||
redef enum Notice::Type += {
|
redef enum Notice::Type += {
|
||||||
## This notice is generated if a packet filter is unable to be compiled.
|
## This notice is generated if a packet filter is unable to be compiled.
|
||||||
Compile_Failure,
|
Compile_Failure,
|
||||||
|
|
||||||
## This notice is generated if a packet filter is fails to install.
|
## This notice is generated if a packet filter is fails to install.
|
||||||
Install_Failure,
|
Install_Failure,
|
||||||
};
|
};
|
||||||
|
@ -26,18 +26,18 @@ export {
|
||||||
type Info: record {
|
type Info: record {
|
||||||
## The time at which the packet filter installation attempt was made.
|
## The time at which the packet filter installation attempt was made.
|
||||||
ts: time &log;
|
ts: time &log;
|
||||||
|
|
||||||
## This is a string representation of the node that applied this
|
## This is a string representation of the node that applied this
|
||||||
## packet filter. It's mostly useful in the context of dynamically
|
## packet filter. It's mostly useful in the context of dynamically
|
||||||
## changing filters on clusters.
|
## changing filters on clusters.
|
||||||
node: string &log &optional;
|
node: string &log &optional;
|
||||||
|
|
||||||
## The packet filter that is being set.
|
## The packet filter that is being set.
|
||||||
filter: string &log;
|
filter: string &log;
|
||||||
|
|
||||||
## Indicate if this is the filter set during initialization.
|
## Indicate if this is the filter set during initialization.
|
||||||
init: bool &log &default=F;
|
init: bool &log &default=F;
|
||||||
|
|
||||||
## Indicate if the filter was applied successfully.
|
## Indicate if the filter was applied successfully.
|
||||||
success: bool &log &default=T;
|
success: bool &log &default=T;
|
||||||
};
|
};
|
||||||
|
@ -48,16 +48,16 @@ export {
|
||||||
## The latter used to be default for Bro versions < 2.0. That has now
|
## The latter used to be default for Bro versions < 2.0. That has now
|
||||||
## changed however to enable port-independent protocol analysis.
|
## changed however to enable port-independent protocol analysis.
|
||||||
const all_packets = T &redef;
|
const all_packets = T &redef;
|
||||||
|
|
||||||
## Filter string which is unconditionally or'ed to the beginning of every
|
## Filter string which is unconditionally or'ed to the beginning of every
|
||||||
## dynamically built filter.
|
## dynamically built filter.
|
||||||
const unrestricted_filter = "" &redef;
|
const unrestricted_filter = "" &redef;
|
||||||
|
|
||||||
## Call this function to build and install a new dynamically built
|
## Call this function to build and install a new dynamically built
|
||||||
## packet filter.
|
## packet filter.
|
||||||
global install: function();
|
global install: function();
|
||||||
|
|
||||||
## This is where the default packet filter is stored and it should not
|
## This is where the default packet filter is stored and it should not
|
||||||
## normally be modified by users.
|
## normally be modified by users.
|
||||||
global default_filter = "<not set yet>";
|
global default_filter = "<not set yet>";
|
||||||
}
|
}
|
||||||
|
@ -89,22 +89,22 @@ function build_default_filter(): string
|
||||||
return "ip or not ip";
|
return "ip or not ip";
|
||||||
|
|
||||||
# Build filter dynamically.
|
# Build filter dynamically.
|
||||||
|
|
||||||
# First the capture_filter.
|
# First the capture_filter.
|
||||||
local cfilter = "";
|
local cfilter = "";
|
||||||
for ( id in capture_filters )
|
for ( id in capture_filters )
|
||||||
cfilter = combine_filters(cfilter, capture_filters[id], "or");
|
cfilter = combine_filters(cfilter, capture_filters[id], "or");
|
||||||
|
|
||||||
# Then the restrict_filter.
|
# Then the restrict_filter.
|
||||||
local rfilter = "";
|
local rfilter = "";
|
||||||
for ( id in restrict_filters )
|
for ( id in restrict_filters )
|
||||||
rfilter = combine_filters(rfilter, restrict_filters[id], "and");
|
rfilter = combine_filters(rfilter, restrict_filters[id], "and");
|
||||||
|
|
||||||
# Finally, join them into one filter.
|
# Finally, join them into one filter.
|
||||||
local filter = combine_filters(rfilter, cfilter, "and");
|
local filter = combine_filters(rfilter, cfilter, "and");
|
||||||
if ( unrestricted_filter != "" )
|
if ( unrestricted_filter != "" )
|
||||||
filter = combine_filters(unrestricted_filter, filter, "or");
|
filter = combine_filters(unrestricted_filter, filter, "or");
|
||||||
|
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,32 +114,32 @@ function install()
|
||||||
|
|
||||||
if ( ! precompile_pcap_filter(DefaultPcapFilter, default_filter) )
|
if ( ! precompile_pcap_filter(DefaultPcapFilter, default_filter) )
|
||||||
{
|
{
|
||||||
NOTICE([$note=Compile_Failure,
|
NOTICE([$note=Compile_Failure,
|
||||||
$msg=fmt("Compiling packet filter failed"),
|
$msg=fmt("Compiling packet filter failed"),
|
||||||
$sub=default_filter]);
|
$sub=default_filter]);
|
||||||
Reporter::fatal(fmt("Bad pcap filter '%s'", default_filter));
|
Reporter::fatal(fmt("Bad pcap filter '%s'", default_filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Do an audit log for the packet filter.
|
# Do an audit log for the packet filter.
|
||||||
local info: Info;
|
local info: Info;
|
||||||
info$ts = network_time();
|
info$ts = network_time();
|
||||||
# If network_time() is 0.0 we're at init time so use the wall clock.
|
# If network_time() is 0.0 we're at init time so use the wall clock.
|
||||||
if ( info$ts == 0.0 )
|
if ( info$ts == 0.0 )
|
||||||
{
|
{
|
||||||
info$ts = current_time();
|
info$ts = current_time();
|
||||||
info$init = T;
|
info$init = T;
|
||||||
}
|
}
|
||||||
info$filter = default_filter;
|
info$filter = default_filter;
|
||||||
|
|
||||||
if ( ! install_pcap_filter(DefaultPcapFilter) )
|
if ( ! install_pcap_filter(DefaultPcapFilter) )
|
||||||
{
|
{
|
||||||
# Installing the filter failed for some reason.
|
# Installing the filter failed for some reason.
|
||||||
info$success = F;
|
info$success = F;
|
||||||
NOTICE([$note=Install_Failure,
|
NOTICE([$note=Install_Failure,
|
||||||
$msg=fmt("Installing packet filter failed"),
|
$msg=fmt("Installing packet filter failed"),
|
||||||
$sub=default_filter]);
|
$sub=default_filter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( reading_live_traffic() || reading_traces() )
|
if ( reading_live_traffic() || reading_traces() )
|
||||||
Log::write(PacketFilter::LOG, info);
|
Log::write(PacketFilter::LOG, info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -601,10 +601,10 @@ function add_signature_file(sold: string, snew: string): string
|
||||||
}
|
}
|
||||||
|
|
||||||
## Signature files to read. Use ``redef signature_files += "foo.sig"`` to
|
## Signature files to read. Use ``redef signature_files += "foo.sig"`` to
|
||||||
## extend. Signature files will be searched relative to ``BRO_PATH``.
|
## extend. Signature files will be searched relative to ``BROPATH``.
|
||||||
global signature_files = "" &add_func = add_signature_file;
|
global signature_files = "" &add_func = add_signature_file;
|
||||||
|
|
||||||
## ``p0f`` fingerprint file to use. Will be searched relative to ``BRO_PATH``.
|
## ``p0f`` fingerprint file to use. Will be searched relative to ``BROPATH``.
|
||||||
const passive_fingerprint_file = "base/misc/p0f.fp" &redef;
|
const passive_fingerprint_file = "base/misc/p0f.fp" &redef;
|
||||||
|
|
||||||
# todo::testing to see if I can remove these without causing problems.
|
# todo::testing to see if I can remove these without causing problems.
|
||||||
|
|
|
@ -28,7 +28,7 @@ event signature_match(state: signature_state, msg: string, data: string) &priori
|
||||||
|
|
||||||
local c = state$conn;
|
local c = state$conn;
|
||||||
local si = Software::Info;
|
local si = Software::Info;
|
||||||
si = [$unparsed_version=msg, $host=c$id$resp_h, $host_p=c$id$resp_p, $software_type=WEB_APPLICATION];
|
si = [$name=msg, $unparsed_version=msg, $host=c$id$resp_h, $host_p=c$id$resp_p, $software_type=WEB_APPLICATION];
|
||||||
si$url = build_url_http(c$http);
|
si$url = build_url_http(c$http);
|
||||||
if ( c$id$resp_h in Software::tracked &&
|
if ( c$id$resp_h in Software::tracked &&
|
||||||
si$name in Software::tracked[c$id$resp_h] )
|
si$name in Software::tracked[c$id$resp_h] )
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// Main analyzer interface.
|
|
||||||
|
|
||||||
#ifndef ANALYZER_H
|
#ifndef ANALYZER_H
|
||||||
#define ANALYZER_H
|
#define ANALYZER_H
|
||||||
|
|
|
@ -154,7 +154,7 @@ void AnonymizeIPAddr_A50::init()
|
||||||
int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits)
|
int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("%s/%d\n",
|
DEBUG_MSG("%s/%d\n",
|
||||||
string(IPAddr(IPAddr::IPv4, &input, IPAddr::Network)).c_str(),
|
IPAddr(IPAddr::IPv4, &input, IPAddr::Network)->AsString().c_str(),
|
||||||
num_bits);
|
num_bits);
|
||||||
|
|
||||||
if ( ! before_anonymization )
|
if ( ! before_anonymization )
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
Brofiler::Brofiler()
|
Brofiler::Brofiler()
|
||||||
: delim('\t'), ignoring(0)
|
: ignoring(0), delim('\t')
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -727,7 +727,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
||||||
{
|
{
|
||||||
const uint32* const kp = AlignType<uint32>(kp0);
|
const uint32* const kp = AlignType<uint32>(kp0);
|
||||||
kp1 = reinterpret_cast<const char*>(kp+4);
|
kp1 = reinterpret_cast<const char*>(kp+4);
|
||||||
|
|
||||||
IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network);
|
IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network);
|
||||||
|
|
||||||
switch ( tag ) {
|
switch ( tag ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
pval = new AddrVal(addr);
|
pval = new AddrVal(addr);
|
||||||
|
|
22
src/Conn.cc
22
src/Conn.cc
|
@ -751,14 +751,14 @@ void Connection::Describe(ODesc* d) const
|
||||||
}
|
}
|
||||||
|
|
||||||
d->SP();
|
d->SP();
|
||||||
d->Add(string(orig_addr).c_str());
|
d->Add(orig_addr);
|
||||||
d->Add(":");
|
d->Add(":");
|
||||||
d->Add(ntohs(orig_port));
|
d->Add(ntohs(orig_port));
|
||||||
|
|
||||||
d->SP();
|
d->SP();
|
||||||
d->AddSP("->");
|
d->AddSP("->");
|
||||||
|
|
||||||
d->Add(string(resp_addr).c_str());
|
d->Add(resp_addr);
|
||||||
d->Add(":");
|
d->Add(":");
|
||||||
d->Add(ntohs(resp_port));
|
d->Add(ntohs(resp_port));
|
||||||
|
|
||||||
|
@ -781,13 +781,8 @@ bool Connection::DoSerialize(SerialInfo* info) const
|
||||||
|
|
||||||
// First we write the members which are needed to
|
// First we write the members which are needed to
|
||||||
// create the HashKey.
|
// create the HashKey.
|
||||||
uint32 orig_a[4];
|
if ( ! SERIALIZE(orig_addr) || ! SERIALIZE(resp_addr) )
|
||||||
uint32 resp_a[4];
|
return false;
|
||||||
orig_addr.CopyIPv6(orig_a);
|
|
||||||
resp_addr.CopyIPv6(resp_a);
|
|
||||||
for ( int j = 0; j < 4; ++j )
|
|
||||||
if ( ! SERIALIZE(orig_a[j]) || ! SERIALIZE(resp_a[j]) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) )
|
if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -834,14 +829,9 @@ bool Connection::DoUnserialize(UnserialInfo* info)
|
||||||
// Build the hash key first. Some of the recursive *::Unserialize()
|
// Build the hash key first. Some of the recursive *::Unserialize()
|
||||||
// functions may need it.
|
// functions may need it.
|
||||||
ConnID id;
|
ConnID id;
|
||||||
uint32 orig_a[4];
|
|
||||||
uint32 resp_a[4];
|
|
||||||
for ( int i = 0; i < 4; ++i )
|
|
||||||
if ( ! UNSERIALIZE(&orig_a[i]) || ! UNSERIALIZE(&resp_a[i]) )
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
orig_addr = IPAddr(IPAddr::IPv6, orig_a, IPAddr::Network);
|
if ( ! UNSERIALIZE(&orig_addr) || ! UNSERIALIZE(&resp_addr) )
|
||||||
resp_addr = IPAddr(IPAddr::IPv6, resp_a, IPAddr::Network);
|
goto error;
|
||||||
|
|
||||||
if ( ! UNSERIALIZE(&orig_port) || ! UNSERIALIZE(&resp_port) )
|
if ( ! UNSERIALIZE(&orig_port) || ! UNSERIALIZE(&resp_port) )
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -139,6 +139,7 @@ bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto)
|
||||||
{
|
{
|
||||||
if ( id->dst_addr.family() == IPAddr::IPv6 )
|
if ( id->dst_addr.family() == IPAddr::IPv6 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dce_rpc_endpoint_addr addr;
|
dce_rpc_endpoint_addr addr;
|
||||||
addr.addr = id->dst_addr;
|
addr.addr = id->dst_addr;
|
||||||
addr.port = ntohs(id->dst_port);
|
addr.port = ntohs(id->dst_port);
|
||||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
const char* uuid_to_string(const u_char* uuid_data);
|
const char* uuid_to_string(const u_char* uuid_data);
|
||||||
|
|
||||||
struct dce_rpc_endpoint_addr {
|
struct dce_rpc_endpoint_addr {
|
||||||
// All fields except addr are in host byteorder.
|
// All fields are in host byteorder.
|
||||||
IPAddr addr;
|
IPAddr addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
TransportProto proto;
|
TransportProto proto;
|
||||||
|
@ -65,7 +65,7 @@ struct dce_rpc_endpoint_addr {
|
||||||
{
|
{
|
||||||
static char buf[128];
|
static char buf[128];
|
||||||
snprintf(buf, sizeof(buf), "%s/%d/%s",
|
snprintf(buf, sizeof(buf), "%s/%d/%s",
|
||||||
string(addr).c_str(), port,
|
addr->AsString().c_str(), port,
|
||||||
proto == TRANSPORT_TCP ? "tcp" :
|
proto == TRANSPORT_TCP ? "tcp" :
|
||||||
(proto == TRANSPORT_UDP ? "udp" : "?"));
|
(proto == TRANSPORT_UDP ? "udp" : "?"));
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,9 @@ public:
|
||||||
// Returns nil if this was an address request.
|
// Returns nil if this was an address request.
|
||||||
const char* ReqHost() const { return req_host; }
|
const char* ReqHost() const { return req_host; }
|
||||||
uint32 ReqAddr() const { return req_addr; }
|
uint32 ReqAddr() const { return req_addr; }
|
||||||
const char* ReqStr() const
|
string ReqStr() const
|
||||||
{
|
{
|
||||||
return req_host ? req_host :
|
return req_host ? req_host : IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network);
|
||||||
string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListVal* Addrs();
|
ListVal* Addrs();
|
||||||
|
@ -199,8 +198,7 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
||||||
req_host = copy_string(req_buf);
|
req_host = copy_string(req_buf);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string s(req_buf);
|
IPAddr addr(req_buf);
|
||||||
IPAddr addr(s);
|
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
addr.GetBytes(&bytes);
|
addr.GetBytes(&bytes);
|
||||||
req_addr = *bytes; //FIXME: IPv6 support
|
req_addr = *bytes; //FIXME: IPv6 support
|
||||||
|
@ -226,8 +224,7 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
||||||
if ( newline )
|
if ( newline )
|
||||||
*newline = '\0';
|
*newline = '\0';
|
||||||
|
|
||||||
string s(buf);
|
IPAddr addr(buf);
|
||||||
IPAddr addr(s);
|
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
addr.GetBytes(&bytes);
|
addr.GetBytes(&bytes);
|
||||||
addrs[i] = *bytes; //FIXME IPv6 support
|
addrs[i] = *bytes; //FIXME IPv6 support
|
||||||
|
@ -350,13 +347,13 @@ void DNS_Mapping::Save(FILE* f) const
|
||||||
{
|
{
|
||||||
fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0,
|
fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0,
|
||||||
req_host ? req_host :
|
req_host ? req_host :
|
||||||
string(IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)).c_str(),
|
IPAddr(IPAddr::IPv4, &req_addr, IPAddr::Network)->AsString()->c_str(),
|
||||||
failed, (names && names[0]) ? names[0] : "*",
|
failed, (names && names[0]) ? names[0] : "*",
|
||||||
num_addrs);
|
num_addrs);
|
||||||
|
|
||||||
for ( int i = 0; i < num_addrs; ++i )
|
for ( int i = 0; i < num_addrs; ++i )
|
||||||
fprintf(f, "%s\n",
|
fprintf(f, "%s\n",
|
||||||
string(IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)).c_str());
|
IPAddr(IPAddr::IPv4, &addrs[i], IPAddr::Network)->AsString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -521,7 +518,7 @@ Val* DNS_Mgr::LookupAddr(uint32 addr)
|
||||||
|
|
||||||
case DNS_FORCE:
|
case DNS_FORCE:
|
||||||
reporter->FatalError("can't find DNS entry for %s in cache",
|
reporter->FatalError("can't find DNS entry for %s in cache",
|
||||||
string(IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)).c_str());
|
IPAddr(IPAddr::IPv4, &addr, IPAddr::Network)->AsString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case DNS_DEFAULT:
|
case DNS_DEFAULT:
|
||||||
|
@ -813,7 +810,7 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al)
|
||||||
for ( int i = 0; i < al->Length(); ++i )
|
for ( int i = 0; i < al->Length(); ++i )
|
||||||
{
|
{
|
||||||
const IPAddr* al_i = al->Index(i)->AsAddr();
|
const IPAddr* al_i = al->Index(i)->AsAddr();
|
||||||
fprintf(f, "%s%s", i > 0 ? "," : "", string(*al_i).c_str());
|
fprintf(f, "%s%s", i > 0 ? "," : "", al_i->AsString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/Desc.cc
12
src/Desc.cc
|
@ -157,6 +157,18 @@ void ODesc::Add(double d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ODesc::Add(const IPAddr& addr)
|
||||||
|
{
|
||||||
|
string s = addr->AsString();
|
||||||
|
AddBytes(s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ODesc::Add(const IPPrefix& prefix)
|
||||||
|
{
|
||||||
|
string s = prefix->AsString();
|
||||||
|
AddBytes(s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void ODesc::AddCS(const char* s)
|
void ODesc::AddCS(const char* s)
|
||||||
{
|
{
|
||||||
int n = strlen(s);
|
int n = strlen(s);
|
||||||
|
|
|
@ -73,6 +73,8 @@ public:
|
||||||
void Add(int64 i);
|
void Add(int64 i);
|
||||||
void Add(uint64 u);
|
void Add(uint64 u);
|
||||||
void Add(double d);
|
void Add(double d);
|
||||||
|
void Add(const IPAddr& addr);
|
||||||
|
void Add(const IPPrefix& prefix);
|
||||||
|
|
||||||
// Add s as a counted string.
|
// Add s as a counted string.
|
||||||
void AddCS(const char* s);
|
void AddCS(const char* s);
|
||||||
|
|
14
src/Expr.cc
14
src/Expr.cc
|
@ -837,8 +837,8 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const
|
||||||
{
|
{
|
||||||
uint32 a1[4];
|
uint32 a1[4];
|
||||||
uint32 a2[4];
|
uint32 a2[4];
|
||||||
v1->AsAddr()->CopyIPv6(a1);
|
v1->AsAddr().CopyIPv6(a1);
|
||||||
v2->AsAddr()->CopyIPv6(a2);
|
v2->AsAddr().CopyIPv6(a2);
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
switch ( tag ) {
|
switch ( tag ) {
|
||||||
|
@ -861,10 +861,10 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const
|
||||||
|
|
||||||
Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const
|
Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const
|
||||||
{
|
{
|
||||||
const IPPrefix* n1 = v1->AsSubNet();
|
const IPPrefix& n1 = v1->AsSubNet();
|
||||||
const IPPrefix* n2 = v2->AsSubNet();
|
const IPPrefix& n2 = v2->AsSubNet();
|
||||||
|
|
||||||
if ( *n1 == *n2 )
|
if ( n1 == n2 )
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
else
|
else
|
||||||
return new Val(0, TYPE_BOOL);
|
return new Val(0, TYPE_BOOL);
|
||||||
|
@ -1673,7 +1673,7 @@ Val* DivideExpr::AddrFold(Val* v1, Val* v2) const
|
||||||
else
|
else
|
||||||
mask = static_cast<uint32>(v2->InternalInt());
|
mask = static_cast<uint32>(v2->InternalInt());
|
||||||
|
|
||||||
return new SubNetVal(*v1->AsAddr(), mask);
|
return new SubNetVal(v1->AsAddr(), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* DivideExpr::DoSimplify()
|
Expr* DivideExpr::DoSimplify()
|
||||||
|
@ -4493,7 +4493,7 @@ Val* InExpr::Fold(Val* v1, Val* v2) const
|
||||||
|
|
||||||
if ( v1->Type()->Tag() == TYPE_ADDR &&
|
if ( v1->Type()->Tag() == TYPE_ADDR &&
|
||||||
v2->Type()->Tag() == TYPE_SUBNET )
|
v2->Type()->Tag() == TYPE_SUBNET )
|
||||||
return new Val(v2->AsSubNetVal()->Contains(*v1->AsAddr()), TYPE_BOOL);
|
return new Val(v2->AsSubNetVal().Contains(v1->AsAddr()), TYPE_BOOL);
|
||||||
|
|
||||||
TableVal* vt = v2->AsTableVal();
|
TableVal* vt = v2->AsTableVal();
|
||||||
if ( vt->Lookup(v1, false) )
|
if ( vt->Lookup(v1, false) )
|
||||||
|
|
|
@ -243,7 +243,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const
|
||||||
d->Add(Conn()->LastTime());
|
d->Add(Conn()->LastTime());
|
||||||
d->AddSP(")");
|
d->AddSP(")");
|
||||||
|
|
||||||
d->Add(string(Conn()->OrigAddr()).c_str());
|
d->Add(Conn()->OrigAddr());
|
||||||
d->Add(".");
|
d->Add(".");
|
||||||
d->Add(type);
|
d->Add(type);
|
||||||
d->Add(".");
|
d->Add(".");
|
||||||
|
@ -252,7 +252,7 @@ void ICMP_Analyzer::Describe(ODesc* d) const
|
||||||
d->SP();
|
d->SP();
|
||||||
d->AddSP("->");
|
d->AddSP("->");
|
||||||
|
|
||||||
d->Add(string(Conn()->RespAddr()).c_str());
|
d->Add(Conn()->RespAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
|
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
|
|
||||||
|
@ -7,7 +9,7 @@ const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
|
||||||
|
|
||||||
void IPAddr::Mask(int top_bits_to_keep)
|
void IPAddr::Mask(int top_bits_to_keep)
|
||||||
{
|
{
|
||||||
if ( top_bits_to_keep <=0 || top_bits_to_keep > 128 )
|
if ( top_bits_to_keep <= 0 || top_bits_to_keep > 128 )
|
||||||
{
|
{
|
||||||
reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep);
|
reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep);
|
||||||
return;
|
return;
|
||||||
|
@ -18,6 +20,7 @@ void IPAddr::Mask(int top_bits_to_keep)
|
||||||
|
|
||||||
int word = 3;
|
int word = 3;
|
||||||
int bits_to_chop = 128 - top_bits_to_keep;
|
int bits_to_chop = 128 - top_bits_to_keep;
|
||||||
|
|
||||||
while ( bits_to_chop >= 32 )
|
while ( bits_to_chop >= 32 )
|
||||||
{
|
{
|
||||||
tmp[word] = 0;
|
tmp[word] = 0;
|
||||||
|
@ -29,12 +32,13 @@ void IPAddr::Mask(int top_bits_to_keep)
|
||||||
w >>= bits_to_chop;
|
w >>= bits_to_chop;
|
||||||
w <<= bits_to_chop;
|
w <<= bits_to_chop;
|
||||||
tmp[word] = htonl(w);
|
tmp[word] = htonl(w);
|
||||||
|
|
||||||
memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr));
|
memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPAddr::ReverseMask(int top_bits_to_chop)
|
void IPAddr::ReverseMask(int top_bits_to_chop)
|
||||||
{
|
{
|
||||||
if ( top_bits_to_chop <=0 || top_bits_to_chop > 128 )
|
if ( top_bits_to_chop <= 0 || top_bits_to_chop > 128 )
|
||||||
{
|
{
|
||||||
reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop);
|
reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop);
|
||||||
return;
|
return;
|
||||||
|
@ -45,6 +49,7 @@ void IPAddr::ReverseMask(int top_bits_to_chop)
|
||||||
|
|
||||||
int word = 0;
|
int word = 0;
|
||||||
int bits_to_chop = top_bits_to_chop;
|
int bits_to_chop = top_bits_to_chop;
|
||||||
|
|
||||||
while ( bits_to_chop >= 32 )
|
while ( bits_to_chop >= 32 )
|
||||||
{
|
{
|
||||||
tmp[word] = 0;
|
tmp[word] = 0;
|
||||||
|
@ -56,20 +61,23 @@ void IPAddr::ReverseMask(int top_bits_to_chop)
|
||||||
w <<= bits_to_chop;
|
w <<= bits_to_chop;
|
||||||
w >>= bits_to_chop;
|
w >>= bits_to_chop;
|
||||||
tmp[word] = htonl(w);
|
tmp[word] = htonl(w);
|
||||||
|
|
||||||
memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr));
|
memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPAddr::Init(const std::string& s)
|
void IPAddr::Init(const std::string& s)
|
||||||
{
|
{
|
||||||
if ( s.find(':') == std::string::npos ) //IPv4
|
if ( s.find(':') == std::string::npos ) // IPv4.
|
||||||
{
|
{
|
||||||
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
||||||
|
|
||||||
if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 )
|
if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 )
|
||||||
{
|
{
|
||||||
reporter->Error("Bad IP address: %s", s.c_str());
|
reporter->Error("Bad IP address: %s", s.c_str());
|
||||||
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( inet_pton(AF_INET6, s.c_str(), in6.s6_addr) <=0 )
|
if ( inet_pton(AF_INET6, s.c_str(), in6.s6_addr) <=0 )
|
||||||
|
@ -80,11 +88,34 @@ void IPAddr::Init(const std::string& s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string IPAddr::AsString() const
|
||||||
|
{
|
||||||
|
if ( family() == IPv4 )
|
||||||
|
{
|
||||||
|
char s[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
|
if ( inet_ntop(AF_INET, &in6.s6_addr[12], s, INET_ADDRSTRLEN) == NULL )
|
||||||
|
return "<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 IPv64 address conversion";
|
||||||
|
else
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length)
|
IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length)
|
||||||
: prefix(in4), length(96 + length)
|
: prefix(in4), length(96 + length)
|
||||||
{
|
{
|
||||||
if ( length > 32 )
|
if ( length > 32 )
|
||||||
reporter->InternalError("Bad in4_addr IPPrefix length : %d", length);
|
reporter->InternalError("Bad in4_addr IPPrefix length : %d", length);
|
||||||
|
|
||||||
prefix.Mask(this->length);
|
prefix.Mask(this->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +124,7 @@ IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length)
|
||||||
{
|
{
|
||||||
if ( length > 128 )
|
if ( length > 128 )
|
||||||
reporter->InternalError("Bad in6_addr IPPrefix length : %d", length);
|
reporter->InternalError("Bad in6_addr IPPrefix length : %d", length);
|
||||||
|
|
||||||
prefix.Mask(this->length);
|
prefix.Mask(this->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,15 +136,19 @@ IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length)
|
||||||
if ( length > 32 )
|
if ( length > 32 )
|
||||||
reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d",
|
reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d",
|
||||||
length);
|
length);
|
||||||
|
|
||||||
this->length = length + 96;
|
this->length = length + 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( length > 128 )
|
if ( length > 128 )
|
||||||
reporter->InternalError("Bad IPAddr(v6) IPPrefix length : %d",
|
reporter->InternalError("Bad IPAddr(v6) IPPrefix length : %d",
|
||||||
length);
|
length);
|
||||||
|
|
||||||
this->length = length;
|
this->length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix.Mask(this->length);
|
prefix.Mask(this->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +157,22 @@ IPPrefix::IPPrefix(const std::string& s, uint8_t length)
|
||||||
{
|
{
|
||||||
if ( prefix.family() == IPAddr::IPv4 && length > 32 )
|
if ( prefix.family() == IPAddr::IPv4 && length > 32 )
|
||||||
reporter->InternalError("Bad string IPPrefix length : %d", length);
|
reporter->InternalError("Bad string IPPrefix length : %d", length);
|
||||||
|
|
||||||
else if ( prefix.family() == IPAddr::IPv6 && length > 128 )
|
else if ( prefix.family() == IPAddr::IPv6 && length > 128 )
|
||||||
reporter->InternalError("Bad string IPPrefix length : %d", length);
|
reporter->InternalError("Bad string IPPrefix length : %d", length);
|
||||||
|
|
||||||
prefix.Mask(this->length);
|
prefix.Mask(this->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string IPPrefix::AsString() const
|
||||||
|
{
|
||||||
|
char l[16];
|
||||||
|
|
||||||
|
if ( prefix.family() == IPAddr::IPv4 )
|
||||||
|
modp_uitoa10(length - 96, l);
|
||||||
|
else
|
||||||
|
modp_uitoa10(length, l);
|
||||||
|
|
||||||
|
return prefix->AsString() +"/" + l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
505
src/IPAddr.h
505
src/IPAddr.h
|
@ -1,3 +1,4 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#ifndef IPADDR_H
|
#ifndef IPADDR_H
|
||||||
#define IPADDR_H
|
#define IPADDR_H
|
||||||
|
@ -11,97 +12,108 @@
|
||||||
|
|
||||||
typedef in_addr in4_addr;
|
typedef in_addr in4_addr;
|
||||||
|
|
||||||
/// Class storing both IPv4 and IPv6 addresses.
|
/**
|
||||||
|
* Class storing both IPv4 and IPv6 addresses.
|
||||||
|
*/
|
||||||
class IPAddr
|
class IPAddr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Address family.
|
/**
|
||||||
|
* Address family.
|
||||||
|
*/
|
||||||
enum Family { IPv4, IPv6 };
|
enum Family { IPv4, IPv6 };
|
||||||
|
|
||||||
/// Byte order.
|
/**
|
||||||
|
* Byte order.
|
||||||
|
*/
|
||||||
enum ByteOrder { Host, Network };
|
enum ByteOrder { Host, Network };
|
||||||
|
|
||||||
/// Constructs the unspecified IPv6 address (all 128 bits zeroed).
|
/**
|
||||||
|
* Constructs the unspecified IPv6 address (all 128 bits zeroed).
|
||||||
|
*/
|
||||||
IPAddr()
|
IPAddr()
|
||||||
{
|
{
|
||||||
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs an address instance from an IPv4 address.
|
/**
|
||||||
///
|
* Constructs an address instance from an IPv4 address.
|
||||||
/// @param in6 The IPv6 address.
|
*
|
||||||
|
* @param in6 The IPv6 address.
|
||||||
|
*/
|
||||||
IPAddr(const in4_addr& in4)
|
IPAddr(const in4_addr& in4)
|
||||||
{
|
{
|
||||||
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
||||||
memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr));
|
memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs an address instance from an IPv6 address.
|
/**
|
||||||
///
|
* Constructs an address instance from an IPv6 address.
|
||||||
/// @param in6 The IPv6 address.
|
*
|
||||||
|
* @param in6 The IPv6 address.
|
||||||
|
*/
|
||||||
IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { }
|
IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { }
|
||||||
|
|
||||||
/// Constructs an address instance from a string representation.
|
/**
|
||||||
///
|
* 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.
|
* @param s String containing an IP address as either a dotted IPv4
|
||||||
|
* address or a hex IPv6 address.
|
||||||
|
*/
|
||||||
IPAddr(const std::string& s)
|
IPAddr(const std::string& s)
|
||||||
{
|
{
|
||||||
Init(s);
|
Init(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs an address instance from a string representation.
|
/**
|
||||||
///
|
* 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.
|
* @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)
|
IPAddr(const BroString& s)
|
||||||
{
|
{
|
||||||
Init(s.CheckString());
|
Init(s.CheckString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs an address instance from a raw byte representation.
|
/**
|
||||||
///
|
* Constructs an address instance from a raw byte representation.
|
||||||
/// @param family The address family.
|
*
|
||||||
///
|
* @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
|
* @param bytes A pointer to the raw byte representation. This must point
|
||||||
/// IPv6.
|
* 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.
|
* @param order Indicates whether the raw representation pointed to
|
||||||
IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
|
* by \a bytes is stored in network or host order.
|
||||||
{
|
*/
|
||||||
if ( family == IPv4 )
|
IPAddr(Family family, const uint32_t* bytes, ByteOrder order);
|
||||||
{
|
|
||||||
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
|
||||||
memcpy(&in6.s6_addr[12], bytes, sizeof(uint32_t));
|
|
||||||
if ( order == Host )
|
|
||||||
{
|
|
||||||
uint32_t* p = (uint32_t*) &in6.s6_addr[12];
|
|
||||||
*p = htonl(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(in6.s6_addr, bytes, sizeof(in6.s6_addr));
|
|
||||||
if ( order == Host )
|
|
||||||
{
|
|
||||||
for ( unsigned int i = 0; i < 4; ++ i)
|
|
||||||
{
|
|
||||||
uint32_t* p = (uint32_t*) &in6.s6_addr[i*4];
|
|
||||||
*p = htonl(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy constructor.
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
IPAddr(const IPAddr& other) : in6(other.in6) { };
|
IPAddr(const IPAddr& other) : in6(other.in6) { };
|
||||||
|
|
||||||
/// Destructor.
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
~IPAddr() { };
|
~IPAddr() { };
|
||||||
|
|
||||||
/// Returns the address' family.
|
/**
|
||||||
|
* Returns the address' family.
|
||||||
|
*/
|
||||||
Family family() const
|
Family family() const
|
||||||
{
|
{
|
||||||
if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 )
|
if ( memcmp(in6.s6_addr, v4_mapped_prefix, 12) == 0 )
|
||||||
|
@ -110,23 +122,14 @@ public:
|
||||||
return IPv6;
|
return IPv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the address represents a loopback device.
|
/**
|
||||||
bool IsLoopback() const
|
* Returns true if the address represents a loopback device.
|
||||||
{
|
*/
|
||||||
if ( family() == IPv4 )
|
bool IsLoopback() const;
|
||||||
return in6.s6_addr[12] == 127;
|
|
||||||
else
|
|
||||||
return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0)
|
|
||||||
&& (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0)
|
|
||||||
&& (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0)
|
|
||||||
&& (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0)
|
|
||||||
&& (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0)
|
|
||||||
&& (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0)
|
|
||||||
&& (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0)
|
|
||||||
&& (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the address represents a multicast address.
|
/**
|
||||||
|
* Returns true if the address represents a multicast address.
|
||||||
|
*/
|
||||||
bool IsMulticast() const
|
bool IsMulticast() const
|
||||||
{
|
{
|
||||||
if ( family() == IPv4 )
|
if ( family() == IPv4 )
|
||||||
|
@ -135,27 +138,31 @@ public:
|
||||||
return in6.s6_addr[0] == 0xff;
|
return in6.s6_addr[0] == 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the address represents a broadcast address.
|
/**
|
||||||
|
* Returns true if the address represents a broadcast address.
|
||||||
|
*/
|
||||||
bool IsBroadcast() const
|
bool IsBroadcast() const
|
||||||
{
|
{
|
||||||
if ( family() == IPv4 )
|
if ( family() == IPv4 )
|
||||||
return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff)
|
return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff)
|
||||||
&& (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff));
|
&& (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff));
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the raw byte representation of the address.
|
/**
|
||||||
///
|
* 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.
|
* @param bytes The pointer to which \a bytes points will be set to
|
||||||
/// The return value indicates how many 32-bit words are valid starting at
|
* the address of the raw representation in network-byte order.
|
||||||
/// that address. The pointer will be valid as long as the address instance
|
* The return value indicates how many 32-bit words are valid starting at
|
||||||
/// exists.
|
* 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.
|
* @return The number of 32-bit words the raw representation uses. This
|
||||||
int GetBytes(uint32_t** bytes)
|
* will be 1 for an IPv4 address and 4 for an IPv6 address.
|
||||||
|
*/
|
||||||
|
int GetBytes(const uint32_t* const * bytes) const
|
||||||
{
|
{
|
||||||
if ( family() == IPv4 )
|
if ( family() == IPv4 )
|
||||||
{
|
{
|
||||||
|
@ -169,51 +176,45 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetBytes(const uint32_t** bytes) const
|
/**
|
||||||
{
|
* Retrieves a copy of the IPv6 raw byte representation of the address.
|
||||||
if ( family() == IPv4 )
|
* If the internal address is IPv4, then the copied bytes use the
|
||||||
{
|
* IPv4 to IPv6 address mapping to return a full 16 bytes.
|
||||||
*bytes = (uint32_t*) &in6.s6_addr[12];
|
*
|
||||||
return 1;
|
* @param bytes The pointer to a memory location in which the
|
||||||
}
|
* raw bytes of the address are to be copied in network byte-order.
|
||||||
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
|
void CopyIPv6(uint32_t* bytes) const
|
||||||
{
|
{
|
||||||
memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr));
|
memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Masks out lower bits of the address.
|
/**
|
||||||
///
|
* 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
|
* @param top_bits_to_keep The number of bits \a not to mask out,
|
||||||
/// interpreted relative to the IPv6 bit width, even if the address
|
* counting from the highest order bit. The value is always
|
||||||
/// is IPv4. That means if compute ``192.168.1.2/16``, you need to
|
* interpreted relative to the IPv6 bit width, even if the address
|
||||||
/// pass in 112 (i.e., 96 + 16). The value must be in the range from
|
* is IPv4. That means if compute ``192.168.1.2/16``, you need to
|
||||||
/// 0 to 128.
|
* 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);
|
void Mask(int top_bits_to_keep);
|
||||||
|
|
||||||
/// Masks out top bits of the address.
|
/**
|
||||||
///
|
* 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
|
* @param top_bits_to_chop The number of bits to mask out, counting
|
||||||
/// to the IPv6 bit width, even if the address is IPv4. So to mask out
|
* from the highest order bit. The value is always interpreted relative
|
||||||
/// the first 16 bits of an IPv4 address, pass in 112 (i.e., 96 + 16).
|
* to the IPv6 bit width, even if the address is IPv4. So to mask out
|
||||||
/// The value must be in the range from 0 to 128.
|
* 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);
|
void ReverseMask(int top_bits_to_chop);
|
||||||
|
|
||||||
/// Assignment operator.
|
/**
|
||||||
|
* Assignment operator.
|
||||||
|
*/
|
||||||
IPAddr& operator=(const IPAddr& other)
|
IPAddr& operator=(const IPAddr& other)
|
||||||
{
|
{
|
||||||
// No self-assignment check here because it's correct without it and
|
// No self-assignment check here because it's correct without it and
|
||||||
|
@ -222,30 +223,22 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a string representation of the address. IPv4 addresses
|
/**
|
||||||
/// will be returned in dotted representation, IPv6 addresses in
|
* Returns a string representation of the address. IPv4 addresses
|
||||||
/// compressed hex.
|
* will be returned in dotted representation, IPv6 addresses in
|
||||||
operator std::string() const
|
* compressed hex.
|
||||||
{
|
*/
|
||||||
if ( family() == IPv4 )
|
string AsString() const;
|
||||||
{
|
|
||||||
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 IPv64 address conversion";
|
|
||||||
else
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Comparison operator for IP address.
|
/**
|
||||||
|
* Returns a string representation of the address. This returns the
|
||||||
|
* same as AsString().
|
||||||
|
*/
|
||||||
|
operator std::string() const { return AsString(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator for IP address.
|
||||||
|
*/
|
||||||
friend bool operator==(const IPAddr& addr1, const IPAddr& addr2)
|
friend bool operator==(const IPAddr& addr1, const IPAddr& addr2)
|
||||||
{
|
{
|
||||||
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0;
|
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0;
|
||||||
|
@ -256,9 +249,11 @@ public:
|
||||||
return ! (addr1 == 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
|
* Comparison operator IP addresses. This defines a well-defined order for
|
||||||
/// their numerical values.
|
* IP addresses. However, the order does not necessarily correspond to
|
||||||
|
* their numerical values.
|
||||||
|
*/
|
||||||
friend bool operator<(const IPAddr& addr1, const IPAddr& addr2)
|
friend bool operator<(const IPAddr& addr1, const IPAddr& addr2)
|
||||||
{
|
{
|
||||||
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0;
|
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0;
|
||||||
|
@ -267,75 +262,145 @@ public:
|
||||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
in6_addr in6; // IPv6 or v4-to-v6-mapped address
|
/**
|
||||||
static const uint8_t v4_mapped_prefix[12]; // top 96 bits of v4-mapped-addr
|
* Initializes an address instance from a string representation.
|
||||||
|
*
|
||||||
/// 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.
|
||||||
/// @param s String containing an IP address as either a dotted IPv4
|
*/
|
||||||
/// address or a hex IPv6 address.
|
|
||||||
void Init(const std::string& s);
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Class storing both IPv4 and IPv6 prefixes
|
inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
|
||||||
/// (i.e., \c 192.168.1.1/16 and \c FD00::/8.
|
{
|
||||||
|
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 ( family() == IPv4 )
|
||||||
|
return in6.s6_addr[12] == 127;
|
||||||
|
|
||||||
|
else
|
||||||
|
return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0)
|
||||||
|
&& (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0)
|
||||||
|
&& (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0)
|
||||||
|
&& (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0)
|
||||||
|
&& (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0)
|
||||||
|
&& (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0)
|
||||||
|
&& (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0)
|
||||||
|
&& (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class storing both IPv4 and IPv6 prefixes
|
||||||
|
* (i.e., \c 192.168.1.1/16 and \c FD00::/8.
|
||||||
|
*/
|
||||||
class IPPrefix
|
class IPPrefix
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructs a prefix instance from an IPv4 address and a prefix
|
/**
|
||||||
/// length.
|
* Constructs a prefix instance from an IPv4 address and a prefix
|
||||||
///
|
* length.
|
||||||
/// @param in4 The IPv4 address.
|
*
|
||||||
///
|
* @param in4 The IPv4 address.
|
||||||
/// @param length The prefix length in the range from 0 to 32.
|
*
|
||||||
|
* @param length The prefix length in the range from 0 to 32.
|
||||||
|
*/
|
||||||
IPPrefix(const in4_addr& in4, uint8_t length);
|
IPPrefix(const in4_addr& in4, uint8_t length);
|
||||||
|
|
||||||
/// Constructs a prefix instance from an IPv6 address and a prefix
|
/**
|
||||||
/// length.
|
* Constructs a prefix instance from an IPv6 address and a prefix
|
||||||
///
|
* length.
|
||||||
/// @param in6 The IPv6 address.
|
*
|
||||||
///
|
* @param in6 The IPv6 address.
|
||||||
/// @param length The prefix length in the range from 0 to 128.
|
*
|
||||||
|
* @param length The prefix length in the range from 0 to 128.
|
||||||
|
*/
|
||||||
IPPrefix(const in6_addr& in6, uint8_t length);
|
IPPrefix(const in6_addr& in6, uint8_t length);
|
||||||
|
|
||||||
/// Constructs a prefix instance from an IPAddr object and prefix length.
|
/**
|
||||||
///
|
* Constructs a prefix instance from an IPAddr object and prefix length.
|
||||||
/// @param addr The IP address.
|
*
|
||||||
///
|
* @param addr The IP address.
|
||||||
/// @param length The prefix length in the range from 0 to 128
|
*
|
||||||
|
* @param length The prefix length in the range from 0 to 128
|
||||||
|
*/
|
||||||
IPPrefix(const IPAddr& addr, uint8_t length);
|
IPPrefix(const IPAddr& addr, uint8_t length);
|
||||||
|
|
||||||
/// Constructs a prefix instance from IP string representation and length.
|
/**
|
||||||
///
|
* Constructs a prefix instance from IP string representation and length.
|
||||||
/// @param s String containing an IP address as either a dotted IPv4
|
*
|
||||||
/// address or a hex IPv6 address.
|
* @param s String containing an IP address as either a dotted IPv4
|
||||||
///
|
* address or a hex IPv6 address.
|
||||||
/// @param length The prefix length in the range from 0 to 128
|
*
|
||||||
|
* @param length The prefix length in the range from 0 to 128
|
||||||
|
*/
|
||||||
IPPrefix(const std::string& s, uint8_t length);
|
IPPrefix(const std::string& s, uint8_t length);
|
||||||
|
|
||||||
/// Copy constructor.
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
IPPrefix(const IPPrefix& other)
|
IPPrefix(const IPPrefix& other)
|
||||||
: prefix(other.prefix), length(other.length) { }
|
: prefix(other.prefix), length(other.length) { }
|
||||||
|
|
||||||
/// Destructor.
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
~IPPrefix() { }
|
~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.
|
* 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; }
|
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.
|
* 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
|
uint8_t Length() const
|
||||||
{
|
{
|
||||||
return prefix.family() == IPAddr::IPv4 ? length - 96 : length;
|
return prefix.family() == 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).
|
* 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; }
|
uint8_t LengthIPv6() const { return length; }
|
||||||
|
|
||||||
/// Assignment operator.
|
/**
|
||||||
|
* Assignment operator.
|
||||||
|
*/
|
||||||
IPPrefix& operator=(const IPPrefix& other)
|
IPPrefix& operator=(const IPPrefix& other)
|
||||||
{
|
{
|
||||||
// No self-assignment check here because it's correct without it and
|
// No self-assignment check here because it's correct without it and
|
||||||
|
@ -345,43 +410,45 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a string representation of the prefix. IPv4 addresses
|
/**
|
||||||
/// will be returned in dotted representation, IPv6 addresses in
|
* Returns a string representation of the prefix. IPv4 addresses
|
||||||
/// compressed hex.
|
* will be returned in dotted representation, IPv6 addresses in
|
||||||
operator std::string() const
|
* compressed hex.
|
||||||
{
|
*/
|
||||||
char l[16];
|
string AsString() const;
|
||||||
if ( prefix.family() == IPAddr::IPv4 )
|
|
||||||
modp_uitoa10(length - 96, l);
|
operator std::string() const { return AsString(); }
|
||||||
else
|
|
||||||
modp_uitoa10(length, l);
|
|
||||||
return std::string(prefix).append("/").append(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
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:
|
private:
|
||||||
IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask().
|
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.
|
uint8_t length; // The bit length of the prefix relative to full IPv6 addr.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Comparison operator for IP prefix.
|
|
||||||
inline 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.
|
|
||||||
inline 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -199,28 +199,21 @@ bool LogVal::Read(SerializationFormat* fmt)
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
{
|
{
|
||||||
uint32 net[5];
|
IPPrefix prefix;
|
||||||
if ( ! (fmt->Read(&net[0], "net0") &&
|
if ( ! fmt->Read(&prefix), "subnet" )
|
||||||
fmt->Read(&net[1], "net1") &&
|
|
||||||
fmt->Read(&net[2], "net2") &&
|
|
||||||
fmt->Read(&net[3], "net3") &&
|
|
||||||
fmt->Read(&net[4], "width")) )
|
|
||||||
return false;
|
return false;
|
||||||
val.subnet_val = new IPPrefix(IPAddr(IPAddr::IPv6, net,
|
|
||||||
IPAddr::Network), net[4]);
|
val.subnet_val = new IPPrefix(prefix);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
{
|
{
|
||||||
uint32 addr[4];
|
IPAddr addr;
|
||||||
if ( ! (fmt->Read(&addr[0], "addr0") &&
|
if ( ! fmt->Read(&addr), "net" )
|
||||||
fmt->Read(&addr[1], "addr1") &&
|
|
||||||
fmt->Read(&addr[2], "addr2") &&
|
|
||||||
fmt->Read(&addr[3], "addr3")) )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network);
|
val.addr_val = new IPAddr(prefix);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,25 +294,11 @@ bool LogVal::Write(SerializationFormat* fmt) const
|
||||||
return fmt->Write(val.uint_val, "uint");
|
return fmt->Write(val.uint_val, "uint");
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
{
|
return fmt->Write(*val.subnet_val, "subnet");
|
||||||
uint32 net[4];
|
|
||||||
val.subnet_val->Prefix().CopyIPv6(net);
|
|
||||||
return fmt->Write(net[0], "net0") &&
|
|
||||||
fmt->Write(net[1], "net1") &&
|
|
||||||
fmt->Write(net[2], "net2") &&
|
|
||||||
fmt->Write(net[3], "net3") &&
|
|
||||||
fmt->Write((uint32)val.subnet_val->Length(), "width");
|
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
{
|
return fmt->Write(*val.addr_val, "addr");
|
||||||
uint32 addr[4];
|
|
||||||
val.addr_val->CopyIPv6(addr);
|
|
||||||
return fmt->Write(addr[0], "addr0") &&
|
|
||||||
fmt->Write(addr[1], "addr1") &&
|
|
||||||
fmt->Write(addr[2], "addr2") &&
|
|
||||||
fmt->Write(addr[3], "addr3");
|
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
case TYPE_TIME:
|
case TYPE_TIME:
|
||||||
|
@ -1086,12 +1065,12 @@ LogVal* LogMgr::ValToLogVal(Val* val, BroType* ty)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
lval->val.subnet_val = new IPPrefix(*val->AsSubNet());
|
lval->val.subnet_val = new IPPrefix(val->AsSubNet());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
{
|
{
|
||||||
lval->val.addr_val = new IPAddr(*val->AsAddr());
|
lval->val.addr_val = new IPAddr(val->AsAddr());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,11 +166,11 @@ bool LogWriterAscii::DoWriteOne(ODesc* desc, LogVal* val, const LogField* field)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
desc->Add(string(*val->val.subnet_val).c_str());
|
desc->Add(*val->val.subnet_val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
desc->Add(string(*val->val.addr_val).c_str());
|
desc->Add(*val->val.addr_val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_TIME:
|
case TYPE_TIME:
|
||||||
|
|
|
@ -42,12 +42,12 @@ void* PrefixTable::Insert(const Val* value, void* data)
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
return Insert(*value->AsAddr(), 128, data);
|
return Insert(value->AsAddr(), 128, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
return Insert(value->AsSubNet()->Prefix(),
|
return Insert(value->AsSubNet().Prefix(),
|
||||||
value->AsSubNet()->LengthIPv6(), data);
|
value->AsSubNet().LengthIPv6(), data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -76,12 +76,12 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
return Lookup(*value->AsAddr(), 128, exact);
|
return Lookup(value->AsAddr(), 128, exact);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
return Lookup(value->AsSubNet()->Prefix(),
|
return Lookup(value->AsSubNet().Prefix(),
|
||||||
value->AsSubNet()->LengthIPv6(), exact);
|
value->AsSubNet().LengthIPv6(), exact);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -115,12 +115,12 @@ void* PrefixTable::Remove(const Val* value)
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
return Remove(*value->AsAddr(), 128);
|
return Remove(value->AsAddr(), 128);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
case TYPE_SUBNET:
|
||||||
return Remove(value->AsSubNet()->Prefix(),
|
return Remove(value->AsSubNet().Prefix(),
|
||||||
value->AsSubNet()->LengthIPv6());
|
value->AsSubNet().LengthIPv6());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -155,20 +155,6 @@ void Reporter::WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* add
|
||||||
delete vl;
|
delete vl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...)
|
|
||||||
{
|
|
||||||
val_list* vl = new val_list(2);
|
|
||||||
vl->append(new AddrVal(orig));
|
|
||||||
vl->append(new AddrVal(resp));
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt_name);
|
|
||||||
DoLog("weird", flow_weird, stderr, 0, vl, false, false, 0, fmt_name, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
delete vl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...)
|
void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...)
|
||||||
{
|
{
|
||||||
val_list* vl = new val_list(2);
|
val_list* vl = new val_list(2);
|
||||||
|
@ -198,11 +184,6 @@ void Reporter::Weird(Val* conn_val, const char* name, const char* addl)
|
||||||
WeirdHelper(conn_weird, conn_val, addl, "%s", name);
|
WeirdHelper(conn_weird, conn_val, addl, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::Weird(const uint32* orig, const uint32* resp, const char* name)
|
|
||||||
{
|
|
||||||
WeirdFlowHelper(orig, resp, "%s", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
|
void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
|
||||||
{
|
{
|
||||||
WeirdFlowHelper(orig, resp, "%s", name);
|
WeirdFlowHelper(orig, resp, "%s", name);
|
||||||
|
|
|
@ -75,7 +75,6 @@ public:
|
||||||
void Weird(const char* name); // Raises net_weird().
|
void Weird(const char* name); // Raises net_weird().
|
||||||
void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_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(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().
|
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
|
// Syslog a message. This methods does nothing if we're running
|
||||||
|
@ -123,7 +122,6 @@ private:
|
||||||
// The order if addl, name needs to be like that since fmt_name can
|
// The order if addl, name needs to be like that since fmt_name can
|
||||||
// contain format specifiers
|
// contain format specifiers
|
||||||
void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...);
|
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, ...);
|
void WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...);
|
||||||
|
|
||||||
int errors;
|
int errors;
|
||||||
|
|
|
@ -1070,14 +1070,16 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to)
|
||||||
{
|
{
|
||||||
const uint32* n;
|
const uint32* n;
|
||||||
uint32 m[4];
|
uint32 m[4];
|
||||||
v->AsSubNet()->Prefix().GetBytes(&n);
|
v->AsSubNet().Prefix().GetBytes(&n);
|
||||||
v->AsSubNetVal()->Mask().CopyIPv6(m);
|
v->AsSubNetVal().Mask().CopyIPv6(m);
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < 4; ++i )
|
for ( unsigned int i = 0; i < 4; ++i )
|
||||||
m[i] = ntohl(m[i]);
|
m[i] = ntohl(m[i]);
|
||||||
|
|
||||||
bool is_v4_mask = m[0] == 0xffffffff &&
|
bool is_v4_mask = m[0] == 0xffffffff &&
|
||||||
m[1] == m[0] && m[2] == m[0];
|
m[1] == m[0] && m[2] == m[0];
|
||||||
|
|
||||||
if ( v->AsSubNet()->Prefix().family() == IPAddr::IPv4 &&
|
if ( v->AsSubNet().Prefix().family() == IPAddr::IPv4 &&
|
||||||
is_v4_mask )
|
is_v4_mask )
|
||||||
{
|
{
|
||||||
mval->val = ntohl(*n);
|
mval->val = ntohl(*n);
|
||||||
|
|
|
@ -50,23 +50,24 @@ void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
|
||||||
// SSH-<protocolmajor>.<protocolminor>-<version>\n
|
// SSH-<protocolmajor>.<protocolminor>-<version>\n
|
||||||
//
|
//
|
||||||
// We're interested in the "version" part here.
|
// We're interested in the "version" part here.
|
||||||
|
|
||||||
if ( length < 4 || memcmp(line, "SSH-", 4) != 0 )
|
if ( length < 4 || memcmp(line, "SSH-", 4) != 0 )
|
||||||
{
|
{
|
||||||
Weird("malformed_ssh_identification");
|
Weird("malformed_ssh_identification");
|
||||||
ProtocolViolation("malformed ssh identification", line, length);
|
ProtocolViolation("malformed ssh identification", line, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for ( i = 4; i < length && line[i] != '-'; ++i )
|
for ( i = 4; i < length && line[i] != '-'; ++i )
|
||||||
;
|
;
|
||||||
|
|
||||||
if ( TCP() )
|
if ( TCP() )
|
||||||
{
|
{
|
||||||
if ( length >= i )
|
if ( length >= i )
|
||||||
{
|
{
|
||||||
IPAddr dst;
|
IPAddr dst;
|
||||||
|
|
||||||
if ( is_orig )
|
if ( is_orig )
|
||||||
dst = TCP()->Orig()->dst_addr;
|
dst = TCP()->Orig()->dst_addr;
|
||||||
else
|
else
|
||||||
|
|
|
@ -230,6 +230,28 @@ bool BinarySerializationFormat::Read(string* v, const char* tag)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag)
|
||||||
|
{
|
||||||
|
string s;
|
||||||
|
if ( ! Read(&s, tag) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*addr = IPAddr(s);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinarySerializationFormat::Read(IPPrefix* prefix, const char* tag)
|
||||||
|
{
|
||||||
|
string s;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if ( ! (Read(&s, tag) && Read(&len, tag)) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*prefix = IPPrefix(IPAddr(s), len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool BinarySerializationFormat::Write(char v, const char* tag)
|
bool BinarySerializationFormat::Write(char v, const char* tag)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag);
|
DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag);
|
||||||
|
@ -299,6 +321,16 @@ bool BinarySerializationFormat::Write(const string& s, const char* tag)
|
||||||
return Write(s.data(), s.size(), tag);
|
return Write(s.data(), s.size(), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BinarySerializationFormat::Write(const IPAddr& addr, const char* tag)
|
||||||
|
{
|
||||||
|
return Write(addr.AsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinarySerializationFormat::Write(const IPPrefix& prefix, const char* tag)
|
||||||
|
{
|
||||||
|
return Write(addr.AsString(), tag) && Write(prefix->Length(), tag);
|
||||||
|
}
|
||||||
|
|
||||||
bool BinarySerializationFormat::WriteOpenTag(const char* tag)
|
bool BinarySerializationFormat::WriteOpenTag(const char* tag)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
virtual bool Read(bool* v, const char* tag) = 0;
|
virtual bool Read(bool* v, const char* tag) = 0;
|
||||||
virtual bool Read(double* d, 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(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().
|
// Returns number of raw bytes read since last call to StartRead().
|
||||||
int BytesRead() const { return bytes_read; }
|
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* s, const char* tag) = 0;
|
||||||
virtual bool Write(const char* buf, int len, 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 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 WriteOpenTag(const char* tag) = 0;
|
||||||
virtual bool WriteCloseTag(const char* tag) = 0;
|
virtual bool WriteCloseTag(const char* tag) = 0;
|
||||||
|
|
|
@ -1103,9 +1103,9 @@ void EventPlayer::Process()
|
||||||
void Packet::Describe(ODesc* d) const
|
void Packet::Describe(ODesc* d) const
|
||||||
{
|
{
|
||||||
const IP_Hdr ip = IP();
|
const IP_Hdr ip = IP();
|
||||||
d->Add(string(ip.SrcAddr()).c_str());
|
d->Add(ip.SrcAddr());
|
||||||
d->Add("->");
|
d->Add("->");
|
||||||
d->Add(string(ip.DstAddr()).c_str());
|
d->Add(ip.DstAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Packet::Serialize(SerialInfo* info) const
|
bool Packet::Serialize(SerialInfo* info) const
|
||||||
|
|
|
@ -287,6 +287,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size));
|
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size));
|
||||||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size);
|
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Weird("unknown_packet_type", hdr, pkt);
|
Weird("unknown_packet_type", hdr, pkt);
|
||||||
|
@ -604,8 +605,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
int record_packet = 1; // whether to record the packet at all
|
int record_packet = 1; // whether to record the packet at all
|
||||||
int record_content = 1; // whether to record its data
|
int record_content = 1; // whether to record its data
|
||||||
|
|
||||||
int is_orig = id.src_addr == conn->OrigAddr() &&
|
int is_orig = (id.src_addr == conn->OrigAddr()) &&
|
||||||
id.src_port == conn->OrigPort();
|
(id.src_port == conn->OrigPort());
|
||||||
|
|
||||||
if ( new_packet && ip4 )
|
if ( new_packet && ip4 )
|
||||||
conn->Event(new_packet, 0, BuildHeader(ip4));
|
conn->Event(new_packet, 0, BuildHeader(ip4));
|
||||||
|
@ -811,16 +812,16 @@ Connection* NetSessions::FindConnection(Val* v)
|
||||||
// types, too.
|
// types, too.
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddr* orig_addr = (*vl)[orig_h]->AsAddr();
|
const IPAddr& orig_addr = (*vl)[orig_h]->AsAddr();
|
||||||
IPAddr* resp_addr = (*vl)[resp_h]->AsAddr();
|
const IPAddr& resp_addr = (*vl)[resp_h]->AsAddr();
|
||||||
|
|
||||||
PortVal* orig_portv = (*vl)[orig_p]->AsPortVal();
|
PortVal* orig_portv = (*vl)[orig_p]->AsPortVal();
|
||||||
PortVal* resp_portv = (*vl)[resp_p]->AsPortVal();
|
PortVal* resp_portv = (*vl)[resp_p]->AsPortVal();
|
||||||
|
|
||||||
ConnID id;
|
ConnID id;
|
||||||
|
|
||||||
id.src_addr = *orig_addr;
|
id.src_addr = orig_addr;
|
||||||
id.dst_addr = *resp_addr;
|
id.dst_addr = resp_addr;
|
||||||
|
|
||||||
id.src_port = htons((unsigned short) orig_portv->Port());
|
id.src_port = htons((unsigned short) orig_portv->Port());
|
||||||
id.dst_port = htons((unsigned short) resp_portv->Port());
|
id.dst_port = htons((unsigned short) resp_portv->Port());
|
||||||
|
|
|
@ -35,9 +35,9 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig)
|
||||||
const uint32* src_bytes;
|
const uint32* src_bytes;
|
||||||
const uint32* dst_bytes;
|
const uint32* dst_bytes;
|
||||||
int n = src_addr.GetBytes(&src_bytes);
|
int n = src_addr.GetBytes(&src_bytes);
|
||||||
dst_addr.GetBytes(&dst_bytes);
|
int m = dst_addr.GetBytes(&dst_bytes);
|
||||||
checksum_base = ones_complement_checksum((void*) src_bytes, n*4, 0);
|
checksum_base = ones_complement_checksum((void*) src_bytes, n*4, 0);
|
||||||
checksum_base = ones_complement_checksum((void*) dst_bytes, n*4, checksum_base);
|
checksum_base = ones_complement_checksum((void*) dst_bytes, m*4, checksum_base);
|
||||||
// Note, for IPv6, strictly speaking this field is 32 bits
|
// Note, for IPv6, strictly speaking this field is 32 bits
|
||||||
// rather than 16 bits. But because the upper bits are all zero,
|
// rather than 16 bits. But because the upper bits are all zero,
|
||||||
// we get the same checksum either way. The same applies to
|
// we get the same checksum either way. The same applies to
|
||||||
|
|
117
src/Val.cc
117
src/Val.cc
|
@ -205,31 +205,10 @@ bool Val::DoSerialize(SerialInfo* info) const
|
||||||
val.string_val->Len());
|
val.string_val->Len());
|
||||||
|
|
||||||
case TYPE_INTERNAL_ADDR:
|
case TYPE_INTERNAL_ADDR:
|
||||||
{
|
return SERIALIZE(*val.addr_val);
|
||||||
const uint32* addrp;
|
|
||||||
int words = val.addr_val->GetBytes(&addrp);
|
|
||||||
if ( ! SERIALIZE(words) )
|
|
||||||
return false;
|
|
||||||
for ( int i = 0; i < words; ++i )
|
|
||||||
if ( ! SERIALIZE(ntohl(addrp[i])) )
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_INTERNAL_SUBNET:
|
case TYPE_INTERNAL_SUBNET:
|
||||||
{
|
return SERIALIZE(*val.subnet_val);
|
||||||
const uint32* addrp;
|
|
||||||
int words = val.subnet_val->Prefix().GetBytes(&addrp);
|
|
||||||
if ( ! (info->s->WriteOpenTag("subnet") && SERIALIZE(words)) )
|
|
||||||
return false;
|
|
||||||
for ( int i = 0; i < words; ++i )
|
|
||||||
if ( ! SERIALIZE(ntohl(addrp[i])) )
|
|
||||||
return false;
|
|
||||||
if ( ! (SERIALIZE(val.subnet_val->Length()) &&
|
|
||||||
info->s->WriteCloseTag("subnet")) )
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_INTERNAL_OTHER:
|
case TYPE_INTERNAL_OTHER:
|
||||||
// Derived classes are responsible for this.
|
// Derived classes are responsible for this.
|
||||||
|
@ -296,71 +275,15 @@ bool Val::DoUnserialize(UnserialInfo* info)
|
||||||
|
|
||||||
case TYPE_INTERNAL_ADDR:
|
case TYPE_INTERNAL_ADDR:
|
||||||
{
|
{
|
||||||
int num_words;
|
val.addr_val = new IPAddr();
|
||||||
if ( ! UNSERIALIZE(&num_words) )
|
return UNSERIALIZE(val.addr_val);
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( num_words != 1 && num_words != 4 )
|
|
||||||
{
|
|
||||||
info->s->Error("bad address type");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 a[4]; // big enough to hold either
|
|
||||||
|
|
||||||
for ( int i = 0; i < num_words; ++i )
|
|
||||||
{
|
|
||||||
if ( ! UNSERIALIZE(&a[i]) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
a[i] = htonl(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( num_words == 1)
|
|
||||||
val.addr_val = new IPAddr(IPAddr::IPv4, a, IPAddr::Network);
|
|
||||||
else
|
|
||||||
val.addr_val = new IPAddr(IPAddr::IPv6, a, IPAddr::Network);
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
|
||||||
case TYPE_INTERNAL_SUBNET:
|
case TYPE_INTERNAL_SUBNET:
|
||||||
{
|
{
|
||||||
int num_words;
|
val.subnet_val = new IPPrefix();
|
||||||
if ( ! UNSERIALIZE(&num_words) )
|
return UNSERIALIZE(val.subnet_val);
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( num_words != 1 && num_words != 4 )
|
|
||||||
{
|
|
||||||
info->s->Error("bad subnet type");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 a[4]; // big enough to hold either
|
|
||||||
|
|
||||||
for ( int i = 0; i < num_words; ++i )
|
|
||||||
{
|
|
||||||
if ( ! UNSERIALIZE(&a[i]) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
a[i] = htonl(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int width;
|
|
||||||
if ( ! UNSERIALIZE(&width) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( num_words == 1 )
|
|
||||||
{
|
|
||||||
IPAddr tmp(IPAddr::IPv4, a, IPAddr::Network);
|
|
||||||
val.subnet_val = new IPPrefix(tmp, width);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IPAddr tmp(IPAddr::IPv6, a, IPAddr::Network);
|
|
||||||
val.subnet_val = new IPPrefix(tmp, width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
|
||||||
case TYPE_INTERNAL_OTHER:
|
case TYPE_INTERNAL_OTHER:
|
||||||
// Derived classes are responsible for this.
|
// Derived classes are responsible for this.
|
||||||
|
@ -569,10 +492,10 @@ void Val::ValDescribe(ODesc* d) const
|
||||||
case TYPE_INTERNAL_UNSIGNED: d->Add(val.uint_val); break;
|
case TYPE_INTERNAL_UNSIGNED: d->Add(val.uint_val); break;
|
||||||
case TYPE_INTERNAL_DOUBLE: d->Add(val.double_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_STRING: d->AddBytes(val.string_val); break;
|
||||||
case TYPE_INTERNAL_ADDR: d->Add(string(*val.addr_val).c_str()); break;
|
case TYPE_INTERNAL_ADDR: d->Add(val.addr_val->AsString().c_str()); break;
|
||||||
|
|
||||||
case TYPE_INTERNAL_SUBNET:
|
case TYPE_INTERNAL_SUBNET:
|
||||||
d->Add(string(*val.subnet_val).c_str());
|
d->Add(val.subnet_val->AsString().c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_INTERNAL_ERROR: d->AddCS("error"); break;
|
case TYPE_INTERNAL_ERROR: d->AddCS("error"); break;
|
||||||
|
@ -683,7 +606,7 @@ ID* MutableVal::Bind() const
|
||||||
ip = htonl(0x7f000001); // 127.0.0.1
|
ip = htonl(0x7f000001); // 127.0.0.1
|
||||||
|
|
||||||
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
|
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
|
||||||
string(IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)).c_str(),
|
IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(),
|
||||||
getpid());
|
getpid());
|
||||||
#else
|
#else
|
||||||
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
|
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
|
||||||
|
@ -935,9 +858,10 @@ bool PortVal::DoUnserialize(UnserialInfo* info)
|
||||||
|
|
||||||
AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR)
|
AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR)
|
||||||
{
|
{
|
||||||
val.addr_val = new IPAddr(string(text));
|
val.addr_val = new IPAddr(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR)
|
AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR)
|
||||||
{
|
{
|
||||||
// ### perhaps do gethostbyaddr here?
|
// ### perhaps do gethostbyaddr here?
|
||||||
|
@ -948,6 +872,7 @@ AddrVal::AddrVal(const uint32* addr) : Val(TYPE_ADDR)
|
||||||
{
|
{
|
||||||
val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network);
|
val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR)
|
AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR)
|
||||||
{
|
{
|
||||||
|
@ -991,6 +916,7 @@ SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET)
|
||||||
const char* sep = strchr(text, '/');
|
const char* sep = strchr(text, '/');
|
||||||
if ( ! sep )
|
if ( ! sep )
|
||||||
Internal("separator missing in SubNetVal::SubNetVal");
|
Internal("separator missing in SubNetVal::SubNetVal");
|
||||||
|
|
||||||
val.subnet_val = new IPPrefix(text, atoi(sep+1));
|
val.subnet_val = new IPPrefix(text, atoi(sep+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,6 +925,7 @@ SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET)
|
||||||
val.subnet_val = new IPPrefix(text, width);
|
val.subnet_val = new IPPrefix(text, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET)
|
SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET)
|
||||||
{
|
{
|
||||||
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
|
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
|
||||||
|
@ -1010,6 +937,7 @@ SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET)
|
||||||
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
|
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
|
||||||
val.subnet_val = new IPPrefix(a, width);
|
val.subnet_val = new IPPrefix(a, width);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SubNetVal::SubNetVal(const IPAddr& addr, int width) : Val(TYPE_SUBNET)
|
SubNetVal::SubNetVal(const IPAddr& addr, int width) : Val(TYPE_SUBNET)
|
||||||
{
|
{
|
||||||
|
@ -1037,6 +965,7 @@ void SubNetVal::ValDescribe(ODesc* d) const
|
||||||
d->Add(string(*val.subnet_val).c_str());
|
d->Add(string(*val.subnet_val).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
IPAddr SubNetVal::Mask() const
|
IPAddr SubNetVal::Mask() const
|
||||||
{
|
{
|
||||||
if ( val.subnet_val->Length() == 0 )
|
if ( val.subnet_val->Length() == 0 )
|
||||||
|
@ -1069,22 +998,20 @@ IPAddr SubNetVal::Mask() const
|
||||||
bool SubNetVal::Contains(const uint32 addr) const
|
bool SubNetVal::Contains(const uint32 addr) const
|
||||||
{
|
{
|
||||||
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
|
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
|
||||||
a.Mask(val.subnet_val->Length());
|
return val.subnet_val->Contains(a);
|
||||||
return a == val.subnet_val->Prefix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubNetVal::Contains(const uint32* addr) const
|
bool SubNetVal::Contains(const uint32* addr) const
|
||||||
{
|
{
|
||||||
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
|
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
|
||||||
a.Mask(val.subnet_val->Length());
|
return val.subnet_val->Contains(a);
|
||||||
return a == val.subnet_val->Prefix();
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool SubNetVal::Contains(const IPAddr& addr) const
|
bool SubNetVal::Contains(const IPAddr& addr) const
|
||||||
{
|
{
|
||||||
IPAddr a(addr);
|
IPAddr a(addr);
|
||||||
a.Mask(val.subnet_val->Length());
|
return val.subnet_val->Contains(a);
|
||||||
return a == val.subnet_val->Prefix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL);
|
IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL);
|
||||||
|
@ -3300,9 +3227,9 @@ int same_atomic_val(const Val* v1, const Val* v2)
|
||||||
case TYPE_INTERNAL_STRING:
|
case TYPE_INTERNAL_STRING:
|
||||||
return Bstr_eq(v1->AsString(), v2->AsString());
|
return Bstr_eq(v1->AsString(), v2->AsString());
|
||||||
case TYPE_INTERNAL_ADDR:
|
case TYPE_INTERNAL_ADDR:
|
||||||
return *v1->AsAddr() == *v2->AsAddr();
|
return v1->AsAddr() == v2->AsAddr();
|
||||||
case TYPE_INTERNAL_SUBNET:
|
case TYPE_INTERNAL_SUBNET:
|
||||||
return *v1->AsSubNet() == *v2->AsSubNet();
|
return v1->AsSubNet() == v2->AsSubNet();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
reporter->InternalError("same_atomic_val called for non-atomic value");
|
reporter->InternalError("same_atomic_val called for non-atomic value");
|
||||||
|
|
16
src/Val.h
16
src/Val.h
|
@ -227,10 +227,10 @@ public:
|
||||||
CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
|
CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
|
||||||
CONST_ACCESSOR(TYPE_VECTOR, vector<Val*>*, vector_val, AsVector)
|
CONST_ACCESSOR(TYPE_VECTOR, vector<Val*>*, vector_val, AsVector)
|
||||||
|
|
||||||
const IPPrefix* AsSubNet() const
|
const IPPrefix& AsSubNet() const
|
||||||
{
|
{
|
||||||
CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name)
|
CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name)
|
||||||
return val.subnet_val;
|
return *val.subnet_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
BroType* AsType() const
|
BroType* AsType() const
|
||||||
|
@ -239,11 +239,11 @@ public:
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IPAddr* AsAddr() const
|
const IPAddr& AsAddr() const
|
||||||
{
|
{
|
||||||
if ( type->Tag() != TYPE_ADDR )
|
if ( type->Tag() != TYPE_ADDR )
|
||||||
BadTag("Val::AsAddr", type_name(type->Tag()));
|
BadTag("Val::AsAddr", type_name(type->Tag()));
|
||||||
return val.addr_val;
|
return *val.addr_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ACCESSOR(tag, ctype, accessor, name) \
|
#define ACCESSOR(tag, ctype, accessor, name) \
|
||||||
|
@ -562,8 +562,10 @@ public:
|
||||||
Val* SizeVal() const;
|
Val* SizeVal() const;
|
||||||
|
|
||||||
// Constructor for address already in network order.
|
// Constructor for address already in network order.
|
||||||
|
#if 0
|
||||||
AddrVal(uint32 addr);
|
AddrVal(uint32 addr);
|
||||||
AddrVal(const uint32* addr);
|
AddrVal(const uint32* addr);
|
||||||
|
#endif
|
||||||
AddrVal(const IPAddr& addr);
|
AddrVal(const IPAddr& addr);
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const;
|
unsigned int MemoryAllocation() const;
|
||||||
|
@ -581,8 +583,10 @@ class SubNetVal : public Val {
|
||||||
public:
|
public:
|
||||||
SubNetVal(const char* text);
|
SubNetVal(const char* text);
|
||||||
SubNetVal(const char* text, int width);
|
SubNetVal(const char* text, int width);
|
||||||
|
#if 0
|
||||||
SubNetVal(uint32 addr, int width);
|
SubNetVal(uint32 addr, int width);
|
||||||
SubNetVal(const uint32* addr, int width);
|
SubNetVal(const uint32* addr, int width);
|
||||||
|
#endif
|
||||||
SubNetVal(const IPAddr& addr, int width);
|
SubNetVal(const IPAddr& addr, int width);
|
||||||
~SubNetVal();
|
~SubNetVal();
|
||||||
|
|
||||||
|
@ -590,10 +594,12 @@ public:
|
||||||
|
|
||||||
const IPAddr& Prefix() const { return val.subnet_val->Prefix(); }
|
const IPAddr& Prefix() const { return val.subnet_val->Prefix(); }
|
||||||
int Width() const { return val.subnet_val->Length(); }
|
int Width() const { return val.subnet_val->Length(); }
|
||||||
|
#if 0
|
||||||
IPAddr Mask() const;
|
IPAddr Mask() const;
|
||||||
|
|
||||||
bool Contains(const uint32 addr) const;
|
bool Contains(const uint32 addr) const;
|
||||||
bool Contains(const uint32* addr) const;
|
bool Contains(const uint32* addr) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool Contains(const IPAddr& addr) const;
|
bool Contains(const IPAddr& addr) const;
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const;
|
unsigned int MemoryAllocation() const;
|
||||||
|
|
81
src/bro.bif
81
src/bro.bif
|
@ -179,9 +179,10 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d)
|
||||||
// This makes only a very slight difference, so not
|
// This makes only a very slight difference, so not
|
||||||
// clear it would e worth the hassle.
|
// clear it would e worth the hassle.
|
||||||
|
|
||||||
const IPAddr* u = v->AsAddr();
|
const IPAddr& u = v->AsAddr();
|
||||||
const uint32* net_order_u;
|
const uint32* net_order_u;
|
||||||
int len = u->GetBytes(&net_order_u);
|
int len = u->GetBytes(&net_order_u);
|
||||||
|
|
||||||
if ( len == 4 )
|
if ( len == 4 )
|
||||||
{
|
{
|
||||||
// We explicitly convert the address to host order
|
// We explicitly convert the address to host order
|
||||||
|
@ -1974,21 +1975,29 @@ function is_local_interface%(ip: addr%) : bool
|
||||||
host[MAXHOSTNAMELEN-1] = '\0';
|
host[MAXHOSTNAMELEN-1] = '\0';
|
||||||
|
|
||||||
struct hostent* ent = gethostbyname2(host, AF_INET);
|
struct hostent* ent = gethostbyname2(host, AF_INET);
|
||||||
|
|
||||||
if ( ent )
|
if ( ent )
|
||||||
|
{
|
||||||
for ( unsigned int len = 0; ent->h_addr_list[len]; ++len )
|
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(IPAddr::IPv4, (uint32*)ent->h_addr_list[len],
|
||||||
IPAddr::Network));
|
IPAddr::Network));
|
||||||
|
}
|
||||||
|
|
||||||
ent = gethostbyname2(host, AF_INET6);
|
ent = gethostbyname2(host, AF_INET6);
|
||||||
|
|
||||||
if ( ent )
|
if ( ent )
|
||||||
|
{
|
||||||
for ( unsigned int len = 0; ent->h_addr_list[len]; ++len )
|
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(IPAddr::IPv6, (uint32*)ent->h_addr_list[len],
|
||||||
IPAddr::Network));
|
IPAddr::Network));
|
||||||
|
}
|
||||||
|
|
||||||
list<IPAddr>::const_iterator it;
|
list<IPAddr>::const_iterator it;
|
||||||
for ( it = addrs.begin(); it != addrs.end(); ++it )
|
for ( it = addrs.begin(); it != addrs.end(); ++it )
|
||||||
if ( *it == *ip->AsAddr() )
|
{
|
||||||
|
if ( *it == ip->AsAddr() )
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
|
}
|
||||||
|
|
||||||
return new Val(0, TYPE_BOOL);
|
return new Val(0, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
@ -2058,7 +2067,7 @@ function is_v4_addr%(a: addr%): bool
|
||||||
## Returns: true if *a* is an IPv6 address, else false.
|
## Returns: true if *a* is an IPv6 address, else false.
|
||||||
function is_v6_addr%(a: addr%): bool
|
function is_v6_addr%(a: addr%): bool
|
||||||
%{
|
%{
|
||||||
if ( a->AsAddr()->family() == IPAddr::IPv6 )
|
if ( a->AsAddr().Family() == IPAddr::IPv6 )
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
else
|
else
|
||||||
return new Val(0, TYPE_BOOL);
|
return new Val(0, TYPE_BOOL);
|
||||||
|
@ -2479,7 +2488,7 @@ function addr_to_ptr_name%(a: addr%): string
|
||||||
## .. bro:see:: addr_to_ptr_name parse_dotted_addr
|
## .. bro:see:: addr_to_ptr_name parse_dotted_addr
|
||||||
function parse_dotted_addr%(s: string%): addr
|
function parse_dotted_addr%(s: string%): addr
|
||||||
%{
|
%{
|
||||||
IPAddr a(string(s->CheckString()));
|
IPAddr a(s->CheckString());
|
||||||
return new AddrVal(a);
|
return new AddrVal(a);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -2991,7 +3000,7 @@ function strftime%(fmt: string, d: time%) : string
|
||||||
## .. bro:see:: remask_addr
|
## .. bro:see:: remask_addr
|
||||||
function mask_addr%(a: addr, top_bits_to_keep: count%): subnet
|
function mask_addr%(a: addr, top_bits_to_keep: count%): subnet
|
||||||
%{
|
%{
|
||||||
return new SubNetVal(*a->AsAddr(), top_bits_to_keep);
|
return new SubNetVal(a->AsAddr(), top_bits_to_keep);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Takes some top bits (e.g., subnet address) from one address and the other
|
## Takes some top bits (e.g., subnet address) from one address and the other
|
||||||
|
@ -3013,9 +3022,9 @@ function mask_addr%(a: addr, top_bits_to_keep: count%): subnet
|
||||||
## .. bro:see:: mask_addr
|
## .. bro:see:: mask_addr
|
||||||
function remask_addr%(a1: addr, a2: addr, top_bits_from_a1: count%): addr
|
function remask_addr%(a1: addr, a2: addr, top_bits_from_a1: count%): addr
|
||||||
%{
|
%{
|
||||||
IPAddr addr1(*a1->AsAddr());
|
IPAddr addr1(a1->AsAddr());
|
||||||
addr1.Mask(top_bits_from_a1);
|
addr1.Mask(top_bits_from_a1);
|
||||||
IPAddr addr2(*a2->AsAddr());
|
IPAddr addr2(a2->AsAddr());
|
||||||
addr1.ReverseMask(top_bits_from_a1);
|
addr1.ReverseMask(top_bits_from_a1);
|
||||||
uint32 x1[4];
|
uint32 x1[4];
|
||||||
uint32 x2[4];
|
uint32 x2[4];
|
||||||
|
@ -3196,13 +3205,13 @@ const char* conn_id_string(Val* c)
|
||||||
Val* id = (*(c->AsRecord()))[0];
|
Val* id = (*(c->AsRecord()))[0];
|
||||||
const val_list* vl = id->AsRecord();
|
const val_list* vl = id->AsRecord();
|
||||||
|
|
||||||
const IPAddr* orig_h = (*vl)[0]->AsAddr();
|
const IPAddr& orig_h = (*vl)[0]->AsAddr();
|
||||||
uint32 orig_p = (*vl)[1]->AsPortVal()->Port();
|
uint32 orig_p = (*vl)[1]->AsPortVal()->Port();
|
||||||
const IPAddr* resp_h = (*vl)[2]->AsAddr();
|
const IPAddr& resp_h = (*vl)[2]->AsAddr();
|
||||||
uint32 resp_p = (*vl)[3]->AsPortVal()->Port();
|
uint32 resp_p = (*vl)[3]->AsPortVal()->Port();
|
||||||
|
|
||||||
return fmt("%s/%u -> %s/%u\n", string(*orig_h).c_str(), orig_p,
|
return fmt("%s/%u -> %s/%u\n", orig_h.AsString().c_str(), orig_p,
|
||||||
string(*resp_h).c_str(), resp_p);
|
resp_h.AsString().c_str(), resp_p);
|
||||||
}
|
}
|
||||||
%%}
|
%%}
|
||||||
|
|
||||||
|
@ -3432,7 +3441,7 @@ function lookup_addr%(host: addr%) : string
|
||||||
frame->SetDelayed();
|
frame->SetDelayed();
|
||||||
trigger->Hold();
|
trigger->Hold();
|
||||||
|
|
||||||
if ( host->AsAddr()->family() != IPAddr::IPv4 )
|
if ( host->AsAddr().Family() != IPAddr::IPv4 )
|
||||||
{
|
{
|
||||||
// FIXME: This is a temporary work-around until we get this
|
// FIXME: This is a temporary work-around until we get this
|
||||||
// fixed. We warn the user once, and always trigger a timeout.
|
// fixed. We warn the user once, and always trigger a timeout.
|
||||||
|
@ -3449,7 +3458,7 @@ function lookup_addr%(host: addr%) : string
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
host->AsAddr()->GetBytes(&bytes);
|
host->AsAddr().GetBytes(&bytes);
|
||||||
dns_mgr->AsyncLookupAddr(*bytes,
|
dns_mgr->AsyncLookupAddr(*bytes,
|
||||||
new LookupHostCallback(trigger, frame->GetCall(), true));
|
new LookupHostCallback(trigger, frame->GetCall(), true));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3558,10 +3567,10 @@ function lookup_location%(a: addr%) : geo_location
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
|
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||||
if ( geoip_v6 && a->AsAddr()->family() == IPAddr::IPv6 )
|
if ( geoip_v6 && a->AsAddr().Family() == IPAddr::IPv6 )
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
geoipv6_t ga;
|
geoipv6_t ga;
|
||||||
memcpy(&ga, bytes, 16);
|
memcpy(&ga, bytes, 16);
|
||||||
if ( have_cityv6_db )
|
if ( have_cityv6_db )
|
||||||
|
@ -3572,10 +3581,10 @@ function lookup_location%(a: addr%) : geo_location
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( geoip && a->AsAddr()->family() == IPAddr::IPv4 )
|
if ( geoip && a->AsAddr().Family() == IPAddr::IPv4 )
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
if ( have_city_db )
|
if ( have_city_db )
|
||||||
gir = GeoIP_record_by_ipnum(geoip, ntohl(*bytes));
|
gir = GeoIP_record_by_ipnum(geoip, ntohl(*bytes));
|
||||||
else
|
else
|
||||||
|
@ -3658,7 +3667,7 @@ function lookup_asn%(a: addr%) : count
|
||||||
if ( a->AsAddr()->family() == IPAddr::IPv6 )
|
if ( a->AsAddr()->family() == IPAddr::IPv6 )
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
geoipv6_t ga;
|
geoipv6_t ga;
|
||||||
memcpy(&ga, bytes, 16);
|
memcpy(&ga, bytes, 16);
|
||||||
gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga);
|
gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga);
|
||||||
|
@ -3666,10 +3675,10 @@ function lookup_asn%(a: addr%) : count
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( a->AsAddr()->family() == IPAddr::IPv4 )
|
if ( a->AsAddr().Family() == IPAddr::IPv4 )
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(*bytes));
|
gir = GeoIP_name_by_ipnum(geoip_asn, ntohl(*bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3953,7 +3962,7 @@ function file_mode%(mode: count%): string
|
||||||
function expect_connection%(orig: addr, resp: addr, resp_p: port,
|
function expect_connection%(orig: addr, resp: addr, resp_p: port,
|
||||||
analyzer: count, tout: interval%) : any
|
analyzer: count, tout: interval%) : any
|
||||||
%{
|
%{
|
||||||
dpm->ExpectConnection(*orig->AsAddr(), *resp->AsAddr(), resp_p->Port(),
|
dpm->ExpectConnection(orig->AsAddr(), resp->AsAddr(), resp_p->Port(),
|
||||||
resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0);
|
resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0);
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
@ -4727,7 +4736,7 @@ function pcap_error%(%): string
|
||||||
## .. todo:: The return value should be changed to any.
|
## .. todo:: The return value should be changed to any.
|
||||||
function install_src_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool
|
function install_src_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool
|
||||||
%{
|
%{
|
||||||
sessions->GetPacketFilter()->AddSrc(*ip->AsAddr(), tcp_flags, prob);
|
sessions->GetPacketFilter()->AddSrc(ip->AsAddr(), tcp_flags, prob);
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -4779,7 +4788,7 @@ function install_src_net_filter%(snet: subnet, tcp_flags: count, prob: double%)
|
||||||
## pcap_error
|
## pcap_error
|
||||||
function uninstall_src_addr_filter%(ip: addr%) : bool
|
function uninstall_src_addr_filter%(ip: addr%) : bool
|
||||||
%{
|
%{
|
||||||
return new Val(sessions->GetPacketFilter()->RemoveSrc(*ip->AsAddr()), TYPE_BOOL);
|
return new Val(sessions->GetPacketFilter()->RemoveSrc(ip->AsAddr()), TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Removes a source subnet filter.
|
## Removes a source subnet filter.
|
||||||
|
@ -4829,7 +4838,7 @@ function uninstall_src_net_filter%(snet: subnet%) : bool
|
||||||
## .. todo:: The return value should be changed to any.
|
## .. todo:: The return value should be changed to any.
|
||||||
function install_dst_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool
|
function install_dst_addr_filter%(ip: addr, tcp_flags: count, prob: double%) : bool
|
||||||
%{
|
%{
|
||||||
sessions->GetPacketFilter()->AddDst(*ip->AsAddr(), tcp_flags, prob);
|
sessions->GetPacketFilter()->AddDst(ip->AsAddr(), tcp_flags, prob);
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -4881,7 +4890,7 @@ function install_dst_net_filter%(snet: subnet, tcp_flags: count, prob: double%)
|
||||||
## pcap_error
|
## pcap_error
|
||||||
function uninstall_dst_addr_filter%(ip: addr%) : bool
|
function uninstall_dst_addr_filter%(ip: addr%) : bool
|
||||||
%{
|
%{
|
||||||
return new Val(sessions->GetPacketFilter()->RemoveDst(*ip->AsAddr()), TYPE_BOOL);
|
return new Val(sessions->GetPacketFilter()->RemoveDst(ip->AsAddr()), TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Removes a destination subnet filter.
|
## Removes a destination subnet filter.
|
||||||
|
@ -5022,7 +5031,7 @@ function capture_state_updates%(filename: string%) : bool
|
||||||
## send_id
|
## send_id
|
||||||
function connect%(ip: addr, p: port, our_class: string, retry: interval, ssl: bool%) : count
|
function connect%(ip: addr, p: port, our_class: string, retry: interval, ssl: bool%) : count
|
||||||
%{
|
%{
|
||||||
return new Val(uint32(remote_serializer->Connect(*ip->AsAddr(), p->Port(),
|
return new Val(uint32(remote_serializer->Connect(ip->AsAddr(), p->Port(),
|
||||||
our_class->CheckString(), retry, ssl)),
|
our_class->CheckString(), retry, ssl)),
|
||||||
TYPE_COUNT);
|
TYPE_COUNT);
|
||||||
%}
|
%}
|
||||||
|
@ -5137,7 +5146,7 @@ function set_compression_level%(p: event_peer, level: count%) : bool
|
||||||
## .. bro:see:: connect disconnect
|
## .. bro:see:: connect disconnect
|
||||||
function listen%(ip: addr, p: port, ssl: bool %) : bool
|
function listen%(ip: addr, p: port, ssl: bool %) : bool
|
||||||
%{
|
%{
|
||||||
return new Val(remote_serializer->Listen(*ip->AsAddr(), p->Port(), ssl), TYPE_BOOL);
|
return new Val(remote_serializer->Listen(ip->AsAddr(), p->Port(), ssl), TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Checks whether the last raised event came from a remote peer.
|
## Checks whether the last raised event came from a remote peer.
|
||||||
|
@ -5393,12 +5402,12 @@ function preserve_prefix%(a: addr, width: count%): any
|
||||||
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
|
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
|
||||||
if ( ip_anon )
|
if ( ip_anon )
|
||||||
{
|
{
|
||||||
if ( a->AsAddr()->family() == IPAddr::IPv6 )
|
if ( a->AsAddr().Family() == IPAddr::IPv6 )
|
||||||
builtin_error("preserve_prefix() not supported for IPv6 addresses");
|
builtin_error("preserve_prefix() not supported for IPv6 addresses");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
ip_anon->PreservePrefix(*bytes, width);
|
ip_anon->PreservePrefix(*bytes, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5418,16 +5427,16 @@ function preserve_prefix%(a: addr, width: count%): any
|
||||||
## .. todo:: Currently dysfunctional.
|
## .. todo:: Currently dysfunctional.
|
||||||
function preserve_subnet%(a: subnet%): any
|
function preserve_subnet%(a: subnet%): any
|
||||||
%{
|
%{
|
||||||
DEBUG_MSG("%s/%d\n", string(a->Prefix()).c_str(), a->Width());
|
DEBUG_MSG("%s/%d\n", a->Prefix().AsString().c_str(), a->Width());
|
||||||
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
|
AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50];
|
||||||
if ( ip_anon )
|
if ( ip_anon )
|
||||||
{
|
{
|
||||||
if ( a->AsSubNet()->Prefix().family() == IPAddr::IPv6 )
|
if ( a->AsSubNet()->Prefix().Family() == IPAddr::IPv6 )
|
||||||
builtin_error("preserve_subnet() not supported for IPv6 addresses");
|
builtin_error("preserve_subnet() not supported for IPv6 addresses");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsSubNet()->Prefix().GetBytes(&bytes);
|
a->AsSubNet().Prefix().GetBytes(&bytes);
|
||||||
ip_anon->PreservePrefix(*bytes, a->AsSubNet()->Length());
|
ip_anon->PreservePrefix(*bytes, a->AsSubNet()->Length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5458,7 +5467,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr
|
||||||
if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES )
|
if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES )
|
||||||
builtin_error("anonymize_addr(): invalid ip addr anonymization class");
|
builtin_error("anonymize_addr(): invalid ip addr anonymization class");
|
||||||
|
|
||||||
if ( a->AsAddr()->family() == IPAddr::IPv6 )
|
if ( a->AsAddr().Family() == IPAddr::IPv6 )
|
||||||
{
|
{
|
||||||
builtin_error("anonymize_addr() not supported for IPv6 addresses");
|
builtin_error("anonymize_addr() not supported for IPv6 addresses");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5466,7 +5475,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
a->AsAddr()->GetBytes(&bytes);
|
a->AsAddr().GetBytes(&bytes);
|
||||||
return new AddrVal(anonymize_ip(*bytes,
|
return new AddrVal(anonymize_ip(*bytes,
|
||||||
(enum ip_addr_anonymization_class_t) anon_class));
|
(enum ip_addr_anonymization_class_t) anon_class));
|
||||||
}
|
}
|
||||||
|
@ -5519,7 +5528,7 @@ function generate_idmef%(src_ip: addr, src_port: port,
|
||||||
newNode(newAddress(
|
newNode(newAddress(
|
||||||
newAttribute("category","ipv4-addr"),
|
newAttribute("category","ipv4-addr"),
|
||||||
newSimpleElement("address",
|
newSimpleElement("address",
|
||||||
copy_string(string(*src_ip->AsAddr()).c_str())),
|
copy_string(src_ip->AsAddr().AsString().c_str())),
|
||||||
NULL), NULL),
|
NULL), NULL),
|
||||||
newService(
|
newService(
|
||||||
newSimpleElement("port",
|
newSimpleElement("port",
|
||||||
|
@ -5529,7 +5538,7 @@ function generate_idmef%(src_ip: addr, src_port: port,
|
||||||
newNode(newAddress(
|
newNode(newAddress(
|
||||||
newAttribute("category","ipv4-addr"),
|
newAttribute("category","ipv4-addr"),
|
||||||
newSimpleElement("address",
|
newSimpleElement("address",
|
||||||
copy_string(string(*dst_ip->AsAddr()).c_str())),
|
copy_string(dst_ip->AsAddr().AsString().c_str())),
|
||||||
NULL), NULL),
|
NULL), NULL),
|
||||||
newService(
|
newService(
|
||||||
newSimpleElement("port",
|
newSimpleElement("port",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue