Merge remote-tracking branch 'origin/master' into topic/robin/dataseries

This commit is contained in:
Robin Sommer 2012-05-14 22:17:26 -07:00
commit be6567f437
149 changed files with 2607 additions and 1126 deletions

144
CHANGES
View file

@ -1,4 +1,148 @@
2.0-336 | 2012-05-14 17:15:44 -0700
* Don't print the various "weird" events to stderr. Address #805.
(Daniel Thayer)
* Generate icmp_error_message event for ICMPv6 error msgs.
Previously, icmp_sent was being generated, but icmp_error_message
contains more info.
* Improved documentation comments for icmp-related events. (Daniel
Thayer)
2.0-330 | 2012-05-14 17:05:56 -0700
* Add `addr_to_uri` script-level function that adds brackets to an
address if it's IPv6 and will be included in a URI or when a
":<port>" needs to be appended to it. (Jon Siwek)
* Also add a test case for content extraction. (Jon Siwek)
* Fix typos and improve INSTALL document. (Daniel Thayer)
* Switching to new btest command TEST-SERIALIZE for communication
tests. (Robin Sommer)
2.0-323 | 2012-05-04 21:04:34 -0700
* Add SHA1 and SHA256 hashing BIFs. Addresses #542.
* Refactor all internal MD5 stuff to use OpenSSL's. (Jon Siwek)
* Changes to open-file caching limits and uncached file unserialization. (Jon Siwek)
- Unserializing files that were previously kicked out of the open-file
cache would cause them to be fopen'd with the original access
permissions which is usually 'w' and causes truncation. They
are now opened in 'a' mode. (addresses #780)
- Add 'max_files_in_cache' script option to manually set the maximum
amount of opened files to keep cached. Mainly this just helped
to create a simple test case for the above change.
- Remove unused NO_HAVE_SETRLIMIT preprocessor switch.
- On systems that don't enforce a limit on number of files opened for
the process, raise default max size of open-file cache from
32 to 512.
2.0-319 | 2012-05-03 13:24:44 -0700
* SSL bugfixes and cleanup. (Seth Hall)
- SSL related files and classes renamed to remove the "binpac" term.
- A small fix for DPD scripts to make the DPD log more helpful if
there are multiple continued failures.
- Fixed the SSL analyzer to make it stop doing repeated violation
messages for some handshake failures.
- Added a $issuer_subject to the SSL log.
- Created a basic test for SSL.
- Fixed parsing of TLS server extensions. (Seth Hall)
2.0-315 | 2012-05-03 11:44:17 -0700
* Add two more TLS extension values that we see in live traffic.
(Bernhard Amann)
* Fixed IPv6 link local unicast CIDR and added IPv6 loopback to
private address space. (Seth Hall)
* Fixed a problem where cluster workers were still processing
notices in some cases. (Seth Hall)
* Added a configure option to specify the 'etc' directory. Addresses
#801. (Daniel Thayer)
2.0-306 | 2012-04-24 14:37:00 -0700
* Add further TLS extension values "extended_random" and
"heartbeat". (Seth Hall)
* Fix problem with extracting FTP passwords and add "ftpuser" as
another anonymous username. (Seth Hall, discovered by Patrik
Lundin).
2.0-303 | 2012-04-19 10:01:06 -0700
* Changes related to ICMPv6 Neighbor Discovery messages. (Jon Siwek)
- The 'icmp_conn' record now contains an 'hlim' field since hop limit
in the IP header is an interesting field for at least these ND
messages.
- Fixed and extended 'icmp_router_advertisement' event parameters.
- Changed 'icmp_neighbor_advertisement' event parameters to add
more of the known boolean flags.
2.0-301 | 2012-04-17 17:58:55 -0700
* Bro now support ICMPv6. (Matti Mantere, Jon Siwek, Robin Sommer,
Daniel Thayer).
Overall, Bro now raises the following ICMP events for v4 and v6 as
appropiate:
event icmp_sent(c: connection, icmp: icmp_conn);
event icmp_echo_request(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string);
event icmp_echo_reply(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string);
event icmp_error_message(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
event icmp_packet_too_big(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
event icmp_time_exceeded(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
event icmp_parameter_problem(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
event icmp_router_solicitation(c: connection, icmp: icmp_conn);
event icmp_router_advertisement(c: connection, icmp: icmp_conn, hop_limit: count, managed: bool, router_lifetime: count, reachable_time: interval, retrans_timer: interval);
event icmp_neighbor_solicitation(c: connection, icmp: icmp_conn, tgt:addr);
event icmp_neighbor_advertisement(c: connection, icmp: icmp_conn, tgt:addr);
event icmp_redirect(c: connection, icmp: icmp_conn, tgt: addr, dest: addr);
The `icmp_conn` record got a new boolean field 'v6' that indicates
whether the ICMP message is v4 or v6.
This change also includes further low-level work on existing IP
and ICMP code, including a reorganization of how ICMPv4 is
handled.
2.0-281 | 2012-04-17 17:40:39 -0700
* Small updates for the bittorrent analyzer to support 64bit types
in binpac. (Seth Hall)
* Removed the attempt at bittorrent resynchronization. (Seth Hall)
2.0-276 | 2012-04-17 17:35:56 -0700
* Add more support for <netinet/ip6.h>'s that lack some structure
definitions. (Jon Siwek)
2.0-273 | 2012-04-16 18:08:56 -0700 2.0-273 | 2012-04-16 18:08:56 -0700
* Removing QR flag from DNS log in response, which should not have * Removing QR flag from DNS log in response, which should not have

56
INSTALL
View file

@ -5,34 +5,44 @@ Installing Bro
Prerequisites Prerequisites
============= =============
Bro relies on the following libraries and tools, which need to be installed Bro requires the following libraries and tools to be installed
before you begin: before you begin:
* CMake 2.6.3 or greater http://www.cmake.org * CMake 2.6.3 or greater http://www.cmake.org
* Libpcap (headers and libraries) http://www.tcpdump.org * Perl (used only during the Bro build process)
* OpenSSL (headers and libraries) http://www.openssl.org * Libpcap headers and libraries http://www.tcpdump.org
* SWIG http://www.swig.org * OpenSSL headers and libraries http://www.openssl.org
* BIND8 headers and libraries
* Libmagic * Libmagic
* Libz * Libz
Bro can make uses of some optional libraries if they are found at * SWIG http://www.swig.org
installation time:
* LibGeoIP For geo-locating IP addresses.
Bro also needs the following tools, but on most systems they will
already come preinstalled:
* Bash (For Bro Control).
* BIND8 (headers and libraries)
* Bison (GNU Parser Generator) * Bison (GNU Parser Generator)
* Flex (Fast Lexical Analyzer) * Flex (Fast Lexical Analyzer)
* Perl (Used only during the Bro build process)
* Bash (for BroControl)
Bro can make use of some optional libraries and tools if they are found at
build time:
* LibGeoIP (for geo-locating IP addresses)
* gperftools (tcmalloc is used to improve memory and CPU usage)
* sendmail (for BroControl)
* ipsumdump (for trace-summary) http://www.cs.ucla.edu/~kohler/ipsumdump
* Ruby executable, library, and headers (for Broccoli Ruby bindings)
Installation Installation
@ -44,7 +54,7 @@ To build and install into ``/usr/local/bro``::
make make
make install make install
This will first build Bro into a directory inside the distribution This will first build Bro in a directory inside the distribution
called ``build/``, using default build options. It then installs all called ``build/``, using default build options. It then installs all
required files into ``/usr/local/bro``, including the Bro binary in required files into ``/usr/local/bro``, including the Bro binary in
``/usr/local/bro/bin/bro``. ``/usr/local/bro/bin/bro``.
@ -60,22 +70,22 @@ choices unless you are creating such a package.
Run ``./configure --help`` for more options. Run ``./configure --help`` for more options.
Depending on the Bro package you downloaded, there may be auxiliary Depending on the Bro package you downloaded, there may be auxiliary
tools and libraries available in the ``aux/`` directory. All of them tools and libraries available in the ``aux/`` directory. Some of them
except for ``aux/bro-aux`` will also be built and installed by doing will be automatically built and installed along with Bro. There are
``make install``. To install the programs that come in the
``aux/bro-aux`` directory, use ``make install-aux``. There are
``--disable-*`` options that can be given to the configure script to ``--disable-*`` options that can be given to the configure script to
turn off unwanted auxiliary projects. turn off unwanted auxiliary projects that would otherwise be installed
automatically. Finally, use ``make install-aux`` to install some of
the other programs that are in the ``aux/bro-aux`` directory.
OpenBSD users, please see our `FAQ OpenBSD users, please see our FAQ at
<http://www.bro-ids.org/documentation/faq.html>` if you are having http://www.bro-ids.org/documentation/faq.html if you are having
problems installing Bro. problems installing Bro.
Running Bro Running Bro
=========== ===========
Bro is a complex program and it takes a bit of time to get familiar Bro is a complex program and it takes a bit of time to get familiar
with it. A good place for newcomers to start is the Quickstart Guide with it. A good place for newcomers to start is the Quick Start Guide
at http://www.bro-ids.org/documentation/quickstart.html. at http://www.bro-ids.org/documentation/quickstart.html.
For developers that wish to run Bro directly from the ``build/`` For developers that wish to run Bro directly from the ``build/``

5
NEWS
View file

@ -43,6 +43,11 @@ Bro 2.1
--enable-perftool-debug to indicate that the switch is only relevant --enable-perftool-debug to indicate that the switch is only relevant
for debugging the heap. for debugging the heap.
- Bro's ICMP analyzer now handles both IPv4 and IPv6 messages with a
joint set of events. The `icmp_conn` record got a new boolean field
'v6' that indicates whether the ICMP message is v4 or v6.
TODO: Extend. TODO: Extend.
Bro 2.0 Bro 2.0

View file

@ -1 +1 @@
2.0-273 2.0-338

@ -1 +1 @@
Subproject commit dd1a3a95f07082efcd5274b21104a038d523d132 Subproject commit 71c37019bc371eb7863fb6aa47a7daa4540f4f1f

@ -1 +1 @@
Subproject commit a59b35bdada8f70fb1a59bf7bb2976534c86d378 Subproject commit d885987e7968669e34504b0403ac89bd13928e9a

@ -1 +1 @@
Subproject commit a4046c2f79b6ab0ac19ae8be94b79c6ce578bea7 Subproject commit 157c18427cb9bb52564e65d8224b95f70dc79e66

@ -1 +1 @@
Subproject commit c86b7e990b4d39cd48c0cb692077aa081b418149 Subproject commit 5137c6375162f121348095205aaaec04a86de632

@ -1 +1 @@
Subproject commit c8e8fe477b5dec635e5ce00f3f764fad069c549c Subproject commit 76876ce0e7da4888c91b3aea024c5cfd36405310

2
cmake

@ -1 +1 @@
Subproject commit 60b28739379da75f26c5c2a312b7886f5209a1cc Subproject commit 49e0201d828e043acc835be6313ae7daaa5c9f52

View file

@ -155,3 +155,47 @@
#ifndef HAVE_DLT_PPP_SERIAL #ifndef HAVE_DLT_PPP_SERIAL
#define DLT_PPP_SERIAL @DLT_PPP_SERIAL@ #define DLT_PPP_SERIAL @DLT_PPP_SERIAL@
#endif #endif
/* IPv6 Next Header values defined by RFC 3542 */
#cmakedefine HAVE_IPPROTO_HOPOPTS
#ifndef HAVE_IPPROTO_HOPOPTS
#define IPPROTO_HOPOPTS 0
#endif
#cmakedefine HAVE_IPPROTO_IPV6
#ifndef HAVE_IPPROTO_IPV6
#define IPPROTO_IPV6 41
#endif
#cmakedefine HAVE_IPPROTO_ROUTING
#ifndef HAVE_IPPROTO_ROUTING
#define IPPROTO_ROUTING 43
#endif
#cmakedefine HAVE_IPPROTO_FRAGMENT
#ifndef HAVE_IPPROTO_FRAGMENT
#define IPPROTO_FRAGMENT 44
#endif
#cmakedefine HAVE_IPPROTO_ESP
#ifndef HAVE_IPPROTO_ESP
#define IPPROTO_ESP 50
#endif
#cmakedefine HAVE_IPPROTO_AH
#ifndef HAVE_IPPROTO_AH
#define IPPROTO_AH 51
#endif
#cmakedefine HAVE_IPPROTO_ICMPV6
#ifndef HAVE_IPPROTO_ICMPV6
#define IPPROTO_ICMPV6 58
#endif
#cmakedefine HAVE_IPPROTO_NONE
#ifndef HAVE_IPPROTO_NONE
#define IPPROTO_NONE 59
#endif
#cmakedefine HAVE_IPPROTO_DSTOPTS
#ifndef HAVE_IPPROTO_DSTOPTS
#define IPPROTO_DSTOPTS 60
#endif
/* IPv6 options structure defined by RFC 3542 */
#cmakedefine HAVE_IP6_OPT
/* Common IPv6 extension structure */
#cmakedefine HAVE_IP6_EXT

31
configure vendored
View file

@ -24,6 +24,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--prefix=PREFIX installation directory [/usr/local/bro] --prefix=PREFIX installation directory [/usr/local/bro]
--scriptdir=PATH root installation directory for Bro scripts --scriptdir=PATH root installation directory for Bro scripts
[PREFIX/share/bro] [PREFIX/share/bro]
--conf-files-dir=PATH config files installation directory [PREFIX/etc]
Optional Features: Optional Features:
--enable-debug compile in debugging mode --enable-debug compile in debugging mode
@ -31,7 +32,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--enable-perftools-debug use Google's perftools for debugging --enable-perftools-debug use Google's perftools for debugging
--disable-broccoli don't build or install the Broccoli library --disable-broccoli don't build or install the Broccoli library
--disable-broctl don't install Broctl --disable-broctl don't install Broctl
--disable-auxtools don't build or install auxilliary tools --disable-auxtools don't build or install auxiliary tools
--disable-python don't try to build python bindings for broccoli --disable-python don't try to build python bindings for broccoli
--disable-ruby don't try to build ruby bindings for broccoli --disable-ruby don't try to build ruby bindings for broccoli
@ -88,13 +89,15 @@ append_cache_entry () {
# set defaults # set defaults
builddir=build builddir=build
prefix=/usr/local/bro
CMakeCacheEntries="" CMakeCacheEntries=""
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local/bro append_cache_entry CMAKE_INSTALL_PREFIX PATH $prefix
append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro append_cache_entry BRO_ROOT_DIR PATH $prefix
append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl append_cache_entry PY_MOD_INSTALL_DIR PATH $prefix/lib/broctl
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING /usr/local/bro/share/bro append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $prefix/share/bro
append_cache_entry BRO_ETC_INSTALL_DIR PATH $prefix/etc
append_cache_entry ENABLE_DEBUG BOOL false append_cache_entry ENABLE_DEBUG BOOL false
append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL false append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL false
append_cache_entry BinPAC_SKIP_INSTALL BOOL true append_cache_entry BinPAC_SKIP_INSTALL BOOL true
append_cache_entry BUILD_SHARED_LIBS BOOL true append_cache_entry BUILD_SHARED_LIBS BOOL true
append_cache_entry INSTALL_AUX_TOOLS BOOL true append_cache_entry INSTALL_AUX_TOOLS BOOL true
@ -122,17 +125,19 @@ while [ $# -ne 0 ]; do
CMakeGenerator="$optarg" CMakeGenerator="$optarg"
;; ;;
--prefix=*) --prefix=*)
prefix=$optarg
append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg
append_cache_entry BRO_ROOT_DIR PATH $optarg append_cache_entry BRO_ROOT_DIR PATH $optarg
append_cache_entry PY_MOD_INSTALL_DIR PATH $optarg/lib/broctl append_cache_entry PY_MOD_INSTALL_DIR PATH $optarg/lib/broctl
if [ "$user_set_scriptdir" != "true" ]; then
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $optarg/share/bro
fi
;; ;;
--scriptdir=*) --scriptdir=*)
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $optarg append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $optarg
user_set_scriptdir="true" user_set_scriptdir="true"
;; ;;
--conf-files-dir=*)
append_cache_entry BRO_ETC_INSTALL_DIR PATH $optarg
user_set_conffilesdir="true"
;;
--enable-debug) --enable-debug)
append_cache_entry ENABLE_DEBUG BOOL true append_cache_entry ENABLE_DEBUG BOOL true
;; ;;
@ -240,6 +245,14 @@ while [ $# -ne 0 ]; do
shift shift
done done
if [ "$user_set_scriptdir" != "true" ]; then
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $prefix/share/bro
fi
if [ "$user_set_conffilesdir" != "true" ]; then
append_cache_entry BRO_ETC_INSTALL_DIR PATH $prefix/etc
fi
if [ -d $builddir ]; then if [ -d $builddir ]; then
# If build directory exists, check if it has a CMake cache # If build directory exists, check if it has a CMake cache
if [ -f $builddir/CMakeCache.txt ]; then if [ -f $builddir/CMakeCache.txt ]; then

View file

@ -105,5 +105,8 @@ event protocol_violation(c: connection, atype: count, aid: count,
reason: string) &priority=-5 reason: string) &priority=-5
{ {
if ( c?$dpd ) if ( c?$dpd )
{
Log::write(DPD::LOG, c$dpd); Log::write(DPD::LOG, c$dpd);
delete c$dpd;
}
} }

View file

@ -23,7 +23,10 @@ redef Cluster::worker2manager_events += /Notice::cluster_notice/;
@if ( Cluster::local_node_type() != Cluster::MANAGER ) @if ( Cluster::local_node_type() != Cluster::MANAGER )
# The notice policy is completely handled by the manager and shouldn't be # The notice policy is completely handled by the manager and shouldn't be
# done by workers or proxies to save time for packet processing. # done by workers or proxies to save time for packet processing.
redef policy = {}; event bro_init() &priority=-11
{
Notice::policy = table();
}
event Notice::begin_suppression(n: Notice::Info) event Notice::begin_suppression(n: Notice::Info)
{ {

View file

@ -92,6 +92,8 @@ type icmp_conn: record {
itype: count; ##< The ICMP type of the packet that triggered the instantiation of the record. itype: count; ##< The ICMP type of the packet that triggered the instantiation of the record.
icode: count; ##< The ICMP code of the packet that triggered the instantiation of the record. icode: count; ##< The ICMP code of the packet that triggered the instantiation of the record.
len: count; ##< The length of the ICMP payload of the packet that triggered the instantiation of the record. len: count; ##< The length of the ICMP payload of the packet that triggered the instantiation of the record.
hlim: count; ##< The encapsulating IP header's Hop Limit value.
v6: bool; ##< True if it's an ICMPv6 packet.
}; };
## Packet context part of an ICMP message. The fields of this record reflect the ## Packet context part of an ICMP message. The fields of this record reflect the
@ -100,11 +102,13 @@ type icmp_conn: record {
## .. bro:see:: icmp_time_exceeded icmp_unreachable ## .. bro:see:: icmp_time_exceeded icmp_unreachable
type icmp_context: record { type icmp_context: record {
id: conn_id; ##< The packet's 4-tuple. id: conn_id; ##< The packet's 4-tuple.
len: count; ##< The lenght of the packet's IP header. len: count; ##< The length of the IP packet (headers + payload).
proto: count; ##< The packet's transport-layer protocol. proto: count; ##< The packet's transport-layer protocol.
frag_offset: count; ##< The packet's fragementation offset. frag_offset: count; ##< The packet's fragementation offset.
## True if the packet's IP header is fully included in the context. If that is not ## True if the packet's IP header is not fully included in the context
## the case, the other fields will all be set to null values. ## or if there is not enough of the transport header to determine source
## and destination ports. If that is the cast, the appropriate fields
## of this record will be set to null values.
bad_hdr_len: bool; bad_hdr_len: bool;
bad_checksum: bool; ##< True if the packet's IP checksum is not correct. bad_checksum: bool; ##< True if the packet's IP checksum is not correct.
MF: bool; ##< True if the packets *more fragements* flag is set. MF: bool; ##< True if the packets *more fragements* flag is set.
@ -947,6 +951,7 @@ const IPPROTO_IPIP = 4; ##< IP encapsulation in IP.
const IPPROTO_TCP = 6; ##< TCP. const IPPROTO_TCP = 6; ##< TCP.
const IPPROTO_UDP = 17; ##< User datagram protocol. const IPPROTO_UDP = 17; ##< User datagram protocol.
const IPPROTO_IPV6 = 41; ##< IPv6 header. const IPPROTO_IPV6 = 41; ##< IPv6 header.
const IPPROTO_ICMPV6 = 58; ##< ICMP for IPv6.
const IPPROTO_RAW = 255; ##< Raw IP packet. const IPPROTO_RAW = 255; ##< Raw IP packet.
# Definitions for IPv6 extension headers. # Definitions for IPv6 extension headers.
@ -2324,6 +2329,11 @@ type bt_tracker_headers: table[string] of string;
## BPF filter the user has set via the -f command line options. Empty if none. ## BPF filter the user has set via the -f command line options. Empty if none.
const cmd_line_bpf_filter = "" &redef; const cmd_line_bpf_filter = "" &redef;
## The maximum number of open files to keep cached at a given time.
## If set to zero, this is automatically determined by inspecting
## the current/maximum limit on open files for the process.
const max_files_in_cache = 0 &redef;
## Deprecated. ## Deprecated.
const log_rotate_interval = 0 sec &redef; const log_rotate_interval = 0 sec &redef;

View file

@ -6,6 +6,7 @@
@load ./utils-commands @load ./utils-commands
@load base/utils/paths @load base/utils/paths
@load base/utils/numbers @load base/utils/numbers
@load base/utils/addrs
module FTP; module FTP;
@ -22,7 +23,7 @@ export {
const default_capture_password = F &redef; const default_capture_password = F &redef;
## User IDs that can be considered "anonymous". ## User IDs that can be considered "anonymous".
const guest_ids = { "anonymous", "ftp", "guest" } &redef; const guest_ids = { "anonymous", "ftp", "ftpuser", "guest" } &redef;
type Info: record { type Info: record {
## Time when the command was sent. ## Time when the command was sent.
@ -160,17 +161,16 @@ function ftp_message(s: Info)
# or it's a deliberately logged command. # or it's a deliberately logged command.
if ( |s$tags| > 0 || (s?$cmdarg && s$cmdarg$cmd in logged_commands) ) if ( |s$tags| > 0 || (s?$cmdarg && s$cmdarg$cmd in logged_commands) )
{ {
if ( s?$password && to_lower(s$user) !in guest_ids ) if ( s?$password &&
! s$capture_password &&
to_lower(s$user) !in guest_ids )
{
s$password = "<hidden>"; s$password = "<hidden>";
}
local arg = s$cmdarg$arg; local arg = s$cmdarg$arg;
if ( s$cmdarg$cmd in file_cmds ) if ( s$cmdarg$cmd in file_cmds )
{ arg = fmt("ftp://%s%s", addr_to_uri(s$id$resp_h), build_path_compressed(s$cwd, arg));
if ( is_v4_addr(s$id$resp_h) )
arg = fmt("ftp://%s%s", s$id$resp_h, build_path_compressed(s$cwd, arg));
else
arg = fmt("ftp://[%s]%s", s$id$resp_h, build_path_compressed(s$cwd, arg));
}
s$ts=s$cmdarg$ts; s$ts=s$cmdarg$ts;
s$command=s$cmdarg$cmd; s$command=s$cmdarg$cmd;

View file

@ -1,6 +1,7 @@
##! Utilities specific for HTTP processing. ##! Utilities specific for HTTP processing.
@load ./main @load ./main
@load base/utils/addrs
module HTTP; module HTTP;
@ -51,7 +52,7 @@ function extract_keys(data: string, kv_splitter: pattern): string_vec
function build_url(rec: Info): string function build_url(rec: Info): string
{ {
local uri = rec?$uri ? rec$uri : "/<missed_request>"; local uri = rec?$uri ? rec$uri : "/<missed_request>";
local host = rec?$host ? rec$host : fmt("%s", rec$id$resp_h); local host = rec?$host ? rec$host : addr_to_uri(rec$id$resp_h);
if ( rec$id$resp_p != 80/tcp ) if ( rec$id$resp_p != 80/tcp )
host = fmt("%s:%s", host, rec$id$resp_p); host = fmt("%s:%s", host, rec$id$resp_p);
return fmt("%s%s", host, uri); return fmt("%s%s", host, uri);

View file

@ -77,8 +77,12 @@ export {
[12] = "srp", [12] = "srp",
[13] = "signature_algorithms", [13] = "signature_algorithms",
[14] = "use_srtp", [14] = "use_srtp",
[15] = "heartbeat",
[35] = "SessionTicket TLS", [35] = "SessionTicket TLS",
[40] = "extended_random",
[13172] = "next_protocol_negotiation", [13172] = "next_protocol_negotiation",
[13175] = "origin_bound_certificates",
[13180] = "encrypted_client_certificates",
[65281] = "renegotiation_info" [65281] = "renegotiation_info"
} &default=function(i: count):string { return fmt("unknown-%d", i); }; } &default=function(i: count):string { return fmt("unknown-%d", i); };

View file

@ -24,6 +24,8 @@ export {
session_id: string &log &optional; session_id: string &log &optional;
## Subject of the X.509 certificate offered by the server. ## Subject of the X.509 certificate offered by the server.
subject: string &log &optional; subject: string &log &optional;
## Subject of the signer of the X.509 certificate offered by the server.
issuer_subject: string &log &optional;
## NotValidBefore field value from the server certificate. ## NotValidBefore field value from the server certificate.
not_valid_before: time &log &optional; not_valid_before: time &log &optional;
## NotValidAfter field value from the serve certificate. ## NotValidAfter field value from the serve certificate.
@ -146,6 +148,7 @@ event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: coun
# Also save other certificate information about the primary cert. # Also save other certificate information about the primary cert.
c$ssl$subject = cert$subject; c$ssl$subject = cert$subject;
c$ssl$issuer_subject = cert$issuer;
c$ssl$not_valid_before = cert$not_valid_before; c$ssl$not_valid_before = cert$not_valid_before;
c$ssl$not_valid_after = cert$not_valid_after; c$ssl$not_valid_after = cert$not_valid_after;
} }

View file

@ -98,3 +98,18 @@ function find_ip_addresses(input: string): string_array
} }
return output; return output;
} }
## Returns the string representation of an IP address suitable for inclusion
## in a URI. For IPv4, this does no special formatting, but for IPv6, the
## address is included in square brackets.
##
## a: the address to make suitable for URI inclusion.
##
## Returns: the string representation of *a* suitable for URI inclusion.
function addr_to_uri(a: addr): string
{
if ( is_v4_addr(a) )
return fmt("%s", a);
else
return fmt("[%s]", a);
}

View file

@ -1,10 +1,11 @@
@load ./addrs
## This function can be used to generate a consistent filename for when ## This function can be used to generate a consistent filename for when
## contents of a file, stream, or connection are being extracted to disk. ## contents of a file, stream, or connection are being extracted to disk.
function generate_extraction_filename(prefix: string, c: connection, suffix: string): string function generate_extraction_filename(prefix: string, c: connection, suffix: string): string
{ {
local conn_info = fmt("%s:%d-%s:%d", local conn_info = fmt("%s:%d-%s:%d", addr_to_uri(c$id$orig_h), c$id$orig_p,
c$id$orig_h, c$id$orig_p, c$id$resp_h, c$id$resp_p); addr_to_uri(c$id$resp_h), c$id$resp_p);
if ( prefix != "" ) if ( prefix != "" )
conn_info = fmt("%s_%s", prefix, conn_info); conn_info = fmt("%s_%s", prefix, conn_info);

View file

@ -10,15 +10,19 @@ export {
const private_address_space: set[subnet] = { const private_address_space: set[subnet] = {
10.0.0.0/8, 10.0.0.0/8,
192.168.0.0/16, 192.168.0.0/16,
172.16.0.0/12,
100.64.0.0/10, # RFC6598 Carrier Grade NAT
127.0.0.0/8, 127.0.0.0/8,
172.16.0.0/12 [fe80::]/10,
[::1]/128,
} &redef; } &redef;
## Networks that are considered "local". ## Networks that are considered "local".
const local_nets: set[subnet] &redef; const local_nets: set[subnet] &redef;
## This is used for retrieving the subnet when you multiple ## This is used for retrieving the subnet when using multiple entries in
## :bro:id:`Site::local_nets`. A membership query can be done with an ## :bro:id:`Site::local_nets`. It's populated automatically from there.
## A membership query can be done with an
## :bro:type:`addr` and the table will yield the subnet it was found ## :bro:type:`addr` and the table will yield the subnet it was found
## within. ## within.
global local_nets_table: table[subnet] of subnet = {}; global local_nets_table: table[subnet] of subnet = {};
@ -40,27 +44,33 @@ export {
## Function that returns true if an address corresponds to one of ## Function that returns true if an address corresponds to one of
## the local networks, false if not. ## the local networks, false if not.
## The function inspects :bro:id:`Site::local_nets`.
global is_local_addr: function(a: addr): bool; global is_local_addr: function(a: addr): bool;
## Function that returns true if an address corresponds to one of ## Function that returns true if an address corresponds to one of
## the neighbor networks, false if not. ## the neighbor networks, false if not.
## The function inspects :bro:id:`Site::neighbor_nets`.
global is_neighbor_addr: function(a: addr): bool; global is_neighbor_addr: function(a: addr): bool;
## Function that returns true if an address corresponds to one of ## Function that returns true if an address corresponds to one of
## the private/unrouted networks, false if not. ## the private/unrouted networks, false if not.
## The function inspects :bro:id:`Site::private_address_space`.
global is_private_addr: function(a: addr): bool; global is_private_addr: function(a: addr): bool;
## Function that returns true if a host name is within a local ## Function that returns true if a host name is within a local
## DNS zone. ## DNS zone.
## The function inspects :bro:id:`Site::local_zones`.
global is_local_name: function(name: string): bool; global is_local_name: function(name: string): bool;
## Function that returns true if a host name is within a neighbor ## Function that returns true if a host name is within a neighbor
## DNS zone. ## DNS zone.
## The function inspects :bro:id:`Site::neighbor_zones`.
global is_neighbor_name: function(name: string): bool; global is_neighbor_name: function(name: string): bool;
## Function that returns a common separated list of email addresses ## Function that returns a common separated list of email addresses
## that are considered administrators for the IP address provided as ## that are considered administrators for the IP address provided as
## an argument. ## an argument.
## The function inspects :bro:id:`Site::local_admins`.
global get_emails: function(a: addr): string; global get_emails: function(a: addr): string;
} }

View file

@ -34,7 +34,7 @@
#include "Portmap.h" #include "Portmap.h"
#include "POP3.h" #include "POP3.h"
#include "SSH.h" #include "SSH.h"
#include "SSL-binpac.h" #include "SSL.h"
#include "Syslog-binpac.h" #include "Syslog-binpac.h"
#include "ConnSizeAnalyzer.h" #include "ConnSizeAnalyzer.h"
@ -49,18 +49,6 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer, { AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
ICMP_Analyzer::Available, 0, false }, ICMP_Analyzer::Available, 0, false },
{ AnalyzerTag::ICMP_TimeExceeded, "ICMP_TIMEEXCEEDED",
ICMP_TimeExceeded_Analyzer::InstantiateAnalyzer,
ICMP_TimeExceeded_Analyzer::Available, 0, false },
{ AnalyzerTag::ICMP_Unreachable, "ICMP_UNREACHABLE",
ICMP_Unreachable_Analyzer::InstantiateAnalyzer,
ICMP_Unreachable_Analyzer::Available, 0, false },
{ AnalyzerTag::ICMP_Echo, "ICMP_ECHO",
ICMP_Echo_Analyzer::InstantiateAnalyzer,
ICMP_Echo_Analyzer::Available, 0, false },
{ AnalyzerTag::ICMP_Redir, "ICMP_REDIR",
ICMP_Redir_Analyzer::InstantiateAnalyzer,
ICMP_Redir_Analyzer::Available, 0, false },
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer, { AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
TCP_Analyzer::Available, 0, false }, TCP_Analyzer::Available, 0, false },
@ -133,8 +121,8 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
HTTP_Analyzer_binpac::InstantiateAnalyzer, HTTP_Analyzer_binpac::InstantiateAnalyzer,
HTTP_Analyzer_binpac::Available, 0, false }, HTTP_Analyzer_binpac::Available, 0, false },
{ AnalyzerTag::SSL, "SSL", { AnalyzerTag::SSL, "SSL",
SSL_Analyzer_binpac::InstantiateAnalyzer, SSL_Analyzer::InstantiateAnalyzer,
SSL_Analyzer_binpac::Available, 0, false }, SSL_Analyzer::Available, 0, false },
{ AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC", { AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC",
Syslog_Analyzer_binpac::InstantiateAnalyzer, Syslog_Analyzer_binpac::InstantiateAnalyzer,
Syslog_Analyzer_binpac::Available, 0, false }, Syslog_Analyzer_binpac::Available, 0, false },

View file

@ -20,9 +20,7 @@ namespace AnalyzerTag {
PIA_TCP, PIA_UDP, PIA_TCP, PIA_UDP,
// Transport-layer analyzers. // Transport-layer analyzers.
ICMP, ICMP, TCP, UDP,
ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, ICMP_Redir,
TCP, UDP,
// Application-layer analyzers (hand-written). // Application-layer analyzers (hand-written).
BitTorrent, BitTorrentTracker, BitTorrent, BitTorrentTracker,

View file

@ -5,7 +5,6 @@
#include "util.h" #include "util.h"
#include "net_util.h" #include "net_util.h"
#include "md5.h"
#include "Anon.h" #include "Anon.h"
#include "Val.h" #include "Val.h"
#include "NetVar.h" #include "NetVar.h"

View file

@ -66,39 +66,44 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig)
{ {
uint64 entry_offset = orig ?
*interp->upflow()->next_message_offset() :
*interp->downflow()->next_message_offset();
uint64& this_stream_len = orig ? stream_len_orig : stream_len_resp;
bool& this_stop = orig ? stop_orig : stop_resp;
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
this_stream_len += len; // TODO: Code commented out for now. I think that shoving data that
// is definitely wrong into the parser seems like a really bad idea.
// The way it's currently tracking the next message offset isn't
// compatible with new 64bit int support in binpac either.
if ( entry_offset < this_stream_len ) //uint64 entry_offset = orig ?
{ // entry point is somewhere in the gap // *interp->upflow()->next_message_offset() :
DeliverWeird("Stopping BitTorrent analysis: cannot recover from content gap", orig); // *interp->downflow()->next_message_offset();
this_stop = true; //uint64& this_stream_len = orig ? stream_len_orig : stream_len_resp;
if ( stop_orig && stop_resp ) //bool& this_stop = orig ? stop_orig : stop_resp;
ProtocolViolation("BitTorrent: content gap and/or protocol violation"); //
} //this_stream_len += len;
else //
{ // fill the gap //if ( entry_offset < this_stream_len )
try // { // entry point is somewhere in the gap
{ // DeliverWeird("Stopping BitTorrent analysis: cannot recover from content gap", orig);
u_char gap[len]; // this_stop = true;
memset(gap, 0, len); // if ( stop_orig && stop_resp )
interp->NewData(orig, gap, gap + len); // ProtocolViolation("BitTorrent: content gap and/or protocol violation");
} // }
catch ( binpac::Exception const &e ) //else
{ // { // fill the gap
DeliverWeird("Stopping BitTorrent analysis: filling content gap failed", orig); // try
this_stop = true; // {
if ( stop_orig && stop_resp ) // u_char gap[len];
ProtocolViolation("BitTorrent: content gap and/or protocol violation"); // memset(gap, 0, len);
} // interp->NewData(orig, gap, gap + len);
} // }
// catch ( binpac::Exception const &e )
// {
// DeliverWeird("Stopping BitTorrent analysis: filling content gap failed", orig);
// this_stop = true;
// if ( stop_orig && stop_resp )
// ProtocolViolation("BitTorrent: content gap and/or protocol violation");
// }
// }
} }
void BitTorrent_Analyzer::EndpointEOF(TCP_Reassembler* endp) void BitTorrent_Analyzer::EndpointEOF(TCP_Reassembler* endp)

View file

@ -247,7 +247,6 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
) )
set(dns_SRCS nb_dns.c)
set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS
-fno-strict-aliasing) -fno-strict-aliasing)
@ -376,7 +375,7 @@ set(bro_SRCS
SMB.cc SMB.cc
SMTP.cc SMTP.cc
SSH.cc SSH.cc
SSL-binpac.cc SSL.cc
Scope.cc Scope.cc
SerializationFormat.cc SerializationFormat.cc
SerialObj.cc SerialObj.cc
@ -403,7 +402,6 @@ set(bro_SRCS
bsd-getopt-long.c bsd-getopt-long.c
bro_inet_ntop.c bro_inet_ntop.c
cq.c cq.c
md5.c
patricia.c patricia.c
setsignal.c setsignal.c
PacketDumper.cc PacketDumper.cc
@ -422,8 +420,8 @@ set(bro_SRCS
logging/writers/DataSeries.cc logging/writers/DataSeries.cc
logging/writers/None.cc logging/writers/None.cc
${dns_SRCS} nb_dns.c
${openssl_SRCS} digest.h
) )
collect_headers(bro_HEADERS ${bro_SRCS}) collect_headers(bro_HEADERS ${bro_SRCS})

View file

@ -2,9 +2,10 @@
#include "config.h" #include "config.h"
#include <openssl/md5.h>
#include "EquivClass.h" #include "EquivClass.h"
#include "DFA.h" #include "DFA.h"
#include "md5.h"
int dfa_state_cache_size = 10000; int dfa_state_cache_size = 10000;
@ -312,8 +313,8 @@ DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas,
{ {
// We assume that state ID's don't exceed 10 digits, plus // We assume that state ID's don't exceed 10 digits, plus
// we allow one more character for the delimiter. // we allow one more character for the delimiter.
md5_byte_t id_tag[nfas.length() * 11 + 1]; u_char id_tag[nfas.length() * 11 + 1];
md5_byte_t* p = id_tag; u_char* p = id_tag;
for ( int i = 0; i < nfas.length(); ++i ) for ( int i = 0; i < nfas.length(); ++i )
{ {
@ -335,12 +336,8 @@ DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas,
// We use the short MD5 instead of the full string for the // We use the short MD5 instead of the full string for the
// HashKey because the data is copied into the key. // HashKey because the data is copied into the key.
md5_state_t state; u_char digest[16];
md5_byte_t digest[16]; MD5(id_tag, p - id_tag, digest);
md5_init(&state);
md5_append(&state, id_tag, p - id_tag);
md5_finish(&state, digest);
*hash = new HashKey(&digest, sizeof(digest)); *hash = new HashKey(&digest, sizeof(digest));
CacheEntry* e = states.Lookup(*hash); CacheEntry* e = states.Lookup(*hash);

View file

@ -185,46 +185,8 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
break; break;
case TRANSPORT_ICMP: { case TRANSPORT_ICMP: {
const struct icmp* icmpp = (const struct icmp *) data; root = icmp = new ICMP_Analyzer(conn);
switch ( icmpp->icmp_type ) { DBG_DPD(conn, "activated ICMP analyzer");
case ICMP_ECHO:
case ICMP_ECHOREPLY:
if ( ICMP_Echo_Analyzer::Available() )
{
root = icmp = new ICMP_Echo_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Echo analyzer");
}
break;
case ICMP_REDIRECT:
if ( ICMP_Redir_Analyzer::Available() )
{
root = new ICMP_Redir_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Redir analyzer");
}
break;
case ICMP_UNREACH:
if ( ICMP_Unreachable_Analyzer::Available() )
{
root = icmp = new ICMP_Unreachable_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Unreachable analyzer");
}
break;
case ICMP_TIMXCEED:
if ( ICMP_TimeExceeded_Analyzer::Available() )
{
root = icmp = new ICMP_TimeExceeded_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Time Exceeded analyzer");
}
break;
}
if ( ! root )
root = icmp = new ICMP_Analyzer(conn);
analyzed = true; analyzed = true;
break; break;
} }

View file

@ -74,9 +74,8 @@ void RotateTimer::Dispatch(double t, int is_expire)
// The following could in principle be part of a "file manager" object. // The following could in principle be part of a "file manager" object.
#define MAX_FILE_CACHE_SIZE 32 #define MAX_FILE_CACHE_SIZE 512
static int num_files_in_cache = 0; static int num_files_in_cache = 0;
static int max_files_in_cache = 0;
static BroFile* head = 0; static BroFile* head = 0;
static BroFile* tail = 0; static BroFile* tail = 0;
@ -87,12 +86,9 @@ double BroFile::default_rotation_size = 0;
// that we should use for the cache. // that we should use for the cache.
static int maximize_num_fds() static int maximize_num_fds()
{ {
#ifdef NO_HAVE_SETRLIMIT
return MAX_FILE_CACHE_SIZE;
#else
struct rlimit rl; struct rlimit rl;
if ( getrlimit(RLIMIT_NOFILE, &rl) < 0 ) if ( getrlimit(RLIMIT_NOFILE, &rl) < 0 )
reporter->InternalError("maximize_num_fds(): getrlimit failed"); reporter->FatalError("maximize_num_fds(): getrlimit failed");
if ( rl.rlim_max == RLIM_INFINITY ) if ( rl.rlim_max == RLIM_INFINITY )
{ {
@ -108,10 +104,9 @@ static int maximize_num_fds()
rl.rlim_cur = rl.rlim_max; rl.rlim_cur = rl.rlim_max;
if ( setrlimit(RLIMIT_NOFILE, &rl) < 0 ) if ( setrlimit(RLIMIT_NOFILE, &rl) < 0 )
reporter->InternalError("maximize_num_fds(): setrlimit failed"); reporter->FatalError("maximize_num_fds(): setrlimit failed");
return rl.rlim_cur / 2; return rl.rlim_cur / 2;
#endif
} }
@ -172,7 +167,7 @@ const char* BroFile::Name() const
return 0; return 0;
} }
bool BroFile::Open(FILE* file) bool BroFile::Open(FILE* file, const char* mode)
{ {
open_time = network_time ? network_time : current_time(); open_time = network_time ? network_time : current_time();
@ -196,7 +191,12 @@ bool BroFile::Open(FILE* file)
InstallRotateTimer(); InstallRotateTimer();
if ( ! f ) if ( ! f )
f = fopen(name, access); {
if ( ! mode )
f = fopen(name, access);
else
f = fopen(name, mode);
}
SetBuf(buffered); SetBuf(buffered);
@ -846,8 +846,8 @@ BroFile* BroFile::Unserialize(UnserialInfo* info)
} }
} }
// Otherwise, open. // Otherwise, open, but don't clobber.
if ( ! file->Open() ) if ( ! file->Open(0, "a") )
{ {
info->s->Error(fmt("cannot open %s: %s", info->s->Error(fmt("cannot open %s: %s",
file->name, strerror(errno))); file->name, strerror(errno)));

View file

@ -87,7 +87,13 @@ protected:
BroFile() { Init(); } BroFile() { Init(); }
void Init(); void Init();
bool Open(FILE* f = 0); // if file is given, it's an open file to use
/**
* If file is given, it's an open file to use already.
* If file is not given and mode is, the filename will be opened with that
* access mode.
*/
bool Open(FILE* f = 0, const char* mode = 0);
BroFile* Prev() { return prev; } BroFile* Prev() { return prev; }
BroFile* Next() { return next; } BroFile* Next() { return next; }

View file

@ -150,7 +150,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n)
{ {
IP_Hdr proto_h(proto_hdr, false); IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
if ( memcmp((const void*) b1, (const void*) b2, n) ) if ( memcmp((const void*) b1, (const void*) b2, n) )
s->Weird("fragment_inconsistency", &proto_h); s->Weird("fragment_inconsistency", &proto_h);
@ -182,7 +182,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
// can happen for benign reasons when we're // can happen for benign reasons when we're
// intermingling parts of two fragmented packets. // intermingling parts of two fragmented packets.
IP_Hdr proto_h(proto_hdr, false); IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
s->Weird("fragment_size_inconsistency", &proto_h); s->Weird("fragment_size_inconsistency", &proto_h);
// We decide to analyze the contiguous portion now. // We decide to analyze the contiguous portion now.
@ -196,7 +196,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
else if ( last_block->upper > frag_size ) else if ( last_block->upper > frag_size )
{ {
IP_Hdr proto_h(proto_hdr, false); IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
s->Weird("fragment_size_inconsistency", &proto_h); s->Weird("fragment_size_inconsistency", &proto_h);
frag_size = last_block->upper; frag_size = last_block->upper;
} }
@ -250,8 +250,8 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
{ {
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40); reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto); const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
reassembled_pkt = new IP_Hdr(reassem6, true, chain); reassembled_pkt = new IP_Hdr(reassem6, true, n, chain);
} }
else else

View file

@ -29,7 +29,6 @@
#include <algorithm> #include <algorithm>
#include "md5.h"
#include "Base64.h" #include "Base64.h"
#include "Stmt.h" #include "Stmt.h"
#include "Scope.h" #include "Scope.h"

View file

@ -9,6 +9,8 @@
#include "Event.h" #include "Event.h"
#include "ICMP.h" #include "ICMP.h"
#include <netinet/icmp6.h>
ICMP_Analyzer::ICMP_Analyzer(Connection* c) ICMP_Analyzer::ICMP_Analyzer(Connection* c)
: TransportLayerAnalyzer(AnalyzerTag::ICMP, c) : TransportLayerAnalyzer(AnalyzerTag::ICMP, c)
{ {
@ -32,7 +34,7 @@ void ICMP_Analyzer::Done()
matcher_state.FinishEndpointMatcher(); matcher_state.FinishEndpointMatcher();
} }
void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data, void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
bool is_orig, int seq, const IP_Hdr* ip, int caplen) bool is_orig, int seq, const IP_Hdr* ip, int caplen)
{ {
assert(ip); assert(ip);
@ -46,13 +48,33 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
PacketContents(data + 8, min(len, caplen) - 8); PacketContents(data + 8, min(len, caplen) - 8);
const struct icmp* icmpp = (const struct icmp*) data; const struct icmp* icmpp = (const struct icmp*) data;
len = arg_len;
if ( ! ignore_checksums && caplen >= len && assert(caplen >= len); // Should have been caught earlier already.
icmp_checksum(icmpp, len) != 0xffff )
if ( ! ignore_checksums )
{ {
Weird("bad_ICMP_checksum"); int chksum = 0;
return;
switch ( ip->NextProto() )
{
case IPPROTO_ICMP:
chksum = icmp_checksum(icmpp, len);
break;
case IPPROTO_ICMPV6:
chksum = icmp6_checksum(icmpp, ip, len);
break;
default:
reporter->InternalError("unexpected IP proto in ICMP analyzer");
break;
}
if ( chksum != 0xffff )
{
Weird("bad_ICMP_checksum");
return;
}
} }
Conn()->SetLastTime(current_timestamp); Conn()->SetLastTime(current_timestamp);
@ -77,7 +99,13 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
else else
len_stat += len; len_stat += len;
NextICMP(current_timestamp, icmpp, len, caplen, data); if ( ip->NextProto() == IPPROTO_ICMP )
NextICMP4(current_timestamp, icmpp, len, caplen, data, ip);
else if ( ip->NextProto() == IPPROTO_ICMPV6 )
NextICMP6(current_timestamp, icmpp, len, caplen, data, ip);
else
reporter->InternalError("unexpected next protocol in ICMP::DeliverPacket()");
if ( caplen >= len ) if ( caplen >= len )
ForwardPacket(len, data, is_orig, seq, ip, caplen); ForwardPacket(len, data, is_orig, seq, ip, caplen);
@ -87,26 +115,94 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
false, false, true); false, false, true);
} }
void ICMP_Analyzer::NextICMP(double /* t */, const struct icmp* /* icmpp */, void ICMP_Analyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
int /* len */, int /* caplen */, const u_char*& data, const IP_Hdr* ip_hdr )
const u_char*& /* data */)
{ {
ICMPEvent(icmp_sent); switch ( icmpp->icmp_type )
{
case ICMP_ECHO:
case ICMP_ECHOREPLY:
Echo(t, icmpp, len, caplen, data, ip_hdr);
break;
case ICMP_UNREACH:
case ICMP_TIMXCEED:
Context4(t, icmpp, len, caplen, data, ip_hdr);
break;
default:
ICMPEvent(icmp_sent, icmpp, len, 0, ip_hdr);
break;
}
} }
void ICMP_Analyzer::ICMPEvent(EventHandlerPtr f) void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
const u_char*& data, const IP_Hdr* ip_hdr )
{ {
switch ( icmpp->icmp_type )
{
// Echo types.
case ICMP6_ECHO_REQUEST:
case ICMP6_ECHO_REPLY:
Echo(t, icmpp, len, caplen, data, ip_hdr);
break;
// Error messages all have the same structure for their context,
// and are handled by the same function.
case ICMP6_PARAM_PROB:
case ICMP6_TIME_EXCEEDED:
case ICMP6_PACKET_TOO_BIG:
case ICMP6_DST_UNREACH:
Context6(t, icmpp, len, caplen, data, ip_hdr);
break;
// Router related messages.
case ND_REDIRECT:
Redirect(t, icmpp, len, caplen, data, ip_hdr);
break;
case ND_ROUTER_ADVERT:
RouterAdvert(t, icmpp, len, caplen, data, ip_hdr);
break;
case ND_NEIGHBOR_ADVERT:
NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr);
break;
case ND_NEIGHBOR_SOLICIT:
NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr);
break;
case ND_ROUTER_SOLICIT:
case ICMP6_ROUTER_RENUMBERING:
Router(t, icmpp, len, caplen, data, ip_hdr);
break;
#if 0
// Currently not specifically implemented.
case MLD_LISTENER_QUERY:
case MLD_LISTENER_REPORT:
case MLD_LISTENER_REDUCTION:
#endif
default:
if ( icmpp->icmp_type < 128 )
Context6(t, icmpp, len, caplen, data, ip_hdr);
else
ICMPEvent(icmp_sent, icmpp, len, 1, ip_hdr);
break;
}
}
void ICMP_Analyzer::ICMPEvent(EventHandlerPtr f, const struct icmp* icmpp,
int len, int icmpv6, const IP_Hdr* ip_hdr)
{
if ( ! f ) if ( ! f )
return; return;
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(BuildICMPVal()); vl->append(BuildICMPVal(icmpp, len, icmpv6, ip_hdr));
ConnectionEvent(f, vl); ConnectionEvent(f, vl);
} }
RecordVal* ICMP_Analyzer::BuildICMPVal() RecordVal* ICMP_Analyzer::BuildICMPVal(const struct icmp* icmpp, int len,
int icmpv6, const IP_Hdr* ip_hdr)
{ {
if ( ! icmp_conn_val ) if ( ! icmp_conn_val )
{ {
@ -114,9 +210,11 @@ RecordVal* ICMP_Analyzer::BuildICMPVal()
icmp_conn_val->Assign(0, new AddrVal(Conn()->OrigAddr())); icmp_conn_val->Assign(0, new AddrVal(Conn()->OrigAddr()));
icmp_conn_val->Assign(1, new AddrVal(Conn()->RespAddr())); icmp_conn_val->Assign(1, new AddrVal(Conn()->RespAddr()));
icmp_conn_val->Assign(2, new Val(type, TYPE_COUNT)); icmp_conn_val->Assign(2, new Val(icmpp->icmp_type, TYPE_COUNT));
icmp_conn_val->Assign(3, new Val(code, TYPE_COUNT)); icmp_conn_val->Assign(3, new Val(icmpp->icmp_code, TYPE_COUNT));
icmp_conn_val->Assign(4, new Val(len, TYPE_COUNT)); icmp_conn_val->Assign(4, new Val(len, TYPE_COUNT));
icmp_conn_val->Assign(5, new Val(ip_hdr->TTL(), TYPE_COUNT));
icmp_conn_val->Assign(6, new Val(icmpv6, TYPE_BOOL));
} }
Ref(icmp_conn_val); Ref(icmp_conn_val);
@ -124,91 +222,115 @@ RecordVal* ICMP_Analyzer::BuildICMPVal()
return icmp_conn_val; return icmp_conn_val;
} }
RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data) TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32* src_port, uint32* dst_port)
{ {
const struct ip* ip = (const struct ip *) data; const u_char* transport_hdr;
uint32 ip_hdr_len = ip->ip_hl * 4; uint32 ip_hdr_len = ip_hdr->HdrLen();
bool ip4 = ip_hdr->IP4_Hdr();
if ( ip4 )
transport_hdr = ((u_char *) ip_hdr->IP4_Hdr() + ip_hdr_len);
else
transport_hdr = ((u_char *) ip_hdr->IP6_Hdr() + ip_hdr_len);
TransportProto proto;
switch ( ip_hdr->NextProto() ) {
case 1: proto = TRANSPORT_ICMP; break;
case 6: proto = TRANSPORT_TCP; break;
case 17: proto = TRANSPORT_UDP; break;
case 58: proto = TRANSPORT_ICMP; break;
default: proto = TRANSPORT_UNKNOWN; break;
}
switch ( proto ) {
case TRANSPORT_ICMP:
{
const struct icmp* icmpp =
(const struct icmp *) transport_hdr;
bool is_one_way; // dummy
*src_port = ntohs(icmpp->icmp_type);
if ( ip4 )
*dst_port = ntohs(ICMP4_counterpart(icmpp->icmp_type,
icmpp->icmp_code, is_one_way));
else
*dst_port = ntohs(ICMP6_counterpart(icmpp->icmp_type,
icmpp->icmp_code, is_one_way));
break;
}
case TRANSPORT_TCP:
{
const struct tcphdr* tp =
(const struct tcphdr *) transport_hdr;
*src_port = ntohs(tp->th_sport);
*dst_port = ntohs(tp->th_dport);
break;
}
case TRANSPORT_UDP:
{
const struct udphdr* up =
(const struct udphdr *) transport_hdr;
*src_port = ntohs(up->uh_sport);
*dst_port = ntohs(up->uh_dport);
break;
}
default:
*src_port = *dst_port = ntohs(0);
break;
}
return proto;
}
RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
{
const IP_Hdr ip_hdr_data((const struct ip*) data, false);
const IP_Hdr* ip_hdr = &ip_hdr_data;
uint32 ip_hdr_len = ip_hdr->HdrLen();
uint32 ip_len, frag_offset; uint32 ip_len, frag_offset;
TransportProto proto = TRANSPORT_UNKNOWN; TransportProto proto = TRANSPORT_UNKNOWN;
int DF, MF, bad_hdr_len, bad_checksum; int DF, MF, bad_hdr_len, bad_checksum;
uint32 src_addr, dst_addr; IPAddr src_addr, dst_addr;
uint32 src_port, dst_port; uint32 src_port, dst_port;
if ( ip_hdr_len < sizeof(struct ip) || ip_hdr_len > uint32(len) ) if ( len < (int)sizeof(struct ip) || ip_hdr_len > uint32(len) )
{ // We don't have an entire IP header. {
// We don't have an entire IP header.
bad_hdr_len = 1; bad_hdr_len = 1;
ip_len = frag_offset = 0; ip_len = frag_offset = 0;
DF = MF = bad_checksum = 0; DF = MF = bad_checksum = 0;
src_addr = dst_addr = 0;
src_port = dst_port = 0; src_port = dst_port = 0;
} }
else else
{ {
bad_hdr_len = 0; bad_hdr_len = 0;
ip_len = ntohs(ip->ip_len); ip_len = ip_hdr->TotalLen();
bad_checksum = ones_complement_checksum((void*) ip, ip_hdr_len, 0) != 0xffff; bad_checksum = (ones_complement_checksum((void*) ip_hdr->IP4_Hdr(), ip_hdr_len, 0) != 0xffff);
src_addr = uint32(ip->ip_src.s_addr); src_addr = ip_hdr->SrcAddr();
dst_addr = uint32(ip->ip_dst.s_addr); dst_addr = ip_hdr->DstAddr();
switch ( ip->ip_p ) { DF = ip_hdr->DF();
case 1: proto = TRANSPORT_ICMP; break; MF = ip_hdr->MF();
case 6: proto = TRANSPORT_TCP; break; frag_offset = ip_hdr->FragOffset();
case 17: proto = TRANSPORT_UDP; break;
// Default uses TRANSPORT_UNKNOWN, per initialization above. if ( uint32(len) >= ip_hdr_len + 4 )
} proto = GetContextProtocol(ip_hdr, &src_port, &dst_port);
else
uint32 frag_field = ntohs(ip->ip_off);
DF = frag_field & 0x4000;
MF = frag_field & 0x2000;
frag_offset = frag_field & /* IP_OFFMASK not portable */ 0x1fff;
const u_char* transport_hdr = ((u_char *) ip + ip_hdr_len);
if ( uint32(len) < ip_hdr_len + 4 )
{ {
// 4 above is the magic number meaning that both // 4 above is the magic number meaning that both
// port numbers are included in the ICMP. // port numbers are included in the ICMP.
bad_hdr_len = 1;
src_port = dst_port = 0; src_port = dst_port = 0;
bad_hdr_len = 1;
} }
switch ( proto ) {
case TRANSPORT_ICMP:
{
const struct icmp* icmpp =
(const struct icmp *) transport_hdr;
bool is_one_way; // dummy
src_port = ntohs(icmpp->icmp_type);
dst_port = ntohs(ICMP_counterpart(icmpp->icmp_type,
icmpp->icmp_code,
is_one_way));
}
break;
case TRANSPORT_TCP:
{
const struct tcphdr* tp =
(const struct tcphdr *) transport_hdr;
src_port = ntohs(tp->th_sport);
dst_port = ntohs(tp->th_dport);
}
break;
case TRANSPORT_UDP:
{
const struct udphdr* up =
(const struct udphdr *) transport_hdr;
src_port = ntohs(up->uh_sport);
dst_port = ntohs(up->uh_dport);
}
break;
default:
src_port = dst_port = ntohs(0);
}
} }
RecordVal* iprec = new RecordVal(icmp_context); RecordVal* iprec = new RecordVal(icmp_context);
@ -218,8 +340,8 @@ RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
id_val->Assign(1, new PortVal(src_port, proto)); id_val->Assign(1, new PortVal(src_port, proto));
id_val->Assign(2, new AddrVal(dst_addr)); id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(dst_port, proto)); id_val->Assign(3, new PortVal(dst_port, proto));
iprec->Assign(0, id_val);
iprec->Assign(0, id_val);
iprec->Assign(1, new Val(ip_len, TYPE_COUNT)); iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
iprec->Assign(2, new Val(proto, TYPE_COUNT)); iprec->Assign(2, new Val(proto, TYPE_COUNT));
iprec->Assign(3, new Val(frag_offset, TYPE_COUNT)); iprec->Assign(3, new Val(frag_offset, TYPE_COUNT));
@ -231,6 +353,66 @@ RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
return iprec; return iprec;
} }
RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
{
int DF = 0, MF = 0, bad_hdr_len = 0;
TransportProto proto = TRANSPORT_UNKNOWN;
IPAddr src_addr;
IPAddr dst_addr;
uint32 ip_len, frag_offset = 0;
uint32 src_port, dst_port;
if ( len < (int)sizeof(struct ip6_hdr) )
{
bad_hdr_len = 1;
ip_len = 0;
src_port = dst_port = 0;
}
else
{
const IP_Hdr ip_hdr_data((const struct ip6_hdr*) data, false, len);
const IP_Hdr* ip_hdr = &ip_hdr_data;
ip_len = ip_hdr->TotalLen();
src_addr = ip_hdr->SrcAddr();
dst_addr = ip_hdr->DstAddr();
frag_offset = ip_hdr->FragOffset();
MF = ip_hdr->MF();
DF = ip_hdr->DF();
if ( uint32(len) >= uint32(ip_hdr->HdrLen() + 4) )
proto = GetContextProtocol(ip_hdr, &src_port, &dst_port);
else
{
// 4 above is the magic number meaning that both
// port numbers are included in the ICMP.
src_port = dst_port = 0;
bad_hdr_len = 1;
}
}
RecordVal* iprec = new RecordVal(icmp_context);
RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(src_port, proto));
id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(dst_port, proto));
iprec->Assign(0, id_val);
iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
iprec->Assign(2, new Val(proto, TYPE_COUNT));
iprec->Assign(3, new Val(frag_offset, TYPE_COUNT));
iprec->Assign(4, new Val(bad_hdr_len, TYPE_BOOL));
// bad_checksum is always false since IPv6 layer doesn't have a checksum.
iprec->Assign(5, new Val(0, TYPE_BOOL));
iprec->Assign(6, new Val(MF, TYPE_BOOL));
iprec->Assign(7, new Val(DF, TYPE_BOOL));
return iprec;
}
bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */) bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
{ {
return 0; return 0;
@ -294,15 +476,20 @@ unsigned int ICMP_Analyzer::MemoryAllocation() const
+ (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0); + (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0);
} }
ICMP_Echo_Analyzer::ICMP_Echo_Analyzer(Connection* c)
: ICMP_Analyzer(AnalyzerTag::ICMP_Echo, c)
{
}
void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len, void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data) int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{ {
EventHandlerPtr f = type == ICMP_ECHO ? icmp_echo_request : icmp_echo_reply; // For handling all Echo related ICMP messages
EventHandlerPtr f = 0;
if ( ip_hdr->NextProto() == IPPROTO_ICMPV6 )
f = (icmpp->icmp_type == ICMP6_ECHO_REQUEST)
? icmp_echo_request : icmp_echo_reply;
else
f = (icmpp->icmp_type == ICMP_ECHO)
? icmp_echo_request : icmp_echo_reply;
if ( ! f ) if ( ! f )
return; return;
@ -313,7 +500,7 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(BuildICMPVal()); vl->append(BuildICMPVal(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr));
vl->append(new Val(iid, TYPE_COUNT)); vl->append(new Val(iid, TYPE_COUNT));
vl->append(new Val(iseq, TYPE_COUNT)); vl->append(new Val(iseq, TYPE_COUNT));
vl->append(new StringVal(payload)); vl->append(new StringVal(payload));
@ -321,66 +508,236 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
ConnectionEvent(f, vl); ConnectionEvent(f, vl);
} }
ICMP_Redir_Analyzer::ICMP_Redir_Analyzer(Connection* c)
: ICMP_Analyzer(AnalyzerTag::ICMP_Redir, c)
{
}
void ICMP_Redir_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len, void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data) int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{ {
uint32 addr = ntohl(icmpp->icmp_hun.ih_void); EventHandlerPtr f = icmp_router_advertisement;
uint32 reachable, retrans;
memcpy(&reachable, data, sizeof(reachable));
memcpy(&retrans, data + sizeof(reachable), sizeof(retrans));
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(BuildICMPVal()); vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
vl->append(new AddrVal(htonl(addr))); vl->append(new Val(icmpp->icmp_num_addrs, TYPE_COUNT)); // Cur Hop Limit
vl->append(new Val(icmpp->icmp_wpa & 0x80, TYPE_BOOL)); // Managed
vl->append(new Val(icmpp->icmp_wpa & 0x40, TYPE_BOOL)); // Other
vl->append(new Val(icmpp->icmp_wpa & 0x20, TYPE_BOOL)); // Home Agent
vl->append(new Val((icmpp->icmp_wpa & 0x18)>>3, TYPE_COUNT)); // Pref
vl->append(new Val(icmpp->icmp_wpa & 0x04, TYPE_BOOL)); // Proxy
vl->append(new Val(icmpp->icmp_wpa & 0x02, TYPE_COUNT)); // Reserved
vl->append(new IntervalVal((double)ntohs(icmpp->icmp_lifetime), Seconds));
vl->append(new IntervalVal((double)ntohl(reachable), Milliseconds));
vl->append(new IntervalVal((double)ntohl(retrans), Milliseconds));
ConnectionEvent(icmp_redirect, vl); ConnectionEvent(f, vl);
} }
void ICMP_Context_Analyzer::NextICMP(double t, const struct icmp* icmpp, void ICMP_Analyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len,
int len, int caplen, const u_char*& data) int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{
EventHandlerPtr f = icmp_neighbor_advertisement;
in6_addr tgtaddr;
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
vl->append(new Val(icmpp->icmp_num_addrs & 0x80, TYPE_BOOL)); // Router
vl->append(new Val(icmpp->icmp_num_addrs & 0x40, TYPE_BOOL)); // Solicited
vl->append(new Val(icmpp->icmp_num_addrs & 0x20, TYPE_BOOL)); // Override
vl->append(new AddrVal(IPAddr(tgtaddr)));
ConnectionEvent(f, vl);
}
void ICMP_Analyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{
EventHandlerPtr f = icmp_neighbor_solicitation;
in6_addr tgtaddr;
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
vl->append(new AddrVal(IPAddr(tgtaddr)));
ConnectionEvent(f, vl);
}
void ICMP_Analyzer::Redirect(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{
EventHandlerPtr f = icmp_redirect;
in6_addr tgtaddr, dstaddr;
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
memcpy(&dstaddr.s6_addr, data + sizeof(tgtaddr.s6_addr), sizeof(dstaddr.s6_addr));
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
vl->append(new AddrVal(IPAddr(tgtaddr)));
vl->append(new AddrVal(IPAddr(dstaddr)));
ConnectionEvent(f, vl);
}
void ICMP_Analyzer::Router(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{ {
EventHandlerPtr f = 0; EventHandlerPtr f = 0;
switch ( type ) {
case ICMP_UNREACH: f = icmp_unreachable; break; switch ( icmpp->icmp_type )
case ICMP_TIMXCEED: f = icmp_time_exceeded; break; {
case ND_ROUTER_SOLICIT:
f = icmp_router_solicitation;
break;
case ICMP6_ROUTER_RENUMBERING:
default:
ICMPEvent(icmp_sent, icmpp, len, 1, ip_hdr);
return;
}
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
ConnectionEvent(f, vl);
} }
void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{
EventHandlerPtr f = 0;
switch ( icmpp->icmp_type )
{
case ICMP_UNREACH:
f = icmp_unreachable;
break;
case ICMP_TIMXCEED:
f = icmp_time_exceeded;
break;
}
if ( f ) if ( f )
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(BuildICMPVal()); vl->append(BuildICMPVal(icmpp, len, 0, ip_hdr));
vl->append(new Val(code, TYPE_COUNT)); vl->append(new Val(icmpp->icmp_code, TYPE_COUNT));
vl->append(ExtractICMPContext(caplen, data)); vl->append(ExtractICMP4Context(caplen, data));
ConnectionEvent(f, vl); ConnectionEvent(f, vl);
} }
} }
int ICMP_counterpart(int icmp_type, int icmp_code, bool& is_one_way) void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
{
EventHandlerPtr f = 0;
switch ( icmpp->icmp_type )
{
case ICMP6_DST_UNREACH:
f = icmp_unreachable;
break;
case ICMP6_PARAM_PROB:
f = icmp_parameter_problem;
break;
case ICMP6_TIME_EXCEEDED:
f = icmp_time_exceeded;
break;
case ICMP6_PACKET_TOO_BIG:
f = icmp_packet_too_big;
break;
default:
f = icmp_error_message;
break;
}
if ( f )
{
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal(icmpp, len, 1, ip_hdr));
vl->append(new Val(icmpp->icmp_code, TYPE_COUNT));
vl->append(ExtractICMP6Context(caplen, data));
ConnectionEvent(f, vl);
}
}
int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
{ {
is_one_way = false; is_one_way = false;
// return the counterpart type if one exists. This allows us // Return the counterpart type if one exists. This allows us
// to track corresponding ICMP requests/replies. // to track corresponding ICMP requests/replies.
// Note that for the two-way ICMP messages, icmp_code is // Note that for the two-way ICMP messages, icmp_code is
// always 0 (RFC 792). // always 0 (RFC 792).
switch ( icmp_type ) { switch ( icmp_type ) {
case ICMP_ECHO: return ICMP_ECHOREPLY; case ICMP_ECHO: return ICMP_ECHOREPLY;
case ICMP_ECHOREPLY: return ICMP_ECHO; case ICMP_ECHOREPLY: return ICMP_ECHO;
case ICMP_TSTAMP: return ICMP_TSTAMPREPLY; case ICMP_TSTAMP: return ICMP_TSTAMPREPLY;
case ICMP_TSTAMPREPLY: return ICMP_TSTAMP; case ICMP_TSTAMPREPLY: return ICMP_TSTAMP;
case ICMP_IREQ: return ICMP_IREQREPLY; case ICMP_IREQ: return ICMP_IREQREPLY;
case ICMP_IREQREPLY: return ICMP_IREQ; case ICMP_IREQREPLY: return ICMP_IREQ;
case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT; case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT;
case ICMP_MASKREQ: return ICMP_MASKREPLY; case ICMP_MASKREQ: return ICMP_MASKREPLY;
case ICMP_MASKREPLY: return ICMP_MASKREQ; case ICMP_MASKREPLY: return ICMP_MASKREQ;
default: is_one_way = true; return icmp_code; default: is_one_way = true; return icmp_code;
} }
} }
int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
{
is_one_way = false;
switch ( icmp_type ) {
case ICMP6_ECHO_REQUEST: return ICMP6_ECHO_REPLY;
case ICMP6_ECHO_REPLY: return ICMP6_ECHO_REQUEST;
case ND_ROUTER_SOLICIT: return ND_ROUTER_ADVERT;
case ND_ROUTER_ADVERT: return ND_ROUTER_SOLICIT;
case ND_NEIGHBOR_SOLICIT: return ND_NEIGHBOR_ADVERT;
case ND_NEIGHBOR_ADVERT: return ND_NEIGHBOR_SOLICIT;
case MLD_LISTENER_QUERY: return MLD_LISTENER_REPORT;
case MLD_LISTENER_REPORT: return MLD_LISTENER_QUERY;
// ICMP node information query and response respectively (not defined in
// icmp6.h)
case 139: return 140;
case 140: return 139;
// Home Agent Address Discovery Request Message and reply
case 144: return 145;
case 145: return 144;
// TODO: Add further counterparts.
default: is_one_way = true; return icmp_code;
}
}

View file

@ -33,21 +33,51 @@ protected:
virtual bool IsReuse(double t, const u_char* pkt); virtual bool IsReuse(double t, const u_char* pkt);
virtual unsigned int MemoryAllocation() const; virtual unsigned int MemoryAllocation() const;
void ICMPEvent(EventHandlerPtr f); void ICMPEvent(EventHandlerPtr f, const struct icmp* icmpp, int len,
int icmpv6, const IP_Hdr* ip_hdr);
void Echo(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void Context(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void Redirect(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void RouterAdvert(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void NeighborAdvert(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void NeighborSolicit(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void Router(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
void Describe(ODesc* d) const; void Describe(ODesc* d) const;
RecordVal* BuildICMPVal(); RecordVal* BuildICMPVal(const struct icmp* icmpp, int len, int icmpv6,
const IP_Hdr* ip_hdr);
virtual void NextICMP(double t, const struct icmp* icmpp, void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
int len, int caplen, const u_char*& data); const u_char*& data, const IP_Hdr* ip_hdr );
RecordVal* ExtractICMPContext(int len, const u_char*& data); RecordVal* ExtractICMP4Context(int len, const u_char*& data);
void Context4(double t, const struct icmp* icmpp, int len, int caplen,
const u_char*& data, const IP_Hdr* ip_hdr);
TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32* src_port,
uint32* dst_port);
void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
const u_char*& data, const IP_Hdr* ip_hdr );
RecordVal* ExtractICMP6Context(int len, const u_char*& data);
void Context6(double t, const struct icmp* icmpp, int len, int caplen,
const u_char*& data, const IP_Hdr* ip_hdr);
RecordVal* icmp_conn_val; RecordVal* icmp_conn_val;
int type; int type;
int code; int code;
int len;
int request_len, reply_len; int request_len, reply_len;
RuleMatcherState matcher_state; RuleMatcherState matcher_state;
@ -56,81 +86,9 @@ private:
void UpdateEndpointVal(RecordVal* endp, int is_orig); void UpdateEndpointVal(RecordVal* endp, int is_orig);
}; };
class ICMP_Echo_Analyzer : public ICMP_Analyzer {
public:
ICMP_Echo_Analyzer(Connection* conn);
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_Echo_Analyzer(conn); }
static bool Available() { return icmp_echo_request || icmp_echo_reply; }
protected:
ICMP_Echo_Analyzer() { }
virtual void NextICMP(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data);
};
class ICMP_Redir_Analyzer : public ICMP_Analyzer {
public:
ICMP_Redir_Analyzer(Connection* conn);
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_Redir_Analyzer(conn); }
static bool Available() { return icmp_redirect; }
protected:
ICMP_Redir_Analyzer() { }
virtual void NextICMP(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data);
};
class ICMP_Context_Analyzer : public ICMP_Analyzer {
public:
ICMP_Context_Analyzer(AnalyzerTag::Tag tag, Connection* conn)
: ICMP_Analyzer(tag, conn) { }
protected:
ICMP_Context_Analyzer() { }
virtual void NextICMP(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data);
};
class ICMP_TimeExceeded_Analyzer : public ICMP_Context_Analyzer {
public:
ICMP_TimeExceeded_Analyzer(Connection* conn)
: ICMP_Context_Analyzer(AnalyzerTag::ICMP_TimeExceeded, conn) { }
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_TimeExceeded_Analyzer(conn); }
static bool Available() { return icmp_time_exceeded; }
protected:
ICMP_TimeExceeded_Analyzer() { }
};
class ICMP_Unreachable_Analyzer : public ICMP_Context_Analyzer {
public:
ICMP_Unreachable_Analyzer(Connection* conn)
: ICMP_Context_Analyzer(AnalyzerTag::ICMP_Unreachable, conn) { }
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_Unreachable_Analyzer(conn); }
static bool Available() { return icmp_unreachable; }
protected:
ICMP_Unreachable_Analyzer() { }
};
// Returns the counterpart type to the given type (e.g., the counterpart // Returns the counterpart type to the given type (e.g., the counterpart
// to ICMP_ECHOREPLY is ICMP_ECHO). // to ICMP_ECHOREPLY is ICMP_ECHO).
extern int ICMP_counterpart(int icmp_type, int icmp_code, bool& is_one_way); extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
extern int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
#endif #endif

View file

@ -419,20 +419,36 @@ static inline bool isIPv6ExtHeader(uint8 type)
} }
} }
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next) void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len,
bool set_next, uint16 next)
{ {
length = 0; length = 0;
uint8 current_type, next_type; uint8 current_type, next_type;
next_type = IPPROTO_IPV6; next_type = IPPROTO_IPV6;
const u_char* hdrs = (const u_char*) ip6; const u_char* hdrs = (const u_char*) ip6;
if ( total_len < (int)sizeof(struct ip6_hdr) )
reporter->InternalError("IPv6_HdrChain::Init with truncated IP header");
do do
{ {
// We can't determine a given header's length if there's less than
// two bytes of data available (2nd byte of extension headers is length)
if ( total_len < 2 )
return;
current_type = next_type; current_type = next_type;
IPv6_Hdr* p = new IPv6_Hdr(current_type, hdrs); IPv6_Hdr* p = new IPv6_Hdr(current_type, hdrs);
next_type = p->NextHdr(); next_type = p->NextHdr();
uint16 len = p->Length(); uint16 cur_len = p->Length();
// If this header is truncated, don't add it to chain, don't go further.
if ( cur_len > total_len )
{
delete p;
return;
}
if ( set_next && next_type == IPPROTO_FRAGMENT ) if ( set_next && next_type == IPPROTO_FRAGMENT )
{ {
@ -444,16 +460,18 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next)
// Check for routing headers and remember final destination address. // Check for routing headers and remember final destination address.
if ( current_type == IPPROTO_ROUTING ) if ( current_type == IPPROTO_ROUTING )
ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, len); ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, cur_len);
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
// Only Mobile IPv6 has a destination option we care about right now. // Only Mobile IPv6 has a destination option we care about right now.
if ( current_type == IPPROTO_DSTOPTS ) if ( current_type == IPPROTO_DSTOPTS )
ProcessDstOpts((const struct ip6_dest*) hdrs, len); ProcessDstOpts((const struct ip6_dest*) hdrs, cur_len);
#endif #endif
hdrs += len; hdrs += cur_len;
length += len; length += cur_len;
total_len -= cur_len;
} while ( current_type != IPPROTO_FRAGMENT && } while ( current_type != IPPROTO_FRAGMENT &&
current_type != IPPROTO_ESP && current_type != IPPROTO_ESP &&
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6

View file

@ -12,7 +12,6 @@
#include <vector> #include <vector>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/ip6.h>
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
@ -142,12 +141,12 @@ public:
/** /**
* Initializes the header chain from an IPv6 header structure. * Initializes the header chain from an IPv6 header structure.
*/ */
IPv6_Hdr_Chain(const struct ip6_hdr* ip6) : IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len) :
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
homeAddr(0), homeAddr(0),
#endif #endif
finalDst(0) finalDst(0)
{ Init(ip6, false); } { Init(ip6, len, false); }
~IPv6_Hdr_Chain() ~IPv6_Hdr_Chain()
{ {
@ -250,14 +249,20 @@ protected:
* Initializes the header chain from an IPv6 header structure, and replaces * Initializes the header chain from an IPv6 header structure, and replaces
* the first next protocol pointer field that points to a fragment header. * the first next protocol pointer field that points to a fragment header.
*/ */
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) : IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next, int len) :
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
homeAddr(0), homeAddr(0),
#endif #endif
finalDst(0) finalDst(0)
{ Init(ip6, true, next); } { Init(ip6, len, true, next); }
void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0); /**
* Initializes the header chain from an IPv6 header structure of a given
* length, possibly setting the first next protocol pointer field that
* points to a fragment header.
*/
void Init(const struct ip6_hdr* ip6, int total_len, bool set_next,
uint16 next = 0);
/** /**
* Process a routing header and allocate/remember the final destination * Process a routing header and allocate/remember the final destination
@ -294,9 +299,21 @@ protected:
IPAddr* finalDst; IPAddr* finalDst;
}; };
/**
* A class that wraps either an IPv4 or IPv6 packet and abstracts methods
* for inquiring about common features between the two.
*/
class IP_Hdr { class IP_Hdr {
public: public:
IP_Hdr(const u_char* p, bool arg_del) /**
* Attempts to construct the header from some blob of data based on IP
* version number. Caller must have already checked that the header
* is not truncated.
* @param p pointer to memory containing an IPv4 or IPv6 packet.
* @param arg_del whether to take ownership of \a p pointer's memory.
* @param len the length of data, in bytes, pointed to by \a p.
*/
IP_Hdr(const u_char* p, bool arg_del, int len)
: ip4(0), ip6(0), del(arg_del), ip6_hdrs(0) : ip4(0), ip6(0), del(arg_del), ip6_hdrs(0)
{ {
if ( ((const struct ip*)p)->ip_v == 4 ) if ( ((const struct ip*)p)->ip_v == 4 )
@ -304,7 +321,7 @@ public:
else if ( ((const struct ip*)p)->ip_v == 6 ) else if ( ((const struct ip*)p)->ip_v == 6 )
{ {
ip6 = (const struct ip6_hdr*)p; ip6 = (const struct ip6_hdr*)p;
ip6_hdrs = new IPv6_Hdr_Chain(ip6); ip6_hdrs = new IPv6_Hdr_Chain(ip6, len);
} }
else else
{ {
@ -314,18 +331,38 @@ public:
} }
} }
/**
* Construct the header wrapper from an IPv4 packet. Caller must have
* already checked that the header is not truncated.
* @param arg_ip4 pointer to memory containing an IPv4 packet.
* @param arg_del whether to take ownership of \a arg_ip4 pointer's memory.
*/
IP_Hdr(const struct ip* arg_ip4, bool arg_del) IP_Hdr(const struct ip* arg_ip4, bool arg_del)
: ip4(arg_ip4), ip6(0), del(arg_del), ip6_hdrs(0) : ip4(arg_ip4), ip6(0), del(arg_del), ip6_hdrs(0)
{ {
} }
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, /**
* Construct the header wrapper from an IPv6 packet. Caller must have
* already checked that the static IPv6 header is not truncated. If
* the packet contains extension headers and they are truncated, that can
* be checked afterwards by comparing \a len with \a TotalLen. E.g.
* NetSessions::DoNextPacket does this to skip truncated packets.
* @param arg_ip6 pointer to memory containing an IPv6 packet.
* @param arg_del whether to take ownership of \a arg_ip6 pointer's memory.
* @param len the packet's length in bytes.
* @param c an already-constructed header chain to take ownership of.
*/
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len,
const IPv6_Hdr_Chain* c = 0) const IPv6_Hdr_Chain* c = 0)
: ip4(0), ip6(arg_ip6), del(arg_del), : ip4(0), ip6(arg_ip6), del(arg_del),
ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6)) ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len))
{ {
} }
/**
* Destructor.
*/
~IP_Hdr() ~IP_Hdr()
{ {
if ( ip6 ) if ( ip6 )
@ -340,8 +377,14 @@ public:
} }
} }
/**
* If an IPv4 packet is wrapped, return a pointer to it, else null.
*/
const struct ip* IP4_Hdr() const { return ip4; } const struct ip* IP4_Hdr() const { return ip4; }
/**
* If an IPv6 packet is wrapped, return a pointer to it, else null.
*/
const struct ip6_hdr* IP6_Hdr() const { return ip6; } const struct ip6_hdr* IP6_Hdr() const { return ip6; }
/** /**
@ -441,9 +484,15 @@ public:
{ return ip4 ? ip4->ip_p : { return ip4 ? ip4->ip_p :
((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); } ((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); }
/**
* Returns the IPv4 Time to Live or IPv6 Hop Limit field.
*/
unsigned char TTL() const unsigned char TTL() const
{ return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; } { return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
/**
* Returns whether the IP header indicates this packet is a fragment.
*/
bool IsFragment() const bool IsFragment() const
{ return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : { return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 :
ip6_hdrs->IsFragment(); } ip6_hdrs->IsFragment(); }

View file

@ -4,6 +4,7 @@
#include "MIME.h" #include "MIME.h"
#include "Event.h" #include "Event.h"
#include "Reporter.h" #include "Reporter.h"
#include "digest.h"
// Here are a few things to do: // Here are a few things to do:
// //
@ -1008,7 +1009,7 @@ void MIME_Mail::Done()
if ( compute_content_hash && mime_content_hash ) if ( compute_content_hash && mime_content_hash )
{ {
u_char* digest = new u_char[16]; u_char* digest = new u_char[16];
md5_finish(&md5_hash, digest); md5_final(&md5_hash, digest);
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(analyzer->BuildConnVal()); vl->append(analyzer->BuildConnVal());
@ -1096,7 +1097,7 @@ void MIME_Mail::SubmitData(int len, const char* buf)
if ( compute_content_hash ) if ( compute_content_hash )
{ {
content_hash_length += len; content_hash_length += len;
md5_append(&md5_hash, (const u_char*) buf, len); md5_update(&md5_hash, (const u_char*) buf, len);
} }
if ( mime_entity_data || mime_all_data ) if ( mime_entity_data || mime_all_data )

View file

@ -2,13 +2,12 @@
#define mime_h #define mime_h
#include <assert.h> #include <assert.h>
#include <openssl/md5.h>
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#include <queue> #include <queue>
using namespace std; using namespace std;
#include "md5.h"
#include "Base64.h" #include "Base64.h"
#include "BroString.h" #include "BroString.h"
#include "Analyzer.h" #include "Analyzer.h"
@ -248,7 +247,7 @@ protected:
int buffer_offset; int buffer_offset;
int compute_content_hash; int compute_content_hash;
int content_hash_length; int content_hash_length;
md5_state_t md5_hash; MD5_CTX md5_hash;
vector<const BroString*> entity_content; vector<const BroString*> entity_content;
vector<const BroString*> all_content; vector<const BroString*> all_content;

View file

@ -167,6 +167,7 @@ TableVal* preserve_orig_addr;
TableVal* preserve_resp_addr; TableVal* preserve_resp_addr;
TableVal* preserve_other_addr; TableVal* preserve_other_addr;
int max_files_in_cache;
double log_rotate_interval; double log_rotate_interval;
double log_max_size; double log_max_size;
RecordType* rotate_info; RecordType* rotate_info;
@ -257,6 +258,7 @@ void init_general_global_var()
state_dir = internal_val("state_dir")->AsStringVal(); state_dir = internal_val("state_dir")->AsStringVal();
state_write_delay = opt_internal_double("state_write_delay"); state_write_delay = opt_internal_double("state_write_delay");
max_files_in_cache = opt_internal_int("max_files_in_cache");
log_rotate_interval = opt_internal_double("log_rotate_interval"); log_rotate_interval = opt_internal_double("log_rotate_interval");
log_max_size = opt_internal_double("log_max_size"); log_max_size = opt_internal_double("log_max_size");
rotate_info = internal_type("rotate_info")->AsRecordType(); rotate_info = internal_type("rotate_info")->AsRecordType();

View file

@ -170,6 +170,7 @@ extern double connection_status_update_interval;
extern StringVal* state_dir; extern StringVal* state_dir;
extern double state_write_delay; extern double state_write_delay;
extern int max_files_in_cache;
extern double log_rotate_interval; extern double log_rotate_interval;
extern double log_max_size; extern double log_max_size;
extern RecordType* rotate_info; extern RecordType* rotate_info;

View file

@ -28,8 +28,8 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src,
const struct ip* ip = (const struct ip*) (pkt + hdr_size); const struct ip* ip = (const struct ip*) (pkt + hdr_size);
if ( ip->ip_v == 4 ) if ( ip->ip_v == 4 )
ip_hdr = new IP_Hdr(ip, false); ip_hdr = new IP_Hdr(ip, false);
else if ( ip->ip_v == 6 ) else if ( ip->ip_v == 6 && (caplen >= sizeof(struct ip6_hdr) + hdr_size) )
ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false); ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false, caplen - hdr_size);
else else
// Weird will be generated later in NetSessions::NextPacket. // Weird will be generated later in NetSessions::NextPacket.
return; return;

View file

@ -149,7 +149,7 @@ void Reporter::WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* add
va_list ap; va_list ap;
va_start(ap, fmt_name); va_start(ap, fmt_name);
DoLog("weird", event, stderr, 0, vl, false, false, 0, fmt_name, ap); DoLog("weird", event, 0, 0, vl, false, false, 0, fmt_name, ap);
va_end(ap); va_end(ap);
delete vl; delete vl;
@ -163,7 +163,7 @@ void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const cha
va_list ap; va_list ap;
va_start(ap, fmt_name); va_start(ap, fmt_name);
DoLog("weird", flow_weird, stderr, 0, vl, false, false, 0, fmt_name, ap); DoLog("weird", flow_weird, 0, 0, vl, false, false, 0, fmt_name, ap);
va_end(ap); va_end(ap);
delete vl; delete vl;
@ -326,7 +326,8 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne
s += buffer; s += buffer;
s += "\n"; s += "\n";
fprintf(out, "%s", s.c_str()); if ( out )
fprintf(out, "%s", s.c_str());
if ( addl ) if ( addl )
{ {

View file

@ -1,21 +1,21 @@
#include "SSL-binpac.h" #include "SSL.h"
#include "TCP_Reassembler.h" #include "TCP_Reassembler.h"
#include "Reporter.h" #include "Reporter.h"
#include "util.h" #include "util.h"
SSL_Analyzer_binpac::SSL_Analyzer_binpac(Connection* c) SSL_Analyzer::SSL_Analyzer(Connection* c)
: TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c) : TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c)
{ {
interp = new binpac::SSL::SSL_Conn(this); interp = new binpac::SSL::SSL_Conn(this);
had_gap = false; had_gap = false;
} }
SSL_Analyzer_binpac::~SSL_Analyzer_binpac() SSL_Analyzer::~SSL_Analyzer()
{ {
delete interp; delete interp;
} }
void SSL_Analyzer_binpac::Done() void SSL_Analyzer::Done()
{ {
TCP_ApplicationAnalyzer::Done(); TCP_ApplicationAnalyzer::Done();
@ -23,23 +23,22 @@ void SSL_Analyzer_binpac::Done()
interp->FlowEOF(false); interp->FlowEOF(false);
} }
void SSL_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) void SSL_Analyzer::EndpointEOF(TCP_Reassembler* endp)
{ {
TCP_ApplicationAnalyzer::EndpointEOF(endp); TCP_ApplicationAnalyzer::EndpointEOF(endp);
interp->FlowEOF(endp->IsOrig()); interp->FlowEOF(endp->IsOrig());
} }
void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig) void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
{ {
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
assert(TCP()); assert(TCP());
if ( TCP()->IsPartial() ) if ( TCP()->IsPartial() )
return; return;
if ( had_gap ) if ( had_gap )
// XXX: If only one side had a content gap, we could still try to // If only one side had a content gap, we could still try to
// deliver data to the other side if the script layer can handle this. // deliver data to the other side if the script layer can handle this.
return; return;
@ -53,7 +52,7 @@ void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void SSL_Analyzer_binpac::Undelivered(int seq, int len, bool orig) void SSL_Analyzer::Undelivered(int seq, int len, bool orig)
{ {
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
had_gap = true; had_gap = true;

View file

@ -1,14 +1,13 @@
#ifndef ssl_binpac_h #ifndef ssl_h
#define ssl_binpac_h #define ssl_h
#include "TCP.h" #include "TCP.h"
#include "ssl_pac.h" #include "ssl_pac.h"
class SSL_Analyzer_binpac : public TCP_ApplicationAnalyzer { class SSL_Analyzer : public TCP_ApplicationAnalyzer {
public: public:
SSL_Analyzer_binpac(Connection* conn); SSL_Analyzer(Connection* conn);
virtual ~SSL_Analyzer_binpac(); virtual ~SSL_Analyzer();
// Overriden from Analyzer. // Overriden from Analyzer.
virtual void Done(); virtual void Done();
@ -19,7 +18,7 @@ public:
virtual void EndpointEOF(TCP_Reassembler* endp); virtual void EndpointEOF(TCP_Reassembler* endp);
static Analyzer* InstantiateAnalyzer(Connection* conn) static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new SSL_Analyzer_binpac(conn); } { return new SSL_Analyzer(conn); }
static bool Available() static bool Available()
{ {

View file

@ -272,6 +272,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
} }
const struct ip* ip = (const struct ip*) (pkt + hdr_size); const struct ip* ip = (const struct ip*) (pkt + hdr_size);
if ( ip->ip_v == 4 ) if ( ip->ip_v == 4 )
{ {
IP_Hdr ip_hdr(ip, false); IP_Hdr ip_hdr(ip, false);
@ -280,7 +281,13 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
else if ( ip->ip_v == 6 ) else if ( ip->ip_v == 6 )
{ {
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false); if ( caplen < sizeof(struct ip6_hdr) )
{
Weird("truncated_IP", hdr, pkt);
return;
}
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen);
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size);
} }
@ -551,7 +558,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
const struct icmp* icmpp = (const struct icmp *) data; const struct icmp* icmpp = (const struct icmp *) data;
id.src_port = icmpp->icmp_type; id.src_port = icmpp->icmp_type;
id.dst_port = ICMP_counterpart(icmpp->icmp_type, id.dst_port = ICMP4_counterpart(icmpp->icmp_type,
icmpp->icmp_code,
id.is_one_way);
id.src_port = htons(id.src_port);
id.dst_port = htons(id.dst_port);
d = &icmp_conns;
break;
}
case IPPROTO_ICMPV6:
{
const struct icmp* icmpp = (const struct icmp *) data;
id.src_port = icmpp->icmp_type;
id.dst_port = ICMP6_counterpart(icmpp->icmp_type,
icmpp->icmp_code, icmpp->icmp_code,
id.is_one_way); id.is_one_way);
@ -669,6 +692,7 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
min_hdr_len = sizeof(struct udphdr); min_hdr_len = sizeof(struct udphdr);
break; break;
case IPPROTO_ICMP: case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
default: default:
// Use for all other packets. // Use for all other packets.
min_hdr_len = ICMP_MINLEN; min_hdr_len = ICMP_MINLEN;
@ -998,6 +1022,9 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
case IPPROTO_UDP: case IPPROTO_UDP:
tproto = TRANSPORT_UDP; tproto = TRANSPORT_UDP;
break; break;
case IPPROTO_ICMPV6:
tproto = TRANSPORT_ICMP;
break;
default: default:
reporter->InternalError("unknown transport protocol"); reporter->InternalError("unknown transport protocol");
break; break;

View file

@ -509,9 +509,9 @@ protected:
#define NUM_PORT_SPACES 4 #define NUM_PORT_SPACES 4
#define PORT_SPACE_MASK 0x30000 #define PORT_SPACE_MASK 0x30000
#define TCP_PORT_MASK 0x10000 #define TCP_PORT_MASK 0x10000
#define UDP_PORT_MASK 0x20000 #define UDP_PORT_MASK 0x20000
#define ICMP_PORT_MASK 0x30000 #define ICMP_PORT_MASK 0x30000
class PortVal : public Val { class PortVal : public Val {
public: public:

View file

@ -10,25 +10,25 @@ flow BitTorrent_Flow(is_orig: bool) {
%member{ %member{
bool handshake_ok; bool handshake_ok;
uint64 _next_message_offset; //uint64 _next_message_offset;
%} %}
%init{ %init{
handshake_ok = false; handshake_ok = false;
_next_message_offset = 0; //_next_message_offset = 0;
%} %}
function next_message_offset(): uint64 #function next_message_offset(): uint64
%{ # %{
return &_next_message_offset; # return &_next_message_offset;
%} # %}
function increment_next_message_offset(go: bool, len: uint32): bool #function increment_next_message_offset(go: bool, len: uint32): bool
%{ # %{
if ( go ) # if ( go )
_next_message_offset += len; # _next_message_offset += len;
return true; # return true;
%} # %}
function is_handshake_delivered(): bool function is_handshake_delivered(): bool
%{ %{

View file

@ -22,8 +22,8 @@ type BitTorrent_Handshake = record {
} &length = 68, &let { } &length = 68, &let {
validate: bool = $context.flow.validate_handshake(pstrlen, pstr); validate: bool = $context.flow.validate_handshake(pstrlen, pstr);
incoffsetffset: bool = #incoffsetffset: bool =
$context.flow.increment_next_message_offset(true, 68); # $context.flow.increment_next_message_offset(true, 68);
deliver: bool = deliver: bool =
$context.flow.deliver_handshake(reserved, info_hash, peer_id); $context.flow.deliver_handshake(reserved, info_hash, peer_id);
}; };
@ -72,8 +72,8 @@ type BitTorrent_PieceHeader(len: uint32) = record {
index: uint32; index: uint32;
begin: uint32; begin: uint32;
} &let { } &let {
incoffset: bool = #incoffset: bool =
$context.flow.increment_next_message_offset(true, len + 5); # $context.flow.increment_next_message_offset(true, len + 5);
}; };
type BitTorrent_Piece(len: uint32) = record { type BitTorrent_Piece(len: uint32) = record {
@ -134,9 +134,9 @@ type BitTorrent_Message = record {
default -> message_id: BitTorrent_MessageID(len.len); default -> message_id: BitTorrent_MessageID(len.len);
}; };
} &length = 4 + len.len, &let { } &length = 4 + len.len, &let {
incoffset: bool = $context.flow.increment_next_message_offset( #incoffset: bool = $context.flow.increment_next_message_offset(
len.len == 0 || message_id.id != TYPE_PIECE, # len.len == 0 || message_id.id != TYPE_PIECE,
4 + len.len); # 4 + len.len);
}; };
type BitTorrent_PDU = case $context.flow.is_handshake_delivered() of { type BitTorrent_PDU = case $context.flow.is_handshake_delivered() of {

View file

@ -6,13 +6,13 @@
%%{ // C segment %%{ // C segment
#include <math.h> #include <math.h>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <sys/stat.h> #include <sys/stat.h>
#include <cstdio> #include <cstdio>
#include "digest.h"
#include "Reporter.h" #include "Reporter.h"
#include "IPAddr.h" #include "IPAddr.h"
@ -530,7 +530,7 @@ function piped_exec%(program: string, to_write: string%): bool
%%{ %%{
static void hash_md5_val(val_list& vlist, unsigned char digest[16]) static void hash_md5_val(val_list& vlist, unsigned char digest[16])
{ {
md5_state_s h; MD5_CTX h;
md5_init(&h); md5_init(&h);
loop_over_list(vlist, i) loop_over_list(vlist, i)
@ -539,16 +539,16 @@ static void hash_md5_val(val_list& vlist, unsigned char digest[16])
if ( v->Type()->Tag() == TYPE_STRING ) if ( v->Type()->Tag() == TYPE_STRING )
{ {
const BroString* str = v->AsString(); const BroString* str = v->AsString();
md5_append(&h, str->Bytes(), str->Len()); md5_update(&h, str->Bytes(), str->Len());
} }
else else
{ {
ODesc d(DESC_BINARY); ODesc d(DESC_BINARY);
v->Describe(&d); v->Describe(&d);
md5_append(&h, (const md5_byte_t *) d.Bytes(), d.Len()); md5_update(&h, (const u_char *) d.Bytes(), d.Len());
} }
} }
md5_finish(&h, digest); md5_final(&h, digest);
} }
static void hmac_md5_val(val_list& vlist, unsigned char digest[16]) static void hmac_md5_val(val_list& vlist, unsigned char digest[16])
@ -556,7 +556,53 @@ static void hmac_md5_val(val_list& vlist, unsigned char digest[16])
hash_md5_val(vlist, digest); hash_md5_val(vlist, digest);
for ( int i = 0; i < 16; ++i ) for ( int i = 0; i < 16; ++i )
digest[i] = digest[i] ^ shared_hmac_md5_key[i]; digest[i] = digest[i] ^ shared_hmac_md5_key[i];
hash_md5(16, digest, digest); MD5(digest, 16, digest);
}
static void hash_sha1_val(val_list& vlist, unsigned char digest[20])
{
SHA_CTX h;
sha1_init(&h);
loop_over_list(vlist, i)
{
Val* v = vlist[i];
if ( v->Type()->Tag() == TYPE_STRING )
{
const BroString* str = v->AsString();
sha1_update(&h, str->Bytes(), str->Len());
}
else
{
ODesc d(DESC_BINARY);
v->Describe(&d);
sha1_update(&h, (const u_char *) d.Bytes(), d.Len());
}
}
sha1_final(&h, digest);
}
static void hash_sha256_val(val_list& vlist, unsigned char digest[32])
{
SHA256_CTX h;
sha256_init(&h);
loop_over_list(vlist, i)
{
Val* v = vlist[i];
if ( v->Type()->Tag() == TYPE_STRING )
{
const BroString* str = v->AsString();
sha256_update(&h, str->Bytes(), str->Len());
}
else
{
ODesc d(DESC_BINARY);
v->Describe(&d);
sha256_update(&h, (const u_char *) d.Bytes(), d.Len());
}
}
sha256_final(&h, digest);
} }
%%} %%}
@ -565,6 +611,8 @@ static void hmac_md5_val(val_list& vlist, unsigned char digest[16])
## Returns: The MD5 hash value of the concatenated arguments. ## Returns: The MD5 hash value of the concatenated arguments.
## ##
## .. bro:see:: md5_hmac md5_hash_init md5_hash_update md5_hash_finish ## .. bro:see:: md5_hmac md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
## ##
## .. note:: ## .. note::
## ##
@ -578,6 +626,46 @@ function md5_hash%(...%): string
return new StringVal(md5_digest_print(digest)); return new StringVal(md5_digest_print(digest));
%} %}
## Computes the SHA1 hash value of the provided list of arguments.
##
## Returns: The SHA1 hash value of the concatenated arguments.
##
## .. bro:see:: md5_hash md5_hmac md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
##
## .. note::
##
## This function performs a one-shot computation of its arguments.
## For incremental hash computation, see :bro:id:`sha1_hash_init` and
## friends.
function sha1_hash%(...%): string
%{
unsigned char digest[20];
hash_sha1_val(@ARG@, digest);
return new StringVal(sha1_digest_print(digest));
%}
## Computes the SHA256 hash value of the provided list of arguments.
##
## Returns: The SHA256 hash value of the concatenated arguments.
##
## .. bro:see:: md5_hash md5_hmac md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash_init sha256_hash_update sha256_hash_finish
##
## .. note::
##
## This function performs a one-shot computation of its arguments.
## For incremental hash computation, see :bro:id:`sha256_hash_init` and
## friends.
function sha256_hash%(...%): string
%{
unsigned char digest[32];
hash_sha256_val(@ARG@, digest);
return new StringVal(sha256_digest_print(digest));
%}
## Computes an HMAC-MD5 hash value of the provided list of arguments. The HMAC ## Computes an HMAC-MD5 hash value of the provided list of arguments. The HMAC
## secret key is generated from available entropy when Bro starts up, or it can ## secret key is generated from available entropy when Bro starts up, or it can
## be specified for repeatability using the ``-K`` command line flag. ## be specified for repeatability using the ``-K`` command line flag.
@ -585,6 +673,8 @@ function md5_hash%(...%): string
## Returns: The HMAC-MD5 hash value of the concatenated arguments. ## Returns: The HMAC-MD5 hash value of the concatenated arguments.
## ##
## .. bro:see:: md5_hash md5_hash_init md5_hash_update md5_hash_finish ## .. bro:see:: md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function md5_hmac%(...%): string function md5_hmac%(...%): string
%{ %{
unsigned char digest[16]; unsigned char digest[16];
@ -593,7 +683,9 @@ function md5_hmac%(...%): string
%} %}
%%{ %%{
static map<BroString, md5_state_s> md5_states; static map<BroString, MD5_CTX> md5_states;
static map<BroString, SHA_CTX> sha1_states;
static map<BroString, SHA256_CTX> sha256_states;
BroString* convert_index_to_string(Val* index) BroString* convert_index_to_string(Val* index)
{ {
@ -618,7 +710,9 @@ BroString* convert_index_to_string(Val* index)
## ##
## index: The unique identifier to associate with this hash computation. ## index: The unique identifier to associate with this hash computation.
## ##
## .. bro:see:: md5_hash md5_hmac md5_hash_update md5_hash_finish ## .. bro:see:: md5_hmac md5_hash md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function md5_hash_init%(index: any%): bool function md5_hash_init%(index: any%): bool
%{ %{
BroString* s = convert_index_to_string(index); BroString* s = convert_index_to_string(index);
@ -626,7 +720,7 @@ function md5_hash_init%(index: any%): bool
if ( md5_states.count(*s) < 1 ) if ( md5_states.count(*s) < 1 )
{ {
md5_state_s h; MD5_CTX h;
md5_init(&h); md5_init(&h);
md5_states[*s] = h; md5_states[*s] = h;
status = 1; status = 1;
@ -636,6 +730,75 @@ function md5_hash_init%(index: any%): bool
return new Val(status, TYPE_BOOL); return new Val(status, TYPE_BOOL);
%} %}
## Initializes SHA1 state to enable incremental hash computation. After
## initializing the SHA1 state with this function, you can feed data to
## :bro:id:`sha1_hash_update` and finally need to call
## :bro:id:`sha1_hash_finish` to finish the computation and get the final hash
## value.
##
## For example, when computing incremental SHA1 values of transferred files in
## multiple concurrent HTTP connections, one would call ``sha1_hash_init(c$id)``
## once before invoking ``sha1_hash_update(c$id, some_more_data)`` in the
## :bro:id:`http_entity_data` event handler. When all data has arrived, a call
## to :bro:id:`sha1_hash_finish` returns the final hash value.
##
## index: The unique identifier to associate with this hash computation.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function sha1_hash_init%(index: any%): bool
%{
BroString* s = convert_index_to_string(index);
int status = 0;
if ( sha1_states.count(*s) < 1 )
{
SHA_CTX h;
sha1_init(&h);
sha1_states[*s] = h;
status = 1;
}
delete s;
return new Val(status, TYPE_BOOL);
%}
## Initializes SHA256 state to enable incremental hash computation. After
## initializing the SHA256 state with this function, you can feed data to
## :bro:id:`sha256_hash_update` and finally need to call
## :bro:id:`sha256_hash_finish` to finish the computation and get the final hash
## value.
##
## For example, when computing incremental SHA256 values of transferred files in
## multiple concurrent HTTP connections, one would call
## ``sha256_hash_init(c$id)`` once before invoking
## ``sha256_hash_update(c$id, some_more_data)`` in the
## :bro:id:`http_entity_data` event handler. When all data has arrived, a call
## to :bro:id:`sha256_hash_finish` returns the final hash value.
##
## index: The unique identifier to associate with this hash computation.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_update sha256_hash_finish
function sha256_hash_init%(index: any%): bool
%{
BroString* s = convert_index_to_string(index);
int status = 0;
if ( sha256_states.count(*s) < 1 )
{
SHA256_CTX h;
sha256_init(&h);
sha256_states[*s] = h;
status = 1;
}
delete s;
return new Val(status, TYPE_BOOL);
%}
## Update the MD5 value associated with a given index. It is required to ## Update the MD5 value associated with a given index. It is required to
## call :bro:id:`md5_hash_init` once before calling this ## call :bro:id:`md5_hash_init` once before calling this
## function. ## function.
@ -644,7 +807,9 @@ function md5_hash_init%(index: any%): bool
## ##
## data: The data to add to the hash computation. ## data: The data to add to the hash computation.
## ##
## .. bro:see:: md5_hash md5_hmac md5_hash_init md5_hash_finish ## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function md5_hash_update%(index: any, data: string%): bool function md5_hash_update%(index: any, data: string%): bool
%{ %{
BroString* s = convert_index_to_string(index); BroString* s = convert_index_to_string(index);
@ -652,7 +817,59 @@ function md5_hash_update%(index: any, data: string%): bool
if ( md5_states.count(*s) > 0 ) if ( md5_states.count(*s) > 0 )
{ {
md5_append(&md5_states[*s], data->Bytes(), data->Len()); md5_update(&md5_states[*s], data->Bytes(), data->Len());
status = 1;
}
delete s;
return new Val(status, TYPE_BOOL);
%}
## Update the SHA1 value associated with a given index. It is required to
## call :bro:id:`sha1_hash_init` once before calling this
## function.
##
## index: The unique identifier to associate with this hash computation.
##
## data: The data to add to the hash computation.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function sha1_hash_update%(index: any, data: string%): bool
%{
BroString* s = convert_index_to_string(index);
int status = 0;
if ( sha1_states.count(*s) > 0 )
{
sha1_update(&sha1_states[*s], data->Bytes(), data->Len());
status = 1;
}
delete s;
return new Val(status, TYPE_BOOL);
%}
## Update the SHA256 value associated with a given index. It is required to
## call :bro:id:`sha256_hash_init` once before calling this
## function.
##
## index: The unique identifier to associate with this hash computation.
##
## data: The data to add to the hash computation.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_finish
function sha256_hash_update%(index: any, data: string%): bool
%{
BroString* s = convert_index_to_string(index);
int status = 0;
if ( sha256_states.count(*s) > 0 )
{
sha256_update(&sha256_states[*s], data->Bytes(), data->Len());
status = 1; status = 1;
} }
@ -666,7 +883,9 @@ function md5_hash_update%(index: any, data: string%): bool
## ##
## Returns: The hash value associated with the computation at *index*. ## Returns: The hash value associated with the computation at *index*.
## ##
## .. bro:see:: md5_hash md5_hmac md5_hash_init md5_hash_update ## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function md5_hash_finish%(index: any%): string function md5_hash_finish%(index: any%): string
%{ %{
BroString* s = convert_index_to_string(index); BroString* s = convert_index_to_string(index);
@ -675,7 +894,7 @@ function md5_hash_finish%(index: any%): string
if ( md5_states.count(*s) > 0 ) if ( md5_states.count(*s) > 0 )
{ {
unsigned char digest[16]; unsigned char digest[16];
md5_finish(&md5_states[*s], digest); md5_final(&md5_states[*s], digest);
md5_states.erase(*s); md5_states.erase(*s);
printable_digest = new StringVal(md5_digest_print(digest)); printable_digest = new StringVal(md5_digest_print(digest));
} }
@ -686,6 +905,62 @@ function md5_hash_finish%(index: any%): string
return printable_digest; return printable_digest;
%} %}
## Returns the final SHA1 digest of an incremental hash computation.
##
## index: The unique identifier of this hash computation.
##
## Returns: The hash value associated with the computation at *index*.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update
## sha256_hash sha256_hash_init sha256_hash_update sha256_hash_finish
function sha1_hash_finish%(index: any%): string
%{
BroString* s = convert_index_to_string(index);
StringVal* printable_digest;
if ( sha1_states.count(*s) > 0 )
{
unsigned char digest[20];
sha1_final(&sha1_states[*s], digest);
sha1_states.erase(*s);
printable_digest = new StringVal(sha1_digest_print(digest));
}
else
printable_digest = new StringVal("");
delete s;
return printable_digest;
%}
## Returns the final SHA256 digest of an incremental hash computation.
##
## index: The unique identifier of this hash computation.
##
## Returns: The hash value associated with the computation at *index*.
##
## .. bro:see:: md5_hmac md5_hash md5_hash_init md5_hash_update md5_hash_finish
## sha1_hash sha1_hash_init sha1_hash_update sha1_hash_finish
## sha256_hash sha256_hash_init sha256_hash_update
function sha256_hash_finish%(index: any%): string
%{
BroString* s = convert_index_to_string(index);
StringVal* printable_digest;
if ( sha256_states.count(*s) > 0 )
{
unsigned char digest[32];
sha256_final(&sha256_states[*s], digest);
sha256_states.erase(*s);
printable_digest = new StringVal(sha256_digest_print(digest));
}
else
printable_digest = new StringVal("");
delete s;
return printable_digest;
%}
## Generates a random number. ## Generates a random number.
## ##
## max: The maximum value the random number. ## max: The maximum value the random number.

92
src/digest.h Normal file
View file

@ -0,0 +1,92 @@
// See the file "COPYING" in the main distribution directory for copyright.
/**
* Wrapper and helper functions for MD5/SHA digest algorithms.
*/
#ifndef bro_digest_h
#define bro_digest_h
#include <openssl/md5.h>
#include <openssl/sha.h>
#include "Reporter.h"
static inline const char* digest_print(const u_char* digest, size_t n)
{
static char buf[256]; // big enough for any of md5/sha1/sha256
for ( size_t i = 0; i < n; ++i )
snprintf(buf + i * 2, 3, "%02x", digest[i]);
return buf;
}
inline const char* md5_digest_print(const u_char digest[MD5_DIGEST_LENGTH])
{
return digest_print(digest, MD5_DIGEST_LENGTH);
}
inline const char* sha1_digest_print(const u_char digest[SHA_DIGEST_LENGTH])
{
return digest_print(digest, SHA_DIGEST_LENGTH);
}
inline const char* sha256_digest_print(const u_char digest[SHA256_DIGEST_LENGTH])
{
return digest_print(digest, SHA256_DIGEST_LENGTH);
}
inline void md5_init(MD5_CTX* c)
{
if ( ! MD5_Init(c) )
reporter->InternalError("MD5_Init failed");
}
inline void md5_update(MD5_CTX* c, const void* data, unsigned long len)
{
if ( ! MD5_Update(c, data, len) )
reporter->InternalError("MD5_Update failed");
}
inline void md5_final(MD5_CTX* c, u_char md[MD5_DIGEST_LENGTH])
{
if ( ! MD5_Final(md, c) )
reporter->InternalError("MD5_Final failed");
}
inline void sha1_init(SHA_CTX* c)
{
if ( ! SHA1_Init(c) )
reporter->InternalError("SHA_Init failed");
}
inline void sha1_update(SHA_CTX* c, const void* data, unsigned long len)
{
if ( ! SHA1_Update(c, data, len) )
reporter->InternalError("SHA_Update failed");
}
inline void sha1_final(SHA_CTX* c, u_char md[SHA_DIGEST_LENGTH])
{
if ( ! SHA1_Final(md, c) )
reporter->InternalError("SHA_Final failed");
}
inline void sha256_init(SHA256_CTX* c)
{
if ( ! SHA256_Init(c) )
reporter->InternalError("SHA256_Init failed");
}
inline void sha256_update(SHA256_CTX* c, const void* data, unsigned long len)
{
if ( ! SHA256_Update(c, data, len) )
reporter->InternalError("SHA256_Update failed");
}
inline void sha256_final(SHA256_CTX* c, u_char md[SHA256_DIGEST_LENGTH])
{
if ( ! SHA256_Final(md, c) )
reporter->InternalError("SHA256_Final failed");
}
#endif //bro_digest_h

View file

@ -762,10 +762,9 @@ event udp_contents%(u: connection, is_orig: bool, contents: string%);
## .. bro:see:: udp_contents udp_reply udp_request ## .. bro:see:: udp_contents udp_reply udp_request
event udp_session_done%(u: connection%); event udp_session_done%(u: connection%);
## Generated for all ICMP messages that are not handled separetely with dedicated ## Generated for all ICMP messages that are not handled separately with dedicated
## ICMP events. Bro's ICMP analyzer handles a number of ICMP messages directly ## ICMP events. Bro's ICMP analyzer handles a number of ICMP messages directly
## with dedicated events. This handlers acts as a fallback for those it doesn't. ## with dedicated events. This event acts as a fallback for those it doesn't.
## The *icmp* record provides more information about the message.
## ##
## See `Wikipedia ## See `Wikipedia
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more ## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
@ -776,8 +775,7 @@ event udp_session_done%(u: connection%);
## icmp: Additional ICMP-specific information augmenting the standard ## icmp: Additional ICMP-specific information augmenting the standard
## connection record *c*. ## connection record *c*.
## ##
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect ## .. bro:see:: icmp_error_message
## icmp_time_exceeded icmp_unreachable
event icmp_sent%(c: connection, icmp: icmp_conn%); event icmp_sent%(c: connection, icmp: icmp_conn%);
## Generated for ICMP *echo request* messages. ## Generated for ICMP *echo request* messages.
@ -798,8 +796,7 @@ event icmp_sent%(c: connection, icmp: icmp_conn%);
## payload: The message-specific data of the packet payload, i.e., everything after ## payload: The message-specific data of the packet payload, i.e., everything after
## the first 8 bytes of the ICMP header. ## the first 8 bytes of the ICMP header.
## ##
## .. bro:see:: icmp_echo_reply icmp_redirect icmp_sent ## .. bro:see:: icmp_echo_reply
## icmp_time_exceeded icmp_unreachable
event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%);
## Generated for ICMP *echo reply* messages. ## Generated for ICMP *echo reply* messages.
@ -820,10 +817,32 @@ event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count,
## payload: The message-specific data of the packet payload, i.e., everything after ## payload: The message-specific data of the packet payload, i.e., everything after
## the first 8 bytes of the ICMP header. ## the first 8 bytes of the ICMP header.
## ##
## .. bro:see:: icmp_echo_request icmp_redirect icmp_sent ## .. bro:see:: icmp_echo_request
## icmp_time_exceeded icmp_unreachable
event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%);
## Generated for all ICMPv6 error messages that are not handled
## separately with dedicated events. Bro's ICMP analyzer handles a number
## of ICMP error messages directly with dedicated events. This event acts
## as a fallback for those it doesn't.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/ICMPv6>`__ for more
## information about the ICMPv6 protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard
## connection record *c*.
##
## code: The ICMP code of the error message.
##
## context: A record with specifics of the original packet that the message refers
## to.
##
## .. bro:see:: icmp_unreachable icmp_packet_too_big
## icmp_time_exceeded icmp_parameter_problem
event icmp_error_message%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
## Generated for ICMP *destination unreachable* messages. ## Generated for ICMP *destination unreachable* messages.
## ##
## See `Wikipedia ## See `Wikipedia
@ -843,10 +862,33 @@ event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, pa
## that if the *unreachable* includes only a partial IP header for some reason, no ## that if the *unreachable* includes only a partial IP header for some reason, no
## fields of *context* will be filled out. ## fields of *context* will be filled out.
## ##
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect icmp_sent ## .. bro:see:: icmp_error_message icmp_packet_too_big
## icmp_time_exceeded ## icmp_time_exceeded icmp_parameter_problem
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
## Generated for ICMPv6 *packet too big* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/ICMPv6>`__ for more
## information about the ICMPv6 protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## code: The ICMP code of the *too big* message.
##
## context: A record with specifics of the original packet that the message refers
## to. *Too big* messages should include the original IP header from the packet
## that triggered them, and Bro parses that into the *context* structure. Note
## that if the *too big* includes only a partial IP header for some reason, no
## fields of *context* will be filled out.
##
## .. bro:see:: icmp_error_message icmp_unreachable
## icmp_time_exceeded icmp_parameter_problem
event icmp_packet_too_big%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
## Generated for ICMP *time exceeded* messages. ## Generated for ICMP *time exceeded* messages.
## ##
## See `Wikipedia ## See `Wikipedia
@ -866,10 +908,125 @@ event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: ic
## if the *exceeded* includes only a partial IP header for some reason, no fields ## if the *exceeded* includes only a partial IP header for some reason, no fields
## of *context* will be filled out. ## of *context* will be filled out.
## ##
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect icmp_sent ## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big
## icmp_unreachable ## icmp_parameter_problem
event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
## Generated for ICMPv6 *parameter problem* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/ICMPv6>`__ for more
## information about the ICMPv6 protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## code: The ICMP code of the *parameter problem* message.
##
## context: A record with specifics of the original packet that the message refers
## to. *Parameter problem* messages should include the original IP header from the packet
## that triggered them, and Bro parses that into the *context* structure. Note that
## if the *parameter problem* includes only a partial IP header for some reason, no fields
## of *context* will be filled out.
##
## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big
## icmp_time_exceeded
event icmp_parameter_problem%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
## Generated for ICMP *router solicitation* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
## information about the ICMP protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## .. bro:see:: icmp_router_advertisement
## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect
event icmp_router_solicitation%(c: connection, icmp: icmp_conn%);
## Generated for ICMP *router advertisement* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
## information about the ICMP protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## cur_hop_limit: The default value that should be placed in Hop Count field
## for outgoing IP packets.
##
## managed: Managed address configuration flag, :rfc:`4861`.
##
## other: Other stateful configuration flag, :rfc:`4861`.
##
## home_agent: Mobile IPv6 home agent flag, :rfc:`3775`.
##
## pref: Router selection preferences, :rfc:`4191`.
##
## proxy: Neighbor discovery proxy flag, :rfc:`4389`.
##
## rsv: Remaining two reserved bits of router advertisement flags.
##
## router_lifetime: How long this router should be used as a default router.
##
## reachable_time: How long a neighbor should be considered reachable.
##
## retrans_timer: How long a host should wait before retransmitting.
##
## .. bro:see:: icmp_router_solicitation
## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect
event icmp_router_advertisement%(c: connection, icmp: icmp_conn, cur_hop_limit: count, managed: bool, other: bool, home_agent: bool, pref: count, proxy: bool, rsv: count, router_lifetime: interval, reachable_time: interval, retrans_timer: interval%);
## Generated for ICMP *neighbor solicitation* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
## information about the ICMP protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## tgt: The IP address of the target of the solicitation.
##
## .. bro:see:: icmp_router_solicitation icmp_router_advertisement
## icmp_neighbor_advertisement icmp_redirect
event icmp_neighbor_solicitation%(c: connection, icmp: icmp_conn, tgt:addr%);
## Generated for ICMP *neighbor advertisement* messages.
##
## See `Wikipedia
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
## information about the ICMP protocol.
##
## c: The connection record for the corresponding ICMP flow.
##
## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*.
##
## router: Flag indicating the sender is a router.
##
## solicited: Flag indicating advertisement is in response to a solicitation.
##
## override: Flag indicating advertisement should override existing caches.
##
## tgt: the Target Address in the soliciting message or the address whose
## link-layer address has changed for unsolicited adverts.
##
## .. bro:see:: icmp_router_solicitation icmp_router_advertisement
## icmp_neighbor_solicitation icmp_redirect
event icmp_neighbor_advertisement%(c: connection, icmp: icmp_conn, router: bool, solicited: bool, override: bool, tgt:addr%);
## Generated for ICMP *redirect* messages. ## Generated for ICMP *redirect* messages.
## ##
## See `Wikipedia ## See `Wikipedia
@ -881,11 +1038,14 @@ event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context:
## icmp: Additional ICMP-specific information augmenting the standard connection ## icmp: Additional ICMP-specific information augmenting the standard connection
## record *c*. ## record *c*.
## ##
## a: The new destination address the message is redirecting to. ## tgt: The address that is supposed to be a better first hop to use for
## ICMP Destination Address.
## ##
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent ## dest: The address of the destination which is redirected to the target.
## icmp_time_exceeded icmp_unreachable ##
event icmp_redirect%(c: connection, icmp: icmp_conn, a: addr%); ## .. bro:see:: icmp_router_solicitation icmp_router_advertisement
## icmp_neighbor_solicitation icmp_neighbor_advertisement
event icmp_redirect%(c: connection, icmp: icmp_conn, tgt: addr, dest: addr%);
## Generated when a TCP connection terminated, passing on statistics about the ## Generated when a TCP connection terminated, passing on statistics about the
## two endpoints. This event is always generated when Bro flushes the internal ## two endpoints. This event is always generated when Bro flushes the internal

View file

@ -1,6 +1,7 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "util.h" #include "util.h"
#include "bro_inet_ntop.h"
#include "threading/SerialTypes.h" #include "threading/SerialTypes.h"
#include "WriterBackend.h" #include "WriterBackend.h"
@ -237,7 +238,7 @@ string WriterBackend::Render(const threading::Value::addr_t& addr) const
{ {
char s[INET_ADDRSTRLEN]; char s[INET_ADDRSTRLEN];
if ( inet_ntop(AF_INET, &addr.in.in4, s, INET_ADDRSTRLEN) == NULL ) if ( ! bro_inet_ntop(AF_INET, &addr.in.in4, s, INET_ADDRSTRLEN) )
return "<bad IPv4 address conversion>"; return "<bad IPv4 address conversion>";
else else
return s; return s;
@ -246,7 +247,7 @@ string WriterBackend::Render(const threading::Value::addr_t& addr) const
{ {
char s[INET6_ADDRSTRLEN]; char s[INET6_ADDRSTRLEN];
if ( inet_ntop(AF_INET6, &addr.in.in6, s, INET6_ADDRSTRLEN) == NULL ) if ( ! bro_inet_ntop(AF_INET6, &addr.in.in6, s, INET6_ADDRSTRLEN) )
return "<bad IPv6 address conversion>"; return "<bad IPv6 address conversion>";
else else
return s; return s;

View file

@ -18,6 +18,8 @@ extern "C" {
} }
#endif #endif
#include <openssl/md5.h>
extern "C" void OPENSSL_add_all_algorithms_conf(void); extern "C" void OPENSSL_add_all_algorithms_conf(void);
#include "bsd-getopt-long.h" #include "bsd-getopt-long.h"
@ -591,8 +593,7 @@ int main(int argc, char** argv)
break; break;
case 'K': case 'K':
hash_md5(strlen(optarg), (const u_char*) optarg, MD5((const u_char*) optarg, strlen(optarg), shared_hmac_md5_key);
shared_hmac_md5_key);
hmac_key_set = 1; hmac_key_set = 1;
break; break;

380
src/md5.c
View file

@ -1,380 +0,0 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

View file

@ -1,90 +0,0 @@
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef md5_INCLUDED
# define md5_INCLUDED
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* md5_INCLUDED */

View file

@ -80,6 +80,33 @@ int mobility_header_checksum(const IP_Hdr* ip)
} }
#endif #endif
int icmp6_checksum(const struct icmp* icmpp, const IP_Hdr* ip, int len)
{
// ICMP6 uses the same checksum function as ICMP4 but a different
// pseudo-header over which it is computed.
uint32 sum;
if ( len % 2 == 1 )
// Add in pad byte.
sum = htons(((const u_char*) icmpp)[len - 1] << 8);
else
sum = 0;
// Pseudo-header as for UDP over IPv6 above.
sum = ones_complement_checksum(ip->SrcAddr(), sum);
sum = ones_complement_checksum(ip->DstAddr(), sum);
uint32 l = htonl(len);
sum = ones_complement_checksum((void*) &l, 4, sum);
uint32 addl_pseudo = htons(IPPROTO_ICMPV6);
sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum);
sum = ones_complement_checksum((void*) icmpp, len, sum);
return sum;
}
#define CLASS_A 0x00000000 #define CLASS_A 0x00000000
#define CLASS_B 0x80000000 #define CLASS_B 0x80000000
#define CLASS_C 0xc0000000 #define CLASS_C 0xc0000000

View file

@ -31,13 +31,82 @@ typedef enum { IPv4, IPv6 } IPFamily;
#ifdef HAVE_NETINET_IP6_H #ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h> #include <netinet/ip6.h>
#else
struct ip6_hdr { #ifndef HAVE_IP6_OPT
uint16 ip6_plen; struct ip6_opt {
uint8 ip6_nxt; uint8 ip6o_type;
uint8 ip6_hlim; uint8 ip6o_len;
}; };
#endif #endif // HAVE_IP6_OPT
#ifndef HAVE_IP6_EXT
struct ip6_ext {
uint8 ip6e_nxt;
uint8 ip6e_len;
};
#endif // HAVE_IP6_EXT
#else
struct ip6_hdr {
union {
struct ip6_hdrctl {
uint32 ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits
flow-ID */
uint16 ip6_un1_plen; /* payload length */
uint8 ip6_un1_nxt; /* next header */
uint8 ip6_un1_hlim; /* hop limit */
} ip6_un1;
uint8 ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */
};
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
struct ip6_opt {
uint8 ip6o_type;
uint8 ip6o_len;
};
struct ip6_ext {
uint8 ip6e_nxt;
uint8 ip6e_len;
};
struct ip6_frag {
uint8 ip6f_nxt; /* next header */
uint8 ip6f_reserved; /* reserved field */
uint16 ip6f_offlg; /* offset, reserved, and flag */
uint32 ip6f_ident; /* identification */
};
struct ip6_hbh {
uint8 ip6h_nxt; /* next header */
uint8 ip6h_len; /* length in units of 8 octets */
/* followed by options */
};
struct ip6_dest {
uint8 ip6d_nxt; /* next header */
uint8 ip6d_len; /* length in units of 8 octets */
/* followed by options */
};
struct ip6_rthdr {
uint8 ip6r_nxt; /* next header */
uint8 ip6r_len; /* length in units of 8 octets */
uint8 ip6r_type; /* routing type */
uint8 ip6r_segleft; /* segments left */
/* followed by routing type specific data */
};
#endif // HAVE_NETINET_IP6_H
// For Solaris. // For Solaris.
#if !defined(TCPOPT_WINDOW) && defined(TCPOPT_WSCALE) #if !defined(TCPOPT_WINDOW) && defined(TCPOPT_WSCALE)
@ -65,16 +134,17 @@ inline int seq_delta(uint32 a, uint32 b)
} }
class IPAddr; class IPAddr;
class IP_Hdr;
// Returns the ones-complement checksum of a chunk of b short-aligned bytes. // Returns the ones-complement checksum of a chunk of b short-aligned bytes.
extern int ones_complement_checksum(const void* p, int b, uint32 sum); extern int ones_complement_checksum(const void* p, int b, uint32 sum);
extern int ones_complement_checksum(const IPAddr& a, uint32 sum); extern int ones_complement_checksum(const IPAddr& a, uint32 sum);
extern int icmp6_checksum(const struct icmp* icmpp, const IP_Hdr* ip, int len);
extern int icmp_checksum(const struct icmp* icmpp, int len); extern int icmp_checksum(const struct icmp* icmpp, int len);
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
class IP_Hdr;
extern int mobility_header_checksum(const IP_Hdr* ip); extern int mobility_header_checksum(const IP_Hdr* ip);
#endif #endif

View file

@ -25,6 +25,7 @@
string orig_label(bool is_orig); string orig_label(bool is_orig);
void free_X509(void *); void free_X509(void *);
X509* d2i_X509_binpac(X509** px, const uint8** in, int len); X509* d2i_X509_binpac(X509** px, const uint8** in, int len);
string handshake_type_label(int type);
%} %}
%code{ %code{
@ -46,6 +47,27 @@ string orig_label(bool is_orig)
return d2i_X509(px, (u_char**) in, len); return d2i_X509(px, (u_char**) in, len);
#endif #endif
} }
string handshake_type_label(int type)
{
switch ( type ) {
case HELLO_REQUEST: return string("HELLO_REQUEST");
case CLIENT_HELLO: return string("CLIENT_HELLO");
case SERVER_HELLO: return string("SERVER_HELLO");
case SESSION_TICKET: return string("SESSION_TICKET");
case CERTIFICATE: return string("CERTIFICATE");
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE");
case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY");
case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE");
case FINISHED: return string("FINISHED");
case CERTIFICATE_URL: return string("CERTIFICATE_URL");
case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS");
default: return string(fmt("UNKNOWN (%d)", type));
}
}
%} %}
@ -88,15 +110,15 @@ refine connection SSL_Conn += {
eof=0; eof=0;
%} %}
%eof{ #%eof{
if ( ! eof && # if ( ! eof &&
state_ != STATE_CONN_ESTABLISHED && # state_ != STATE_CONN_ESTABLISHED &&
state_ != STATE_TRACK_LOST && # state_ != STATE_TRACK_LOST &&
state_ != STATE_INITIAL ) # state_ != STATE_INITIAL )
bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s", # bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s",
state_label(state_).c_str())); # state_label(state_).c_str()));
++eof; # ++eof;
%} #%}
%cleanup{ %cleanup{
%} %}
@ -133,11 +155,6 @@ refine connection SSL_Conn += {
cipher_suites16 : uint16[], cipher_suites16 : uint16[],
cipher_suites24 : uint24[]) : bool cipher_suites24 : uint24[]) : bool
%{ %{
if ( state_ == STATE_TRACK_LOST )
bro_analyzer()->ProtocolViolation(fmt("unexpected client hello message from %s in state %s",
orig_label(${rec.is_orig}).c_str(),
state_label(old_state_).c_str()));
if ( ! version_ok(version) ) if ( ! version_ok(version) )
bro_analyzer()->ProtocolViolation(fmt("unsupported client SSL version 0x%04x", version)); bro_analyzer()->ProtocolViolation(fmt("unsupported client SSL version 0x%04x", version));
@ -175,11 +192,6 @@ refine connection SSL_Conn += {
cipher_suites24 : uint24[], cipher_suites24 : uint24[],
comp_method : uint8) : bool comp_method : uint8) : bool
%{ %{
if ( state_ == STATE_TRACK_LOST )
bro_analyzer()->ProtocolViolation(fmt("unexpected server hello message from %s in state %s",
orig_label(${rec.is_orig}).c_str(),
state_label(old_state_).c_str()));
if ( ! version_ok(version) ) if ( ! version_ok(version) )
bro_analyzer()->ProtocolViolation(fmt("unsupported server SSL version 0x%04x", version)); bro_analyzer()->ProtocolViolation(fmt("unsupported server SSL version 0x%04x", version));
else else
@ -229,11 +241,6 @@ refine connection SSL_Conn += {
function proc_certificate(rec: SSLRecord, certificates : bytestring[]) : bool function proc_certificate(rec: SSLRecord, certificates : bytestring[]) : bool
%{ %{
if ( state_ == STATE_TRACK_LOST )
bro_analyzer()->ProtocolViolation(fmt("unexpected certificate message from %s in state %s",
orig_label(${rec.is_orig}).c_str(),
state_label(old_state_).c_str()));
if ( certificates->size() == 0 ) if ( certificates->size() == 0 )
return true; return true;
@ -362,6 +369,7 @@ refine connection SSL_Conn += {
handshake_type_label(${hs.msg_type}).c_str(), handshake_type_label(${hs.msg_type}).c_str(),
orig_label(is_orig).c_str(), orig_label(is_orig).c_str(),
state_label(old_state_).c_str())); state_label(old_state_).c_str()));
return true; return true;
%} %}

View file

@ -17,35 +17,6 @@ enum ContentType {
UNKNOWN_OR_V2_ENCRYPTED = 400 UNKNOWN_OR_V2_ENCRYPTED = 400
}; };
%code{
string* record_type_label(int type)
{
switch ( type ) {
case CHANGE_CIPHER_SPEC:
return new string("CHANGE_CIPHER_SPEC");
case ALERT:
return new string("ALERT");
case HANDSHAKE:
return new string("HANDSHAKE");
case APPLICATION_DATA:
return new string("APPLICATION_DATA");
case V2_ERROR:
return new string("V2_ERROR");
case V2_CLIENT_HELLO:
return new string("V2_CLIENT_HELLO");
case V2_CLIENT_MASTER_KEY:
return new string("V2_CLIENT_MASTER_KEY");
case V2_SERVER_HELLO:
return new string("V2_SERVER_HELLO");
case UNKNOWN_OR_V2_ENCRYPTED:
return new string("UNKNOWN_OR_V2_ENCRYPTED");
default:
return new string(fmt("UNEXPECTED (%d)", type));
}
}
%}
enum SSLVersions { enum SSLVersions {
UNKNOWN_VERSION = 0x0000, UNKNOWN_VERSION = 0x0000,
SSLv20 = 0x0002, SSLv20 = 0x0002,

View file

@ -23,7 +23,6 @@ type uint24 = record {
string state_label(int state_nr); string state_label(int state_nr);
double get_time_from_asn1(const ASN1_TIME * atime); double get_time_from_asn1(const ASN1_TIME * atime);
string handshake_type_label(int type);
%} %}
extern type to_int; extern type to_int;
@ -268,28 +267,6 @@ enum HandshakeType {
CERTIFICATE_STATUS = 22, # RFC 3546 CERTIFICATE_STATUS = 22, # RFC 3546
}; };
%code{
string handshake_type_label(int type)
{
switch ( type ) {
case HELLO_REQUEST: return string("HELLO_REQUEST");
case CLIENT_HELLO: return string("CLIENT_HELLO");
case SERVER_HELLO: return string("SERVER_HELLO");
case SESSION_TICKET: return string("SESSION_TICKET");
case CERTIFICATE: return string("CERTIFICATE");
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE");
case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY");
case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE");
case FINISHED: return string("FINISHED");
case CERTIFICATE_URL: return string("CERTIFICATE_URL");
case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS");
default: return string(fmt("UNKNOWN (%d)", type));
}
}
%}
###################################################################### ######################################################################
# V3 Change Cipher Spec Protocol (7.1.) # V3 Change Cipher Spec Protocol (7.1.)
@ -425,6 +402,10 @@ type ServerHello(rec: SSLRecord) = record {
session_id : uint8[session_len]; session_id : uint8[session_len];
cipher_suite : uint16[1]; cipher_suite : uint16[1];
compression_method : uint8; compression_method : uint8;
# This weirdness is to deal with the possible existence or absence
# of the following fields.
ext_len: uint16[] &until($element == 0 || $element != 0);
extensions : SSLExtension(rec)[] &until($input.length() == 0);
} &let { } &let {
state_changed : bool = state_changed : bool =
$context.connection.transition(STATE_CLIENT_HELLO_RCVD, $context.connection.transition(STATE_CLIENT_HELLO_RCVD,

View file

@ -27,6 +27,8 @@
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <libgen.h> #include <libgen.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#ifdef HAVE_MALLINFO #ifdef HAVE_MALLINFO
# include <malloc.h> # include <malloc.h>
@ -35,7 +37,6 @@
#include "input.h" #include "input.h"
#include "util.h" #include "util.h"
#include "Obj.h" #include "Obj.h"
#include "md5.h"
#include "Val.h" #include "Val.h"
#include "NetVar.h" #include "NetVar.h"
#include "Net.h" #include "Net.h"
@ -546,24 +547,6 @@ bool is_dir(const char* path)
return S_ISDIR(st.st_mode); return S_ISDIR(st.st_mode);
} }
void hash_md5(size_t size, const unsigned char* bytes, unsigned char digest[16])
{
md5_state_s h;
md5_init(&h);
md5_append(&h, bytes, size);
md5_finish(&h, digest);
}
const char* md5_digest_print(const unsigned char digest[16])
{
static char digest_print[256];
for ( int i = 0; i < 16; ++i )
snprintf(digest_print + i * 2, 3, "%02x", digest[i]);
return digest_print;
}
int hmac_key_set = 0; int hmac_key_set = 0;
uint8 shared_hmac_md5_key[16]; uint8 shared_hmac_md5_key[16];
@ -572,12 +555,12 @@ void hmac_md5(size_t size, const unsigned char* bytes, unsigned char digest[16])
if ( ! hmac_key_set ) if ( ! hmac_key_set )
reporter->InternalError("HMAC-MD5 invoked before the HMAC key is set"); reporter->InternalError("HMAC-MD5 invoked before the HMAC key is set");
hash_md5(size, bytes, digest); MD5(bytes, size, digest);
for ( int i = 0; i < 16; ++i ) for ( int i = 0; i < 16; ++i )
digest[i] ^= shared_hmac_md5_key[i]; digest[i] ^= shared_hmac_md5_key[i];
hash_md5(16, digest, digest); MD5(digest, 16, digest);
} }
static bool read_random_seeds(const char* read_file, uint32* seed, static bool read_random_seeds(const char* read_file, uint32* seed,
@ -724,7 +707,7 @@ void init_random_seed(uint32 seed, const char* read_file, const char* write_file
if ( ! hmac_key_set ) if ( ! hmac_key_set )
{ {
hash_md5(sizeof(buf), (u_char*) buf, shared_hmac_md5_key); MD5((const u_char*) buf, sizeof(buf), shared_hmac_md5_key);
hmac_key_set = 1; hmac_key_set = 1;
} }

View file

@ -136,16 +136,12 @@ extern bool ensure_dir(const char *dirname);
bool is_dir(const char* path); bool is_dir(const char* path);
extern uint8 shared_hmac_md5_key[16]; extern uint8 shared_hmac_md5_key[16];
extern void hash_md5(size_t size, const unsigned char* bytes,
unsigned char digest[16]);
extern int hmac_key_set; extern int hmac_key_set;
extern unsigned char shared_hmac_md5_key[16]; extern unsigned char shared_hmac_md5_key[16];
extern void hmac_md5(size_t size, const unsigned char* bytes, extern void hmac_md5(size_t size, const unsigned char* bytes,
unsigned char digest[16]); unsigned char digest[16]);
extern const char* md5_digest_print(const unsigned char digest[16]);
// Initializes RNGs for bro_random() and MD5 usage. If seed is given, then // Initializes RNGs for bro_random() and MD5 usage. If seed is given, then
// it is used (to provide determinism). If load_file is given, the seeds // it is used (to provide determinism). If load_file is given, the seeds
// (both random & MD5) are loaded from that file. This takes precedence // (both random & MD5) are loaded from that file. This takes precedence

View file

@ -0,0 +1,4 @@
f97c5d29941bfb1b2fdab0874906ab82
7b0391feb2e0cd271f1cf39aafb4376f
f97c5d29941bfb1b2fdab0874906ab82
7b0391feb2e0cd271f1cf39aafb4376f

View file

@ -0,0 +1,4 @@
fe05bcdcdc4928012781a5f1a2a77cbb5398e106
3e949019500deb1369f13d9644d420d3a920aa5e
fe05bcdcdc4928012781a5f1a2a77cbb5398e106
3e949019500deb1369f13d9644d420d3a920aa5e

View file

@ -0,0 +1,4 @@
7692c3ad3540bb803c020b3aee66cd8887123234ea0c6e7143c0add73ff431ed
4592092e1061c7ea85af2aed194621cc17a2762bae33a79bf8ce33fd0168b801
7692c3ad3540bb803c020b3aee66cd8887123234ea0c6e7143c0add73ff431ed
4592092e1061c7ea85af2aed194621cc17a2762bae33a79bf8ce33fd0168b801

View file

@ -1,9 +1,83 @@
1332784981.078396 weird: bad_IP_checksum #separator \x09
1332784885.686428 weird: bad_TCP_checksum #set_separator ,
1332784933.501023 weird: bad_UDP_checksum #empty_field (empty)
1332785210.013051 weird: routing0_hdr #unset_field -
1332785210.013051 weird: bad_TCP_checksum #path weird
1332782580.798420 weird: routing0_hdr #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
1332782580.798420 weird: bad_UDP_checksum #types time string addr port addr port string string bool string
1332785250.469132 weird: bad_TCP_checksum 1332784981.078396 - - - - - bad_IP_checksum - F bro
1332781342.923813 weird: bad_UDP_checksum #separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332784885.686428 UWkUyAuUGXf 127.0.0.1 30000 127.0.0.1 80 bad_TCP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332784933.501023 UWkUyAuUGXf 127.0.0.1 30000 127.0.0.1 13000 bad_UDP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075363.536871 UWkUyAuUGXf 192.168.1.100 8 192.168.1.101 0 bad_ICMP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332785210.013051 - - - - - routing0_hdr - F bro
1332785210.013051 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 30000 2001:78:1:32::2 80 bad_TCP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332782580.798420 - - - - - routing0_hdr - F bro
1332782580.798420 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 30000 2001:78:1:32::2 13000 bad_UDP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075111.800086 - - - - - routing0_hdr - F bro
1334075111.800086 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 128 2001:78:1:32::1 129 bad_ICMP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332785250.469132 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 30000 2001:4f8:4:7:2e0:81ff:fe52:9a6b 80 bad_TCP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332781342.923813 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 30000 2001:4f8:4:7:2e0:81ff:fe52:9a6b 13000 bad_UDP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334074939.467194 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 128 2001:4f8:4:7:2e0:81ff:fe52:9a6b 129 bad_ICMP_checksum - F bro

View file

@ -1,2 +1,56 @@
1332785125.596793 weird: routing0_hdr #separator \x09
1332782508.592037 weird: routing0_hdr #set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334074939.467194 UWkUyAuUGXf 2001:4f8:4:7:2e0:81ff:fe52:ffff 128 2001:4f8:4:7:2e0:81ff:fe52:9a6b 129 bad_ICMP_checksum - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332785125.596793 - - - - - routing0_hdr - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1332782508.592037 - - - - - routing0_hdr - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075027.053380 - - - - - routing0_hdr - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075027.053380 - - - - - routing0_hdr - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075027.053380 - - - - - routing0_hdr - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334075027.053380 - - - - - routing0_hdr - F bro

View file

@ -1 +0,0 @@
1333663011.602839 weird: unknown_protocol_135

View file

@ -0,0 +1,8 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1333663011.602839 - - - - - unknown_protocol_135 - F bro

View file

@ -0,0 +1,4 @@
opened
write 0
write 3
write 6

View file

@ -0,0 +1,4 @@
opened
write 1
write 4
write 7

View file

@ -0,0 +1,4 @@
opened
write 2
write 5
write 8

View file

@ -0,0 +1,6 @@
opened
write 0
opened
write 3
opened
write 6

View file

@ -0,0 +1,6 @@
opened
write 1
opened
write 4
opened
write 7

View file

@ -0,0 +1,6 @@
opened
write 2
opened
write 5
opened
write 8

View file

@ -0,0 +1,12 @@
icmp_unreachable (code=0)
conn_id: [orig_h=10.0.0.1, orig_p=3/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=3, icode=0, len=0, hlim=64, v6=F]
icmp_context: [id=[orig_h=::, orig_p=0/unknown, resp_h=::, resp_p=0/unknown], len=0, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
icmp_unreachable (code=0)
conn_id: [orig_h=10.0.0.1, orig_p=3/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=3, icode=0, len=20, hlim=64, v6=F]
icmp_context: [id=[orig_h=10.0.0.2, orig_p=0/unknown, resp_h=10.0.0.1, resp_p=0/unknown], len=20, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
icmp_unreachable (code=3)
conn_id: [orig_h=192.168.1.102, orig_p=3/icmp, resp_h=192.168.1.1, resp_p=3/icmp]
icmp_conn: [orig_h=192.168.1.102, resp_h=192.168.1.1, itype=3, icode=3, len=148, hlim=128, v6=F]
icmp_context: [id=[orig_h=192.168.1.1, orig_p=53/udp, resp_h=192.168.1.102, resp_p=59207/udp], len=163, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]

View file

@ -0,0 +1,20 @@
icmp_unreachable (code=3)
conn_id: [orig_h=192.168.1.102, orig_p=3/icmp, resp_h=192.168.1.1, resp_p=3/icmp]
icmp_conn: [orig_h=192.168.1.102, resp_h=192.168.1.1, itype=3, icode=3, len=148, hlim=128, v6=F]
icmp_context: [id=[orig_h=192.168.1.1, orig_p=53/udp, resp_h=192.168.1.102, resp_p=59207/udp], len=163, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_time_exceeded (code=0)
conn_id: [orig_h=10.0.0.1, orig_p=11/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=11, icode=0, len=32, hlim=64, v6=F]
icmp_context: [id=[orig_h=10.0.0.2, orig_p=30000/udp, resp_h=10.0.0.1, resp_p=13000/udp], len=32, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_echo_request (id=34844, seq=0, payload=O\x85\xe0C\0^N\xeb\xff^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, hlim=64, v6=F]
icmp_echo_reply (id=34844, seq=0, payload=O\x85\xe0C\0^N\xeb\xff^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, hlim=64, v6=F]
icmp_echo_request (id=34844, seq=1, payload=O\x85\xe0D\0^N\xf0}^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, hlim=64, v6=F]
icmp_echo_reply (id=34844, seq=1, payload=O\x85\xe0D\0^N\xf0}^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, hlim=64, v6=F]

View file

@ -0,0 +1,16 @@
icmp_unreachable (code=0)
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=0, hlim=64, v6=T]
icmp_context: [id=[orig_h=::, orig_p=0/unknown, resp_h=::, resp_p=0/unknown], len=0, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
icmp_unreachable (code=0)
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=40, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=0/unknown, resp_h=fe80::dead, resp_p=0/unknown], len=48, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
icmp_unreachable (code=0)
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=60, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=60, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_unreachable (code=0)
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=48, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=0/unknown, resp_h=fe80::dead, resp_p=0/unknown], len=48, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]

View file

@ -0,0 +1,68 @@
icmp_unreachable (code=0)
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=60, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=60, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_packet_too_big (code=0)
conn_id: [orig_h=fe80::dead, orig_p=2/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=2, icode=0, len=52, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_time_exceeded (code=0)
conn_id: [orig_h=fe80::dead, orig_p=3/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=3, icode=0, len=52, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_parameter_problem (code=0)
conn_id: [orig_h=fe80::dead, orig_p=4/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=4, icode=0, len=52, hlim=64, v6=T]
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
icmp_echo_request (id=1, seq=3, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_reply (id=1, seq=3, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_request (id=1, seq=4, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_reply (id=1, seq=4, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_request (id=1, seq=5, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_reply (id=1, seq=5, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_request (id=1, seq=6, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_echo_reply (id=1, seq=6, payload=abcdefghijklmnopqrstuvwabcdefghi)
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, hlim=128, v6=T]
icmp_redirect (tgt=fe80::cafe, dest=fe80::babe)
conn_id: [orig_h=fe80::dead, orig_p=137/icmp, resp_h=fe80::beef, resp_p=0/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=137, icode=0, len=32, hlim=255, v6=T]
icmp_router_advertisement
cur_hop_limit=13
managed=T
other=F
home_agent=T
pref=3
proxy=F
rsv=0
router_lifetime=30.0 mins
reachable_time=3.0 secs 700.0 msecs
retrans_timer=1.0 sec 300.0 msecs
conn_id: [orig_h=fe80::dead, orig_p=134/icmp, resp_h=fe80::beef, resp_p=133/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=134, icode=0, len=8, hlim=255, v6=T]
icmp_neighbor_advertisement (tgt=fe80::babe)
router=T
solicited=F
override=T
conn_id: [orig_h=fe80::dead, orig_p=136/icmp, resp_h=fe80::beef, resp_p=135/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=136, icode=0, len=16, hlim=255, v6=T]
icmp_router_solicitation
conn_id: [orig_h=fe80::dead, orig_p=133/icmp, resp_h=fe80::beef, resp_p=134/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=133, icode=0, len=0, hlim=255, v6=T]
icmp_neighbor_solicitation (tgt=fe80::babe)
conn_id: [orig_h=fe80::dead, orig_p=135/icmp, resp_h=fe80::beef, resp_p=136/icmp]
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=135, icode=0, len=16, hlim=255, v6=T]

View file

@ -0,0 +1,24 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334160095.895421 - - - - - truncated_IP - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334156241.519125 - - - - - truncated_IP - F bro
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path weird
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string
1334094648.590126 - - - - - truncated_IP - F bro

View file

@ -1,7 +1,7 @@
==== atomic ==== atomic
-10 -10
2 2
1330035434.516896 1336411585.166009
2.0 mins 2.0 mins
F F
1.5 1.5

View file

@ -1,7 +1,7 @@
==== atomic a 1 ==== ==== atomic a 1 ====
-4L -4 -4L -4
42 42 42 42
1330035434.5180 1336411585.1711
60.0 60.0
True True True True
3.14 3.14
@ -14,7 +14,7 @@ True True
==== atomic a 2 ==== ==== atomic a 2 ====
-10L -10 -10L -10
2 2 2 2
1330035434.5169 1336411585.1660
120.0 120.0
False False False False
1.5 1.5
@ -27,7 +27,7 @@ False False
==== atomic b 2 ==== ==== atomic b 2 ====
-10L -10 -10L -10
<broccoli.count instance at > 2 <broccoli.count instance at > 2
<broccoli.time instance at > 1330035434.5169 <broccoli.time instance at > 1336411585.1660
<broccoli.interval instance at > 120.0 <broccoli.interval instance at > 120.0
False False False False
1.5 1.5

View file

@ -5,15 +5,15 @@
#path local #path local
#fields ts id.orig_h #fields ts id.orig_h
#types time addr #types time addr
1300475168.855330 141.142.220.118 1300475168.859163 141.142.220.118
1300475168.652003 141.142.220.118 1300475168.652003 141.142.220.118
1300475168.895267 141.142.220.118 1300475168.895267 141.142.220.118
1300475168.902635 141.142.220.118
1300475168.892936 141.142.220.118
1300475168.855305 141.142.220.118 1300475168.855305 141.142.220.118
1300475168.859163 141.142.220.118
1300475168.892913 141.142.220.118 1300475168.892913 141.142.220.118
1300475168.724007 141.142.220.118 1300475168.724007 141.142.220.118
1300475168.892936 141.142.220.118 1300475168.855330 141.142.220.118
1300475168.902635 141.142.220.118
1300475168.891644 141.142.220.118 1300475168.891644 141.142.220.118
1300475170.862384 141.142.220.226 1300475170.862384 141.142.220.226
1300475168.853899 141.142.220.118 1300475168.853899 141.142.220.118

View file

@ -0,0 +1,22 @@
USER anonymous
PASS test
SYST
FEAT
PWD
EPSV
LIST
EPSV
NLST
TYPE I
SIZE robots.txt
EPSV
RETR robots.txt
MDTM robots.txt
SIZE robots.txt
EPRT |2|2001:470:1f11:81f:c999:d94:aa7c:2e3e|49189|
RETR robots.txt
MDTM robots.txt
TYPE A
EPRT |2|2001:470:1f11:81f:c999:d94:aa7c:2e3e|49190|
LIST
QUIT

View file

@ -0,0 +1,73 @@
220 ftp.NetBSD.org FTP server (NetBSD-ftpd 20100320) ready.
331 Guest login ok, type your name as password.
230-
The NetBSD Project FTP Server located in Redwood City, CA, USA
1 Gbps connectivity courtesy of , ,
Internet Systems Consortium WELCOME! /( )`
\ \___ / |
+--- Currently Supported Platforms ----+ /- _ `-/ '
| acorn[26,32], algor, alpha, amd64, | (/\/ \ \ /\
| amiga[,ppc], arc, atari, bebox, | / / | ` \
| cats, cesfic, cobalt, dreamcast, | O O ) / |
| evb[arm,mips,ppc,sh3], hp[300,700], | `-^--'`< '
| hpc[arm,mips,sh], i386, | (_.) _ ) /
| ibmnws, iyonix, luna68k, | .___/` /
| mac[m68k,ppc], mipsco, mmeye, | `-----' /
| mvme[m68k,ppc], netwinders, | <----. __ / __ \
| news[m68k,mips], next68k, ofppc, | <----|====O)))==) \) /====
| playstation2, pmax, prep, sandpoint, | <----' `--' `.__,' \
| sbmips, sgimips, shark, sparc[,64], | | |
| sun[2,3], vax, x68k, xen | \ /
+--------------------------------------+ ______( (_ / \_____
See our website at http://www.NetBSD.org/ ,' ,-----' | \
We log all FTP transfers and commands. `--{__________) (FL) \/
230-
EXPORT NOTICE
Please note that portions of this FTP site contain cryptographic
software controlled under the Export Administration Regulations (EAR).
None of this software may be downloaded or otherwise exported or
re-exported into (or to a national or resident of) Cuba, Iran, Libya,
Sudan, North Korea, Syria or any other country to which the U.S. has
embargoed goods.
By downloading or using said software, you are agreeing to the
foregoing and you are representing and warranting that you are not
located in, under the control of, or a national or resident of any
such country or on any such list.
230 Guest login ok, access restrictions apply.
215 UNIX Type: L8 Version: NetBSD-ftpd 20100320
211-Features supported
MDTM
MLST Type*;Size*;Modify*;Perm*;Unique*;
REST STREAM
SIZE
TVFS
211 End
257 "/" is the current directory.
229 Entering Extended Passive Mode (|||57086|)
150 Opening ASCII mode data connection for '/bin/ls'.
226 Transfer complete.
229 Entering Extended Passive Mode (|||57087|)
150 Opening ASCII mode data connection for 'file list'.
226 Transfer complete.
200 Type set to I.
213 77
229 Entering Extended Passive Mode (|||57088|)
150 Opening BINARY mode data connection for 'robots.txt' (77 bytes).
226 Transfer complete.
213 20090816112038
213 77
200 EPRT command successful.
150 Opening BINARY mode data connection for 'robots.txt' (77 bytes).
226 Transfer complete.
213 20090816112038
200 Type set to A.
200 EPRT command successful.
150 Opening ASCII mode data connection for '/bin/ls'.
226 Transfer complete.
221-
Data traffic for this session was 154 bytes in 2 files.
Total traffic for this session was 4512 bytes in 5 transfers.
221 Thank you for using the FTP service on ftp.NetBSD.org.

View file

@ -0,0 +1,8 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ssl
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id subject issuer_subject not_valid_before not_valid_after last_alert
#types time string addr port addr port string string string string string string time time string
1335538392.319381 UWkUyAuUGXf 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA ssl.gstatic.com - CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US 1334102677.000000 1365639277.000000 -

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more