diff --git a/CHANGES b/CHANGES index 6f1ccab9b8..e90e85f125 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,59 @@ +2.4-422 | 2016-03-21 19:48:30 -0700 + + * Adapt to recent change in CAF CMake script. (Matthias Vallentin) + + * Deprecate --with-libcaf in favor of --with-caf, as already done in + Broker. (Matthias Vallentin) + +2.4-418 | 2016-03-21 12:22:15 -0700 + + * Add protocol confirmation to MySQL analyzer. (Vlad Grigorescu) + + * Check that there is only one of &read_expire, &write_expire, + &create_expire. (Johanna Amann) + + * Fixed &read_expire for subnet-indexed tables, plus test case. (Jan + Grashoefer) + + * Add filter_subnet_table() that works similar to matching_subnet() + but returns a filtered view of the original set/table only + containing the changed subnets. (Jan Grashoefer) + + * Fix bug in tablue values' tracking read operations. (Johanna + Amann) + + * Update TLS constants and extensions from IANA. (Johanna Amann) + +2.4-406 | 2016-03-11 14:27:47 -0800 + + * Add NetControl and OpenFlow frameworks. (Johanna Amann) + +2.4-313 | 2016-03-08 07:47:57 -0800 + + * Remove old string functions in C++ code. This removes the + functions: strcasecmp_n, strchr_n, and strrchr_n. (Johanna Amann) + +2.4-307 | 2016-03-07 13:33:45 -0800 + + * Add "disable_analyzer_after_detection" and remove + "skip_processing_after_detection". Addresses BIT-1545. + (Aaron Eppert & Johanna Amann) + + * Add bad_HTTP_request_with_version weird (William Glodek) + +2.4-299 | 2016-03-04 12:51:55 -0800 + + * More detailed installation instructions for FreeBSD 9.X. (Johanna Amann) + + * Update CMake OpenSSL checks. (Johanna Amann) + + * "SUBSCRIBE" is a valid SIP. message per RFC 3265. Addresses + BIT-1529. (Johanna Amann) + + * Update documentation for connection log's RSTR. Addresses BIT-1535 + (Johanna Amann) + 2.4-284 | 2016-02-17 14:12:15 -0800 * Fix sometimes failing dump-events test. (Johanna Amann) @@ -1936,21 +1991,21 @@ 2.3-beta-18 | 2014-06-06 13:11:50 -0700 * Add two more SSL events, one triggered for each handshake message - and one triggered for the tls change cipherspec message. (Bernhard + and one triggered for the tls change cipherspec message. (Johanna Amann) * Small SSL bug fix. In case SSL::disable_analyzer_after_detection was set to false, the ssl_established event would fire after each - data packet once the session is established. (Bernhard Amann) + data packet once the session is established. (Johanna Amann) 2.3-beta-16 | 2014-06-06 13:05:44 -0700 * Re-activate notice suppression for expiring certificates. - (Bernhard Amann) + (Johanna Amann) 2.3-beta-14 | 2014-06-05 14:43:33 -0700 - * Add new TLS extension type numbers from IANA (Bernhard Amann) + * Add new TLS extension type numbers from IANA (Johanna Amann) * Switch to double hashing for Bloomfilters for better performance. (Matthias Vallentin) @@ -1960,7 +2015,7 @@ (Matthias Vallentin) * Make buffer for X509 certificate subjects larger. Addresses - BIT-1195 (Bernhard Amann) + BIT-1195 (Johanna Amann) 2.3-beta-5 | 2014-05-29 15:34:42 -0500 @@ -1982,19 +2037,19 @@ * Release 2.3-beta - * Clean up OpenSSL data structures on exit. (Bernhard Amann) + * Clean up OpenSSL data structures on exit. (Johanna Amann) - * Fixes for OCSP & x509 analysis memory leak issues. (Bernhard Amann) + * Fixes for OCSP & x509 analysis memory leak issues. (Johanna Amann) * Remove remaining references to BROMAGIC (Daniel Thayer) * Fix typos and formatting in event and BiF documentation (Daniel Thayer) * Update intel framework plugin for ssl server_name extension API - changes. (Bernhard Amann, Justin Azoff) + changes. (Johanna Amann, Justin Azoff) * Fix expression errors in SSL/x509 scripts when unparseable data - is in certificate chain. (Bernhard Amann) + is in certificate chain. (Johanna Amann) 2.2-478 | 2014-05-19 15:31:33 -0500 @@ -2003,7 +2058,7 @@ 2.2-477 | 2014-05-19 14:13:00 -0500 - * Fix X509::Result record's "result" field to be set internally as type int instead of type count. (Bernhard Amann) + * Fix X509::Result record's "result" field to be set internally as type int instead of type count. (Johanna Amann) * Fix a couple of doc build warnings (Daniel Thayer) @@ -2021,19 +2076,19 @@ * New script policy/protocols/ssl/validate-ocsp.bro that adds OSCP validation to ssl.log. The work is done by a new bif - x509_ocsp_verify(). (Bernhard Amann) + x509_ocsp_verify(). (Johanna Amann) * STARTTLS support for POP3 and SMTP. The SSL analyzer takes over when seen. smtp.log now logs when a connection switches to SSL. - (Bernhard Amann) + (Johanna Amann) - * Replace errors when parsing x509 certs with weirds. (Bernhard + * Replace errors when parsing x509 certs with weirds. (Johanna Amann) - * Improved Heartbleed attack/scan detection. (Bernhard Amann) + * Improved Heartbleed attack/scan detection. (Johanna Amann) * Let TLS analyzer fail better when no longer in sync with the data - stream. (Bernhard Amann) + stream. (Johanna Amann) 2.2-444 | 2014-05-16 14:10:32 -0500 @@ -2052,7 +2107,7 @@ 2.2-427 | 2014-05-15 13:37:23 -0400 - * Fix dynamic SumStats update on clusters (Bernhard Amann) + * Fix dynamic SumStats update on clusters (Johanna Amann) 2.2-425 | 2014-05-08 16:34:44 -0700 @@ -2104,11 +2159,11 @@ * Add DH support to SSL analyzer. When using DHE or DH-Anon, sever key parameters are now available in scriptland. Also add script to - alert on weak certificate keys or weak dh-params. (Bernhard Amann) + alert on weak certificate keys or weak dh-params. (Johanna Amann) - * Add a few more ciphers Bro did not know at all so far. (Bernhard Amann) + * Add a few more ciphers Bro did not know at all so far. (Johanna Amann) - * Log chosen curve when using ec cipher suite in TLS. (Bernhard Amann) + * Log chosen curve when using ec cipher suite in TLS. (Johanna Amann) 2.2-397 | 2014-05-01 20:29:20 -0700 @@ -2120,7 +2175,7 @@ (Jon Siwek) * Correct a notice for heartbleed. The notice is thrown correctly, - just the message conteined wrong values. (Bernhard Amann) + just the message conteined wrong values. (Johanna Amann) * Improve/standardize some malloc/realloc return value checks. (Jon Siwek) @@ -2147,7 +2202,7 @@ 2.2-377 | 2014-04-24 16:57:54 -0700 * A larger set of SSL improvements and extensions. Addresses - BIT-1178. (Bernhard Amann) + BIT-1178. (Johanna Amann) - Fixes TLS protocol version detection. It also should bail-out correctly on non-tls-connections now @@ -2208,9 +2263,9 @@ 2.2-335 | 2014-04-10 15:04:57 -0700 - * Small logic fix for main SSL script. (Bernhard Amann) + * Small logic fix for main SSL script. (Johanna Amann) - * Update DPD signatures for detecting TLS 1.2. (Bernhard Amann) + * Update DPD signatures for detecting TLS 1.2. (Johanna Amann) * Remove unused data member of SMTP_Analyzer to silence a Coverity warning. (Jon Siwek) @@ -2239,7 +2294,7 @@ 2.2-315 | 2014-04-01 16:50:01 -0700 * Change logging's "#types" description of sets to "set". Addresses - BIT-1163 (Bernhard Amann) + BIT-1163 (Johanna Amann) 2.2-313 | 2014-04-01 16:40:19 -0700 @@ -2254,7 +2309,7 @@ (Jon Siwek) * Fix potential memory leak in x509 parser reported by Coverity. - (Bernhard Amann) + (Johanna Amann) 2.2-304 | 2014-03-30 23:05:54 +0200 @@ -2325,7 +2380,7 @@ from the certificates (e.g. elliptic curve information, subject alternative names, basic constraints). Certificate validation also was improved, should be easier to use and exposes information like - the full verified certificate chain. (Bernhard Amann) + the full verified certificate chain. (Johanna Amann) This update changes the format of ssl.log and adds a new x509.log with certificate information. Furthermore all x509 events and @@ -2363,7 +2418,7 @@ 2.2-256 | 2014-03-30 19:57:28 +0200 * For the summary statistics framewirk, change all &create_expire - attributes to &read_expire in the cluster part. (Bernhard Amann) + attributes to &read_expire in the cluster part. (Johanna Amann) 2.2-254 | 2014-03-30 19:55:22 +0200 @@ -2387,7 +2442,7 @@ 2.2-244 | 2014-03-17 08:24:17 -0700 * Fix compile errror on FreeBSD caused by wrong include file order. - (Bernhard Amann) + (Johanna Amann) 2.2-240 | 2014-03-14 10:23:54 -0700 @@ -2483,7 +2538,7 @@ * Improve SSL logging so that connections are logged even when the ssl_established event is not generated as well as other small SSL - fixes. (Bernhard Amann) + fixes. (Johanna Amann) 2.2-206 | 2014-03-03 16:52:28 -0800 @@ -2500,7 +2555,7 @@ * Allow iterating over bif functions with result type vector of any. This changes the internal type that is used to signal that a vector is unspecified from any to void. Addresses BIT-1144 - (Bernhard Amann) + (Johanna Amann) 2.2-197 | 2014-02-28 15:36:58 -0800 @@ -2508,37 +2563,37 @@ 2.2-194 | 2014-02-28 14:50:53 -0800 - * Remove packet sorter. Addresses BIT-700. (Bernhard Amann) + * Remove packet sorter. Addresses BIT-700. (Johanna Amann) 2.2-192 | 2014-02-28 09:46:43 -0800 - * Update Mozilla root bundle. (Bernhard Amann) + * Update Mozilla root bundle. (Johanna Amann) 2.2-190 | 2014-02-27 07:34:44 -0800 - * Adjust timings of a few leak tests. (Bernhard Amann) + * Adjust timings of a few leak tests. (Johanna Amann) 2.2-187 | 2014-02-25 07:24:42 -0800 - * More Google TLS extensions that are being actively used. (Bernhard + * More Google TLS extensions that are being actively used. Johanna( Amann) * Remove unused, and potentially unsafe, function - ListVal::IncludedInString. (Bernhard Amann) + ListVal::IncludedInString. (Johanna Amann) 2.2-184 | 2014-02-24 07:28:18 -0800 * New TLS constants from https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01. - (Bernhard Amann) + (Johanna Amann) 2.2-180 | 2014-02-20 17:29:14 -0800 * New SSL alert descriptions from https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04. - (Bernhard Amann) + (Johanna Amann) - * Update SQLite. (Bernhard Amann) + * Update SQLite. (Johanna Amann) 2.2-177 | 2014-02-20 17:27:46 -0800 @@ -2569,7 +2624,7 @@ 'modbus_read_fifo_queue_response' event handler. (Jon Siwek) * Add channel_id TLS extension number. This number is not IANA - defined, but we see it being actively used. (Bernhard Amann) + defined, but we see it being actively used. (Johanna Amann) * Test baseline updates for DNS change. (Robin Sommer) @@ -2611,7 +2666,7 @@ 2.2-147 | 2014-02-07 08:06:53 -0800 - * Fix x509-extension test sometimes failing. (Bernhard Amann) + * Fix x509-extension test sometimes failing. (Johanna Amann) 2.2-144 | 2014-02-06 20:31:18 -0800 @@ -2647,7 +2702,7 @@ 2.2-128 | 2014-01-30 15:58:47 -0800 - * Add leak test for Exec module. (Bernhard Amann) + * Add leak test for Exec module. (Johanna Amann) * Fix file_over_new_connection event to trigger when entire file is missed. (Jon Siwek) @@ -2665,7 +2720,7 @@ 2.2-120 | 2014-01-28 10:25:23 -0800 * Fix and extend x509_extension() event, which now actually returns - the extension. (Bernhard Amann) + the extension. (Johanna Amann) New event signauture: @@ -2780,7 +2835,7 @@ * Several improvements to input framework error handling for more robustness and more helpful error messages. Includes tests for - many cases. (Bernhard Amann) + many cases. (Johanna Amann) 2.2-66 | 2013-12-09 13:54:16 -0800 @@ -2806,7 +2861,7 @@ * Fix memory leak in input framework. If the input framework was used to read event streams and those streams contained records with more than one field, not all elements of the threading Values - were cleaned up. Addresses BIT-1103. (Bernhard Amann) + were cleaned up. Addresses BIT-1103. (Johanna Amann) * Minor Broxygen improvements. Addresses BIT-1098. (Jon Siwek) @@ -2850,7 +2905,7 @@ 2.2-40 | 2013-12-04 12:16:38 -0800 * ssl_client_hello() now receives a vector of ciphers, instead of a - set, to preserve their order. (Bernhard Amann) + set, to preserve their order. (Johanna Amann) 2.2-38 | 2013-12-04 12:10:54 -0800 @@ -2987,13 +3042,13 @@ 2.2-beta-157 | 2013-10-25 11:11:17 -0700 * Extend the documentation of the SQLite reader/writer framework. - (Bernhard Amann) + (Johanna Amann) * Fix inclusion of wrong example file in scripting tutorial. - Reported by Michael Auger @LM4K. (Bernhard Amann) + Reported by Michael Auger @LM4K. (Johanna Amann) * Alternative fix for the thrading deadlock issue to avoid potential - performance impact. (Bernhard Amann) + performance impact. (Johanna Amann) 2.2-beta-152 | 2013-10-24 18:16:49 -0700 @@ -3006,7 +3061,7 @@ 2.2-beta-150 | 2013-10-24 16:32:14 -0700 * Change temporary ASCII reader workaround for getline() on - Mavericks to permanent fix. (Bernhard Amann) + Mavericks to permanent fix. (Johanna Amann) 2.2-beta-148 | 2013-10-24 14:34:35 -0700 @@ -3020,7 +3075,7 @@ * Intel framework notes added to NEWS. (Seth Hall) * Temporary OSX Mavericks libc++ issue workaround for getline() - problem in ASCII reader. (Bernhard Amann) + problem in ASCII reader. (Johanna Amann) * Change test of identify_data BIF to ignore charset as it may vary with libmagic version. (Jon Siwek) @@ -3063,16 +3118,16 @@ 2.2-beta-80 | 2013-10-18 13:18:05 -0700 - * SQLite reader/writer documentation. (Bernhard Amann) + * SQLite reader/writer documentation. (Johanna Amann) * Check that the SQLite reader is only used in MANUAL reading mode. - (Bernhard Amann) + (Johanna Amann) * Rename the SQLite writer "dbname" configuration option to - "tablename". (Bernhard Amann) + "tablename". (Johanna Amann) * Remove the "dbname" configuration option from the SQLite reader as - it wasn't used there. (Bernhard Amann) + it wasn't used there. (Johanna Amann) 2.2-beta-73 | 2013-10-14 14:28:25 -0700 @@ -3104,9 +3159,9 @@ 2.2-beta-55 | 2013-10-10 13:36:38 -0700 - * A couple of new TLS extension numbers. (Bernhard Amann) + * A couple of new TLS extension numbers. (Johanna Amann) - * Suport for three more new TLS ciphers. (Bernhard Amann) + * Suport for three more new TLS ciphers. (Johanna Amann) * Removing ICSI notary from default site config. (Robin Sommer) @@ -3151,7 +3206,7 @@ 2.2-beta-18 | 2013-10-02 10:28:17 -0700 - * Add support for further TLS cipher suites. (Bernhard Amann) + * Add support for further TLS cipher suites. (Johanna Amann) 2.2-beta-13 | 2013-10-01 11:31:55 -0700 @@ -3201,7 +3256,7 @@ * Add links to Intelligence Framework documentation. (Daniel Thayer) - * Update Mozilla root CA list. (Bernhard Amann, Jon Siwek) + * Update Mozilla root CA list. (Johanna Amann, Jon Siwek) * Update documentation of required packages. (Daniel Thayer) @@ -3212,10 +3267,10 @@ 2.1-1357 | 2013-09-18 14:58:52 -0700 - * Update HLL API and its documentation. (Bernhard Amann) + * Update HLL API and its documentation. (Johanna Amann) * Fix case in HLL where hll_error_margin could be undefined. - (Bernhard Amann) + (Johanna Amann) 2.1-1352 | 2013-09-18 14:42:28 -0700 @@ -3276,7 +3331,7 @@ * Support for probabilistic set cardinality, using the HyperLogLog - algorithm. (Bernhard Amann, Soumya Basu) + algorithm. (Johanna Amann, Soumya Basu) Bro now provides the following BiFs: @@ -3315,7 +3370,7 @@ 2.1-1137 | 2013-08-27 13:26:44 -0700 * Add BiF hexstr_to_bytestring() that does exactly the opposite of - bytestring_to_hexstr(). (Bernhard Amann) + bytestring_to_hexstr(). (Johanna Amann) 2.1-1135 | 2013-08-27 12:16:26 -0700 @@ -3387,7 +3442,7 @@ 2.1-1078 | 2013-08-19 09:29:30 -0700 - * Moving sqlite code into new external 3rdparty submodule. (Bernhard + * Moving sqlite code into new external 3rdparty submodule. Johanna( Amann) 2.1-1074 | 2013-08-14 10:29:54 -0700 @@ -3487,12 +3542,12 @@ 2.1-1007 | 2013-08-01 15:41:54 -0700 - * More function documentation. (Bernhard Amann) + * More function documentation. (Johanna Amann) 2.1-1004 | 2013-08-01 14:37:43 -0700 * Adding a probabilistic data structure for computing "top k" - elements. (Bernhard Amann) + elements. (Johanna Amann) The corresponding functions are: @@ -3526,7 +3581,7 @@ 2.1-948 | 2013-07-31 20:08:28 -0700 * Fix segfault caused by merging an empty bloom-filter with a - bloom-filter already containing values. (Bernhard Amann) + bloom-filter already containing values. (Johanna Amann) 2.1-945 | 2013-07-30 10:05:10 -0700 @@ -3666,12 +3721,12 @@ 2.1-814 | 2013-07-15 18:18:20 -0700 * Fixing raw reader crash when accessing nonexistant file, and - memory leak when reading from file. Addresses #1038. (Bernhard + memory leak when reading from file. Addresses #1038. (Johanna Amann) 2.1-811 | 2013-07-14 08:01:54 -0700 - * Bump sqlite to 3.7.17. (Bernhard Amann) + * Bump sqlite to 3.7.17. (Johanna Amann) * Small test fixes. (Seth Hall) @@ -3721,7 +3776,7 @@ 2.1-780 | 2013-07-03 16:46:26 -0700 * Rewrite of the RAW input reader for improved robustness and new - features. (Bernhard Amann) This includes: + features. (Johanna Amann) This includes: - Send "end_of_data" event for all kind of streams. - Send "process_finished" event with exit code of child @@ -3850,12 +3905,12 @@ 2.1-656 | 2013-05-17 15:58:07 -0700 - * Fix mutex lock problem for writers. (Bernhard Amann) + * Fix mutex lock problem for writers. (Johanna Amann) 2.1-654 | 2013-05-17 13:49:52 -0700 * Tweaks to sqlite3 configuration to address threading issues. - (Bernhard Amann) + (Johanna Amann) 2.1-651 | 2013-05-17 13:37:16 -0700 @@ -3881,7 +3936,7 @@ 2.1-640 | 2013-05-15 17:24:09 -0700 - * Support for cleaning up threads that have terminated. (Bernhard + * Support for cleaning up threads that have terminated. (Johanna Amann and Robin Sommer). Includes: - Both logging and input frameworks now clean up threads once @@ -3898,14 +3953,14 @@ 2.1-626 | 2013-05-15 16:09:31 -0700 * Add "reservoir" sampler for SumStats framework. This maintains - a set of N uniquely distributed random samples. (Bernhard Amann) + a set of N uniquely distributed random samples. (Johanna Amann) 2.1-619 | 2013-05-15 16:01:42 -0700 * SQLite reader and writer combo. This allows to read/write persistent data from on disk SQLite databases. The current interface is quite low-level, we'll add higher-level abstractions - in the future. (Bernhard Amann) + in the future. (Johanna Amann) 2.1-576 | 2013-05-15 14:29:09 -0700 @@ -3926,7 +3981,7 @@ 2.1-500 | 2013-05-10 19:22:24 -0700 * Fix to prevent merge-hook of SumStat's unique plugin from damaging - source data. (Bernhard Amann) + source data. (Johanna Amann) 2.1-498 | 2013-05-03 17:44:08 -0700 @@ -3942,7 +3997,7 @@ 2.1-492 | 2013-05-02 12:46:26 -0700 * Work-around for sumstats framework not propagating updates after - intermediate check in cluster environments. (Bernhard Amann) + intermediate check in cluster environments. (Johanna Amann) * Always apply tcp_connection_attempt. Before this change it was only applied when a connection_attempt() event handler was @@ -3997,7 +4052,7 @@ 2.1-380 | 2013-03-18 12:18:10 -0700 * Fix gcc compile warnings in base64 encoder and benchmark reader. - (Bernhard Amann) + (Johanna Amann) 2.1-377 | 2013-03-17 17:36:09 -0700 @@ -4006,10 +4061,10 @@ 2.1-375 | 2013-03-17 13:14:26 -0700 * Add base64 encoding functionality, including new BiFs - encode_base64() and encode_base64_custom(). (Bernhard Amann) + encode_base64() and encode_base64_custom(). (Johanna Amann) * Replace call to external "openssl" in extract-certs-pem.bro with - that encode_base64(). (Bernhard Amann) + that encode_base64(). (Johanna Amann) * Adding a test for extract-certs-pem.pem. (Robin Sommer) @@ -4043,7 +4098,7 @@ 2.1-357 | 2013-03-08 09:18:35 -0800 - * Fix race-condition in table-event test. (Bernhard Amann) + * Fix race-condition in table-event test. (Johanna Amann) * s/bro-ids.org/bro.org/g. (Robin Sommer) @@ -4060,9 +4115,9 @@ 2.1-347 | 2013-03-06 16:48:44 -0800 - * Remove unused parameter from vector assignment method. (Bernhard Amann) + * Remove unused parameter from vector assignment method. (Johanna Amann) - * Remove the byte_len() and length() bifs. (Bernhard Amann) + * Remove the byte_len() and length() bifs. (Johanna Amann) 2.1-342 | 2013-03-06 15:42:52 -0800 @@ -4114,7 +4169,7 @@ 2.1-319 | 2013-02-04 09:45:34 -0800 - * Update input tests to use exit_only_after_terminate. (Bernhard + * Update input tests to use exit_only_after_terminate. (Johanna Amann) * New option exit_only_after_terminate to prevent Bro from exiting. @@ -4146,7 +4201,7 @@ 2.1-302 | 2013-01-23 16:17:29 -0800 * Refactoring ASCII formatting/parsing from loggers/readers into a - separate AsciiFormatter class. (Bernhard Amann) + separate AsciiFormatter class. (Johanna Amann) * Fix uninitialized locals in event/hook handlers from having a value. Addresses #932. (Jon Siwek) @@ -4177,7 +4232,7 @@ * Removing unused class member. (Robin Sommer) * Add opaque type-ignoring for the accept_unsupported_types input - framework option. (Bernhard Amann) + framework option. (Johanna Amann) 2.1-271 | 2013-01-08 10:18:57 -0800 @@ -4258,7 +4313,7 @@ 2.1-229 | 2012-12-14 14:46:12 -0800 * Fix memory leak in ASCII reader when encoutering errors in input. - (Bernhard Amann) + (Johanna Amann) * Improvements for the "bad checksums" detector to make it detect bad TCP checksums. (Seth Hall) @@ -4329,7 +4384,7 @@ yet. Addresses #66. (Jon Siwek) * Fix segfault: Delete correct entry in error case in input - framework. (Bernhard Amann) + framework. (Johanna Amann) * Bad record constructor initializers now give an error. Addresses #34. (Jon Siwek) @@ -4587,7 +4642,7 @@ * Rename the Input Framework's update_finished event to end_of_data. It will now not only fire after table-reads have been completed, but also after the last event of a whole-file-read (or - whole-db-read, etc.). (Bernhard Amann) + whole-db-read, etc.). (Johanna Amann) * Fix for DNS log problem when a DNS response is seen with 0 RRs. (Seth Hall) @@ -4602,7 +4657,7 @@ 2.1-61 | 2012-10-12 09:32:48 -0700 * Fix bug in the input framework: the config table did not work. - (Bernhard Amann) + (Johanna Amann) 2.1-58 | 2012-10-08 10:10:09 -0700 @@ -4637,7 +4692,7 @@ * Fix for the input framework: BroStrings were constructed without a final \0, which makes them unusable by basically all internal - functions (like to_count). (Bernhard Amann) + functions (like to_count). (Johanna Amann) * Remove deprecated script functionality (see NEWS for details). (Daniel Thayer) @@ -4689,7 +4744,7 @@ * Small change to non-blocking DNS initialization. (Jon Siwek) * Reorder a few statements in scan.l to make 1.5msecs etc work. - Adresses #872. (Bernhard Amann) + Adresses #872. (Johanna Amann) 2.1-6 | 2012-09-06 23:23:14 -0700 @@ -4718,11 +4773,11 @@ * Fix uninitialized value for 'is_partial' in TCP analyzer. (Jon Siwek) - * Parse 64-bit consts in Bro scripts correctly. (Bernhard Amann) + * Parse 64-bit consts in Bro scripts correctly. (Johanna Amann) - * Output 64-bit counts correctly on 32-bit machines (Bernhard Amann) + * Output 64-bit counts correctly on 32-bit machines (Johanna Amann) - * Input framework fixes, including: (Bernhard Amann) + * Input framework fixes, including: (Johanna Amann) - One of the change events got the wrong parameters. @@ -4763,7 +4818,7 @@ 2.1-beta-45 | 2012-08-22 16:11:10 -0700 * Add an option to the input framework that allows the user to chose - to not die upon encountering files/functions. (Bernhard Amann) + to not die upon encountering files/functions. (Johanna Amann) 2.1-beta-41 | 2012-08-22 16:05:21 -0700 @@ -4782,7 +4837,7 @@ 2.1-beta-35 | 2012-08-22 08:44:52 -0700 * Add testcase for input framework reading sets (rather than - tables). (Bernhard Amann) + tables). (Johanna Amann) 2.1-beta-31 | 2012-08-21 15:46:05 -0700 @@ -4841,9 +4896,9 @@ 2.1-beta-6 | 2012-08-10 12:22:52 -0700 - * Fix bug in input framework with an edge case. (Bernhard Amann) + * Fix bug in input framework with an edge case. (Johanna Amann) - * Fix small bug in input framework test script. (Bernhard Amann) + * Fix small bug in input framework test script. (Johanna Amann) 2.1-beta-3 | 2012-08-03 10:46:49 -0700 @@ -4892,13 +4947,13 @@ writers that don't have a postprocessor. (Seth Hall) * Update input framework documentation to reflect want_record - change. (Bernhard Amann) + change. (Johanna Amann) * Fix crash when encountering an InterpreterException in a predicate - in logging or input Framework. (Bernhard Amann) + in logging or input Framework. (Johanna Amann) * Input framework: Make want_record=T the default for events - (Bernhard Amann) + (Johanna Amann) * Changing the start/end markers in logs to open/close now reflecting wall clock. (Robin Sommer) @@ -4920,10 +4975,10 @@ * Add comprehensive error handling for close() calls. (Jon Siwek) - * Add more test cases for input framework. (Bernhard Amann) + * Add more test cases for input framework. (Johanna Amann) * Input framework: make error output for non-matching event types - much more verbose. (Bernhard Amann) + much more verbose. (Johanna Amann) 2.0-877 | 2012-07-25 17:20:34 -0700 @@ -4963,12 +5018,12 @@ * Fix initialization problem in logging class. (Jon Siwek) * Input framework now accepts escaped ASCII values as input (\x##), - and unescapes appropiately. (Bernhard Amann) + and unescapes appropiately. (Johanna Amann) * Make reading ASCII logfiles work when the input separator is - different from \t. (Bernhard Amann) + different from \t. (Johanna Amann) - * A number of smaller fixes for input framework. (Bernhard Amann) + * A number of smaller fixes for input framework. (Johanna Amann) 2.0-851 | 2012-07-24 15:04:14 -0700 @@ -4988,7 +5043,7 @@ * Reworking parts of the internal threading/logging/input APIs for thread-safety. (Robin Sommer) - * Bugfix for SSL version check. (Bernhard Amann) + * Bugfix for SSL version check. (Johanna Amann) * Changing a HTTP DPD from port 3138 to 3128. Addresses #857. (Robin Sommer) @@ -5008,7 +5063,7 @@ #763. (Robin Sommer) * Fix bug, where in dns.log rcode always was set to 0/NOERROR when - no reply package was seen. (Bernhard Amann) + no reply package was seen. (Johanna Amann) * Updating to Mozilla's current certificate bundle. (Seth Hall) @@ -5024,7 +5079,7 @@ * Remove baselines for some leak-detecting unit tests. (Jon Siwek) * Unblock SIGFPE, SIGILL, SIGSEGV and SIGBUS for threads, so that - they now propagate to the main thread. Adresses #848. (Bernhard + they now propagate to the main thread. Adresses #848. (Johanna Amann) 2.0-761 | 2012-07-12 08:14:38 -0700 @@ -5032,7 +5087,7 @@ * Some small fixes to further reduce SOCKS false positive logs. (Seth Hall) * Calls to pthread_mutex_unlock now log the reason for failures. - (Bernhard Amann) + (Johanna Amann) 2.0-757 | 2012-07-11 08:30:19 -0700 @@ -5063,11 +5118,11 @@ 2.0-733 | 2012-07-02 15:31:24 -0700 - * Extending the input reader DoInit() API. (Bernhard Amann). It now + * Extending the input reader DoInit() API. (Johanna Amann). It now provides a Info struct similar to what we introduced for log writers, including a corresponding "config" key/value table. - * Fix to make writer-info work when debugging is enabled. (Bernhard + * Fix to make writer-info work when debugging is enabled. (Johanna Amann) 2.0-726 | 2012-07-02 15:19:15 -0700 @@ -5106,7 +5161,7 @@ * Set input frontend type before starting the thread. This means that the thread type will be output correctly in the error - message. (Bernhard Amann) + message. (Johanna Amann) 2.0-719 | 2012-07-02 14:49:03 -0700 @@ -5195,7 +5250,7 @@ 2.0-622 | 2012-06-15 15:38:43 -0700 - * Input framework updates. (Bernhard Amann) + * Input framework updates. (Johanna Amann) - Disable streaming reads from executed commands. This lead to hanging Bros because pclose apparently can wait for eternity if @@ -5274,7 +5329,7 @@ * A new input framework enables scripts to read in external data dynamically on the fly as Bro is processing network traffic. - (Bernhard Amann) + (Johanna Amann) Currently, the framework supports reading ASCII input that's structured similar as Bro's log files as well as raw blobs of @@ -5441,7 +5496,7 @@ 2.0-315 | 2012-05-03 11:44:17 -0700 * Add two more TLS extension values that we see in live traffic. - (Bernhard Amann) + (Johanna Amann) * Fixed IPv6 link local unicast CIDR and added IPv6 loopback to private address space. (Seth Hall) @@ -5829,7 +5884,7 @@ 2.0-41 | 2012-02-03 04:10:53 -0500 - * Updates to the Software framework to simplify the API. (Bernhard + * Updates to the Software framework to simplify the API. (Johanna Amann) 2.0-40 | 2012-02-03 01:55:27 -0800 @@ -5972,7 +6027,7 @@ 2.0-beta-152 | 2012-01-03 14:51:34 -0800 - * Notices now record the transport-layer protocol. (Bernhard Amann) + * Notices now record the transport-layer protocol. (Johanna Amann) 2.0-beta-150 | 2012-01-03 14:42:45 -0800 @@ -5999,7 +6054,7 @@ assignments. Addresses #722. (Jon Siwek) * Make log headers include the type of data stored inside a set or - vector ("vector[string]"). (Bernhard Amann) + vector ("vector[string]"). (Johanna Amann) 2.0-beta-126 | 2011-12-18 15:18:05 -0800 @@ -6136,11 +6191,11 @@ * Fix order of include directories. (Jon Siwek) * Catch if logged vectors do not contain only atomic types. - (Bernhard Amann) + (Johanna Amann) 2.0-beta-47 | 2011-11-16 08:24:33 -0800 - * Catch if logged sets do not contain only atomic types. (Bernhard + * Catch if logged sets do not contain only atomic types. (Johanna Amann) * Promote libz and libmagic to required dependencies. (Jon Siwek) diff --git a/CMakeLists.txt b/CMakeLists.txt index b96923aa56..374af64a18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ endif () include_directories(BEFORE ${PCAP_INCLUDE_DIR} - ${OpenSSL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} ${BIND_INCLUDE_DIR} ${BinPAC_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} @@ -141,7 +141,7 @@ endif () set(brodeps ${BinPAC_LIBRARY} ${PCAP_LIBRARY} - ${OpenSSL_LIBRARIES} + ${OPENSSL_LIBRARIES} ${BIND_LIBRARY} ${ZLIB_LIBRARY} ${JEMALLOC_LIBRARIES} diff --git a/NEWS b/NEWS index e8c0268644..86c3b1891a 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ New Dependencies New Functionality ----------------- +- Bro now includes the NetControl framework. The framework allows for easy + interaction of Bro with hard- and software switches, firewalls, etc. + - Bro now supports the Radiotap header for 802.11 frames. - Bro now tracks VLAN IDs. To record them inside the connection log, @@ -37,12 +40,37 @@ New Functionality argument that will be used for decoding errors into weird.log (instead of reporter.log). +- Two new built-in functions for handling set[subnet] and table[subnet]: + + - check_subnet(subnet, table) checks if a specific subnet is a member + of a set/table. This is different from the "in" operator, which always + performs a longest prefix match. + + - matching_subnets(subnet, table) returns all subnets of the set or table + that contain the given subnet. + + - filter_subnet_table(subnet, table) works like check_subnet, but returns + a table containing all matching entries. + +- Several built-in functions for handling IP addresses and subnets were added: + + - is_v4_subnet(subnet) checks whether a subnet specification is IPv4. + + - is_v6_subnet(subnet) checks whether a subnet specification is IPv6. + + - addr_to_subnet(addr) converts an IP address to a /32 subnet. + + - subnet_to_addr(subnet) returns the IP address part of a subnet. + + - subnet_width(subnet) returns the width of a subnet. + - The IRC analyzer now recognizes StartTLS sessions and enable the SSL analyzer for them. - New Bro plugins in aux/plugins: - af_packet: Native AF_PACKET support. + - kafka : Log writer interfacing to Kafka. - myricom: Native Myricom SNF v3 support. - pf_ring: Native PF_RING support. - redis: An experimental log writer for Redis. @@ -51,6 +79,9 @@ New Functionality Changed Functionality --------------------- +- ``SSH::skip_processing_after_detection`` was removed. The functionality was + replaced by ``SSH::disable_analyzer_after_detection``. + - Some script-level identifier have changed their names: snaplen -> Pcap::snaplen diff --git a/VERSION b/VERSION index 3ba21a7f12..032d05a7ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4-284 +2.4-422 diff --git a/aux/binpac b/aux/binpac index 1a6ec48bf5..424d40c1e8 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 1a6ec48bf57027f1449a8a6a7a19a19db4a12517 +Subproject commit 424d40c1e8d5888311b50c0e5a9dfc9c5f818b66 diff --git a/aux/bro-aux b/aux/bro-aux index 99ef7a101a..105dfe4ad6 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 99ef7a101a06b89a5ae880e7a1493b8b56f8240e +Subproject commit 105dfe4ad6c4ae4563b21cb0466ee350f0af0d43 diff --git a/aux/broccoli b/aux/broccoli index 31d62cc657..6ded82da49 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 31d62cc6570d38ce570422c99d04ef86fa825c04 +Subproject commit 6ded82da498d805def6aa129cd7691d3b7287c37 diff --git a/aux/broctl b/aux/broctl index 5f29450196..583f3a3ff1 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 5f29450196bb6238012d81c72cd0fc324ca9a7c5 +Subproject commit 583f3a3ff1847cf96a87f865d5cf0f36fae9dd67 diff --git a/aux/broker b/aux/broker index 3db1884fbb..6684ab5109 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 3db1884fbb5f0e1f2b669d8d3f549583e3b3cea4 +Subproject commit 6684ab5109f526fb535013760f17a4c8dff093ae diff --git a/aux/btest b/aux/btest index 83465a00c1..4bea8fa948 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 83465a00c14771dff8349a11f9481a937ed3cd8c +Subproject commit 4bea8fa948be2bc86ff92399137131bc1c029b08 diff --git a/aux/plugins b/aux/plugins index d251af520c..ab61be0c4f 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit d251af520ccdede694d7b3b7bcbc47df1080508c +Subproject commit ab61be0c4f128c976f72dfa5a09a87cd842f387a diff --git a/cmake b/cmake index 3fcb71abc1..537e45afe1 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 3fcb71abc1697c23d16b987340e957639275ec21 +Subproject commit 537e45afe1006a10f73847fab5f13d28ce43fc4d diff --git a/configure b/configure index f94085f9d3..8859a6fa9b 100755 --- a/configure +++ b/configure @@ -226,7 +226,7 @@ while [ $# -ne 0 ]; do append_cache_entry DISABLE_RUBY_BINDINGS BOOL false ;; --with-openssl=*) - append_cache_entry OpenSSL_ROOT_DIR PATH $optarg + append_cache_entry OPENSSL_ROOT_DIR PATH $optarg ;; --with-bind=*) append_cache_entry BIND_ROOT_DIR PATH $optarg @@ -276,8 +276,12 @@ while [ $# -ne 0 ]; do --with-swig=*) append_cache_entry SWIG_EXECUTABLE PATH $optarg ;; + --with-caf=*) + append_cache_entry CAF_ROOT_DIR PATH $optarg + ;; --with-libcaf=*) - append_cache_entry LIBCAF_ROOT_DIR PATH $optarg + echo "warning: --with-libcaf deprecated, use --with-caf instead" + append_cache_entry CAF_ROOT_DIR PATH $optarg ;; --with-rocksdb=*) append_cache_entry ROCKSDB_ROOT_DIR PATH $optarg diff --git a/doc/install/install.rst b/doc/install/install.rst index a9f1c85bdd..60c7cf27d1 100644 --- a/doc/install/install.rst +++ b/doc/install/install.rst @@ -75,6 +75,21 @@ To install the required dependencies, you can use: Note that in older versions of FreeBSD, you might have to use the "pkg_add -r" command instead of "pkg install". + For older versions of FreeBSD (especially FreeBSD 9.x), the system compiler + is not new enough to compile Bro. For these systems, you will have to install + a newer compiler using pkg; the ``clang34`` package should work. + + You will also have to define several environment variables on these older + systems to use the new compiler and headers similar to this before calling + configure: + + .. console:: + + export CC=clang34 + export CXX=clang++34 + export CXXFLAGS="-stdlib=libc++ -I${LOCALBASE}/include/c++/v1 -L${LOCALBASE}/lib" + export LDFLAGS="-pthread" + * Mac OS X: Compiling source code on Macs requires first installing Xcode_ (in older diff --git a/scripts/base/frameworks/netcontrol/__load__.bro b/scripts/base/frameworks/netcontrol/__load__.bro new file mode 100644 index 0000000000..a8e391f7c8 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/__load__.bro @@ -0,0 +1,15 @@ +@load ./types +@load ./main +@load ./plugins +@load ./drop +@load ./shunt +@load ./catch-and-release + +# The cluster framework must be loaded first. +@load base/frameworks/cluster + +@if ( Cluster::is_enabled() ) +@load ./cluster +@else +@load ./non-cluster +@endif diff --git a/scripts/base/frameworks/netcontrol/catch-and-release.bro b/scripts/base/frameworks/netcontrol/catch-and-release.bro new file mode 100644 index 0000000000..a95954ac07 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -0,0 +1,104 @@ +##! Implementation of catch-and-release functionality for NetControl. + +module NetControl; + +@load ./main +@load ./drop + +export { + ## Stops all packets involving an IP address from being forwarded. This function + ## uses catch-and-release functionality, where the IP address is only dropped for + ## a short amount of time that is incremented steadily when the IP is encountered + ## again. + ## + ## a: The address to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_address_catch_release: function(a: addr, location: string &default="") : string; + + ## Time intervals for which a subsequent drops of the same IP take + ## effect. + const catch_release_intervals: vector of interval = vector(10min, 1hr, 24hrs, 7days) &redef; +} + +function per_block_interval(t: table[addr] of count, idx: addr): interval + { + local ct = t[idx]; + + # watch for the time of the next block... + local blocktime = catch_release_intervals[ct]; + if ( (ct+1) in catch_release_intervals ) + blocktime = catch_release_intervals[ct+1]; + + return blocktime; + } + +# This is the internally maintained table containing all the currently going on catch-and-release +# blocks. +global blocks: table[addr] of count = {} + &create_expire=0secs + &expire_func=per_block_interval; + +function current_block_interval(s: set[addr], idx: addr): interval + { + if ( idx !in blocks ) + { + Reporter::error(fmt("Address %s not in blocks while inserting into current_blocks!", idx)); + return 0sec; + } + + return catch_release_intervals[blocks[idx]]; + } + +global current_blocks: set[addr] = set() + &create_expire=0secs + &expire_func=current_block_interval; + +function drop_address_catch_release(a: addr, location: string &default=""): string + { + if ( a in blocks ) + { + Reporter::warning(fmt("Address %s already blocked using catch-and-release - ignoring duplicate", a)); + return ""; + } + + local block_interval = catch_release_intervals[0]; + local ret = drop_address(a, block_interval, location); + if ( ret != "" ) + { + blocks[a] = 0; + add current_blocks[a]; + } + + return ret; + } + +function check_conn(a: addr) + { + if ( a in blocks ) + { + if ( a in current_blocks ) + # block has not been applied yet? + return; + + # ok, this one returned again while still in the backoff period. + local try = blocks[a]; + if ( (try+1) in catch_release_intervals ) + ++try; + + blocks[a] = try; + add current_blocks[a]; + local block_interval = catch_release_intervals[try]; + drop_address(a, block_interval, "Re-drop by catch-and-release"); + } + } + +event new_connection(c: connection) + { + # let's only check originating connections... + check_conn(c$id$orig_h); + } diff --git a/scripts/base/frameworks/netcontrol/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro new file mode 100644 index 0000000000..7f635b4375 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -0,0 +1,99 @@ +##! Cluster support for the NetControl framework. + +@load ./main +@load base/frameworks/cluster + +module NetControl; + +export { + ## This is the event used to transport add_rule calls to the manager. + global cluster_netcontrol_add_rule: event(r: Rule); + + ## This is the event used to transport remove_rule calls to the manager. + global cluster_netcontrol_remove_rule: event(id: string); +} + +## Workers need ability to forward commands to manager. +redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove)_rule/; +## Workers need to see the result events from the manager. +redef Cluster::manager2worker_events += /NetControl::rule_(added|removed|timeout|error)/; + + +function activate(p: PluginState, priority: int) + { + # we only run the activate function on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + activate_impl(p, priority); + } + +global local_rule_count: count = 1; + +function add_rule(r: Rule) : string + { + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return add_rule_impl(r); + else + { + if ( r$id == "" ) + r$id = cat(Cluster::node, ":", ++local_rule_count); + + event NetControl::cluster_netcontrol_add_rule(r); + return r$id; + } + } + +function remove_rule(id: string) : bool + { + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return remove_rule_impl(id); + else + { + event NetControl::cluster_netcontrol_remove_rule(id); + return T; # well, we can't know here. So - just hope... + } + } + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event NetControl::cluster_netcontrol_add_rule(r: Rule) + { + add_rule_impl(r); + } + +event NetControl::cluster_netcontrol_remove_rule(id: string) + { + remove_rule_impl(id); + } +@endif + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event rule_expire(r: Rule, p: PluginState) &priority=-5 + { + rule_expire_impl(r, p); + } + +event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 + { + rule_added_impl(r, p, msg); + + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) + schedule r$expire { rule_expire(r, p) }; + } + +event rule_removed(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_removed_impl(r, p, msg); + } + +event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) &priority=-5 + { + rule_timeout_impl(r, i, p); + } + +event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_error_impl(r, p, msg); + } +@endif + diff --git a/scripts/base/frameworks/netcontrol/drop.bro b/scripts/base/frameworks/netcontrol/drop.bro new file mode 100644 index 0000000000..63c70f0e88 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/drop.bro @@ -0,0 +1,98 @@ +##! Implementation of the drop functionality for NetControl. + +module NetControl; + +@load ./main + +export { + redef enum Log::ID += { DROP }; + + ## Stops all packets involving an IP address from being forwarded. + ## + ## a: The address to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_address: function(a: addr, t: interval, location: string &default="") : string; + + ## Stops all packets involving an connection address from being forwarded. + ## + ## c: The connection to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_connection: function(c: conn_id, t: interval, location: string &default="") : string; + + type DropInfo: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log; + orig_h: addr &log; ##< The originator's IP address. + orig_p: port &log &optional; ##< The originator's port number. + resp_h: addr &log &optional; ##< The responder's IP address. + resp_p: port &log &optional; ##< The responder's port number. + ## Expiry time of the shunt + expire: interval &log; + ## Location where the underlying action was triggered. + location: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::ShuntInfo` + ## record as it is sent on to the logging framework. + global log_netcontrol_drop: event(rec: DropInfo); +} + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::DROP, [$columns=DropInfo, $ev=log_netcontrol_drop, $path="netcontrol_drop"]); + } + +function drop_connection(c: conn_id, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=CONNECTION, $conn=c]; + local r: Rule = [$ty=DROP, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = DropInfo($ts=network_time(), $rule_id=id, $orig_h=c$orig_h, $orig_p=c$orig_p, $resp_h=c$resp_h, $resp_p=c$resp_p, $expire=t); + + if ( location != "" ) + log$location=location; + + Log::write(DROP, log); + + return id; + } + +function drop_address(a: addr, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; + local r: Rule = [$ty=DROP, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = DropInfo($ts=network_time(), $rule_id=id, $orig_h=a, $expire=t); + + if ( location != "" ) + log$location=location; + + Log::write(DROP, log); + + return id; + } + diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro new file mode 100644 index 0000000000..563188921d --- /dev/null +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -0,0 +1,935 @@ +##! Bro's packet aquisition and control framework. +##! +##! This plugin-based framework allows to control the traffic that Bro monitors +##! as well as, if having access to the forwarding path, the traffic the network +##! forwards. By default, the framework lets everything through, to both Bro +##! itself as well as on the network. Scripts can then add rules to impose +##! restrictions on entities, such as specific connections or IP addresses. +##! +##! This framework has two APIs: a high-level and low-level. The high-level API +##! provides convinience functions for a set of common operations. The +##! low-level API provides full flexibility. + +module NetControl; + +@load ./plugin +@load ./types + +export { + ## The framework's logging stream identifier. + redef enum Log::ID += { LOG }; + + # ### + # ### Generic functions and events. + # ### + + # Activates a plugin. + # + # p: The plugin to acticate. + # + # priority: The higher the priority, the earlier this plugin will be checked + # whether it supports an operation, relative to other plugins. + global activate: function(p: PluginState, priority: int); + + # Event that is used to initialize plugins. Place all plugin initialization + # related functionality in this event. + global NetControl::init: event(); + + # Event that is raised once all plugins activated in ``NetControl::init`` have finished + # their initialization. + global NetControl::init_done: event(); + + # ### + # ### High-level API. + # ### + + # ### Note - other high level primitives are in catch-and-release.bro, shunt.bro and + # ### drop.bro + + ## Allows all traffic involving a specific IP address to be forwarded. + ## + ## a: The address to be whitelistet. + ## + ## t: How long to whitelist it, with 0 being indefinitly. + ## + ## location: An optional string describing whitelist was triddered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global whitelist_address: function(a: addr, t: interval, location: string &default="") : string; + + ## Allows all traffic involving a specific IP subnet to be forwarded. + ## + ## s: The subnet to be whitelistet. + ## + ## t: How long to whitelist it, with 0 being indefinitly. + ## + ## location: An optional string describing whitelist was triddered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global whitelist_subnet: function(s: subnet, t: interval, location: string &default="") : string; + + ## Redirects an uni-directional flow to another port. + ## + ## f: The flow to redirect. + ## + ## out_port: Port to redirect the flow to + ## + ## t: How long to leave the redirect in place, with 0 being indefinitly. + ## + ## location: An optional string describing where the redirect was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global redirect_flow: function(f: flow_id, out_port: count, t: interval, location: string &default="") : string; + + ## Quarantines a host by redirecting rewriting DNS queries to the network dns server dns + ## to the host. Host has to answer to all queries with its own address. Only http communication + ## from infected to quarantinehost is allowed. + ## + ## infected: the host to quarantine + ## + ## dns: the network dns server + ## + ## quarantine: the quarantine server running a dns and a web server + ## + ## t: how long to leave the quarantine in place + ## + ## Returns: Vector of inserted rules on success, empty list on failure. + global quarantine_host: function(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string; + + ## Flushes all state. + global clear: function(); + + # ### + # ### Low-level API. + # ### + + ###### Manipulation of rules. + + ## Installs a rule. + ## + ## r: The rule to install. + ## + ## Returns: If succesful, returns an ID string unique to the rule that can later + ## be used to refer to it. If unsuccessful, returns an empty string. The ID is also + ## assigned to ``r$id``. Note that "successful" means "a plugin knew how to handle + ## the rule", it doesn't necessarily mean that it was indeed successfully put in + ## place, because that might happen asynchronously and thus fail only later. + global add_rule: function(r: Rule) : string; + + ## Removes a rule. + ## + ## id: The rule to remove, specified as the ID returned by :bro:id:`add_rule` . + ## + ## Returns: True if succesful, the relevant plugin indicated that it knew how + ## to handle the removal. Note that again "success" means the plugin accepted the + ## removal. They might still fail to put it into effect, as that might happen + ## asynchronously and thus go wrong at that point. + global remove_rule: function(id: string) : bool; + + ## Searches all rules affecting a certain IP address. + ## + ## ip: The ip address to search for + ## + ## Returns: vector of all rules affecting the IP address + global find_rules_addr: function(ip: addr) : vector of Rule; + + ## Searches all rules affecting a certain subnet. + ## + ## sn: The subnet to search for + ## + ## Returns: vector of all rules affecting the subnet + global find_rules_subnet: function(sn: subnet) : vector of Rule; + + ###### Asynchronous feedback on rules. + + ## Confirms that a rule was put in place. + ## + ## r: The rule now in place. + ## + ## p: The state for the plugin that put it into place. + ## + ## msg: An optional informational message by the plugin. + global rule_added: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Reports that a rule was removed due to a remove: function() call. + ## + ## r: The rule now removed. + ## + ## p: The state for the plugin that had the rule in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global rule_removed: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Reports that a rule was removed internally due to a timeout. + ## + ## r: The rule now removed. + ## + ## i: Additional flow information, if supported by the protocol. + ## + ## p: The state for the plugin that had the rule in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global rule_timeout: event(r: Rule, i: FlowInfo, p: PluginState); + + ## Reports an error when operating on a rule. + ## + ## r: The rule that encountered an error. + ## + ## p: The state for the plugin that reported the error. + ## + ## msg: An optional informational message by the plugin. + global rule_error: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Hook that allows the modification of rules passed to add_rule before they + ## are passed on to the plugins. If one of the hooks uses break, the rule is + ## ignored and not passed on to any plugin. + ## + ## r: The rule to be added + global NetControl::rule_policy: hook(r: Rule); + + ##### Plugin functions + + ## Function called by plugins once they finished their activation. After all + ## plugins defined in bro_init finished to activate, rules will start to be sent + ## to the plugins. Rules that scripts try to set before the backends are ready + ## will be discarded. + global plugin_activated: function(p: PluginState); + + ## Type of an entry in the NetControl log. + type InfoCategory: enum { + ## A log entry reflecting a framework message. + MESSAGE, + ## A log entry reflecting a framework message. + ERROR, + ## A log entry about about a rule. + RULE + }; + + ## State of an entry in the NetControl log. + type InfoState: enum { + REQUESTED, + SUCCEEDED, + FAILED, + REMOVED, + TIMEOUT, + }; + + ## The record type defining the column fields of the NetControl log. + type Info: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log &optional; + ## Type of the log entry. + category: InfoCategory &log &optional; + ## The command the log entry is about. + cmd: string &log &optional; + ## State the log entry reflects. + state: InfoState &log &optional; + ## String describing an action the entry is about. + action: string &log &optional; + ## The target type of the action. + target: TargetType &log &optional; + ## Type of the entity the log entry is about. + entity_type: string &log &optional; + ## String describing the entity the log entry is about. + entity: string &log &optional; + ## String describing the optional modification of the entry (e.h. redirect) + mod: string &log &optional; + ## String with an additional message. + msg: string &log &optional; + ## Number describing the priority of the log entry + priority: int &log &optional; + ## Expiry time of the log entry + expire: interval &log &optional; + ## Location where the underlying action was triggered. + location: string &log &optional; + ## Plugin triggering the log entry. + plugin: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::Info` + ## record as it is sent on to the logging framework. + global log_netcontrol: event(rec: Info); +} + +redef record Rule += { + ##< Internally set to the plugins handling the rule. + _plugin_ids: set[count] &default=count_set(); + ##< Internally set to the plugins on which the rule is currently active. + _active_plugin_ids: set[count] &default=count_set(); + ##< Track if the rule was added succesfully by all responsible plugins. + _added: bool &default=F; +}; + +# Variable tracking the state of plugin activation. Once all plugins that +# have been added in bro_init are activated, this will switch to T and +# the event NetControl::init_done will be raised. +global plugins_active: bool = F; + +# Set to true at the end of bro_init (with very low priority). +# Used to track when plugin activation could potentially be finished +global bro_init_done: bool = F; + +# The counters that are used to generate the rule and plugin IDs +global rule_counter: count = 1; +global plugin_counter: count = 1; + +# List of the currently active plugins +global plugins: vector of PluginState; +global plugin_ids: table[count] of PluginState; + +# These tables hold information about rules. +global rules: table[string] of Rule; # Rules indexed by id and cid + +# All rules that apply to a certain subnet/IP address. +global rules_by_subnets: table[subnet] of set[string]; + +# Rules pertaining to a specific entity. +# There always only can be one rule of each type for one entity. +global rule_entities: table[Entity, RuleType] of Rule; + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::LOG, [$columns=Info, $ev=log_netcontrol, $path="netcontrol"]); + } + +function entity_to_info(info: Info, e: Entity) + { + info$entity_type = fmt("%s", e$ty); + + switch ( e$ty ) { + case ADDRESS: + info$entity = fmt("%s", e$ip); + break; + + case CONNECTION: + info$entity = fmt("%s/%d<->%s/%d", + e$conn$orig_h, e$conn$orig_p, + e$conn$resp_h, e$conn$resp_p); + break; + + case FLOW: + local ffrom_ip = "*"; + local ffrom_port = "*"; + local fto_ip = "*"; + local fto_port = "*"; + local ffrom_mac = "*"; + local fto_mac = "*"; + if ( e$flow?$src_h ) + ffrom_ip = cat(e$flow$src_h); + if ( e$flow?$src_p ) + ffrom_port = fmt("%d", e$flow$src_p); + if ( e$flow?$dst_h ) + fto_ip = cat(e$flow$dst_h); + if ( e$flow?$dst_p ) + fto_port = fmt("%d", e$flow$dst_p); + info$entity = fmt("%s/%s->%s/%s", + ffrom_ip, ffrom_port, + fto_ip, fto_port); + if ( e$flow?$src_m || e$flow?$dst_m ) + { + if ( e$flow?$src_m ) + ffrom_mac = e$flow$src_m; + if ( e$flow?$dst_m ) + fto_mac = e$flow$dst_m; + + info$entity = fmt("%s (%s->%s)", info$entity, ffrom_mac, fto_mac); + } + break; + + case MAC: + info$entity = e$mac; + break; + + default: + info$entity = ""; + break; + } + } + +function rule_to_info(info: Info, r: Rule) + { + info$action = fmt("%s", r$ty); + info$target = r$target; + info$rule_id = r$id; + info$expire = r$expire; + info$priority = r$priority; + + if ( r?$location && r$location != "" ) + info$location = r$location; + + if ( r$ty == REDIRECT ) + info$mod = fmt("-> %d", r$out_port); + + if ( r$ty == MODIFY ) + { + local mfrom_ip = "_"; + local mfrom_port = "_"; + local mto_ip = "_"; + local mto_port = "_"; + local mfrom_mac = "_"; + local mto_mac = "_"; + if ( r$mod?$src_h ) + mfrom_ip = cat(r$mod$src_h); + if ( r$mod?$src_p ) + mfrom_port = fmt("%d", r$mod$src_p); + if ( r$mod?$dst_h ) + mto_ip = cat(r$mod$dst_h); + if ( r$mod?$dst_p ) + mto_port = fmt("%d", r$mod$dst_p); + + if ( r$mod?$src_m ) + mfrom_mac = r$mod$src_m; + if ( r$mod?$dst_m ) + mto_mac = r$mod$dst_m; + + info$mod = fmt("Src: %s/%s (%s) Dst: %s/%s (%s)", + mfrom_ip, mfrom_port, mfrom_mac, mto_ip, mto_port, mto_mac); + + if ( r$mod?$redirect_port ) + info$mod = fmt("%s -> %d", info$mod, r$mod$redirect_port); + + } + + entity_to_info(info, r$entity); + } + +function log_msg(msg: string, p: PluginState) + { + Log::write(LOG, [$ts=network_time(), $category=MESSAGE, $msg=msg, $plugin=p$plugin$name(p)]); + } + +function log_error(msg: string, p: PluginState) + { + Log::write(LOG, [$ts=network_time(), $category=ERROR, $msg=msg, $plugin=p$plugin$name(p)]); + } + +function log_msg_no_plugin(msg: string) + { + Log::write(LOG, [$ts=network_time(), $category=MESSAGE, $msg=msg]); + } + +function log_rule(r: Rule, cmd: string, state: InfoState, p: PluginState, msg: string &default="") + { + local info: Info = [$ts=network_time()]; + info$category = RULE; + info$cmd = cmd; + info$state = state; + info$plugin = p$plugin$name(p); + if ( msg != "" ) + info$msg = msg; + + rule_to_info(info, r); + + Log::write(LOG, info); + } + +function log_rule_error(r: Rule, msg: string, p: PluginState) + { + local info: Info = [$ts=network_time(), $category=ERROR, $msg=msg, $plugin=p$plugin$name(p)]; + rule_to_info(info, r); + Log::write(LOG, info); + } + +function log_rule_no_plugin(r: Rule, state: InfoState, msg: string) + { + local info: Info = [$ts=network_time()]; + info$category = RULE; + info$state = state; + info$msg = msg; + + rule_to_info(info, r); + + Log::write(LOG, info); + } + +function whitelist_address(a: addr, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; + local r: Rule = [$ty=WHITELIST, $priority=whitelist_priority, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + return add_rule(r); + } + +function whitelist_subnet(s: subnet, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=s]; + local r: Rule = [$ty=WHITELIST, $priority=whitelist_priority, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + return add_rule(r); + } + + +function redirect_flow(f: flow_id, out_port: count, t: interval, location: string &default="") : string + { + local flow = NetControl::Flow( + $src_h=addr_to_subnet(f$src_h), + $src_p=f$src_p, + $dst_h=addr_to_subnet(f$dst_h), + $dst_p=f$dst_p + ); + local e: Entity = [$ty=FLOW, $flow=flow]; + local r: Rule = [$ty=REDIRECT, $target=FORWARD, $entity=e, $expire=t, $location=location, $out_port=out_port]; + + return add_rule(r); + } + +function quarantine_host(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string + { + local orules: vector of string = vector(); + local edrop: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected))]; + local rdrop: Rule = [$ty=DROP, $target=FORWARD, $entity=edrop, $expire=t, $location=location]; + orules[|orules|] = add_rule(rdrop); + + local todnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(dns), $dst_p=53/udp)]; + local todnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=todnse, $expire=t, $location=location, $mod=FlowMod($dst_h=quarantine), $priority=+5); + orules[|orules|] = add_rule(todnsr); + + local fromdnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(dns), $src_p=53/udp, $dst_h=addr_to_subnet(infected))]; + local fromdnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=fromdnse, $expire=t, $location=location, $mod=FlowMod($src_h=dns), $priority=+5); + orules[|orules|] = add_rule(fromdnsr); + + local wle: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(quarantine), $dst_p=80/tcp)]; + local wlr = Rule($ty=WHITELIST, $target=FORWARD, $entity=wle, $expire=t, $location=location, $priority=+5); + orules[|orules|] = add_rule(wlr); + + return orules; + } + +function check_plugins() + { + if ( plugins_active ) + return; + + local all_active = T; + for ( i in plugins ) + { + local p = plugins[i]; + if ( p$_activated == F ) + all_active = F; + } + + if ( all_active ) + { + plugins_active = T; + + # Skip log message if there are no plugins + if ( |plugins| > 0 ) + log_msg_no_plugin("plugin initialization done"); + + event NetControl::init_done(); + } + } + +function plugin_activated(p: PluginState) + { + local id = p$_id; + if ( id !in plugin_ids ) + { + log_error("unknown plugin activated", p); + return; + } + plugin_ids[id]$_activated = T; + log_msg("activation finished", p); + + if ( bro_init_done ) + check_plugins(); + } + +event bro_init() &priority=-5 + { + event NetControl::init(); + } + +event NetControl::init() &priority=-20 + { + bro_init_done = T; + + check_plugins(); + + if ( plugins_active == F ) + log_msg_no_plugin("waiting for plugins to initialize"); + } + +# Low-level functions that only runs on the manager (or standalone) Bro node. + +function activate_impl(p: PluginState, priority: int) + { + p$_priority = priority; + plugins[|plugins|] = p; + sort(plugins, function(p1: PluginState, p2: PluginState) : int { return p2$_priority - p1$_priority; }); + + plugin_ids[plugin_counter] = p; + p$_id = plugin_counter; + ++plugin_counter; + + # perform one-time initialization + if ( p$plugin?$init ) + { + log_msg(fmt("activating plugin with priority %d", priority), p); + p$plugin$init(p); + } + else + { + # no initialization necessary, mark plugin as active right away + plugin_activated(p); + } + + } + +function add_one_subnet_entry(s: subnet, r: Rule) + { + if ( ! check_subnet(s, rules_by_subnets) ) + rules_by_subnets[s] = set(r$id); + else + add rules_by_subnets[s][r$id]; + } + +function add_subnet_entry(rule: Rule) + { + local e = rule$entity; + if ( e$ty == ADDRESS ) + { + add_one_subnet_entry(e$ip, rule); + } + else if ( e$ty == CONNECTION ) + { + add_one_subnet_entry(addr_to_subnet(e$conn$orig_h), rule); + add_one_subnet_entry(addr_to_subnet(e$conn$resp_h), rule); + } + else if ( e$ty == FLOW ) + { + if ( e$flow?$src_h ) + add_one_subnet_entry(e$flow$src_h, rule); + if ( e$flow?$dst_h ) + add_one_subnet_entry(e$flow$dst_h, rule); + } + } + +function remove_one_subnet_entry(s: subnet, r: Rule) + { + if ( ! check_subnet(s, rules_by_subnets) ) + return; + + if ( r$id !in rules_by_subnets[s] ) + return; + + delete rules_by_subnets[s][r$id]; + if ( |rules_by_subnets[s]| == 0 ) + delete rules_by_subnets[s]; + } + +function remove_subnet_entry(rule: Rule) + { + local e = rule$entity; + if ( e$ty == ADDRESS ) + { + remove_one_subnet_entry(e$ip, rule); + } + else if ( e$ty == CONNECTION ) + { + remove_one_subnet_entry(addr_to_subnet(e$conn$orig_h), rule); + remove_one_subnet_entry(addr_to_subnet(e$conn$resp_h), rule); + } + else if ( e$ty == FLOW ) + { + if ( e$flow?$src_h ) + remove_one_subnet_entry(e$flow$src_h, rule); + if ( e$flow?$dst_h ) + remove_one_subnet_entry(e$flow$dst_h, rule); + } + } + +function find_rules_subnet(sn: subnet) : vector of Rule + { + local ret: vector of Rule = vector(); + + local matches = matching_subnets(sn, rules_by_subnets); + + for ( m in matches ) + { + local sn_entry = matches[m]; + local rule_ids = rules_by_subnets[sn_entry]; + for ( rule_id in rules_by_subnets[sn_entry] ) + { + if ( rule_id in rules ) + ret[|ret|] = rules[rule_id]; + else + Reporter::error("find_rules_subnet - internal data structure error, missing rule"); + } + } + + return ret; + } + +function find_rules_addr(ip: addr) : vector of Rule + { + return find_rules_subnet(addr_to_subnet(ip)); + } + +function add_rule_impl(rule: Rule) : string + { + if ( ! plugins_active ) + { + log_rule_no_plugin(rule, FAILED, "plugins not initialized yet"); + return ""; + } + + rule$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. + + if ( ! rule?$id || rule$id == "" ) + rule$id = cat(rule$cid); + + if ( ! hook NetControl::rule_policy(rule) ) + return ""; + + if ( [rule$entity, rule$ty] in rule_entities ) + { + log_rule_no_plugin(rule, FAILED, "discarded duplicate insertion"); + return ""; + } + + local accepted = F; + local priority: int = +0; + + for ( i in plugins ) + { + local p = plugins[i]; + + if ( p$_activated == F ) + next; + + # in this case, rule was accepted by earlier plugin and this plugin has a lower + # priority. Abort and do not send there... + if ( accepted == T && p$_priority != priority ) + break; + + if ( p$plugin$add_rule(p, rule) ) + { + accepted = T; + priority = p$_priority; + log_rule(rule, "ADD", REQUESTED, p); + + add rule$_plugin_ids[p$_id]; + } + } + + if ( accepted ) + { + rules[rule$id] = rule; + rule_entities[rule$entity, rule$ty] = rule; + + add_subnet_entry(rule); + + return rule$id; + } + + log_rule_no_plugin(rule, FAILED, "not supported"); + return ""; + } + +function remove_rule_plugin(r: Rule, p: PluginState): bool + { + local success = T; + + if ( ! p$plugin$remove_rule(p, r) ) + { + # still continue and send to other plugins + log_rule_error(r, "remove failed", p); + success = F; + } + else + { + log_rule(r, "REMOVE", REQUESTED, p); + } + + return success; + } + +function remove_rule_impl(id: string) : bool + { + if ( id !in rules ) + { + Reporter::error(fmt("Rule %s does not exist in NetControl::remove_rule", id)); + return F; + } + + local r = rules[id]; + + local success = T; + for ( plugin_id in r$_active_plugin_ids ) + { + local p = plugin_ids[plugin_id]; + success = remove_rule_plugin(r, p); + } + + return success; + } + +function rule_expire_impl(r: Rule, p: PluginState) &priority=-5 + { + # do not emit timeout events on shutdown + if ( bro_is_terminating() ) + return; + + if ( r$id !in rules ) + # Removed already. + return; + + event NetControl::rule_timeout(r, FlowInfo(), p); # timeout implementation will handle the removal + } + +function rule_added_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Addition of unknown rule", p); + return; + } + + # use our version to prevent operating on copies. + local rule = rules[r$id]; + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(rule, "Rule added to non-responsible plugin", p); + return; + } + + log_rule(r, "ADD", SUCCEEDED, p, msg); + + add rule$_active_plugin_ids[p$_id]; + if ( |rule$_plugin_ids| == |rule$_active_plugin_ids| ) + { + # rule was completely added. + rule$_added = T; + } + } + +function rule_cleanup(r: Rule) + { + if ( |r$_active_plugin_ids| > 0 ) + return; + + remove_subnet_entry(r); + + delete rule_entities[r$entity, r$ty]; + delete rules[r$id]; + } + +function rule_removed_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Removal of non-existing rule", p); + return; + } + + # use our version to prevent operating on copies. + local rule = rules[r$id]; + + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Removed from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + delete rule$_active_plugin_ids[p$_id]; + } + + log_rule(rule, "REMOVE", SUCCEEDED, p, msg); + rule_cleanup(rule); + } + +function rule_timeout_impl(r: Rule, i: FlowInfo, p: PluginState) + { + if ( r$id !in rules ) + { + log_rule_error(r, "Timeout of non-existing rule", p); + return; + } + + local rule = rules[r$id]; + + local msg = ""; + if ( i?$packet_count ) + msg = fmt("Packets: %d", i$packet_count); + if ( i?$byte_count ) + { + if ( msg != "" ) + msg = msg + " "; + msg = fmt("%sBytes: %s", msg, i$byte_count); + } + + log_rule(rule, "EXPIRE", TIMEOUT, p, msg); + + if ( ! p$plugin$can_expire ) + { + # in this case, we actually have to delete the rule and the timeout + # call just originated locally + remove_rule_plugin(rule, p); + return; + } + + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Timeout from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + delete rule$_active_plugin_ids[p$_id]; + } + + rule_cleanup(rule); + } + +function rule_error_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Error of non-existing rule", p); + return; + } + + local rule = rules[r$id]; + + log_rule_error(rule, msg, p); + + # Remove the plugin both from active and all plugins of the rule. If there + # are no plugins left afterwards - delete it + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Error from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + # error during removal. Let's pretend it worked. + delete rule$_plugin_ids[p$_id]; + delete rule$_active_plugin_ids[p$_id]; + rule_cleanup(rule); + } + else + { + # error during insertion. Meh. If we are the only plugin, remove the rule again. + # Otherwhise - keep it, minus us. + delete rule$_plugin_ids[p$_id]; + if ( |rule$_plugin_ids| == 0 ) + { + rule_cleanup(rule); + } + } + } + +function clear() + { + for ( id in rules ) + remove_rule(id); + } diff --git a/scripts/base/frameworks/netcontrol/non-cluster.bro b/scripts/base/frameworks/netcontrol/non-cluster.bro new file mode 100644 index 0000000000..4098586be4 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/non-cluster.bro @@ -0,0 +1,47 @@ +module NetControl; + +@load ./main + +function activate(p: PluginState, priority: int) + { + activate_impl(p, priority); + } + +function add_rule(r: Rule) : string + { + return add_rule_impl(r); + } + +function remove_rule(id: string) : bool + { + return remove_rule_impl(id); + } + +event rule_expire(r: Rule, p: PluginState) &priority=-5 + { + rule_expire_impl(r, p); + } + +event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 + { + rule_added_impl(r, p, msg); + + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) + schedule r$expire { rule_expire(r, p) }; + } + +event rule_removed(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_removed_impl(r, p, msg); + } + +event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) &priority=-5 + { + rule_timeout_impl(r, i, p); + } + +event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_error_impl(r, p, msg); + } + diff --git a/scripts/base/frameworks/netcontrol/plugin.bro b/scripts/base/frameworks/netcontrol/plugin.bro new file mode 100644 index 0000000000..7d0ee13a81 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugin.bro @@ -0,0 +1,89 @@ +##! Plugin interface for NetControl backends. + +module NetControl; + +@load ./types + +export { + ## State for a plugin instance. + type PluginState: record { + ## Table for a plugin to store custom, instance-specfific state. + config: table[string] of string &default=table(); + + ## Unique plugin identifier -- used for backlookup of plugins from Rules. Set internally. + _id: count &optional; + + ## Set internally. + _priority: int &default=+0; + + ## Set internally. Signifies if the plugin has returned that it has activated succesfully + _activated: bool &default=F; + }; + + # Definition of a plugin. + # + # Generally a plugin needs to implement only what it can support. By + # returning failure, it indicates that it can't support something and the + # the framework will then try another plugin, if available; or inform the + # that the operation failed. If a function isn't implemented by a plugin, + # that's considered an implicit failure to support the operation. + # + # If plugin accepts a rule operation, it *must* generate one of the reporting + # events ``rule_{added,remove,error}`` to signal if it indeed worked out; + # this is separate from accepting the operation because often a plugin + # will only know later (i.e., asynchrously) if that was an error for + # something it thought it could handle. + type Plugin: record { + # Returns a descriptive name of the plugin instance, suitable for use in logging + # messages. Note that this function is not optional. + name: function(state: PluginState) : string; + + ## If true, plugin can expire rules itself. If false, + ## framework will manage rule expiration. + can_expire: bool; + + # One-time initialization function called when plugin gets registered, and + # before any other methods are called. + # + # If this function is provided, NetControl assumes that the plugin has to + # perform, potentially lengthy, initialization before the plugin will become + # active. In this case, the plugin has to call ``NetControl::plugin_activated``, + # once initialization finishes. + init: function(state: PluginState) &optional; + + # One-time finalization function called when a plugin is shutdown; no further + # functions will be called afterwords. + done: function(state: PluginState) &optional; + + # Implements the add_rule() operation. If the plugin accepts the rule, + # it returns true, false otherwise. The rule will already have its + # ``id`` field set, which the plugin may use for identification + # purposes. + add_rule: function(state: PluginState, r: Rule) : bool &optional; + + # Implements the remove_rule() operation. This will only be called for + # rules that the plugins has previously accepted with add_rule(). The + # ``id`` field will match that of the add_rule() call. Generally, + # a plugin that accepts an add_rule() should also accept the + # remove_rule(). + remove_rule: function(state: PluginState, r: Rule) : bool &optional; + + # A transaction groups a number of operations. The plugin can add them internally + # and postpone putting them into effect until committed. This allows to build a + # configuration of multiple rules at once, including replaying a previous state. + transaction_begin: function(state: PluginState) &optional; + transaction_end: function(state: PluginState) &optional; + }; + + # Table for a plugin to store instance-specific configuration information. + # + # Note, it would be nicer to pass the Plugin instance to all the below, instead + # of this state table. However Bro's type resolver has trouble with refering to a + # record type from inside itself. + redef record PluginState += { + ## The plugin that the state belongs to. (Defined separately + ## because of cyclic type dependency.) + plugin: Plugin &optional; + }; + +} diff --git a/scripts/base/frameworks/netcontrol/plugins/__load__.bro b/scripts/base/frameworks/netcontrol/plugins/__load__.bro new file mode 100644 index 0000000000..255cee5f69 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/__load__.bro @@ -0,0 +1,5 @@ +@load ./debug +@load ./openflow +@load ./packetfilter +@load ./broker +@load ./acld diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro new file mode 100644 index 0000000000..76661bc857 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -0,0 +1,294 @@ +##! Acld plugin for the netcontrol framework. + +module NetControl; + +@load ../main +@load ../plugin +@load base/frameworks/broker + +export { + type AclRule : record { + command: string; + cookie: count; + arg: string; + comment: string &optional; + }; + + type AcldConfig: record { + ## The acld topic used to send events to + acld_topic: string; + ## Broker host to connect to + acld_host: addr; + ## Broker port to connect to + acld_port: port; + ## Do we accept rules for the monitor path? Default false + monitor: bool &default=F; + ## Do we accept rules for the forward path? Default true + forward: bool &default=T; + + ## Predicate that is called on rule insertion or removal. + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## Returns: T if the rule can be handled by the current backend, F otherwhise + check_pred: function(p: PluginState, r: Rule): bool &optional; + }; + + ## Instantiates the acld plugin. + global create_acld: function(config: AcldConfig) : PluginState; + + redef record PluginState += { + acld_config: AcldConfig &optional; + ## The ID of this acld instance - for the mapping to PluginStates + acld_id: count &optional; + }; + + ## Hook that is called after a rule is converted to an acld rule. + ## The hook may modify the rule before it is sent to acld. + ## Setting the acld command to F will cause the rule to be rejected + ## by the plugin + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## ar: The acld rule to be inserted or removed + global NetControl::acld_rule_policy: hook(p: PluginState, r: Rule, ar: AclRule); + + ## Events that are sent from us to Broker + global acld_add_rule: event(id: count, r: Rule, ar: AclRule); + global acld_remove_rule: event(id: count, r: Rule, ar: AclRule); + + ## Events that are sent from Broker to us + global acld_rule_added: event(id: count, r: Rule, msg: string); + global acld_rule_removed: event(id: count, r: Rule, msg: string); + global acld_rule_error: event(id: count, r: Rule, msg: string); +} + +global netcontrol_acld_peers: table[port, string] of PluginState; +global netcontrol_acld_topics: set[string] = set(); +global netcontrol_acld_id: table[count] of PluginState = table(); +global netcontrol_acld_current_id: count = 0; + +const acld_add_to_remove: table[string] of string = { + ["drop"] = "restore", + ["whitelist"] = "remwhitelist", + ["blockhosthost"] = "restorehosthost", + ["droptcpport"] = "restoretcpport", + ["dropudpport"] = "restoreudpport", + ["droptcpdsthostport"] ="restoretcpdsthostport", + ["dropudpdsthostport"] ="restoreudpdsthostport", + ["permittcpdsthostport"] ="unpermittcpdsthostport", + ["permitudpdsthostport"] ="unpermitudpdsthostport", + ["nullzero"] ="nonullzero" +}; + +event NetControl::acld_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_added(r, p, msg); + } + +event NetControl::acld_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_removed(r, p, msg); + } + +event NetControl::acld_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_error(r, p, msg); + } + +function acld_name(p: PluginState) : string + { + return fmt("Acld-%s", p$acld_config$acld_topic); + } + +# check that subnet specifies an addr +function check_sn(sn: subnet) : bool + { + if ( is_v4_subnet(sn) && subnet_width(sn) == 32 ) + return T; + if ( is_v6_subnet(sn) && subnet_width(sn) == 128 ) + return T; + + Reporter::error(fmt("Acld: rule_to_acl_rule was given a subnet that does not specify a distinct address where needed - %s", sn)); + return F; + } + +function rule_to_acl_rule(p: PluginState, r: Rule) : AclRule + { + local e = r$entity; + + local command: string = ""; + local arg: string = ""; + + if ( e$ty == ADDRESS ) + { + if ( r$ty == DROP ) + command = "drop"; + else if ( r$ty == WHITELIST ) + command = "whitelist"; + arg = cat(e$ip); + } + else if ( e$ty == FLOW ) + { + local f = e$flow; + if ( ( ! f?$src_h ) && ( ! f?$src_p ) && f?$dst_h && f?$dst_p && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( !check_sn(f$dst_h) ) + command = ""; # invalid addr, do nothing + else if ( is_tcp_port(f$dst_p) && r$ty == DROP ) + command = "droptcpdsthostport"; + else if ( is_tcp_port(f$dst_p) && r$ty == WHITELIST ) + command = "permittcpdsthostport"; + else if ( is_udp_port(f$dst_p) && r$ty == DROP) + command = "dropucpdsthostport"; + else if ( is_udp_port(f$dst_p) && r$ty == WHITELIST) + command = "permitucpdsthostport"; + + arg = fmt("%s %d", subnet_to_addr(f$dst_h), f$dst_p); + } + else if ( f?$src_h && ( ! f?$src_p ) && f?$dst_h && ( ! f?$dst_p ) && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( !check_sn(f$src_h) || !check_sn(f$dst_h) ) + command = ""; + else if ( r$ty == DROP ) + command = "blockhosthost"; + arg = fmt("%s %s", subnet_to_addr(f$src_h), subnet_to_addr(f$dst_h)); + } + else if ( ( ! f?$src_h ) && ( ! f?$src_p ) && ( ! f?$dst_h ) && f?$dst_p && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( is_tcp_port(f$dst_p) && r$ty == DROP ) + command = "droptcpport"; + else if ( is_udp_port(f$dst_p) && r$ty == DROP ) + command = "dropudpport"; + arg = fmt("%d", f$dst_p); + } + } + + local ar = AclRule($command=command, $cookie=r$cid, $arg=arg); + if ( r?$location ) + ar$comment = r$location; + + hook NetControl::acld_rule_policy(p, r, ar); + + return ar; + } + +function acld_check_rule(p: PluginState, r: Rule) : bool + { + local c = p$acld_config; + + if ( p$acld_config?$check_pred ) + return p$acld_config$check_pred(p, r); + + if ( r$target == MONITOR && c$monitor ) + return T; + + if ( r$target == FORWARD && c$forward ) + return T; + + return F; + } + +function acld_add_rule_fun(p: PluginState, r: Rule) : bool + { + if ( ! acld_check_rule(p, r) ) + return F; + + local ar = rule_to_acl_rule(p, r); + + if ( ar$command == "" ) + return F; + + BrokerComm::event(p$acld_config$acld_topic, BrokerComm::event_args(acld_add_rule, p$acld_id, r, ar)); + return T; + } + +function acld_remove_rule_fun(p: PluginState, r: Rule) : bool + { + if ( ! acld_check_rule(p, r) ) + return F; + + local ar = rule_to_acl_rule(p, r); + if ( ar$command in acld_add_to_remove ) + ar$command = acld_add_to_remove[ar$command]; + else + return F; + + BrokerComm::event(p$acld_config$acld_topic, BrokerComm::event_args(acld_remove_rule, p$acld_id, r, ar)); + return T; + } + +function acld_init(p: PluginState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(p$acld_config$acld_host), p$acld_config$acld_port, 1sec); + BrokerComm::subscribe_to_events(p$acld_config$acld_topic); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in netcontrol_acld_peers ) + # ok, this one was none of ours... + return; + + local p = netcontrol_acld_peers[peer_port, peer_address]; + plugin_activated(p); + } + +global acld_plugin = Plugin( + $name=acld_name, + $can_expire = F, + $add_rule = acld_add_rule_fun, + $remove_rule = acld_remove_rule_fun, + $init = acld_init + ); + +function create_acld(config: AcldConfig) : PluginState + { + if ( config$acld_topic in netcontrol_acld_topics ) + Reporter::warning(fmt("Topic %s was added to NetControl acld plugin twice. Possible duplication of commands", config$acld_topic)); + else + add netcontrol_acld_topics[config$acld_topic]; + + local host = cat(config$acld_host); + local p: PluginState = [$acld_config=config, $plugin=acld_plugin, $acld_id=netcontrol_acld_current_id]; + + if ( [config$acld_port, host] in netcontrol_acld_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl acld plugin twice.", host, config$acld_port)); + else + netcontrol_acld_peers[config$acld_port, host] = p; + + netcontrol_acld_id[netcontrol_acld_current_id] = p; + ++netcontrol_acld_current_id; + + return p; + } + diff --git a/scripts/base/frameworks/netcontrol/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro new file mode 100644 index 0000000000..619b6b607b --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -0,0 +1,163 @@ +##! Broker plugin for the netcontrol framework. Sends the raw data structures +##! used in NetControl on to Broker to allow for easy handling, e.g., of +##! command-line scripts. + +module NetControl; + +@load ../main +@load ../plugin +@load base/frameworks/broker + +export { + ## Instantiates the broker plugin. + global create_broker: function(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState; + + redef record PluginState += { + ## The broker topic used to send events to + broker_topic: string &optional; + ## The ID of this broker instance - for the mapping to PluginStates + broker_id: count &optional; + ## Broker host to connect to + broker_host: addr &optional; + ## Broker port to connect to + broker_port: port &optional; + }; + + global broker_add_rule: event(id: count, r: Rule); + global broker_remove_rule: event(id: count, r: Rule); + + global broker_rule_added: event(id: count, r: Rule, msg: string); + global broker_rule_removed: event(id: count, r: Rule, msg: string); + global broker_rule_error: event(id: count, r: Rule, msg: string); + global broker_rule_timeout: event(id: count, r: Rule, i: FlowInfo); +} + +global netcontrol_broker_peers: table[port, string] of PluginState; +global netcontrol_broker_topics: set[string] = set(); +global netcontrol_broker_id: table[count] of PluginState = table(); +global netcontrol_broker_current_id: count = 0; + +event NetControl::broker_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_added(r, p, msg); + } + +event NetControl::broker_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_removed(r, p, msg); + } + +event NetControl::broker_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_error(r, p, msg); + } + +event NetControl::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_timeout(r, i, p); + } + +function broker_name(p: PluginState) : string + { + return fmt("Broker-%s", p$broker_topic); + } + +function broker_add_rule_fun(p: PluginState, r: Rule) : bool + { + BrokerComm::event(p$broker_topic, BrokerComm::event_args(broker_add_rule, p$broker_id, r)); + return T; + } + +function broker_remove_rule_fun(p: PluginState, r: Rule) : bool + { + BrokerComm::event(p$broker_topic, BrokerComm::event_args(broker_remove_rule, p$broker_id, r)); + return T; + } + +function broker_init(p: PluginState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(p$broker_host), p$broker_port, 1sec); + BrokerComm::subscribe_to_events(p$broker_topic); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in netcontrol_broker_peers ) + return; + + local p = netcontrol_broker_peers[peer_port, peer_address]; + plugin_activated(p); + } + +global broker_plugin = Plugin( + $name=broker_name, + $can_expire = F, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun, + $init = broker_init + ); + +global broker_plugin_can_expire = Plugin( + $name=broker_name, + $can_expire = T, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun, + $init = broker_init + ); + +function create_broker(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState + { + if ( topic in netcontrol_broker_topics ) + Reporter::warning(fmt("Topic %s was added to NetControl broker plugin twice. Possible duplication of commands", topic)); + else + add netcontrol_broker_topics[topic]; + + local plugin = broker_plugin; + if ( can_expire ) + plugin = broker_plugin_can_expire; + + local p: PluginState = [$broker_host=host, $broker_port=host_port, $plugin=plugin, $broker_topic=topic, $broker_id=netcontrol_broker_current_id]; + + if ( [host_port, cat(host)] in netcontrol_broker_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl broker plugin twice.", host, host_port)); + else + netcontrol_broker_peers[host_port, cat(host)] = p; + + netcontrol_broker_id[netcontrol_broker_current_id] = p; + ++netcontrol_broker_current_id; + + return p; + } diff --git a/scripts/base/frameworks/netcontrol/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro new file mode 100644 index 0000000000..f421dc55e3 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -0,0 +1,99 @@ +##! Debugging plugin for the NetControl framework, providing insight into +##! executed operations. + +@load ../plugin +@load ../main + +module NetControl; + +export { + ## Instantiates a debug plugin for the NetControl framework. The debug + ## plugin simply logs the operations it receives. + ## + ## do_something: If true, the plugin will claim it supports all operations; if + ## false, it will indicate it doesn't support any. + global create_debug: function(do_something: bool) : PluginState; +} + +function do_something(p: PluginState) : bool + { + return p$config["all"] == "1"; + } + +function debug_name(p: PluginState) : string + { + return fmt("Debug-%s", (do_something(p) ? "All" : "None")); + } + +function debug_log(p: PluginState, msg: string) + { + print fmt("netcontrol debug (%s): %s", debug_name(p), msg); + } + +function debug_init(p: PluginState) + { + debug_log(p, "init"); + plugin_activated(p); + } + +function debug_done(p: PluginState) + { + debug_log(p, "init"); + } + +function debug_add_rule(p: PluginState, r: Rule) : bool + { + local s = fmt("add_rule: %s", r); + debug_log(p, s); + + if ( do_something(p) ) + { + event NetControl::rule_added(r, p); + return T; + } + + return F; + } + +function debug_remove_rule(p: PluginState, r: Rule) : bool + { + local s = fmt("remove_rule: %s", r); + debug_log(p, s); + + event NetControl::rule_removed(r, p); + return T; + } + +function debug_transaction_begin(p: PluginState) + { + debug_log(p, "transaction_begin"); + } + +function debug_transaction_end(p: PluginState) + { + debug_log(p, "transaction_end"); + } + +global debug_plugin = Plugin( + $name=debug_name, + $can_expire = F, + $init = debug_init, + $done = debug_done, + $add_rule = debug_add_rule, + $remove_rule = debug_remove_rule, + $transaction_begin = debug_transaction_begin, + $transaction_end = debug_transaction_end + ); + +function create_debug(do_something: bool) : PluginState + { + local p: PluginState = [$plugin=debug_plugin]; + + # FIXME: Why's the default not working? + p$config = table(); + p$config["all"] = (do_something ? "1" : "0"); + + return p; + } + + diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro new file mode 100644 index 0000000000..44a8bb2f1a --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -0,0 +1,432 @@ +##! OpenFlow plugin for the NetControl framework. + +@load ../main +@load ../plugin +@load base/frameworks/openflow + +module NetControl; + +export { + type OfConfig: record { + monitor: bool &default=T; + forward: bool &default=T; + idle_timeout: count &default=0; + table_id: count &optional; + priority_offset: int &default=+0; ##< add this to all rule priorities. Can be useful if you want the openflow priorities be offset from the netcontrol priorities without having to write a filter function. + + ## Predicate that is called on rule insertion or removal. + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## Returns: T if the rule can be handled by the current backend, F otherwhise + check_pred: function(p: PluginState, r: Rule): bool &optional; + match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional; + flow_mod_pred: function(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod &optional; + }; + + redef record PluginState += { + ## OpenFlow controller for NetControl OpenFlow plugin + of_controller: OpenFlow::Controller &optional; + ## OpenFlow configuration record that is passed on initialization + of_config: OfConfig &optional; + }; + + type OfTable: record { + p: PluginState; + r: Rule; + c: count &default=0; # how many replies did we see so far? needed for ids where we have multiple rules... + packet_count: count &default=0; + byte_count: count &default=0; + duration_sec: double &default=0.0; + }; + + ## the time interval after which an openflow message is considered to be timed out + ## and we delete it from our internal tracking. + const openflow_message_timeout = 20secs &redef; + + ## the time interval after we consider a flow timed out. This should be fairly high (or + ## even disabled) if you expect a lot of long flows. However, one also will have state + ## buildup for quite a while if keeping this around... + const openflow_flow_timeout = 24hrs &redef; + + ## Instantiates an openflow plugin for the NetControl framework. + global create_openflow: function(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState; +} + +global of_messages: table[count, OpenFlow::ofp_flow_mod_command] of OfTable &create_expire=openflow_message_timeout + &expire_func=function(t: table[count, OpenFlow::ofp_flow_mod_command] of OfTable, idx: any): interval + { + local rid: count; + local command: OpenFlow::ofp_flow_mod_command; + [rid, command] = idx; + + local p = t[rid, command]$p; + local r = t[rid, command]$r; + event NetControl::rule_error(r, p, "Timeout during rule insertion/removal"); + return 0secs; + }; + +global of_flows: table[count] of OfTable &create_expire=openflow_flow_timeout; +global of_instances: table[string] of PluginState; + +function openflow_name(p: PluginState) : string + { + return fmt("Openflow-%s", p$of_controller$describe(p$of_controller$state)); + } + +function openflow_check_rule(p: PluginState, r: Rule) : bool + { + local c = p$of_config; + + if ( p$of_config?$check_pred ) + return p$of_config$check_pred(p, r); + + if ( r$target == MONITOR && c$monitor ) + return T; + + if ( r$target == FORWARD && c$forward ) + return T; + + return F; + } + +function openflow_match_pred(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match) : vector of OpenFlow::ofp_match + { + if ( p$of_config?$match_pred ) + return p$of_config$match_pred(p, e, m); + + return m; + } + +function openflow_flow_mod_pred(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod + { + if ( p$of_config?$flow_mod_pred ) + return p$of_config$flow_mod_pred(p, r, m); + + return m; + } + +function determine_dl_type(s: subnet): count + { + local pdl = OpenFlow::ETH_IPv4; + if ( is_v6_subnet(s) ) + pdl = OpenFlow::ETH_IPv6; + + return pdl; + } + +function determine_proto(p: port): count + { + local proto = OpenFlow::IP_TCP; + if ( is_udp_port(p) ) + proto = OpenFlow::IP_UDP; + else if ( is_icmp_port(p) ) + proto = OpenFlow::IP_ICMP; + + return proto; + } + +function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_match + { + local v : vector of OpenFlow::ofp_match = vector(); + + if ( e$ty == CONNECTION ) + { + v[|v|] = OpenFlow::match_conn(e$conn); # forward and... + v[|v|] = OpenFlow::match_conn(e$conn, T); # reverse + return openflow_match_pred(p, e, v); + } + + if ( e$ty == MAC ) + { + v[|v|] = OpenFlow::ofp_match( + $dl_src=e$mac + ); + v[|v|] = OpenFlow::ofp_match( + $dl_dst=e$mac + ); + + return openflow_match_pred(p, e, v); + } + + local dl_type = OpenFlow::ETH_IPv4; + + if ( e$ty == ADDRESS ) + { + if ( is_v6_subnet(e$ip) ) + dl_type = OpenFlow::ETH_IPv6; + + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_src=e$ip + ); + + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_dst=e$ip + ); + + return openflow_match_pred(p, e, v); + } + + local proto = OpenFlow::IP_TCP; + + if ( e$ty == FLOW ) + { + local m = OpenFlow::ofp_match(); + local f = e$flow; + + if ( f?$src_m ) + m$dl_src=f$src_m; + if ( f?$dst_m ) + m$dl_dst=f$dst_m; + + if ( f?$src_h ) + { + m$dl_type = determine_dl_type(f$src_h); + m$nw_src = f$src_h; + } + + if ( f?$dst_h ) + { + m$dl_type = determine_dl_type(f$dst_h); + m$nw_dst = f$dst_h; + } + + if ( f?$src_p ) + { + m$nw_proto = determine_proto(f$src_p); + m$tp_src = port_to_count(f$src_p); + } + + if ( f?$dst_p ) + { + m$nw_proto = determine_proto(f$dst_p); + m$tp_dst = port_to_count(f$dst_p); + } + + v[|v|] = m; + + return openflow_match_pred(p, e, v); + } + + Reporter::error(fmt("Entity type %s not supported for openflow yet", cat(e$ty))); + return openflow_match_pred(p, e, v); + } + +function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow_mod + { + local c = p$of_config; + + local flow_mod = OpenFlow::ofp_flow_mod( + $cookie=OpenFlow::generate_cookie(r$cid*2), # leave one space for the cases in which we need two rules. + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=c$idle_timeout, + $priority=int_to_count(r$priority + c$priority_offset), + $flags=OpenFlow::OFPFF_SEND_FLOW_REM # please notify us when flows are removed + ); + + if ( r?$expire ) + flow_mod$hard_timeout = double_to_count(interval_to_double(r$expire)); + if ( c?$table_id ) + flow_mod$table_id = c$table_id; + + if ( r$ty == DROP ) + { + # default, nothing to do. We simply do not add an output port to the rule... + } + else if ( r$ty == WHITELIST ) + { + # at the moment our interpretation of whitelist is to hand this off to the switches L2/L3 routing. + flow_mod$actions$out_ports = vector(OpenFlow::OFPP_NORMAL); + } + else if ( r$ty == MODIFY ) + { + # if no ports are given, just assume normal pipeline... + flow_mod$actions$out_ports = vector(OpenFlow::OFPP_NORMAL); + + local mod = r$mod; + if ( mod?$redirect_port ) + flow_mod$actions$out_ports = vector(mod$redirect_port); + + if ( mod?$src_h ) + flow_mod$actions$nw_src = mod$src_h; + if ( mod?$dst_h ) + flow_mod$actions$nw_dst = mod$dst_h; + if ( mod?$src_m ) + flow_mod$actions$dl_src = mod$src_m; + if ( mod?$dst_m ) + flow_mod$actions$dl_dst = mod$dst_m; + if ( mod?$src_p ) + flow_mod$actions$tp_src = mod$src_p; + if ( mod?$dst_p ) + flow_mod$actions$tp_dst = mod$dst_p; + } + else if ( r$ty == REDIRECT ) + { + # redirect to port c + flow_mod$actions$out_ports = vector(r$out_port); + } + else + { + Reporter::error(fmt("Rule type %s not supported for openflow yet", cat(r$ty))); + } + + return openflow_flow_mod_pred(p, r, flow_mod); + } + +function openflow_add_rule(p: PluginState, r: Rule) : bool + { + if ( ! openflow_check_rule(p, r) ) + return F; + + local flow_mod = openflow_rule_to_flow_mod(p, r); + local matches = entity_to_match(p, r$entity); + + for ( i in matches ) + { + if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + { + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); + flow_mod = copy(flow_mod); + ++flow_mod$cookie; + } + else + event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); + } + + return T; + } + +function openflow_remove_rule(p: PluginState, r: Rule) : bool + { + if ( ! openflow_check_rule(p, r) ) + return F; + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(r$cid*2), + $command=OpenFlow::OFPFC_DELETE + ]; + + if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); + else + { + event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); + return F; + } + + # if this was an address or mac match, we also need to remove the reverse + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + local flow_mod_2 = copy(flow_mod); + ++flow_mod_2$cookie; + OpenFlow::flow_mod(p$of_controller, [], flow_mod_2); + } + + return T; + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; + if ( [id, flow_mod$command] !in of_messages ) + return; + + local r = of_messages[id,flow_mod$command]$r; + local p = of_messages[id,flow_mod$command]$p; + local c = of_messages[id,flow_mod$command]$c; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_messages[id,flow_mod$command]$c; + if ( of_messages[id,flow_mod$command]$c < 2 ) + return; # will do stuff once the second part arrives... + } + + delete of_messages[id,flow_mod$command]; + + if ( p$of_controller$supports_flow_removed ) + of_flows[id] = OfTable($p=p, $r=r); + + if ( flow_mod$command == OpenFlow::OFPFC_ADD ) + event NetControl::rule_added(r, p, msg); + else if ( flow_mod$command == OpenFlow::OFPFC_DELETE || flow_mod$command == OpenFlow::OFPFC_DELETE_STRICT ) + event NetControl::rule_removed(r, p, msg); + } + +event OpenFlow::flow_mod_failure(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; + if ( [id, flow_mod$command] !in of_messages ) + return; + + local r = of_messages[id,flow_mod$command]$r; + local p = of_messages[id,flow_mod$command]$p; + delete of_messages[id,flow_mod$command]; + + event NetControl::rule_error(r, p, msg); + } + +event OpenFlow::flow_removed(name: string, match: OpenFlow::ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count) + { + local id = OpenFlow::get_cookie_uid(cookie)/2; + if ( id !in of_flows ) + return; + + local rec = of_flows[id]; + local r = rec$r; + local p = rec$p; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_flows[id]$c; + if ( of_flows[id]$c < 2 ) + return; # will do stuff once the second part arrives... + else + event NetControl::rule_timeout(r, FlowInfo($duration=double_to_interval((rec$duration_sec+duration_sec)/2), $packet_count=packet_count+rec$packet_count, $byte_count=byte_count+rec$byte_count), p); + + return; + } + + event NetControl::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); + } + +function openflow_init(p: PluginState) + { + local name = p$of_controller$state$_name; + if ( name in of_instances ) + Reporter::error(fmt("OpenFlow instance %s added to NetControl twice.", name)); + + of_instances[name] = p; + + # let's check, if our OpenFlow controller is already active. If not, we have to wait for it to become active. + if ( p$of_controller$state$_activated ) + plugin_activated(p); + } + +event OpenFlow::controller_activated(name: string, controller: OpenFlow::Controller) + { + if ( name in of_instances ) + plugin_activated(of_instances[name]); + } + +global openflow_plugin = Plugin( + $name=openflow_name, + $can_expire = T, + $init = openflow_init, +# $done = openflow_done, + $add_rule = openflow_add_rule, + $remove_rule = openflow_remove_rule +# $transaction_begin = openflow_transaction_begin, +# $transaction_end = openflow_transaction_end + ); + +function create_openflow(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState + { + local p: PluginState = [$plugin=openflow_plugin, $of_controller=controller, $of_config=config]; + + return p; + } diff --git a/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro new file mode 100644 index 0000000000..437c08eb73 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro @@ -0,0 +1,113 @@ +##! NetControl plugin for the process-level PacketFilter that comes with +##! Bro. Since the PacketFilter in Bro is quite limited in scope +##! and can only add/remove filters for addresses, this is quite +##! limited in scope at the moment. + +module NetControl; + +@load ../plugin + +export { + ## Instantiates the packetfilter plugin. + global create_packetfilter: function() : PluginState; +} + +# Check if we can handle this rule. If it specifies ports or +# anything Bro cannot handle, simply ignore it for now. +function packetfilter_check_rule(r: Rule) : bool + { + if ( r$ty != DROP ) + return F; + + if ( r$target != MONITOR ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + return T; + + if ( e$ty != FLOW ) # everything else requires ports or MAC stuff + return F; + + if ( e$flow?$src_p || e$flow?$dst_p || e$flow?$src_m || e$flow?$dst_m ) + return F; + + return T; + } + + +function packetfilter_add_rule(p: PluginState, r: Rule) : bool + { + if ( ! packetfilter_check_rule(r) ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + { + install_src_net_filter(e$ip, 0, 1.0); + install_dst_net_filter(e$ip, 0, 1.0); + return T; + } + + if ( e$ty == FLOW ) + { + local f = e$flow; + if ( f?$src_h ) + install_src_net_filter(f$src_h, 0, 1.0); + if ( f?$dst_h ) + install_dst_net_filter(f$dst_h, 0, 1.0); + + return T; + } + + return F; + } + +function packetfilter_remove_rule(p: PluginState, r: Rule) : bool + { + if ( ! packetfilter_check_rule(r) ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + { + uninstall_src_net_filter(e$ip); + uninstall_dst_net_filter(e$ip); + return T; + } + + if ( e$ty == FLOW ) + { + local f = e$flow; + if ( f?$src_h ) + uninstall_src_net_filter(f$src_h); + if ( f?$dst_h ) + uninstall_dst_net_filter(f$dst_h); + + return T; + } + + return F; + } + +function packetfilter_name(p: PluginState) : string + { + return "Packetfilter"; + } + +global packetfilter_plugin = Plugin( + $name=packetfilter_name, + $can_expire = F, +# $init = packetfilter_init, +# $done = packetfilter_done, + $add_rule = packetfilter_add_rule, + $remove_rule = packetfilter_remove_rule + ); + +function create_packetfilter() : PluginState + { + local p: PluginState = [$plugin=packetfilter_plugin]; + + return p; + } + diff --git a/scripts/base/frameworks/netcontrol/shunt.bro b/scripts/base/frameworks/netcontrol/shunt.bro new file mode 100644 index 0000000000..e1a5715582 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/shunt.bro @@ -0,0 +1,69 @@ +##! Implementation of the shunt functionality for NetControl. + +module NetControl; + +@load ./main + +export { + redef enum Log::ID += { SHUNT }; + + ## Stops forwarding a uni-directional flow's packets to Bro. + ## + ## f: The flow to shunt. + ## + ## t: How long to leave the shunt in place, with 0 being indefinitly. + ## + ## location: An optional string describing where the shunt was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : string; + + type ShuntInfo: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log; + ## Flow ID of the shunted flow + f: flow_id &log; + ## Expiry time of the shunt + expire: interval &log; + ## Location where the underlying action was triggered. + location: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::ShuntInfo` + ## record as it is sent on to the logging framework. + global log_netcontrol_shunt: event(rec: ShuntInfo); +} + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::SHUNT, [$columns=ShuntInfo, $ev=log_netcontrol_shunt, $path="netcontrol_shunt"]); + } + +function shunt_flow(f: flow_id, t: interval, location: string &default="") : string + { + local flow = NetControl::Flow( + $src_h=addr_to_subnet(f$src_h), + $src_p=f$src_p, + $dst_h=addr_to_subnet(f$dst_h), + $dst_p=f$dst_p + ); + local e: Entity = [$ty=FLOW, $flow=flow]; + local r: Rule = [$ty=DROP, $target=MONITOR, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = ShuntInfo($ts=network_time(), $rule_id=id, $f=f, $expire=t); + if ( location != "" ) + log$location=location; + + Log::write(SHUNT, log); + + return id; + } + diff --git a/scripts/base/frameworks/netcontrol/types.bro b/scripts/base/frameworks/netcontrol/types.bro new file mode 100644 index 0000000000..440d63d8bc --- /dev/null +++ b/scripts/base/frameworks/netcontrol/types.bro @@ -0,0 +1,109 @@ +##! Types used by the NetControl framework. + +module NetControl; + +export { + const default_priority: int = +0 &redef; + const whitelist_priority: int = +5 &redef; + + ## Type of a :bro:id:`Entity` for defining an action. + type EntityType: enum { + ADDRESS, ##< Activity involving a specific IP address. + CONNECTION, ##< All of a bi-directional connection's activity. + FLOW, ##< All of a uni-directional flow's activity. Can contain wildcards. + MAC, ##< Activity involving a MAC address. + }; + + ## Type of a :bro:id:`Flow` for defining a flow. + type Flow: record { + src_h: subnet &optional; ##< The source IP address/subnet. + src_p: port &optional; ##< The source port number. + dst_h: subnet &optional; ##< The destination IP address/subnet. + dst_p: port &optional; ##< The desintation port number. + src_m: string &optional; ##< The source MAC address. + dst_m: string &optional; ##< The destination MAC address. + }; + + ## Type defining the enity an :bro:id:`Rule` is operating on. + type Entity: record { + ty: EntityType; ##< Type of entity. + conn: conn_id &optional; ##< Used with :bro:id:`CONNECTION` . + flow: Flow &optional; ##< Used with :bro:id:`FLOW` . + ip: subnet &optional; ##< Used with bro:id:`ADDRESS`; can specifiy a CIDR subnet. + mac: string &optional; ##< Used with :bro:id:`MAC`. + }; + + ## Target of :bro:id:`Rule` action. + type TargetType: enum { + FORWARD, #< Apply rule actively to traffic on forwarding path. + MONITOR, #< Apply rule passively to traffic sent to Bro for monitoring. + }; + + ## Type of rules that the framework supports. Each type lists the + ## :bro:id:`Rule` argument(s) it uses, if any. + ## + ## Plugins may extend this type to define their own. + type RuleType: enum { + ## Stop forwarding all packets matching entity. + ## + ## No arguments. + DROP, + + ## Begin modifying all packets matching entity. + ## + ## .. todo:: + ## Define arguments. + MODIFY, + + ## Begin redirecting all packets matching entity. + ## + ## .. todo:: + ## c: output port to redirect traffic to. + REDIRECT, + + ## Whitelists all packets of an entity, meaning no restrictions will be applied. + ## While whitelisting is the default if no rule matches an this can type can be + ## used to override lower-priority rules that would otherwise take effect for the + ## entity. + WHITELIST, + }; + + ## Type of a :bro:id:`FlowMod` for defining a flow modification action. + type FlowMod: record { + src_h: addr &optional; ##< The source IP address. + src_p: count &optional; ##< The source port number. + dst_h: addr &optional; ##< The destination IP address. + dst_p: count &optional; ##< The desintation port number. + src_m: string &optional; ##< The source MAC address. + dst_m: string &optional; ##< The destination MAC address. + redirect_port: count &optional; + }; + + ## A rule for the framework to put in place. Of all rules currently in + ## place, the first match will be taken, sorted by priority. All + ## further rules will be ignored. + type Rule: record { + ty: RuleType; ##< Type of rule. + target: TargetType; ##< Where to apply rule. + entity: Entity; ##< Entity to apply rule to. + expire: interval &optional; ##< Timeout after which to expire the rule. + priority: int &default=default_priority; ##< Priority if multiple rules match an entity (larger value is higher priority). + location: string &optional; ##< Optional string describing where/what installed the rule. + + out_port: count &optional; ##< Argument for bro:id:`REDIRECT` rules. + mod: FlowMod &optional; ##< Argument for :bro:id:`MODIFY` rules. + + id: string &default=""; ##< Internally determined unique ID for this rule. Will be set when added. + cid: count &default=0; ##< Internally determined unique numeric ID for this rule. Set when added. + }; + + ## Information of a flow that can be provided by switches when the flow times out. + ## Currently this is heavily influenced by the data that OpenFlow returns by default. + ## That being said - their design makes sense and this is probably the data one + ## can expect to be available. + type FlowInfo: record { + duration: interval &optional; ##< total duration of the rule + packet_count: count &optional; ##< number of packets exchanged over connections matched by the rule + byte_count: count &optional; ##< total bytes exchanged over connections matched by the rule + }; +} diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro new file mode 100644 index 0000000000..bd9128b5aa --- /dev/null +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -0,0 +1,13 @@ +@load ./consts +@load ./types +@load ./main +@load ./plugins + +# The cluster framework must be loaded first. +@load base/frameworks/cluster + +@if ( Cluster::is_enabled() ) +@load ./cluster +@else +@load ./non-cluster +@endif diff --git a/scripts/base/frameworks/openflow/cluster.bro b/scripts/base/frameworks/openflow/cluster.bro new file mode 100644 index 0000000000..28de1db3c3 --- /dev/null +++ b/scripts/base/frameworks/openflow/cluster.bro @@ -0,0 +1,120 @@ +##! Cluster support for the OpenFlow framework. + +@load ./main +@load base/frameworks/cluster + +module OpenFlow; + +export { + ## This is the event used to transport flow_mod messages to the manager. + global cluster_flow_mod: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod); + + ## This is the event used to transport flow_clear messages to the manager. + global cluster_flow_clear: event(name: string); +} + +## Workers need ability to forward commands to manager. +redef Cluster::worker2manager_events += /OpenFlow::cluster_flow_(mod|clear)/; + +# the flow_mod function wrapper +function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool + { + if ( ! controller?$flow_mod ) + return F; + + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return controller$flow_mod(controller$state, match, flow_mod); + else + event OpenFlow::cluster_flow_mod(controller$state$_name, match, flow_mod); + + return T; + } + +function flow_clear(controller: Controller): bool + { + if ( ! controller?$flow_clear ) + return F; + + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return controller$flow_clear(controller$state); + else + event OpenFlow::cluster_flow_clear(controller$state$_name); + + return T; + } + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event OpenFlow::cluster_flow_mod(name: string, match: ofp_match, flow_mod: ofp_flow_mod) + { + if ( name !in name_to_controller ) + { + Reporter::error(fmt("OpenFlow controller %s not found in mapping on master", name)); + return; + } + + local c = name_to_controller[name]; + + if ( ! c$state$_activated ) + return; + + if ( c?$flow_mod ) + c$flow_mod(c$state, match, flow_mod); + } + +event OpenFlow::cluster_flow_clear(name: string) + { + if ( name !in name_to_controller ) + { + Reporter::error(fmt("OpenFlow controller %s not found in mapping on master", name)); + return; + } + + local c = name_to_controller[name]; + + if ( ! c$state$_activated ) + return; + + if ( c?$flow_clear ) + c$flow_clear(c$state); + } +@endif + +function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + controller$state$_name = cat(tpe, name); + controller$state$_plugin = tpe; + + # we only run the init functions on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + register_controller_impl(tpe, name, controller); + } + +function unregister_controller(controller: Controller) + { + # we only run the on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + unregister_controller_impl(controller); + } + +function lookup_controller(name: string): vector of Controller + { + # we only run the on the manager. Otherwhise we don't have a mapping or state -> return empty + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return vector(); + + # I am not quite sure if we can actually get away with this - in the + # current state, this means that the individual nodes cannot lookup + # a controller by name. + # + # This means that there can be no reactions to things on the actual + # worker nodes - because they cannot look up a name. On the other hand - + # currently we also do not even send the events to the worker nodes (at least + # not if we are using broker). Because of that I am not really feeling that + # badly about it... + + return lookup_controller_impl(name); + } diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro new file mode 100644 index 0000000000..ca956702a7 --- /dev/null +++ b/scripts/base/frameworks/openflow/consts.bro @@ -0,0 +1,229 @@ +##! Constants used by the OpenFlow framework. + +# All types/constants not specific to OpenFlow will be defined here +# unitl they somehow get into Bro. + +module OpenFlow; + +# Some cookie specific constants. +# first 24 bits +const COOKIE_BID_SIZE = 16777216; +# start at bit 40 (1 << 40) +const COOKIE_BID_START = 1099511627776; +# bro specific cookie ID shall have the 42 bit set (1 << 42) +const BRO_COOKIE_ID = 4; +# 8 bits group identifier +const COOKIE_GID_SIZE = 256; +# start at bit 32 (1 << 32) +const COOKIE_GID_START = 4294967296; +# 32 bits unique identifier +const COOKIE_UID_SIZE = 4294967296; +# start at bit 0 (1 << 0) +const COOKIE_UID_START = 0; + +export { + # All ethertypes can be found at + # http://standards.ieee.org/develop/regauth/ethertype/eth.txt + # but are not interesting for us at this point +#type ethertype: enum { + # Internet protocol version 4 + const ETH_IPv4 = 0x0800; + # Address resolution protocol + const ETH_ARP = 0x0806; + # Wake on LAN + const ETH_WOL = 0x0842; + # Reverse address resolution protocol + const ETH_RARP = 0x8035; + # Appletalk + const ETH_APPLETALK = 0x809B; + # Appletalk address resolution protocol + const ETH_APPLETALK_ARP = 0x80F3; + # IEEE 802.1q & IEEE 802.1aq + const ETH_VLAN = 0x8100; + # Novell IPX old + const ETH_IPX_OLD = 0x8137; + # Novell IPX + const ETH_IPX = 0x8138; + # Internet protocol version 6 + const ETH_IPv6 = 0x86DD; + # IEEE 802.3x + const ETH_ETHER_FLOW_CONTROL = 0x8808; + # Multiprotocol Label Switching unicast + const ETH_MPLS_UNICAST = 0x8847; + # Multiprotocol Label Switching multicast + const ETH_MPLS_MULTICAST = 0x8848; + # Point-to-point protocol over Ethernet discovery phase (rfc2516) + const ETH_PPPOE_DISCOVERY = 0x8863; + # Point-to-point protocol over Ethernet session phase (rfc2516) + const ETH_PPPOE_SESSION = 0x8864; + # Jumbo frames + const ETH_JUMBO_FRAMES = 0x8870; + # IEEE 802.1X + const ETH_EAP_OVER_LAN = 0x888E; + # IEEE 802.1ad & IEEE 802.1aq + const ETH_PROVIDER_BRIDING = 0x88A8; + # IEEE 802.1ae + const ETH_MAC_SECURITY = 0x88E5; + # IEEE 802.1ad (QinQ) + const ETH_QINQ = 0x9100; +#}; + + # A list of ip protocol numbers can be found at + # http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers +#type iptype: enum { + # IPv6 Hop-by-Hop Option (RFC2460) + const IP_HOPOPT = 0x00; + # Internet Control Message Protocol (RFC792) + const IP_ICMP = 0x01; + # Internet Group Management Protocol (RFC1112) + const IP_IGMP = 0x02; + # Gateway-to-Gateway Protocol (RFC823) + const IP_GGP = 0x03; + # IP-Within-IP (encapsulation) (RFC2003) + const IP_IPIP = 0x04; + # Internet Stream Protocol (RFC1190;RFC1819) + const IP_ST = 0x05; + # Tansmission Control Protocol (RFC793) + const IP_TCP = 0x06; + # Core-based trees (RFC2189) + const IP_CBT = 0x07; + # Exterior Gateway Protocol (RFC888) + const IP_EGP = 0x08; + # Interior Gateway Protocol (any private interior + # gateway (used by Cisco for their IGRP)) + const IP_IGP = 0x09; + # User Datagram Protocol (RFC768) + const IP_UDP = 0x11; + # Reliable Datagram Protocol (RFC908) + const IP_RDP = 0x1B; + # IPv6 Encapsulation (RFC2473) + const IP_IPv6 = 0x29; + # Resource Reservation Protocol (RFC2205) + const IP_RSVP = 0x2E; + # Generic Routing Encapsulation (RFC2784;RFC2890) + const IP_GRE = 0x2F; + # Open Shortest Path First (RFC1583) + const IP_OSPF = 0x59; + # Multicast Transport Protocol + const IP_MTP = 0x5C; + # IP-within-IP Encapsulation Protocol (RFC2003) + ### error 0x5E; + # Ethernet-within-IP Encapsulation Protocol (RFC3378) + const IP_ETHERIP = 0x61; + # Layer Two Tunneling Protocol Version 3 (RFC3931) + const IP_L2TP = 0x73; + # Intermediate System to Intermediate System (IS-IS) Protocol over IPv4 (RFC1142;RFC1195) + const IP_ISIS = 0x7C; + # Fibre Channel + const IP_FC = 0x85; + # Multiprotocol Label Switching Encapsulated in IP (RFC4023) + const IP_MPLS = 0x89; +#}; + + ## Return value for a cookie from a flow + ## which is not added, modified or deleted + ## from the bro openflow framework + const INVALID_COOKIE = 0xffffffffffffffff; + # Openflow pysical port definitions + ## Send the packet out the input port. This + ## virual port must be explicitly used in + ## order to send back out of the input port. + const OFPP_IN_PORT = 0xfffffff8; + ## Perform actions in flow table. + ## NB: This can only be the destination port + ## for packet-out messages. + const OFPP_TABLE = 0xfffffff9; + ## Process with normal L2/L3 switching. + const OFPP_NORMAL = 0xfffffffa; + ## All pysical ports except input port and + ## those disabled by STP. + const OFPP_FLOOD = 0xfffffffb; + ## All pysical ports except input port. + const OFPP_ALL = 0xfffffffc; + ## Send to controller. + const OFPP_CONTROLLER = 0xfffffffd; + ## Local openflow "port". + const OFPP_LOCAL = 0xfffffffe; + ## Wildcard port used only for flow mod (delete) and flow stats requests. + const OFPP_ANY = 0xffffffff; + # Openflow no buffer constant. + const OFP_NO_BUFFER = 0xffffffff; + ## Send flow removed message when flow + ## expires or is deleted. + const OFPFF_SEND_FLOW_REM = 0x1; + ## Check for overlapping entries first. + const OFPFF_CHECK_OVERLAP = 0x2; + ## Remark this is for emergency. + ## Flows added with this are only used + ## when the controller is disconnected. + const OFPFF_EMERG = 0x4; + + # Wildcard table used for table config, + # flow stats and flow deletes. + const OFPTT_ALL = 0xff; + + ## Openflow action_type definitions + ## + ## The openflow action type defines + ## what actions openflow can take + ## to modify a packet + type ofp_action_type: enum { + ## Output to switch port. + OFPAT_OUTPUT = 0x0000, + ## Set the 802.1q VLAN id. + OFPAT_SET_VLAN_VID = 0x0001, + ## Set the 802.1q priority. + OFPAT_SET_VLAN_PCP = 0x0002, + ## Strip the 802.1q header. + OFPAT_STRIP_VLAN = 0x0003, + ## Ethernet source address. + OFPAT_SET_DL_SRC = 0x0004, + ## Ethernet destination address. + OFPAT_SET_DL_DST = 0x0005, + ## IP source address + OFPAT_SET_NW_SRC = 0x0006, + ## IP destination address. + OFPAT_SET_NW_DST = 0x0007, + ## IP ToS (DSCP field, 6 bits). + OFPAT_SET_NW_TOS = 0x0008, + ## TCP/UDP source port. + OFPAT_SET_TP_SRC = 0x0009, + ## TCP/UDP destination port. + OFPAT_SET_TP_DST = 0x000a, + ## Output to queue. + OFPAT_ENQUEUE = 0x000b, + ## Vendor specific + OFPAT_VENDOR = 0xffff, + }; + + ## Openflow flow_mod_command definitions + ## + ## The openflow flow_mod_command describes + ## of what kind an action is. + type ofp_flow_mod_command: enum { + ## New flow. + OFPFC_ADD = 0x0, + ## Modify all matching flows. + OFPFC_MODIFY = 0x1, + ## Modify entry strictly matching wildcards. + OFPFC_MODIFY_STRICT = 0x2, + ## Delete all matching flows. + OFPFC_DELETE = 0x3, + ## Strictly matching wildcards and priority. + OFPFC_DELETE_STRICT = 0x4, + }; + + ## Openflow config flag definitions + ## + ## TODO: describe + type ofp_config_flags: enum { + ## No special handling for fragments. + OFPC_FRAG_NORMAL = 0, + ## Drop fragments. + OFPC_FRAG_DROP = 1, + ## Reassemble (only if OFPC_IP_REASM set). + OFPC_FRAG_REASM = 2, + OFPC_FRAG_MASK = 3, + }; + +} diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro new file mode 100644 index 0000000000..889929c641 --- /dev/null +++ b/scripts/base/frameworks/openflow/main.bro @@ -0,0 +1,289 @@ +##! Bro's OpenFlow control framework +##! +##! This plugin-based framework allows to control OpenFlow capable +##! switches by implementing communication to an OpenFlow controller +##! via plugins. The framework has to be instantiated via the new function +##! in one of the plugins. This framework only offers very low-level +##! functionality; if you want to use OpenFlow capable switches, e.g., +##! for shunting, please look at the PACF framework, which provides higher +##! level functions and can use the OpenFlow framework as a backend. + +module OpenFlow; + +@load ./consts +@load ./types + +export { + ## Global flow_mod function. + ## + ## controller: The controller which should execute the flow modification + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## Returns: F on error or if the plugin does not support the operation, T when the operation was queued. + global flow_mod: function(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool; + + ## Clear the current flow table of the controller. + ## + ## controller: The controller which should execute the flow modification + ## + ## Returns: F on error or if the plugin does not support the operation, T when the operation was queued. + global flow_clear: function(controller: Controller): bool; + + ## Event confirming successful modification of a flow rule. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## msg: An optional informational message by the plugin. + global flow_mod_success: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + ## Reports an error while installing a flow Rule. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## msg: Message to describe the event. + global flow_mod_failure: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + ## Reports that a flow was removed by the switch because of either the hard or the idle timeout. + ## This message is only generated by controllers that indicate that they support flow removal + ## in supports_flow_removed. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which was used to create the flow. + ## + ## cookie: The cookie that was specified when creating the flow. + ## + ## priority: The priority that was specified when creating the flow. + ## + ## reason: The reason for flow removal (OFPRR_*) + ## + ## duration_sec: duration of the flow in seconds + ## + ## packet_count: packet count of the flow + ## + ## byte_count: byte count of the flow + global flow_removed: event(name: string, match: ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count); + + ## Convert a conn_id record into an ofp_match record that can be used to + ## create match objects for OpenFlow. + ## + ## id: the conn_id record that describes the record. + ## + ## reverse: reverse the sources and destinations when creating the match record (default F) + ## + ## Returns: ofp_match object for the conn_id record. + global match_conn: function(id: conn_id, reverse: bool &default=F): ofp_match; + + # ### + # ### Low-level functions for cookie handling and plugin registration. + # ### + + ## Function to get the unique id out of a given cookie. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie unique id. + global get_cookie_uid: function(cookie: count): count; + + ## Function to get the group id out of a given cookie. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie group id. + global get_cookie_gid: function(cookie: count): count; + + ## Function to generate a new cookie using our group id. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie group id. + global generate_cookie: function(cookie: count &default=0): count; + + ## Function to register a controller instance. This function + ## is called automatically by the plugin _new functions. + ## + ## tpe: type of this plugin + ## + ## name: unique name of this controller instance. + ## + ## controller: The controller to register + global register_controller: function(tpe: OpenFlow::Plugin, name: string, controller: Controller); + + ## Function to unregister a controller instance. This function + ## should be called when a specific controller should no longer + ## be used. + ## + ## controller: The controller to unregister + global unregister_controller: function(controller: Controller); + + ## Function to signal that a controller finished activation and is + ## ready to use. Will throw the ``OpenFlow::controller_activated`` + ## event. + global controller_init_done: function(controller: Controller); + + ## Event that is raised once a controller finishes initialization + ## and is completely activated. + ## name: unique name of this controller instance. + ## + ## controller: The controller that finished activation. + global OpenFlow::controller_activated: event(name: string, controller: Controller); + + ## Function to lookup a controller instance by name + ## + ## name: unique name of the controller to look up + ## + ## Returns: one element vector with controller, if found. Empty vector otherwhise. + global lookup_controller: function(name: string): vector of Controller; +} + +global name_to_controller: table[string] of Controller; + + +function match_conn(id: conn_id, reverse: bool &default=F): ofp_match + { + local dl_type = ETH_IPv4; + local proto = IP_TCP; + + local orig_h: addr; + local orig_p: port; + local resp_h: addr; + local resp_p: port; + + if ( reverse == F ) + { + orig_h = id$orig_h; + orig_p = id$orig_p; + resp_h = id$resp_h; + resp_p = id$resp_p; + } + else + { + orig_h = id$resp_h; + orig_p = id$resp_p; + resp_h = id$orig_h; + resp_p = id$orig_p; + } + + if ( is_v6_addr(orig_h) ) + dl_type = ETH_IPv6; + + if ( is_udp_port(orig_p) ) + proto = IP_UDP; + else if ( is_icmp_port(orig_p) ) + proto = IP_ICMP; + + return ofp_match( + $dl_type=dl_type, + $nw_proto=proto, + $nw_src=addr_to_subnet(orig_h), + $tp_src=port_to_count(orig_p), + $nw_dst=addr_to_subnet(resp_h), + $tp_dst=port_to_count(resp_p) + ); + } + +# local function to forge a flow_mod cookie for this framework. +# all flow entries from the openflow framework should have the +# 42 bit of the cookie set. +function generate_cookie(cookie: count &default=0): count + { + local c = BRO_COOKIE_ID * COOKIE_BID_START; + + if ( cookie >= COOKIE_UID_SIZE ) + Reporter::warning(fmt("The given cookie uid '%d' is > 32bit and will be discarded", cookie)); + else + c += cookie; + + return c; + } + +# local function to check if a given flow_mod cookie is forged from this framework. +function is_valid_cookie(cookie: count): bool + { + if ( cookie / COOKIE_BID_START == BRO_COOKIE_ID ) + return T; + + Reporter::warning(fmt("The given Openflow cookie '%d' is not valid", cookie)); + + return F; + } + +function get_cookie_uid(cookie: count): count + { + if( is_valid_cookie(cookie) ) + return (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START)); + + return INVALID_COOKIE; + } + +function get_cookie_gid(cookie: count): count + { + if( is_valid_cookie(cookie) ) + return ( + (cookie - (COOKIE_BID_START * BRO_COOKIE_ID) - + (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START))) / + COOKIE_GID_START + ); + + return INVALID_COOKIE; + } + +function controller_init_done(controller: Controller) + { + if ( controller$state$_name !in name_to_controller ) + { + Reporter::error(fmt("Openflow initialized unknown plugin %s successfully?", controller$state$_name)); + return; + } + + controller$state$_activated = T; + event OpenFlow::controller_activated(controller$state$_name, controller); + } + +# Functions that are called from cluster.bro and non-cluster.bro + +function register_controller_impl(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + if ( controller$state$_name in name_to_controller ) + { + Reporter::error(fmt("OpenFlow Controller %s was already registered. Ignored duplicate registration", controller$state$_name)); + return; + } + + name_to_controller[controller$state$_name] = controller; + + if ( controller?$init ) + controller$init(controller$state); + else + controller_init_done(controller); + } + +function unregister_controller_impl(controller: Controller) + { + if ( controller$state$_name in name_to_controller ) + delete name_to_controller[controller$state$_name]; + else + Reporter::error("OpenFlow Controller %s was not registered in unregister."); + + if ( controller?$destroy ) + controller$destroy(controller$state); + } + +function lookup_controller_impl(name: string): vector of Controller + { + if ( name in name_to_controller ) + return vector(name_to_controller[name]); + else + return vector(); + } diff --git a/scripts/base/frameworks/openflow/non-cluster.bro b/scripts/base/frameworks/openflow/non-cluster.bro new file mode 100644 index 0000000000..22b5980924 --- /dev/null +++ b/scripts/base/frameworks/openflow/non-cluster.bro @@ -0,0 +1,44 @@ +@load ./main + +module OpenFlow; + +# the flow_mod function wrapper +function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool + { + if ( ! controller$state$_activated ) + return F; + + if ( controller?$flow_mod ) + return controller$flow_mod(controller$state, match, flow_mod); + else + return F; + } + +function flow_clear(controller: Controller): bool + { + if ( ! controller$state$_activated ) + return F; + + if ( controller?$flow_clear ) + return controller$flow_clear(controller$state); + else + return F; + } + +function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + controller$state$_name = cat(tpe, name); + controller$state$_plugin = tpe; + + register_controller_impl(tpe, name, controller); + } + +function unregister_controller(controller: Controller) + { + unregister_controller_impl(controller); + } + +function lookup_controller(name: string): vector of Controller + { + return lookup_controller_impl(name); + } diff --git a/scripts/base/frameworks/openflow/plugins/__load__.bro b/scripts/base/frameworks/openflow/plugins/__load__.bro new file mode 100644 index 0000000000..e387132034 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/__load__.bro @@ -0,0 +1,3 @@ +@load ./ryu +@load ./log +@load ./broker diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro new file mode 100644 index 0000000000..d6cf52a92c --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -0,0 +1,95 @@ +##! OpenFlow plugin for interfacing to controllers via Broker. + +@load base/frameworks/openflow +@load base/frameworks/broker + +module OpenFlow; + +export { + redef enum Plugin += { + BROKER, + }; + + ## Broker controller constructor. + ## + ## host: Controller ip. + ## + ## host_port: Controller listen port. + ## + ## topic: broker topic to send messages to. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global broker_new: function(name: string, host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller; + + redef record ControllerState += { + ## Controller ip. + broker_host: addr &optional; + ## Controller listen port. + broker_port: port &optional; + ## OpenFlow switch datapath id. + broker_dpid: count &optional; + ## Topic to sent events for this controller to + broker_topic: string &optional; + }; + + global broker_flow_mod: event(name: string, dpid: count, match: ofp_match, flow_mod: ofp_flow_mod); + global broker_flow_clear: event(name: string, dpid: count); +} + +global broker_peers: table[port, string] of Controller; + +function broker_describe(state: ControllerState): string + { + return fmt("Broker-%s:%d-%d", state$broker_host, state$broker_port, state$broker_dpid); + } + +function broker_flow_mod_fun(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_mod, state$_name, state$broker_dpid, match, flow_mod)); + + return T; + } + +function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool + { + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_clear, state$_name, state$broker_dpid)); + + return T; + } + +function broker_init(state: OpenFlow::ControllerState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(state$broker_host), state$broker_port, 1sec); + BrokerComm::subscribe_to_events(state$broker_topic); # openflow success and failure events are directly sent back via the other plugin via broker. + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in broker_peers ) + # ok, this one was none of ours... + return; + + local p = broker_peers[peer_port, peer_address]; + controller_init_done(p); + delete broker_peers[peer_port, peer_address]; + } + +# broker controller constructor +function broker_new(name: string, host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic), + $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe, $supports_flow_removed=T, $init=broker_init); + + register_controller(OpenFlow::BROKER, name, c); + + if ( [host_port, cat(host)] in broker_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl acld plugin twice.", host, host_port)); + else + broker_peers[host_port, cat(host)] = c; + + return c; + } + diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro new file mode 100644 index 0000000000..18aa0c1584 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -0,0 +1,76 @@ +##! OpenFlow plugin that outputs flow-modification commands +##! to a Bro log file. + +@load base/frameworks/openflow +@load base/frameworks/logging + +module OpenFlow; + +export { + redef enum Plugin += { + OFLOG, + }; + + redef enum Log::ID += { LOG }; + + ## Log controller constructor. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## success_event: If true, flow_mod_success is raised for each logged line. + ## + ## Returns: OpenFlow::Controller record + global log_new: function(dpid: count, success_event: bool &default=T): OpenFlow::Controller; + + redef record ControllerState += { + ## OpenFlow switch datapath id. + log_dpid: count &optional; + ## Raise or do not raise success event + log_success_event: bool &optional; + }; + + ## The record type which contains column fields of the OpenFlow log. + type Info: record { + ## Network time + ts: time &log; + ## OpenFlow switch datapath id + dpid: count &log; + ## OpenFlow match fields + match: ofp_match &log; + ## OpenFlow modify flow entry message + flow_mod: ofp_flow_mod &log; + }; + + ## Event that can be handled to access the :bro:type:`OpenFlow::Info` + ## record as it is sent on to the logging framework. + global log_openflow: event(rec: Info); +} + +event bro_init() &priority=5 + { + Log::create_stream(OpenFlow::LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]); + } + +function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + Log::write(OpenFlow::LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); + if ( state$log_success_event ) + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); + + return T; + } + +function log_describe(state: ControllerState): string + { + return fmt("Log-%d", state$log_dpid); + } + +function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($log_dpid=dpid, $log_success_event=success_event), + $flow_mod=log_flow_mod, $describe=log_describe, $supports_flow_removed=F); + + register_controller(OpenFlow::OFLOG, cat(dpid), c); + + return c; + } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro new file mode 100644 index 0000000000..69d51adc9b --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -0,0 +1,190 @@ +##! OpenFlow plugin for the Ryu controller. + +@load base/frameworks/openflow +@load base/utils/active-http +@load base/utils/exec +@load base/utils/json + +module OpenFlow; + +export { + redef enum Plugin += { + RYU, + }; + + ## Ryu controller constructor. + ## + ## host: Controller ip. + ## + ## host_port: Controller listen port. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global ryu_new: function(host: addr, host_port: count, dpid: count): OpenFlow::Controller; + + redef record ControllerState += { + ## Controller ip. + ryu_host: addr &optional; + ## Controller listen port. + ryu_port: count &optional; + ## OpenFlow switch datapath id. + ryu_dpid: count &optional; + ## Enable debug mode - output JSON to stdout; do not perform actions + ryu_debug: bool &default=F; + }; +} + +# Ryu ReST API flow_mod URL-path +const RYU_FLOWENTRY_PATH = "/stats/flowentry/"; +# Ryu ReST API flow_stats URL-path +#const RYU_FLOWSTATS_PATH = "/stats/flow/"; + +# Ryu ReST API action_output type. +type ryu_flow_action: record { + # Ryu uses strings as its ReST API output action. + _type: string; + # The output port for type OUTPUT + _port: count &optional; +}; + +# The ReST API documentation can be found at +# https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf +# Ryu ReST API flow_mod type. +type ryu_ofp_flow_mod: record { + dpid: count; + cookie: count &optional; + cookie_mask: count &optional; + table_id: count &optional; + idle_timeout: count &optional; + hard_timeout: count &optional; + priority: count &optional; + flags: count &optional; + match: OpenFlow::ofp_match; + actions: vector of ryu_flow_action; + out_port: count &optional; + out_group: count &optional; +}; + +# Mapping between ofp flow mod commands and ryu urls +const ryu_url: table[ofp_flow_mod_command] of string = { + [OFPFC_ADD] = "add", + [OFPFC_MODIFY] = "modify", + [OFPFC_MODIFY_STRICT] = "modify_strict", + [OFPFC_DELETE] = "delete", + [OFPFC_DELETE_STRICT] = "delete_strict", +}; + +# Ryu flow_mod function +function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + if ( state$_plugin != RYU ) + { + Reporter::error("Ryu openflow plugin was called with state of non-ryu plugin"); + return F; + } + + # Generate ryu_flow_actions because their type differs (using strings as type). + local flow_actions: vector of ryu_flow_action = vector(); + + for ( i in flow_mod$actions$out_ports ) + flow_actions[|flow_actions|] = ryu_flow_action($_type="OUTPUT", $_port=flow_mod$actions$out_ports[i]); + + # Generate our ryu_flow_mod record for the ReST API call. + local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( + $dpid=state$ryu_dpid, + $cookie=flow_mod$cookie, + $idle_timeout=flow_mod$idle_timeout, + $hard_timeout=flow_mod$hard_timeout, + $priority=flow_mod$priority, + $flags=flow_mod$flags, + $match=match, + $actions=flow_actions + ); + + if ( flow_mod?$out_port ) + mod$out_port = flow_mod$out_port; + if ( flow_mod?$out_group ) + mod$out_group = flow_mod$out_group; + + # Type of the command + local command_type: string; + + if ( flow_mod$command in ryu_url ) + command_type = ryu_url[flow_mod$command]; + else + { + Reporter::warning(fmt("The given OpenFlow command type '%s' is not available", cat(flow_mod$command))); + return F; + } + + local url=cat("http://", cat(state$ryu_host), ":", cat(state$ryu_port), RYU_FLOWENTRY_PATH, command_type); + + if ( state$ryu_debug ) + { + print url; + print to_json(mod); + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); + return T; + } + + # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=url, + $method="POST", + $client_data=to_json(mod) + ); + + # Execute call to Ryu's ReST API + when ( local result = ActiveHTTP::request(request) ) + { + if(result$code == 200) + event OpenFlow::flow_mod_success(state$_name, match, flow_mod, result$body); + else + { + Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); + event OpenFlow::flow_mod_failure(state$_name, match, flow_mod, result$body); + return F; + } + } + + return T; + } + +function ryu_flow_clear(state: OpenFlow::ControllerState): bool + { + local url=cat("http://", cat(state$ryu_host), ":", cat(state$ryu_port), RYU_FLOWENTRY_PATH, "clear", "/", state$ryu_dpid); + + if ( state$ryu_debug ) + { + print url; + return T; + } + + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=url, + $method="DELETE" + ); + + when ( local result = ActiveHTTP::request(request) ) + { + } + + return T; + } + +function ryu_describe(state: ControllerState): string + { + return fmt("Ryu-%d-http://%s:%d", state$ryu_dpid, state$ryu_host, state$ryu_port); + } + +# Ryu controller constructor +function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid), + $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe, $supports_flow_removed=F); + + register_controller(OpenFlow::RYU, cat(host,host_port,dpid), c); + + return c; + } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro new file mode 100644 index 0000000000..f527cd51a7 --- /dev/null +++ b/scripts/base/frameworks/openflow/types.bro @@ -0,0 +1,132 @@ +##! Types used by the OpenFlow framework. + +module OpenFlow; + +@load ./consts + +export { + ## Available openflow plugins + type Plugin: enum { + ## Internal placeholder plugin + INVALID, + }; + + ## Controller related state. + ## Can be redefined by plugins to + ## add state. + type ControllerState: record { + ## Internally set to the type of plugin used. + _plugin: Plugin &optional; + ## Internally set to the unique name of the controller. + _name: string &optional; + ## Internally set to true once the controller is activated + _activated: bool &default=F; + } &redef; + + ## Openflow match definition. + ## + ## The openflow match record describes + ## which packets match to a specific + ## rule in a flow table. + type ofp_match: record { + # Input switch port. + in_port: count &optional; + # Ethernet source address. + dl_src: string &optional; + # Ethernet destination address. + dl_dst: string &optional; + # Input VLAN id. + dl_vlan: count &optional; + # Input VLAN priority. + dl_vlan_pcp: count &optional; + # Ethernet frame type. + dl_type: count &optional; + # IP ToS (actually DSCP field, 6bits). + nw_tos: count &optional; + # IP protocol or lower 8 bits of ARP opcode. + nw_proto: count &optional; + # At the moment, we store both v4 and v6 in the same fields. + # This is not how OpenFlow does it, we might want to change that... + # IP source address. + nw_src: subnet &optional; + # IP destination address. + nw_dst: subnet &optional; + # TCP/UDP source port. + tp_src: count &optional; + # TCP/UDP destination port. + tp_dst: count &optional; + } &log; + + ## The actions that can be taken in a flow. + ## (Sepearate record to make ofp_flow_mod less crowded) + type ofp_flow_action: record { + ## Output ports to send data to. + out_ports: vector of count &default=vector(); + ## set vlan vid to this value + vlan_vid: count &optional; + ## set vlan priority to this value + vlan_pcp: count &optional; + ## strip vlan tag + vlan_strip: bool &default=F; + ## set ethernet source address + dl_src: string &optional; + ## set ethernet destination address + dl_dst: string &optional; + ## set ip tos to this value + nw_tos: count &optional; + ## set source to this ip + nw_src: addr &optional; + ## set destination to this ip + nw_dst: addr &optional; + ## set tcp/udp source port + tp_src: count &optional; + ## set tcp/udp destination port + tp_dst: count &optional; + } &log; + + ## Openflow flow_mod definition, describing the action to perform. + type ofp_flow_mod: record { + ## Opaque controller-issued identifier. + # This is optional in the specification - but let's force + # it so we always can identify our flows... + cookie: count; # &default=BRO_COOKIE_ID * COOKIE_BID_START; + # Flow actions + ## Table to put the flow in. OFPTT_ALL can be used for delete, + ## to delete flows from all matching tables. + table_id: count &optional; + ## One of OFPFC_*. + command: ofp_flow_mod_command; # &default=OFPFC_ADD; + ## Idle time before discarding (seconds). + idle_timeout: count &default=0; + ## Max time before discarding (seconds). + hard_timeout: count &default=0; + ## Priority level of flow entry. + priority: count &default=0; + ## For OFPFC_DELETE* commands, require matching entried to include + ## this as an output port/group. OFPP_ANY/OFPG_ANY means no restrictions. + out_port: count &optional; + out_group: count &optional; + ## Bitmap of the OFPFF_* flags + flags: count &default=0; + ## Actions to take on match + actions: ofp_flow_action &default=ofp_flow_action(); + } &log; + + ## Controller record representing an openflow controller + type Controller: record { + ## Controller related state. + state: ControllerState; + ## Does the controller support the flow_removed event? + supports_flow_removed: bool; + ## function that describes the controller. Has to be implemented. + describe: function(state: ControllerState): string; + ## one-time initialization function. If defined, controller_init_done has to be called once initialization finishes. + init: function (state: ControllerState) &optional; + ## one-time destruction function + destroy: function (state: ControllerState) &optional; + ## flow_mod function + flow_mod: function(state: ControllerState, match: ofp_match, flow_mod: ofp_flow_mod): bool &optional; + ## flow_clear function + flow_clear: function(state: ControllerState): bool &optional; + }; +} diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index d3c539bba0..bdc3a92a27 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -39,6 +39,13 @@ type count_set: set[count]; ## directly and then remove this alias. type index_vec: vector of count; +## A vector of subnets. +## +## .. todo:: We need this type definition only for declaring builtin functions +## via ``bifcl``. We should extend ``bifcl`` to understand composite types +## directly and then remove this alias. +type subnet_vec: vector of subnet; + ## A vector of any, used by some builtin functions to store a list of varying ## types. ## @@ -120,6 +127,18 @@ type conn_id: record { resp_p: port; ##< The responder's port number. } &log; +## The identifying 4-tuple of a uni-directional flow. +## +## .. note:: It's actually a 5-tuple: the transport-layer protocol is stored as +## part of the port values, `src_p` and `dst_p`, and can be extracted from +## them with :bro:id:`get_port_transport_proto`. +type flow_id : record { + src_h: addr; ##< The source IP address. + src_p: port; ##< The source port number. + dst_h: addr; ##< The destination IP address. + dst_p: port; ##< The desintation port number. +} &log; + ## Specifics about an ICMP conversation. ICMP events typically pass this in ## addition to :bro:type:`conn_id`. ## diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 3d465b66bc..fd2b1c7cff 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,6 +37,8 @@ @load base/frameworks/reporter @load base/frameworks/sumstats @load base/frameworks/tunnels +@load base/frameworks/openflow +@load base/frameworks/netcontrol @load base/protocols/conn @load base/protocols/dhcp diff --git a/scripts/base/protocols/conn/main.bro b/scripts/base/protocols/conn/main.bro index 015c5520db..c6eef5d2d5 100644 --- a/scripts/base/protocols/conn/main.bro +++ b/scripts/base/protocols/conn/main.bro @@ -47,7 +47,7 @@ export { ## S2 Connection established and close attempt by originator seen (but no reply from responder). ## S3 Connection established and close attempt by responder seen (but no reply from originator). ## RSTO Connection established, originator aborted (sent a RST). - ## RSTR Established, responder aborted. + ## RSTR Responder sent a RST. ## RSTOS0 Originator sent a SYN followed by a RST, we never saw a SYN-ACK from the responder. ## RSTRH Responder sent a SYN ACK followed by a RST, we never saw a SYN from the (purported) originator. ## SH Originator sent a SYN followed by a FIN, we never saw a SYN ACK from the responder (hence the connection was "half" open). diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index f98e33b315..717b3a0669 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -213,7 +213,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior # on a different file could be checked, but the file size will # be overwritten by the server response to the RETR command # if that's given as well which would be more correct. - c$ftp$file_size = extract_count(msg); + c$ftp$file_size = extract_count(msg, F); } # PASV and EPSV processing diff --git a/scripts/base/protocols/sip/main.bro b/scripts/base/protocols/sip/main.bro index dbe3c54800..dc790ad560 100644 --- a/scripts/base/protocols/sip/main.bro +++ b/scripts/base/protocols/sip/main.bro @@ -80,7 +80,7 @@ export { ## that the SIP analyzer will only accept methods consisting solely ## of letters ``[A-Za-z]``. const sip_methods: set[string] = { - "REGISTER", "INVITE", "ACK", "CANCEL", "BYE", "OPTIONS", "NOTIFY" + "REGISTER", "INVITE", "ACK", "CANCEL", "BYE", "OPTIONS", "NOTIFY", "SUBSCRIBE" } &redef; ## Event that can be handled to access the SIP record as it is sent on @@ -153,7 +153,7 @@ function flush_pending(c: connection) # We don't use pending elements at index 0. if ( r == 0 ) next; - + Log::write(SIP::LOG, c$sip_state$pending[r]); } } diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index d9e1e2b3cf..fad2da0b8e 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -46,11 +46,10 @@ export { ## authentication success or failure when compression is enabled. const compression_algorithms = set("zlib", "zlib@openssh.com") &redef; - ## If true, we tell the event engine to not look at further data - ## packets after the initial SSH handshake. Helps with performance - ## (especially with large file transfers) but precludes some - ## kinds of analyses. Defaults to T. - const skip_processing_after_detection = T &redef; + ## If true, after detection detach the SSH analyzer from the connection + ## to prevent continuing to process encrypted traffic. Helps with performance + ## (especially with large file transfers). + const disable_analyzer_after_detection = T &redef; ## Event that can be handled to access the SSH record as it is sent on ## to the logging framework. @@ -70,6 +69,8 @@ redef record Info += { # Store capabilities from the first host for # comparison with the second (internal use) capabilities: Capabilities &optional; + ## Analzyer ID + analyzer_id: count &optional; }; redef record connection += { @@ -130,11 +131,8 @@ event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=5 c$ssh$auth_success = T; - if ( skip_processing_after_detection) - { - skip_further_processing(c$id); - set_record_packets(c$id, F); - } + if ( disable_analyzer_after_detection ) + disable_analyzer(c$id, c$ssh$analyzer_id); } event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=-5 @@ -179,7 +177,7 @@ function find_bidirectional_alg(client_prefs: Algorithm_Prefs, server_prefs: Alg # Usually these are the same, but if they're not, return the details return c_to_s == s_to_c ? c_to_s : fmt("To server: %s, to client: %s", c_to_s, s_to_c); } - + event ssh_capabilities(c: connection, cookie: string, capabilities: Capabilities) { if ( !c?$ssh || ( c$ssh?$capabilities && c$ssh$capabilities$is_server == capabilities$is_server ) ) @@ -233,3 +231,12 @@ event ssh2_server_host_key(c: connection, key: string) &priority=5 { generate_fingerprint(c, key); } + +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=20 + { + if ( atype == Analyzer::ANALYZER_SSH ) + { + set_session(c); + c$ssh$analyzer_id = aid; + } + } diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index 7a95d63cc6..35cfc7681d 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -109,7 +109,7 @@ export { [7] = "client_authz", [8] = "server_authz", [9] = "cert_type", - [10] = "elliptic_curves", + [10] = "elliptic_curves", # new name: supported_groups - draft-ietf-tls-negotiated-ff-dhe [11] = "ec_point_formats", [12] = "srp", [13] = "signature_algorithms", @@ -120,9 +120,10 @@ export { [18] = "signed_certificate_timestamp", [19] = "client_certificate_type", [20] = "server_certificate_type", - [21] = "padding", # temporary till 2016-03-12 + [21] = "padding", [22] = "encrypt_then_mac", [23] = "extended_master_secret", + [24] = "token_binding", # temporary till 2017-02-04 - draft-ietf-tokbind-negotiation [35] = "SessionTicket TLS", [40] = "extended_random", [13172] = "next_protocol_negotiation", @@ -165,7 +166,10 @@ export { [26] = "brainpoolP256r1", [27] = "brainpoolP384r1", [28] = "brainpoolP512r1", - # draft-ietf-tls-negotiated-ff-dhe-05 + # Temporary till 2017-03-01 - draft-ietf-tls-rfc4492bis + [29] = "ecdh_x25519", + [30] = "ecdh_x448", + # draft-ietf-tls-negotiated-ff-dhe-10 [256] = "ffdhe2048", [257] = "ffdhe3072", [258] = "ffdhe4096", diff --git a/scripts/base/utils/json.bro b/scripts/base/utils/json.bro new file mode 100644 index 0000000000..b6d0093b58 --- /dev/null +++ b/scripts/base/utils/json.bro @@ -0,0 +1,105 @@ +##! Functions to assist with generating JSON data from Bro data scructures. +# We might want to implement this in core somtime, this looks... hacky at best. + +@load base/utils/strings + +## A function to convert arbitrary Bro data into a JSON string. +## +## v: The value to convert to JSON. Typically a record. +## +## only_loggable: If the v value is a record this will only cause +## fields with the &log attribute to be included in the JSON. +## +## returns: a JSON formatted string. +function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string + { + local tn = type_name(v); + switch ( tn ) + { + case "type": + return ""; + + case "string": + return cat("\"", gsub(gsub(clean(v), /\\/, "\\\\"), /\"/, "\\\""), "\""); + + case "port": + return cat(port_to_count(to_port(cat(v)))); + + case "addr": + fallthrough; + case "subnet": + return cat("\"", v, "\""); + + case "int": + fallthrough; + case "count": + fallthrough; + case "time": + fallthrough; + case "double": + fallthrough; + case "bool": + fallthrough; + case "enum": + return cat(v); + + default: + break; + } + + if ( /^record/ in tn ) + { + local rec_parts: string_vec = vector(); + + local ft = record_fields(v); + for ( field in ft ) + { + local field_desc = ft[field]; + # replace the escape pattern in the field. + if( field_escape_pattern in field ) + field = cat(sub(field, field_escape_pattern, "")); + if ( field_desc?$value && (!only_loggable || field_desc$log) ) + { + local onepart = cat("\"", field, "\": ", to_json(field_desc$value, only_loggable)); + rec_parts[|rec_parts|] = onepart; + } + } + return cat("{", join_string_vec(rec_parts, ", "), "}"); + } + + # None of the following are supported. + else if ( /^set/ in tn ) + { + local set_parts: string_vec = vector(); + local sa: set[bool] = v; + for ( sv in sa ) + { + set_parts[|set_parts|] = to_json(sv, only_loggable); + } + return cat("[", join_string_vec(set_parts, ", "), "]"); + } + else if ( /^table/ in tn ) + { + local tab_parts: vector of string = vector(); + local ta: table[bool] of any = v; + for ( ti in ta ) + { + local ts = to_json(ti); + local if_quotes = (ts[0] == "\"") ? "" : "\""; + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", to_json(ta[ti], only_loggable)); + } + return cat("{", join_string_vec(tab_parts, ", "), "}"); + } + else if ( /^vector/ in tn ) + { + local vec_parts: string_vec = vector(); + local va: vector of any = v; + for ( vi in va ) + { + vec_parts[|vec_parts|] = to_json(va[vi], only_loggable); + } + return cat("[", join_string_vec(vec_parts, ", "), "]"); + } + + return "\"\""; + } diff --git a/scripts/base/utils/numbers.bro b/scripts/base/utils/numbers.bro index da8c15d7a0..d2adb49ea2 100644 --- a/scripts/base/utils/numbers.bro +++ b/scripts/base/utils/numbers.bro @@ -1,10 +1,26 @@ -## Extract the first integer found in the given string. -## If no integer can be found, 0 is returned. -function extract_count(s: string): count + +## Extract an integer from a string. +## +## s: The string to search for a number. +## +## get_first: Provide `F` if you would like the last number found. +## +## Returns: The request integer from the given string or 0 if +## no integer was found. +function extract_count(s: string, get_first: bool &default=T): count { - local parts = split_string_n(s, /[0-9]+/, T, 1); - if ( 1 in parts ) - return to_count(parts[1]); + local extract_num_pattern = /[0-9]+/; + if ( get_first ) + { + local first_parts = split_string_n(s, extract_num_pattern, T, 1); + if ( 1 in first_parts ) + return to_count(first_parts[1]); + } else - return 0; + { + local last_parts = split_string_all(s, extract_num_pattern); + if ( |last_parts| > 1 ) + return to_count(last_parts[|last_parts|-2]); + } + return 0; } diff --git a/src/Attr.cc b/src/Attr.cc index 4bfbcf2ad7..14b00bd0d7 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -375,12 +375,33 @@ void Attributes::CheckAttr(Attr* a) case ATTR_EXPIRE_READ: case ATTR_EXPIRE_WRITE: case ATTR_EXPIRE_CREATE: + { if ( type->Tag() != TYPE_TABLE ) { Error("expiration only applicable to tables"); break; } + int num_expires = 0; + if ( attrs ) + { + loop_over_list(*attrs, i) + { + Attr* a = (*attrs)[i]; + if ( a->Tag() == ATTR_EXPIRE_READ || + a->Tag() == ATTR_EXPIRE_WRITE || + a->Tag() == ATTR_EXPIRE_CREATE ) + num_expires++; + } + } + + if ( num_expires > 1 ) + { + Error("set/table can only have one of &read_expire, &write_expire, &create_expire"); + break; + } + } + #if 0 //### not easy to test this w/o knowing the ID. if ( ! IsGlobal() ) diff --git a/src/Desc.cc b/src/Desc.cc index 3cdc35bfe5..4654454129 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -351,3 +351,24 @@ void ODesc::Clear() } } +bool ODesc::PushType(const BroType* type) + { + auto res = encountered_types.insert(type); + return std::get<1>(res); + } + +bool ODesc::PopType(const BroType* type) + { + size_t res = encountered_types.erase(type); + return (res == 1); + } + +bool ODesc::FindType(const BroType* type) + { + auto res = encountered_types.find(type); + + if ( res != encountered_types.end() ) + return true; + + return false; + } diff --git a/src/Desc.h b/src/Desc.h index cc6ba3a662..df850378c4 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -23,6 +23,7 @@ typedef enum { class BroFile; class IPAddr; class IPPrefix; +class BroType; class ODesc { public: @@ -140,6 +141,12 @@ public: void Clear(); + // Used to determine recursive types. Records push their types on here; + // if the same type (by address) is re-encountered, processing aborts. + bool PushType(const BroType* type); + bool PopType(const BroType* type); + bool FindType(const BroType* type); + protected: void Indent(); @@ -190,6 +197,8 @@ protected: int do_flush; int include_stats; int indent_with_spaces; + + std::set encountered_types; }; #endif diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index d31203c9d3..007e08349c 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -1,7 +1,7 @@ #include "PrefixTable.h" #include "Reporter.h" -inline static prefix_t* make_prefix(const IPAddr& addr, int width) +prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width) { prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); @@ -13,9 +13,14 @@ inline static prefix_t* make_prefix(const IPAddr& addr, int width) return prefix; } +IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix) + { + return IPPrefix(IPAddr(IPv6, reinterpret_cast(&prefix->add.sin6), IPAddr::Network), prefix->bitlen, 1); + } + void* PrefixTable::Insert(const IPAddr& addr, int width, void* data) { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = patricia_lookup(tree, prefix); Deref_Prefix(prefix); @@ -57,13 +62,39 @@ void* PrefixTable::Insert(const Val* value, void* data) } } +list> PrefixTable::FindAll(const IPAddr& addr, int width) const + { + std::list> out; + prefix_t* prefix = MakePrefix(addr, width); + + int elems = 0; + patricia_node_t** list = nullptr; + + patricia_search_all(tree, prefix, &list, &elems); + + for ( int i = 0; i < elems; ++i ) + out.push_back(std::make_tuple(PrefixToIPPrefix(list[i]->prefix), list[i]->data)); + + Deref_Prefix(prefix); + free(list); + return out; + } + +list> PrefixTable::FindAll(const SubNetVal* value) const + { + return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); + } + void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = exact ? patricia_search_exact(tree, prefix) : patricia_search_best(tree, prefix); + int elems = 0; + patricia_node_t** list = nullptr; + Deref_Prefix(prefix); return node ? node->data : 0; } @@ -94,7 +125,7 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const void* PrefixTable::Remove(const IPAddr& addr, int width) { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = patricia_search_exact(tree, prefix); Deref_Prefix(prefix); diff --git a/src/PrefixTable.h b/src/PrefixTable.h index 2e5f43a0a8..6606b77e81 100644 --- a/src/PrefixTable.h +++ b/src/PrefixTable.h @@ -36,6 +36,10 @@ public: void* Lookup(const IPAddr& addr, int width, bool exact = false) const; void* Lookup(const Val* value, bool exact = false) const; + // Returns list of all found matches or empty list otherwise. + list> FindAll(const IPAddr& addr, int width) const; + list> FindAll(const SubNetVal* value) const; + // Returns pointer to data or nil if not found. void* Remove(const IPAddr& addr, int width); void* Remove(const Val* value); @@ -45,6 +49,10 @@ public: iterator InitIterator(); void* GetNext(iterator* i); +private: + static prefix_t* MakePrefix(const IPAddr& addr, int width); + static IPPrefix PrefixToIPPrefix(prefix_t* p); + patricia_tree_t* tree; }; diff --git a/src/Type.cc b/src/Type.cc index 75f1f445df..1a6a4d36b8 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1045,6 +1045,8 @@ TypeDecl* RecordType::FieldDecl(int field) void RecordType::Describe(ODesc* d) const { + d->PushType(this); + if ( d->IsReadable() ) { if ( d->IsShort() && GetName().size() ) @@ -1064,10 +1066,13 @@ void RecordType::Describe(ODesc* d) const d->Add(int(Tag())); DescribeFields(d); } + + d->PopType(this); } void RecordType::DescribeReST(ODesc* d, bool roles_only) const { + d->PushType(this); d->Add(":bro:type:`record`"); if ( num_fields == 0 ) @@ -1075,6 +1080,7 @@ void RecordType::DescribeReST(ODesc* d, bool roles_only) const d->NL(); DescribeFieldsReST(d, false); + d->PopType(this); } const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) @@ -1129,7 +1135,12 @@ void RecordType::DescribeFields(ODesc* d) const const TypeDecl* td = FieldDecl(i); d->Add(td->id); d->Add(":"); - td->type->Describe(d); + + if ( d->FindType(td->type) ) + d->Add(""); + else + td->type->Describe(d); + d->Add(";"); } } @@ -1170,7 +1181,11 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const } const TypeDecl* td = FieldDecl(i); - td->DescribeReST(d); + + if ( d->FindType(td->type) ) + d->Add(""); + else + td->DescribeReST(d); if ( func_args ) continue; diff --git a/src/Type.h b/src/Type.h index e3d1167166..9f7a439986 100644 --- a/src/Type.h +++ b/src/Type.h @@ -182,6 +182,7 @@ public: CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); return (const FuncType*) this; } + FuncType* AsFuncType() { CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); @@ -201,7 +202,7 @@ public: } const VectorType* AsVectorType() const - { + { CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType"); return (VectorType*) this; } @@ -219,19 +220,19 @@ public: } VectorType* AsVectorType() - { + { CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType"); return (VectorType*) this; } const TypeType* AsTypeType() const - { + { CHECK_TYPE_TAG(TYPE_TYPE, "BroType::AsTypeType"); return (TypeType*) this; } TypeType* AsTypeType() - { + { CHECK_TYPE_TAG(TYPE_TYPE, "BroType::AsTypeType"); return (TypeType*) this; } diff --git a/src/Val.cc b/src/Val.cc index 01a849c639..ed4ca40e14 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1787,7 +1787,16 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) { TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index); if ( v ) + { + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) + { + v->SetExpireAccess(network_time); + if ( LoggingAccess() && expire_time ) + ReadOperation(index, v); + } + return v->Value() ? v->Value() : this; + } if ( ! use_default_val ) return 0; @@ -1810,9 +1819,7 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) if ( v ) { - if ( attrs && - ! (attrs->FindAttr(ATTR_EXPIRE_WRITE) || - attrs->FindAttr(ATTR_EXPIRE_CREATE)) ) + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) { v->SetExpireAccess(network_time); if ( LoggingAccess() && expire_time ) @@ -1833,6 +1840,57 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) return def; } +VectorVal* TableVal::LookupSubnets(const SubNetVal* search) + { + if ( ! subnets ) + reporter->InternalError("LookupSubnets called on wrong table type"); + + VectorVal* result = new VectorVal(internal_type("subnet_vec")->AsVectorType()); + + auto matches = subnets->FindAll(search); + for ( auto element : matches ) + { + SubNetVal* s = new SubNetVal(get<0>(element)); + result->Assign(result->Size(), s); + } + + return result; + } + +TableVal* TableVal::LookupSubnetValues(const SubNetVal* search) + { + if ( ! subnets ) + reporter->InternalError("LookupSubnetValues called on wrong table type"); + + TableVal* nt = new TableVal(this->Type()->Ref()->AsTableType()); + + auto matches = subnets->FindAll(search); + for ( auto element : matches ) + { + SubNetVal* s = new SubNetVal(get<0>(element)); + TableEntryVal* entry = reinterpret_cast(get<1>(element)); + + if ( entry && entry->Value() ) + nt->Assign(s, entry->Value()->Ref()); + else + nt->Assign(s, 0); // set + + if ( entry ) + { + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) + { + entry->SetExpireAccess(network_time); + if ( LoggingAccess() && expire_time ) + ReadOperation(s, entry); + } + } + + Unref(s); // assign does not consume index + } + + return nt; + } + bool TableVal::UpdateTimestamp(Val* index) { TableEntryVal* v; @@ -1854,7 +1912,7 @@ bool TableVal::UpdateTimestamp(Val* index) return false; v->SetExpireAccess(network_time); - if ( attrs->FindAttr(ATTR_EXPIRE_READ) ) + if ( LoggingAccess() && attrs->FindAttr(ATTR_EXPIRE_READ) ) ReadOperation(index, v); return true; @@ -2478,7 +2536,7 @@ bool TableVal::DoUnserialize(UnserialInfo* info) } // If necessary, activate the expire timer. - if ( attrs) + if ( attrs ) { CheckExpireAttr(ATTR_EXPIRE_READ); CheckExpireAttr(ATTR_EXPIRE_WRITE); diff --git a/src/Val.h b/src/Val.h index 86d75af94a..a49a2e2235 100644 --- a/src/Val.h +++ b/src/Val.h @@ -790,6 +790,16 @@ public: // need to Ref/Unref it when calling the default function. Val* Lookup(Val* index, bool use_default_val = true); + // For a table[subnet]/set[subnet], return all subnets that cover + // the given subnet. + // Causes an internal error if called for any other kind of table. + VectorVal* LookupSubnets(const SubNetVal* s); + + // For a set[subnet]/table[subnet], return a new table that only contains + // entries that cover the given subnet. + // Causes an internal error if called for any other kind of table. + TableVal* LookupSubnetValues(const SubNetVal* s); + // Sets the timestamp for the given index to network time. // Returns false if index does not exist. bool UpdateTimestamp(Val* index); @@ -814,6 +824,11 @@ public: int Size() const { return AsTable()->Length(); } int RecursiveSize() const; + // Returns the Prefix table used inside the table (if present). + // This allows us to do more direct queries to this specialized + // type that the general Table API does not allow. + const PrefixTable* Subnets() const { return subnets; } + void Describe(ODesc* d) const override; void InitTimer(double delay); diff --git a/src/analyzer/protocol/finger/Finger.cc b/src/analyzer/protocol/finger/Finger.cc index 6a5865383b..a9818ff7af 100644 --- a/src/analyzer/protocol/finger/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -54,7 +54,9 @@ void Finger_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig if ( long_cnt ) line = skip_whitespace(line+2, end_of_line); - const char* at = strchr_n(line, end_of_line, '@'); + assert(line <= end_of_line); + size_t n = end_of_line >= line ? end_of_line - line : 0; // just to be sure if assertions aren't on. + const char* at = reinterpret_cast(memchr(line, '@', n)); const char* host = 0; if ( ! at ) at = host = end_of_line; diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index 36c92ed6e6..490a9d2324 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -1209,7 +1209,15 @@ int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) const char* end_of_method = get_HTTP_token(line, end_of_line); if ( end_of_method == line ) + { + // something went wrong with get_HTTP_token + // perform a weak test to see if the string "HTTP/" + // is found at the end of the RequestLine + if ( end_of_line - 9 >= line && strncasecmp(end_of_line - 9, " HTTP/", 6) == 0 ) + goto bad_http_request_with_version; + goto error; + } rest = skip_whitespace(end_of_method, end_of_line); @@ -1230,6 +1238,10 @@ int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) return 1; +bad_http_request_with_version: + reporter->Weird(Conn(), "bad_HTTP_request_with_version"); + return 0; + error: reporter->Weird(Conn(), "bad_HTTP_request"); return 0; @@ -1370,7 +1382,7 @@ void HTTP_Analyzer::HTTP_Request() const char* method = (const char*) request_method->AsString()->Bytes(); int method_len = request_method->AsString()->Len(); - if ( strcasecmp_n(method_len, method, "CONNECT") == 0 ) + if ( strncasecmp(method, "CONNECT", method_len) == 0 ) connect_request = true; if ( http_request ) @@ -1564,7 +1576,7 @@ int HTTP_Analyzer::ExpectReplyMessageBody() const BroString* method = UnansweredRequestMethod(); - if ( method && strcasecmp_n(method->Len(), (const char*) (method->Bytes()), "HEAD") == 0 ) + if ( method && strncasecmp((const char*) (method->Bytes()), "HEAD", method->Len()) == 0 ) return HTTP_BODY_NOT_EXPECTED; if ( (reply_code >= 100 && reply_code < 200) || diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 8d57da3477..f668be921c 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -153,8 +153,10 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) else { const char* sys_type = line; - const char* colon = strchr_n(line, end_of_line, ':'); - const char* comma = strchr_n(line, end_of_line, ','); + assert(line <= end_of_line); + size_t n = end_of_line >= line ? end_of_line - line : 0; // just to be sure if assertions aren't on. + const char* colon = reinterpret_cast(memchr(line, ':', n)); + const char* comma = reinterpret_cast(memchr(line, ',', n)); if ( ! colon ) { BadReply(length, orig_line); diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index d968be09cf..bcdfe03248 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -148,7 +148,7 @@ void MIME_Mail::Undelivered(int len) int strcasecmp_n(data_chunk_t s, const char* t) { - return ::strcasecmp_n(s.length, s.data, t); + return strncasecmp(s.data, t, s.length); } int MIME_count_leading_lws(int len, const char* data) diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 2108401436..66710fb2bb 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -19,6 +19,9 @@ refine flow MySQL_Flow += { function proc_mysql_handshake_response_packet(msg: Handshake_Response_Packet): bool %{ + if ( ${msg.version} == 9 || ${msg.version == 10} ) + connection()->bro_analyzer()->ProtocolConfirmation(); + if ( mysql_handshake ) { if ( ${msg.version} == 10 ) diff --git a/src/analyzer/protocol/smtp/SMTP.cc b/src/analyzer/protocol/smtp/SMTP.cc index 6a19848d86..efc55ecc74 100644 --- a/src/analyzer/protocol/smtp/SMTP.cc +++ b/src/analyzer/protocol/smtp/SMTP.cc @@ -809,7 +809,7 @@ void SMTP_Analyzer::ProcessExtension(int ext_len, const char* ext) if ( ! ext ) return; - if ( ! strcasecmp_n(ext_len, ext, "PIPELINING") ) + if ( ! strncasecmp(ext, "PIPELINING", ext_len) ) pipelining = 1; } @@ -819,7 +819,7 @@ int SMTP_Analyzer::ParseCmd(int cmd_len, const char* cmd) return -1; for ( int code = SMTP_CMD_EHLO; code < SMTP_CMD_LAST; ++code ) - if ( ! strcasecmp_n(cmd_len, cmd, smtp_cmd_word[code - SMTP_CMD_EHLO]) ) + if ( ! strncasecmp(cmd, smtp_cmd_word[code - SMTP_CMD_EHLO], cmd_len) ) return code; return -1; diff --git a/src/bro.bif b/src/bro.bif index b0465b9609..2c55c2bc95 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1031,6 +1031,72 @@ function clear_table%(v: any%): any return 0; %} +## Gets all subnets that contain a given subnet from a set/table[subnet] +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: All the keys of the set or table that cover the subnet searched for. +function matching_subnets%(search: subnet, t: any%): subnet_vec + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("matching_subnets needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + return t->AsTableVal()->LookupSubnets(search); + %} + +## For a set[subnet]/table[subnet], create a new table that contains all entries that +## contain a given subnet. +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: A new table that contains all the entries that cover the subnet searched for. +function filter_subnet_table%(search: subnet, t: any%): any + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("filter_subnet_table needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + return t->AsTableVal()->LookupSubnetValues(search); + %} + +## Checks if a specific subnet is a member of a set/table[subnet]. +## In difference to the ``in`` operator, this performs an exact match, not +## a longest prefix match. +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: True if the exact subnet is a member, false otherwise. +function check_subnet%(search: subnet, t: any%): bool + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("check_subnet needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + const PrefixTable* pt = t->AsTableVal()->Subnets(); + if ( ! pt ) + { + reporter->Error("check_subnet encountered nonexisting prefix table."); + return nullptr; + } + + void* res = pt->Lookup(search, true); + + return new Val (res != nullptr, TYPE_BOOL); + %} + ## Checks whether two objects reference the same internal object. This function ## uses equality comparison of C++ raw pointer values to determine if the two ## objects are the same. @@ -2078,6 +2144,33 @@ function is_v6_addr%(a: addr%): bool return new Val(0, TYPE_BOOL); %} +## Returns whether a subnet specification is IPv4 or not. +## +## s: the subnet to check. +## +## Returns: true if *a* is an IPv4 subnet, else false. +function is_v4_subnet%(s: subnet%): bool + %{ + if ( s->AsSubNet().Prefix().GetFamily() == IPv4 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + +## Returns whether a subnet specification is IPv6 or not. +## +## s: the subnet to check. +## +## Returns: true if *a* is an IPv6 subnet, else false. +function is_v6_subnet%(s: subnet%): bool + %{ + if ( s->AsSubNet().Prefix().GetFamily() == IPv6 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + + # =========================================================================== # # Conversion @@ -2368,6 +2461,44 @@ function to_subnet%(sn: string%): subnet return ret; %} +## Converts a :bro:type:`addr` to a :bro:type:`subnet`. +## +## a: The address to convert. +## +## Returns: The *a* address as a :bro:type:`subnet`. +## +## .. bro:see:: to_subset +function addr_to_subnet%(a: addr%): subnet + %{ + int width = (a->AsAddr().GetFamily() == IPv4 ? 32 : 128); + return new SubNetVal(a->AsAddr(), width); + %} + +## Converts a :bro:type:`subnet` to a :bro:type:`addr` by +## extracting the prefix. +## +## s: The subnet to convert. +## +## Returns: The *s* subnet as a :bro:type:`addr`. +## +## .. bro:see:: to_subset +function subnet_to_addr%(sn: subnet%): addr + %{ + return new AddrVal(sn->Prefix()); + %} + +## Returns the width of a :bro:type:`subnet`. +## +## s: The subnet to convert. +## +## Returns: The width of the subnet. +## +## .. bro:see:: to_subset +function subnet_width%(sn: subnet%): count + %{ + return new Val(sn->Width(), TYPE_COUNT); + %} + ## Converts a :bro:type:`string` to a :bro:type:`double`. ## ## str: The :bro:type:`string` to convert. diff --git a/src/broker/CMakeLists.txt b/src/broker/CMakeLists.txt index 7329bfd46e..988855cafb 100644 --- a/src/broker/CMakeLists.txt +++ b/src/broker/CMakeLists.txt @@ -10,8 +10,8 @@ if ( ROCKSDB_INCLUDE_DIR ) include_directories(BEFORE ${ROCKSDB_INCLUDE_DIR}) endif () -include_directories(BEFORE ${LIBCAF_INCLUDE_DIR_CORE}) -include_directories(BEFORE ${LIBCAF_INCLUDE_DIR_IO}) +include_directories(BEFORE ${CAF_INCLUDE_DIR_CORE}) +include_directories(BEFORE ${CAF_INCLUDE_DIR_IO}) set(comm_SRCS Data.cc diff --git a/src/patricia.c b/src/patricia.c index c4815b40ec..552019be09 100644 --- a/src/patricia.c +++ b/src/patricia.c @@ -1,3 +1,8 @@ +/* + * Johanna Amann + * + * Added patricia_search_all function. + */ /* * Dave Plonka * @@ -61,6 +66,7 @@ static char copyright[] = #include /* memcpy, strchr, strlen */ #include /* for inet_addr */ #include /* for u_short, etc. */ +#include #include "patricia.h" @@ -561,6 +567,105 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) return (NULL); } +bool +patricia_search_all (patricia_tree_t *patricia, prefix_t *prefix, patricia_node_t ***list, int *n) +{ + patricia_node_t *node; + patricia_node_t *stack[PATRICIA_MAXBITS + 1]; + u_char *addr; + u_int bitlen; + int cnt = 0; + + assert (patricia); + assert (prefix); + assert (prefix->bitlen <= patricia->maxbits); + assert (n); + assert (list); + assert (*list == NULL); + + *n = 0; + + if (patricia->head == NULL) + return (NULL); + + node = patricia->head; + addr = prefix_touchar (prefix); + bitlen = prefix->bitlen; + + while (node->bit < bitlen) { + + if (node->prefix) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: push %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + stack[cnt++] = node; + } + + if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { +#ifdef PATRICIA_DEBUG + if (node->prefix) + fprintf (stderr, "patricia_search_all: take right %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: take right at %d\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->r; + } else { +#ifdef PATRICIA_DEBUG + if (node->prefix) + fprintf (stderr, "patricia_search_all: take left %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: take left at %d\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->l; + } + + if (node == NULL) + break; + } + + if (node && node->prefix) + stack[cnt++] = node; + +#ifdef PATRICIA_DEBUG + if (node == NULL) + fprintf (stderr, "patricia_search_all: stop at null\n"); + else if (node->prefix) + fprintf (stderr, "patricia_search_all: stop at %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: stop at %d\n", node->bit); +#endif /* PATRICIA_DEBUG */ + + if (cnt <= 0) + return false; + + // ok, now we have an upper bound of how much we can return. Let's just alloc that... + patricia_node_t **outlist = calloc(cnt, sizeof(patricia_node_t*)); + + while (--cnt >= 0) { + node = stack[cnt]; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: pop %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + if (comp_with_mask (prefix_tochar (node->prefix), prefix_tochar (prefix), node->prefix->bitlen)) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: found %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + outlist[*n] = node; + (*n)++; + } + } + *list = outlist; + return (*n == 0); +} + /* if inclusive != 0, "best" may be the given prefix itself */ patricia_node_t * diff --git a/src/patricia.h b/src/patricia.h index dc67226362..3a9badd29a 100644 --- a/src/patricia.h +++ b/src/patricia.h @@ -104,6 +104,7 @@ typedef struct _patricia_tree_t { patricia_node_t *patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix); +bool patricia_search_all (patricia_tree_t *patricia, prefix_t *prefix, patricia_node_t ***list, int *n); patricia_node_t *patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix); patricia_node_t * patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusive); diff --git a/src/util.cc b/src/util.cc index 6a03859a3c..0ea89beb90 100644 --- a/src/util.cc +++ b/src/util.cc @@ -323,24 +323,6 @@ string to_upper(const std::string& s) return t; } -const char* strchr_n(const char* s, const char* end_of_s, char ch) - { - for ( ; s < end_of_s; ++s ) - if ( *s == ch ) - return s; - - return 0; - } - -const char* strrchr_n(const char* s, const char* end_of_s, char ch) - { - for ( --end_of_s; end_of_s >= s; --end_of_s ) - if ( *end_of_s == ch ) - return end_of_s; - - return 0; - } - int decode_hex(char ch) { if ( ch >= '0' && ch <= '9' ) @@ -382,27 +364,6 @@ const char* strpbrk_n(size_t len, const char* s, const char* charset) return 0; } -int strcasecmp_n(int b_len, const char* b, const char* t) - { - if ( ! b ) - return -1; - - int i; - for ( i = 0; i < b_len; ++i ) - { - char c1 = islower(b[i]) ? toupper(b[i]) : b[i]; - char c2 = islower(t[i]) ? toupper(t[i]) : t[i]; - - if ( c1 < c2 ) - return -1; - - if ( c1 > c2 ) - return 1; - } - - return t[i] != '\0'; - } - #ifndef HAVE_STRCASESTR // This code is derived from software contributed to BSD by Chris Torek. char* strcasestr(const char* s, const char* find) @@ -421,7 +382,7 @@ char* strcasestr(const char* s, const char* find) if ( sc == 0 ) return 0; } while ( char(tolower((unsigned char) sc)) != c ); - } while ( strcasecmp_n(len, s, find) != 0 ); + } while ( strncasecmp(s, find, len) != 0 ); --s; } diff --git a/src/util.h b/src/util.h index 901bb44d1c..15d1a059cd 100644 --- a/src/util.h +++ b/src/util.h @@ -143,11 +143,8 @@ extern char* get_word(char*& s); extern void get_word(int length, const char* s, int& pwlen, const char*& pw); extern void to_upper(char* s); extern std::string to_upper(const std::string& s); -extern const char* strchr_n(const char* s, const char* end_of_s, char ch); -extern const char* strrchr_n(const char* s, const char* end_of_s, char ch); extern int decode_hex(char ch); extern unsigned char encode_hex(int h); -extern int strcasecmp_n(int s_len, const char* s, const char* t); #ifndef HAVE_STRCASESTR extern char* strcasestr(const char* s, const char* find); #endif diff --git a/testing/btest/Baseline/bifs.check_subnet/output b/testing/btest/Baseline/bifs.check_subnet/output new file mode 100644 index 0000000000..d2f111f555 --- /dev/null +++ b/testing/btest/Baseline/bifs.check_subnet/output @@ -0,0 +1,8 @@ +in says: 10.2.0.2/32 is member +check_subnet says: 10.2.0.2/32 is no member +in says: 10.2.0.2/31 is member +check_subnet says: 10.2.0.2/31 is member +in says: 10.0.0.0/9 is member +check_subnet says: 10.0.0.0/9 is no member +in says: 10.0.0.0/8 is member +check_subnet says: 10.0.0.0/8 is member diff --git a/testing/btest/Baseline/bifs.filter_subnet_table/output b/testing/btest/Baseline/bifs.filter_subnet_table/output new file mode 100644 index 0000000000..d86ca621a5 --- /dev/null +++ b/testing/btest/Baseline/bifs.filter_subnet_table/output @@ -0,0 +1,20 @@ +{ +10.0.0.0/8, +10.2.0.2/31, +10.2.0.0/16 +} +{ +[10.0.0.0/8] = a, +[10.2.0.2/31] = c, +[10.2.0.0/16] = b +} +{ +[10.0.0.0/8] = a, +[10.3.0.0/16] = e +} +{ + +} +{ + +} diff --git a/testing/btest/Baseline/bifs.matching_subnets/output b/testing/btest/Baseline/bifs.matching_subnets/output new file mode 100644 index 0000000000..e051d89b79 --- /dev/null +++ b/testing/btest/Baseline/bifs.matching_subnets/output @@ -0,0 +1,18 @@ +{ +10.0.0.0/8, +10.3.0.0/16, +10.2.0.2/31, +2607:f8b0:4007:807::/64, +10.2.0.0/16, +5.2.0.0/32, +5.5.0.0/25, +10.1.0.0/16, +5.0.0.0/8, +2607:f8b0:4007:807::200e/128, +7.2.0.0/32, +2607:f8b0:4008:807::/64 +} +[10.2.0.2/31, 10.2.0.0/16, 10.0.0.0/8] +[2607:f8b0:4007:807::200e/128, 2607:f8b0:4007:807::/64] +[] +[10.0.0.0/8] diff --git a/testing/btest/Baseline/bifs.subnet_to_addr/error b/testing/btest/Baseline/bifs.subnet_to_addr/error new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/bifs.subnet_to_addr/output b/testing/btest/Baseline/bifs.subnet_to_addr/output new file mode 100644 index 0000000000..8c89b3920a --- /dev/null +++ b/testing/btest/Baseline/bifs.subnet_to_addr/output @@ -0,0 +1,3 @@ +subnet_to_addr(0.0.0.0/32) = 0.0.0.0 (SUCCESS) +subnet_to_addr(1.2.0.0/16) = 1.2.0.0 (SUCCESS) +subnet_to_addr(2607:f8b0:4005:803::200e/128) = 2607:f8b0:4005:803::200e (SUCCESS) diff --git a/testing/btest/Baseline/bifs.subnet_version/out b/testing/btest/Baseline/bifs.subnet_version/out new file mode 100644 index 0000000000..328bff6687 --- /dev/null +++ b/testing/btest/Baseline/bifs.subnet_version/out @@ -0,0 +1,4 @@ +T +F +F +T diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 6a240c88ad..85fe19eb96 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2015-08-31-05-07-15 +#open 2016-02-17-20-30-50 #fields name #types string scripts/base/init-bare.bro @@ -188,6 +188,30 @@ scripts/base/init-default.bro scripts/base/frameworks/sumstats/non-cluster.bro scripts/base/frameworks/tunnels/__load__.bro scripts/base/frameworks/tunnels/main.bro + scripts/base/frameworks/openflow/__load__.bro + scripts/base/frameworks/openflow/consts.bro + scripts/base/frameworks/openflow/types.bro + scripts/base/frameworks/openflow/main.bro + scripts/base/frameworks/openflow/plugins/__load__.bro + scripts/base/frameworks/openflow/plugins/ryu.bro + scripts/base/utils/json.bro + scripts/base/frameworks/openflow/plugins/log.bro + scripts/base/frameworks/openflow/plugins/broker.bro + scripts/base/frameworks/openflow/non-cluster.bro + scripts/base/frameworks/netcontrol/__load__.bro + scripts/base/frameworks/netcontrol/types.bro + scripts/base/frameworks/netcontrol/main.bro + scripts/base/frameworks/netcontrol/plugin.bro + scripts/base/frameworks/netcontrol/plugins/__load__.bro + scripts/base/frameworks/netcontrol/plugins/debug.bro + scripts/base/frameworks/netcontrol/plugins/openflow.bro + scripts/base/frameworks/netcontrol/plugins/packetfilter.bro + scripts/base/frameworks/netcontrol/plugins/broker.bro + scripts/base/frameworks/netcontrol/plugins/acld.bro + scripts/base/frameworks/netcontrol/drop.bro + scripts/base/frameworks/netcontrol/shunt.bro + scripts/base/frameworks/netcontrol/catch-and-release.bro + scripts/base/frameworks/netcontrol/non-cluster.bro scripts/base/protocols/conn/__load__.bro scripts/base/protocols/conn/main.bro scripts/base/protocols/conn/contents.bro @@ -273,4 +297,4 @@ scripts/base/init-default.bro scripts/base/misc/find-checksum-offloading.bro scripts/base/misc/find-filtered-trace.bro scripts/policy/misc/loaded-scripts.bro -#close 2015-08-31-05-07-15 +#close 2016-02-17-20-30-50 diff --git a/testing/btest/Baseline/coverage.find-bro-logs/out b/testing/btest/Baseline/coverage.find-bro-logs/out index 3deca99848..0b2a9445c1 100644 --- a/testing/btest/Baseline/coverage.find-bro-logs/out +++ b/testing/btest/Baseline/coverage.find-bro-logs/out @@ -23,8 +23,12 @@ loaded_scripts modbus modbus_register_change mysql +net_control +netcontrol_drop +netcontrol_shunt notice notice_alarm +open_flow packet_filter pe radius diff --git a/testing/btest/Baseline/coverage.init-default/missing_loads b/testing/btest/Baseline/coverage.init-default/missing_loads index b5fbf644d5..826ca4af87 100644 --- a/testing/btest/Baseline/coverage.init-default/missing_loads +++ b/testing/btest/Baseline/coverage.init-default/missing_loads @@ -3,6 +3,8 @@ -./frameworks/cluster/nodes/worker.bro -./frameworks/cluster/setup-connections.bro -./frameworks/intel/cluster.bro +-./frameworks/netcontrol/cluster.bro -./frameworks/notice/cluster.bro +-./frameworks/openflow/cluster.bro -./frameworks/packet-filter/cluster.bro -./frameworks/sumstats/cluster.bro diff --git a/testing/btest/Baseline/language.expire_multiple-2/output b/testing/btest/Baseline/language.expire_multiple-2/output new file mode 100644 index 0000000000..ffcdb6ff80 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple-2/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple-2/expire_multiple.test, line 2: set/table can only have one of &read_expire, &write_expire, &create_expire (&write_expire=1.0 sec, &create_expire=3.0 secs) diff --git a/testing/btest/Baseline/language.expire_multiple-3/output b/testing/btest/Baseline/language.expire_multiple-3/output new file mode 100644 index 0000000000..1dc2e3e765 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple-3/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple-3/expire_multiple.test, line 2: set/table can only have one of &read_expire, &write_expire, &create_expire (&write_expire=1.0 sec, &read_expire=3.0 secs) diff --git a/testing/btest/Baseline/language.expire_multiple/output b/testing/btest/Baseline/language.expire_multiple/output new file mode 100644 index 0000000000..a616c84de7 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple/expire_multiple.test, line 4: set/table can only have one of &read_expire, &write_expire, &create_expire (&create_expire=1.0 sec, &read_expire=1.0 sec) diff --git a/testing/btest/Baseline/language.expire_subnet/output b/testing/btest/Baseline/language.expire_subnet/output new file mode 100644 index 0000000000..70ca3943cb --- /dev/null +++ b/testing/btest/Baseline/language.expire_subnet/output @@ -0,0 +1,27 @@ +All: +0 --> zero +2 --> two +4 --> four +1 --> one +3 --> three +192.168.3.0/24 --> three +192.168.0.0/16 --> zero +192.168.4.0/24 --> four +192.168.1.0/24 --> one +192.168.2.0/24 --> two +Time: 0 secs + +Accessed table nums: two; three +Accessed table nets: two; three, zero +Time: 7.0 secs 518.0 msecs 828.0 usecs + +Expired Num: 0 --> zero at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 4 --> four at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 1 --> one at 8.0 secs 835.0 msecs 30.0 usecs +Expired Subnet: 192.168.4.0/24 --> four at 8.0 secs 835.0 msecs 30.0 usecs +Expired Subnet: 192.168.1.0/24 --> one at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 2 --> two at 15.0 secs 150.0 msecs 681.0 usecs +Expired Num: 3 --> three at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.3.0/24 --> three at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.0.0/16 --> zero at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.2.0/24 --> two at 15.0 secs 150.0 msecs 681.0 usecs diff --git a/testing/btest/Baseline/language.record-function-recursion/out b/testing/btest/Baseline/language.record-function-recursion/out new file mode 100644 index 0000000000..b143d5339b --- /dev/null +++ b/testing/btest/Baseline/language.record-function-recursion/out @@ -0,0 +1,2 @@ +[id=, inner=] +record { id:count; inner:record { create:function(input:;) : string; }; } diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 7a5718b1db..25808a20d8 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -164,8 +164,12 @@ 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice_alarm, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=packet_filter, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> @@ -199,8 +203,12 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) -> @@ -220,7 +228,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Cluster::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Communication::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Conn::LOG)) -> @@ -235,8 +243,12 @@ 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Intel::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (KRB::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Modbus::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::DROP)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::SHUNT)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Notice::ALARM_LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Notice::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (OpenFlow::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (PE::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (PacketFilter::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (RADIUS::LOG)) -> @@ -270,8 +282,12 @@ 0.000000 MetaHookPost CallFunction(Log::add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::add_filter, , (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> @@ -305,8 +321,12 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) -> @@ -326,7 +346,9 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(NetControl::check_plugins, , ()) -> +0.000000 MetaHookPost CallFunction(NetControl::init, , ()) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, , ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::build, , ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, )) -> @@ -361,6 +383,7 @@ 0.000000 MetaHookPost CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) -> 0.000000 MetaHookPost DrainEvents() -> 0.000000 MetaHookPost LoadFile(../main) -> -1 +0.000000 MetaHookPost LoadFile(../plugin) -> -1 0.000000 MetaHookPost LoadFile(./Bro_ARP.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_AYIYA.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_AsciiReader.ascii.bif.bro) -> -1 @@ -434,13 +457,16 @@ 0.000000 MetaHookPost LoadFile(./Bro_X509.functions.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_X509.types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_ZIP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./acld) -> -1 0.000000 MetaHookPost LoadFile(./addrs) -> -1 0.000000 MetaHookPost LoadFile(./analyzer.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./average) -> -1 0.000000 MetaHookPost LoadFile(./bloom-filter.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./bro.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./broker) -> -1 0.000000 MetaHookPost LoadFile(./broxygen.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./cardinality-counter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./catch-and-release) -> -1 0.000000 MetaHookPost LoadFile(./comm.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./const.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./consts) -> -1 @@ -448,6 +474,8 @@ 0.000000 MetaHookPost LoadFile(./contents) -> -1 0.000000 MetaHookPost LoadFile(./data.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./dcc-send) -> -1 +0.000000 MetaHookPost LoadFile(./debug) -> -1 +0.000000 MetaHookPost LoadFile(./drop) -> -1 0.000000 MetaHookPost LoadFile(./entities) -> -1 0.000000 MetaHookPost LoadFile(./event.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./exec) -> -1 @@ -463,6 +491,7 @@ 0.000000 MetaHookPost LoadFile(./input) -> -1 0.000000 MetaHookPost LoadFile(./input.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./last) -> -1 +0.000000 MetaHookPost LoadFile(./log) -> -1 0.000000 MetaHookPost LoadFile(./logging.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./magic) -> -1 0.000000 MetaHookPost LoadFile(./main) -> -1 @@ -473,14 +502,19 @@ 0.000000 MetaHookPost LoadFile(./mozilla-ca-list) -> -1 0.000000 MetaHookPost LoadFile(./netstats) -> -1 0.000000 MetaHookPost LoadFile(./non-cluster) -> -1 +0.000000 MetaHookPost LoadFile(./openflow) -> -1 +0.000000 MetaHookPost LoadFile(./packetfilter) -> -1 0.000000 MetaHookPost LoadFile(./patterns) -> -1 +0.000000 MetaHookPost LoadFile(./plugin) -> -1 0.000000 MetaHookPost LoadFile(./plugins) -> -1 0.000000 MetaHookPost LoadFile(./polling) -> -1 0.000000 MetaHookPost LoadFile(./postprocessors) -> -1 0.000000 MetaHookPost LoadFile(./reporter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./ryu) -> -1 0.000000 MetaHookPost LoadFile(./sample) -> -1 0.000000 MetaHookPost LoadFile(./scp) -> -1 0.000000 MetaHookPost LoadFile(./sftp) -> -1 +0.000000 MetaHookPost LoadFile(./shunt) -> -1 0.000000 MetaHookPost LoadFile(./site) -> -1 0.000000 MetaHookPost LoadFile(./std-dev) -> -1 0.000000 MetaHookPost LoadFile(./store.bif.bro) -> -1 @@ -489,6 +523,7 @@ 0.000000 MetaHookPost LoadFile(./thresholds) -> -1 0.000000 MetaHookPost LoadFile(./top-k.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./topk) -> -1 +0.000000 MetaHookPost LoadFile(./types) -> -1 0.000000 MetaHookPost LoadFile(./types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./types.bro) -> -1 0.000000 MetaHookPost LoadFile(./unique) -> -1 @@ -548,14 +583,17 @@ 0.000000 MetaHookPost LoadFile(base<...>/input.bif) -> -1 0.000000 MetaHookPost LoadFile(base<...>/intel) -> -1 0.000000 MetaHookPost LoadFile(base<...>/irc) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/json) -> -1 0.000000 MetaHookPost LoadFile(base<...>/krb) -> -1 0.000000 MetaHookPost LoadFile(base<...>/logging) -> -1 0.000000 MetaHookPost LoadFile(base<...>/logging.bif) -> -1 0.000000 MetaHookPost LoadFile(base<...>/main) -> -1 0.000000 MetaHookPost LoadFile(base<...>/modbus) -> -1 0.000000 MetaHookPost LoadFile(base<...>/mysql) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/netcontrol) -> -1 0.000000 MetaHookPost LoadFile(base<...>/notice) -> -1 0.000000 MetaHookPost LoadFile(base<...>/numbers) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/openflow) -> -1 0.000000 MetaHookPost LoadFile(base<...>/packet-filter) -> -1 0.000000 MetaHookPost LoadFile(base<...>/paths) -> -1 0.000000 MetaHookPost LoadFile(base<...>/patterns) -> -1 @@ -588,6 +626,7 @@ 0.000000 MetaHookPost LoadFile(base<...>/urls) -> -1 0.000000 MetaHookPost LoadFile(base<...>/utils) -> -1 0.000000 MetaHookPost LoadFile(base<...>/x509) -> -1 +0.000000 MetaHookPost QueueEvent(NetControl::init()) -> false 0.000000 MetaHookPost QueueEvent(bro_init()) -> false 0.000000 MetaHookPost QueueEvent(filter_change_tracking()) -> false 0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, , (Analyzer::ANALYZER_BACKDOOR)) @@ -756,8 +795,12 @@ 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice_alarm, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=packet_filter, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) @@ -791,8 +834,12 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) @@ -812,7 +859,7 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Conn::LOG)) @@ -827,8 +874,12 @@ 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Intel::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (KRB::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Modbus::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::DROP)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::SHUNT)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Notice::ALARM_LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Notice::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (OpenFlow::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (PE::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (PacketFilter::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (RADIUS::LOG)) @@ -862,8 +913,12 @@ 0.000000 MetaHookPre CallFunction(Log::add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::add_filter, , (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) @@ -897,8 +952,12 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) @@ -918,7 +977,9 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(NetControl::check_plugins, , ()) +0.000000 MetaHookPre CallFunction(NetControl::init, , ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, , ()) 0.000000 MetaHookPre CallFunction(PacketFilter::build, , ()) 0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, )) @@ -953,6 +1014,7 @@ 0.000000 MetaHookPre CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) 0.000000 MetaHookPre DrainEvents() 0.000000 MetaHookPre LoadFile(../main) +0.000000 MetaHookPre LoadFile(../plugin) 0.000000 MetaHookPre LoadFile(./Bro_ARP.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_AYIYA.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_AsciiReader.ascii.bif.bro) @@ -1026,13 +1088,16 @@ 0.000000 MetaHookPre LoadFile(./Bro_X509.functions.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_X509.types.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_ZIP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./acld) 0.000000 MetaHookPre LoadFile(./addrs) 0.000000 MetaHookPre LoadFile(./analyzer.bif.bro) 0.000000 MetaHookPre LoadFile(./average) 0.000000 MetaHookPre LoadFile(./bloom-filter.bif.bro) 0.000000 MetaHookPre LoadFile(./bro.bif.bro) +0.000000 MetaHookPre LoadFile(./broker) 0.000000 MetaHookPre LoadFile(./broxygen.bif.bro) 0.000000 MetaHookPre LoadFile(./cardinality-counter.bif.bro) +0.000000 MetaHookPre LoadFile(./catch-and-release) 0.000000 MetaHookPre LoadFile(./comm.bif.bro) 0.000000 MetaHookPre LoadFile(./const.bif.bro) 0.000000 MetaHookPre LoadFile(./consts) @@ -1040,6 +1105,8 @@ 0.000000 MetaHookPre LoadFile(./contents) 0.000000 MetaHookPre LoadFile(./data.bif.bro) 0.000000 MetaHookPre LoadFile(./dcc-send) +0.000000 MetaHookPre LoadFile(./debug) +0.000000 MetaHookPre LoadFile(./drop) 0.000000 MetaHookPre LoadFile(./entities) 0.000000 MetaHookPre LoadFile(./event.bif.bro) 0.000000 MetaHookPre LoadFile(./exec) @@ -1055,6 +1122,7 @@ 0.000000 MetaHookPre LoadFile(./input) 0.000000 MetaHookPre LoadFile(./input.bif.bro) 0.000000 MetaHookPre LoadFile(./last) +0.000000 MetaHookPre LoadFile(./log) 0.000000 MetaHookPre LoadFile(./logging.bif.bro) 0.000000 MetaHookPre LoadFile(./magic) 0.000000 MetaHookPre LoadFile(./main) @@ -1065,14 +1133,19 @@ 0.000000 MetaHookPre LoadFile(./mozilla-ca-list) 0.000000 MetaHookPre LoadFile(./netstats) 0.000000 MetaHookPre LoadFile(./non-cluster) +0.000000 MetaHookPre LoadFile(./openflow) +0.000000 MetaHookPre LoadFile(./packetfilter) 0.000000 MetaHookPre LoadFile(./patterns) +0.000000 MetaHookPre LoadFile(./plugin) 0.000000 MetaHookPre LoadFile(./plugins) 0.000000 MetaHookPre LoadFile(./polling) 0.000000 MetaHookPre LoadFile(./postprocessors) 0.000000 MetaHookPre LoadFile(./reporter.bif.bro) +0.000000 MetaHookPre LoadFile(./ryu) 0.000000 MetaHookPre LoadFile(./sample) 0.000000 MetaHookPre LoadFile(./scp) 0.000000 MetaHookPre LoadFile(./sftp) +0.000000 MetaHookPre LoadFile(./shunt) 0.000000 MetaHookPre LoadFile(./site) 0.000000 MetaHookPre LoadFile(./std-dev) 0.000000 MetaHookPre LoadFile(./store.bif.bro) @@ -1081,6 +1154,7 @@ 0.000000 MetaHookPre LoadFile(./thresholds) 0.000000 MetaHookPre LoadFile(./top-k.bif.bro) 0.000000 MetaHookPre LoadFile(./topk) +0.000000 MetaHookPre LoadFile(./types) 0.000000 MetaHookPre LoadFile(./types.bif.bro) 0.000000 MetaHookPre LoadFile(./types.bro) 0.000000 MetaHookPre LoadFile(./unique) @@ -1140,14 +1214,17 @@ 0.000000 MetaHookPre LoadFile(base<...>/input.bif) 0.000000 MetaHookPre LoadFile(base<...>/intel) 0.000000 MetaHookPre LoadFile(base<...>/irc) +0.000000 MetaHookPre LoadFile(base<...>/json) 0.000000 MetaHookPre LoadFile(base<...>/krb) 0.000000 MetaHookPre LoadFile(base<...>/logging) 0.000000 MetaHookPre LoadFile(base<...>/logging.bif) 0.000000 MetaHookPre LoadFile(base<...>/main) 0.000000 MetaHookPre LoadFile(base<...>/modbus) 0.000000 MetaHookPre LoadFile(base<...>/mysql) +0.000000 MetaHookPre LoadFile(base<...>/netcontrol) 0.000000 MetaHookPre LoadFile(base<...>/notice) 0.000000 MetaHookPre LoadFile(base<...>/numbers) +0.000000 MetaHookPre LoadFile(base<...>/openflow) 0.000000 MetaHookPre LoadFile(base<...>/packet-filter) 0.000000 MetaHookPre LoadFile(base<...>/paths) 0.000000 MetaHookPre LoadFile(base<...>/patterns) @@ -1180,6 +1257,7 @@ 0.000000 MetaHookPre LoadFile(base<...>/urls) 0.000000 MetaHookPre LoadFile(base<...>/utils) 0.000000 MetaHookPre LoadFile(base<...>/x509) +0.000000 MetaHookPre QueueEvent(NetControl::init()) 0.000000 MetaHookPre QueueEvent(bro_init()) 0.000000 MetaHookPre QueueEvent(filter_change_tracking()) 0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_BACKDOOR) @@ -1347,8 +1425,12 @@ 0.000000 | HookCallFunction Log::__add_filter(Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice_alarm, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=packet_filter, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) @@ -1382,8 +1464,12 @@ 0.000000 | HookCallFunction Log::__create_stream(Intel::LOG, [columns=, ev=Intel::log_intel, path=intel]) 0.000000 | HookCallFunction Log::__create_stream(KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos]) 0.000000 | HookCallFunction Log::__create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt]) 0.000000 | HookCallFunction Log::__create_stream(Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm]) 0.000000 | HookCallFunction Log::__create_stream(Notice::LOG, [columns=, ev=Notice::log_notice, path=notice]) +0.000000 | HookCallFunction Log::__create_stream(OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow]) 0.000000 | HookCallFunction Log::__create_stream(PE::LOG, [columns=, ev=PE::log_pe, path=pe]) 0.000000 | HookCallFunction Log::__create_stream(PacketFilter::LOG, [columns=, ev=, path=packet_filter]) 0.000000 | HookCallFunction Log::__create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius]) @@ -1403,7 +1489,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) @@ -1418,8 +1504,12 @@ 0.000000 | HookCallFunction Log::add_default_filter(Intel::LOG) 0.000000 | HookCallFunction Log::add_default_filter(KRB::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Modbus::LOG) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::DROP) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::LOG) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::SHUNT) 0.000000 | HookCallFunction Log::add_default_filter(Notice::ALARM_LOG) 0.000000 | HookCallFunction Log::add_default_filter(Notice::LOG) +0.000000 | HookCallFunction Log::add_default_filter(OpenFlow::LOG) 0.000000 | HookCallFunction Log::add_default_filter(PE::LOG) 0.000000 | HookCallFunction Log::add_default_filter(PacketFilter::LOG) 0.000000 | HookCallFunction Log::add_default_filter(RADIUS::LOG) @@ -1453,8 +1543,12 @@ 0.000000 | HookCallFunction Log::add_filter(Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::add_filter(RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) @@ -1488,8 +1582,12 @@ 0.000000 | HookCallFunction Log::create_stream(Intel::LOG, [columns=, ev=Intel::log_intel, path=intel]) 0.000000 | HookCallFunction Log::create_stream(KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos]) 0.000000 | HookCallFunction Log::create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus]) +0.000000 | HookCallFunction Log::create_stream(NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop]) +0.000000 | HookCallFunction Log::create_stream(NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol]) +0.000000 | HookCallFunction Log::create_stream(NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt]) 0.000000 | HookCallFunction Log::create_stream(Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm]) 0.000000 | HookCallFunction Log::create_stream(Notice::LOG, [columns=, ev=Notice::log_notice, path=notice]) +0.000000 | HookCallFunction Log::create_stream(OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow]) 0.000000 | HookCallFunction Log::create_stream(PE::LOG, [columns=, ev=PE::log_pe, path=pe]) 0.000000 | HookCallFunction Log::create_stream(PacketFilter::LOG, [columns=, ev=, path=packet_filter]) 0.000000 | HookCallFunction Log::create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius]) @@ -1509,7 +1607,9 @@ 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction NetControl::check_plugins() +0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) @@ -1548,10 +1648,12 @@ 0.000000 | HookLoadFile <...>/bro 0.000000 | HookLoadFile base<...>/bif 0.000000 | HookLoadFile base<...>/bro +0.000000 | HookQueueEvent NetControl::init() 0.000000 | HookQueueEvent bro_init() 0.000000 | HookQueueEvent filter_change_tracking() 1362692526.869344 MetaHookPost BroObjDtor() -> 1362692526.869344 MetaHookPost CallFunction(ChecksumOffloading::check, , ()) -> +1362692526.869344 MetaHookPost CallFunction(NetControl::check_conn, , (141.142.228.5)) -> 1362692526.869344 MetaHookPost CallFunction(filter_change_tracking, , ()) -> 1362692526.869344 MetaHookPost CallFunction(net_stats, , ()) -> 1362692526.869344 MetaHookPost CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> @@ -1562,6 +1664,7 @@ 1362692526.869344 MetaHookPost UpdateNetworkTime(1362692526.869344) -> 1362692526.869344 MetaHookPre BroObjDtor() 1362692526.869344 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692526.869344 MetaHookPre CallFunction(NetControl::check_conn, , (141.142.228.5)) 1362692526.869344 MetaHookPre CallFunction(filter_change_tracking, , ()) 1362692526.869344 MetaHookPre CallFunction(net_stats, , ()) 1362692526.869344 MetaHookPre CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) @@ -1573,6 +1676,7 @@ 1362692526.869344 | HookBroObjDtor 1362692526.869344 | HookUpdateNetworkTime 1362692526.869344 1362692526.869344 | HookCallFunction ChecksumOffloading::check() +1362692526.869344 | HookCallFunction NetControl::check_conn(141.142.228.5) 1362692526.869344 | HookCallFunction filter_change_tracking() 1362692526.869344 | HookCallFunction net_stats() 1362692526.869344 | HookCallFunction new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out new file mode 100644 index 0000000000..d36130b29b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out @@ -0,0 +1,7 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=nullzero, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=nonullzero, cookie=4, arg=192.168.18.50/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out new file mode 100644 index 0000000000..fd7f00bb7c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out new file mode 100644 index 0000000000..6890484529 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out @@ -0,0 +1,7 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=drop, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=restore, cookie=4, arg=192.168.18.50/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out new file mode 100644 index 0000000000..fd7f00bb7c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log new file mode 100644 index 0000000000..2811185c09 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log @@ -0,0 +1,26 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-10-49 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +1457565049.807080 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457565049.807080 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457565049.807080 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457565051.874738 worker-1:2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +#close 2016-03-09-23-10-54 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout new file mode 100644 index 0000000000..846bb1b653 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout @@ -0,0 +1,11 @@ +netcontrol debug (Debug-All): init +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.17.1/32, src_p=32/tcp, dst_h=192.168.17.2/32, dst_p=32/tcp, src_m=, dst_m=], ip=, mac=], expire=30.0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=1.1.2.2/32, mac=], expire=15.0 secs, priority=0, location=Hi there, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=1.2.3.4/32, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.17.1/32, src_p=32/tcp, dst_h=192.168.17.2/32, dst_p=32/tcp, src_m=, dst_m=], ip=, mac=], expire=30.0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=, dst_p=, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=6, cid=6, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::MODIFY, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=8.8.8.8/32, dst_p=53/udp, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=[src_h=, src_p=, dst_h=127.0.0.3, dst_p=, src_m=, dst_m=, redirect_port=], id=7, cid=7, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::MODIFY, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=8.8.8.8/32, src_p=53/udp, dst_h=127.0.0.2/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=[src_h=8.8.8.8, src_p=, dst_h=, dst_p=, src_m=, dst_m=, redirect_port=], id=8, cid=8, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=127.0.0.3/32, dst_p=80/tcp, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=, id=9, cid=9, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::MAC, conn=, flow=, ip=, mac=FF:FF:FF:FF:FF:FF], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=10, cid=10, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=, src_m=FF:FF:FF:FF:FF:FF, dst_m=], ip=, mac=], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=11, cid=11, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log new file mode 100644 index 0000000000..da4487f10f --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -0,0 +1,32 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-22-21-13 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +1457562073.119593 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457562073.119593 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457562073.119593 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457562073.119593 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 - - 0 30.000000 - Debug-All +1457562073.119593 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457562073.119593 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457562073.119593 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 -> 5 - 0 30.000000 - Debug-All +1457562073.119593 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457562073.119593 7 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 127.0.0.3/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 8 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->127.0.0.2/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 9 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457562073.119593 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457562073.119593 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457562073.119593 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 - - 0 30.000000 - Debug-All +1457562073.119593 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457562073.119593 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457562073.119593 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 -> 5 - 0 30.000000 - Debug-All +1457562073.119593 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457562073.119593 7 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 127.0.0.3/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 8 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->127.0.0.2/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 9 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457562073.119593 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457562073.119593 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +#close 2016-03-09-22-21-13 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log new file mode 100644 index 0000000000..e777e7655a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol_drop +#open 2016-02-17-20-21-38 +#fields ts rule_id orig_h orig_p resp_h resp_p expire location +#types time string addr port addr port interval string +1455740498.301865 3 1.1.2.2 - - - 15.000000 Hi there +#close 2016-02-17-20-21-38 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log new file mode 100644 index 0000000000..2f3dc11da7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol_shunt +#open 2016-02-17-19-21-47 +#fields ts rule_id f.src_h f.src_p f.dst_h f.dst_p expire location +#types time string addr port addr port interval string +1455736907.597588 2 192.168.17.1 32 192.168.17.2 32 30.000000 - +#close 2016-02-17-19-21-47 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out new file mode 100644 index 0000000000..3b02eef7c7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out @@ -0,0 +1,5 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log new file mode 100644 index 0000000000..fb1381e291 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log @@ -0,0 +1,23 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-08-22-15-15 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Broker-bro/event/netcontroltest +0.000000 - NetControl::MESSAGE - - - - - - - waiting for plugins to initialize - - - - +1457475314.791475 - NetControl::MESSAGE - - - - - - - activation finished - - - Broker-bro/event/netcontroltest +1457475314.791475 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457475315.175411 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175411 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::ERROR - - NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - Removal of non-existing rule 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::ERROR - - NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Removal of non-existing rule 0 36000.000000 - Broker-bro/event/netcontroltest +#close 2016-03-08-22-15-15 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out new file mode 100644 index 0000000000..31d94be31e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP +rule timeout, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule timeout, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP, [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log new file mode 100644 index 0000000000..f3bd6fafe0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-42-34 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +1398529018.678276 3 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 3600.000000 Re-drop by catch-and-release - +1398529018.678276 4 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 86400.000000 Re-drop by catch-and-release - +1398529018.678276 5 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 604800.000000 Re-drop by catch-and-release - +1398529018.678276 6 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 604800.000000 Re-drop by catch-and-release - +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +#close 2016-03-09-23-42-34 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout new file mode 100644 index 0000000000..7d21c082f7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout @@ -0,0 +1,19 @@ +netcontrol debug (Debug-All): init +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +Dumping state +{ + +} +{ + +} +{ + +} diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log new file mode 100644 index 0000000000..780c3d9c64 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-06-58 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1394747126.854788 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - - 0 0.000000 - Debug-All +1394747126.854788 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - - 0 0.000000 - Debug-All +1394747129.505358 3 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - discarded duplicate insertion 0 0.000000 - - +#close 2016-03-09-23-06-58 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out new file mode 100644 index 0000000000..b29ce14d29 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out @@ -0,0 +1,6 @@ +1 +[ty=NetControl::ADDRESS, conn=, flow=, ip=1.2.3.4/32, mac=] +0 +4 +[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=8.8.8.8/32, dst_p=53/udp, src_m=, dst_m=], ip=, mac=], NetControl::MODIFY +[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log new file mode 100644 index 0000000000..2936694e2a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -0,0 +1,16 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-15-50 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 - - 0 30.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 -> 5 - 0 30.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 - - 0 30.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 -> 5 - 0 30.000000 - Debug-All +#close 2016-03-09-23-15-50 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log new file mode 100644 index 0000000000..986c1cd5a2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -0,0 +1,49 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-40-32 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 10 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 10 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529020.091883 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529020.091883 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529020.091883 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529020.091883 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529020.091883 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529020.091883 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529020.091883 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529020.091883 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529020.091883 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529020.091883 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529020.091883 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529020.091883 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +#close 2016-03-09-23-40-32 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log new file mode 100644 index 0000000000..ead5d70ec7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log @@ -0,0 +1,21 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-03-09-23-40-54 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 74.125.239.97/32 56981 443 4398046511108 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - - 192.168.18.50/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511112 - OpenFlow::OFPFC_ADD 0 0 5 - - 1 4294967290 - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - - 192.168.18.50/32 - - 4398046511113 - OpenFlow::OFPFC_ADD 0 0 5 - - 1 4294967290 - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 74.125.239.97/32 56981 443 4398046511114 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 5 - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511108 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511110 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511111 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511112 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511113 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511114 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +#close 2016-03-09-23-40-54 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log new file mode 100644 index 0000000000..abab12a0c9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -0,0 +1,25 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-28-53 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1254722767.875996 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 30.000000 - Openflow-Log-42 +1254722767.875996 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 74.53.140.153/32 - - 0 15.000000 - Openflow-Log-42 +1254722767.875996 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 30.000000 - Openflow-Log-42 +1254722767.875996 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 74.53.140.153/32 - - 0 15.000000 - Openflow-Log-42 +1437831787.861602 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - - 0 30.000000 - Openflow-Log-42 +1437831787.861602 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.102/32 - - 0 15.000000 - Openflow-Log-42 +1437831787.861602 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - - 0 30.000000 - Openflow-Log-42 +1437831787.861602 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.102/32 - - 0 15.000000 - Openflow-Log-42 +1437831799.610433 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - - 0 30.000000 - Openflow-Log-42 +1437831799.610433 7 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 17.167.150.73/32 - - 0 15.000000 - Openflow-Log-42 +1437831799.610433 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - - 0 30.000000 - Openflow-Log-42 +1437831799.610433 7 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 17.167.150.73/32 - - 0 15.000000 - Openflow-Log-42 +#close 2016-03-09-23-28-53 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log new file mode 100644 index 0000000000..6cff86bdb2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-03-09-23-28-53 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511108 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 74.53.140.153/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 74.53.140.153/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.100/32 192.168.133.102/32 49648 25 4398046511112 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - - 192.168.133.102/32 - - - 4398046511114 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - - - 192.168.133.102/32 - - 4398046511115 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 192.168.133.100/32 17.167.150.73/32 49655 443 4398046511116 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - - 17.167.150.73/32 - - - 4398046511118 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - - - 17.167.150.73/32 - - 4398046511119 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +#close 2016-03-09-23-28-53 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log new file mode 100644 index 0000000000..f4674275e9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log @@ -0,0 +1,14 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2016-02-12-03-18-52 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1254722767.492060 CXWv6p3arKYeMETxOg 10.10.1.4 56166 10.10.1.1 53 udp dns 0.034025 34 100 SF - - 0 Dd 1 62 1 128 (empty) +1254722776.690444 CCvvfg3TEfuqmmG4bh 10.10.1.20 138 10.10.1.255 138 udp - - - - S0 - - 0 D 1 229 0 0 (empty) +1254722767.529046 CjhGID4nQcgTWjvg4c 10.10.1.4 1470 74.53.140.153 25 tcp - 0.346950 0 0 S1 - - 0 Sh 1 48 1 48 (empty) +1437831787.856895 CRJuHdVW0XPVINV8a 192.168.133.100 49648 192.168.133.102 25 tcp - 0.004707 0 0 S1 - - 0 Sh 1 64 1 60 (empty) +1437831776.764391 CsRx2w45OKnoww6xl4 192.168.133.100 49285 66.196.121.26 5050 tcp - 0.343008 41 0 OTH - - 0 Da 1 93 1 52 (empty) +#close 2016-02-12-03-18-52 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log new file mode 100644 index 0000000000..0da63fd6f5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log @@ -0,0 +1,21 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-08-22-48-10 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->*/* - - 0 36000.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 192.169.18.1/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->192.168.18.50/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->192.169.18.1/32/80 - - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->*/* - - 0 36000.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 192.169.18.1/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->192.168.18.50/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->192.169.18.1/32/80 - - 5 36000.000000 - Openflow-Log-42 +#close 2016-03-08-22-48-10 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log new file mode 100644 index 0000000000..64d6cabaf5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-12-03-28-52 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 36000 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - 17 192.168.18.50/32 8.8.8.8/32 - 53 4398046511110 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - 192.169.18.1 - - +1398529018.678276 42 - - - - - 2048 - 17 8.8.8.8/32 192.168.18.50/32 53 - 4398046511112 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - 8.8.8.8 - - - +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 192.169.18.1/32 - 80 4398046511114 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - - - - +#close 2016-02-12-03-28-52 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log new file mode 100644 index 0000000000..957af822e2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log @@ -0,0 +1,17 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-06-49 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457564809.281931 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564809.281931 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +#close 2016-03-09-23-06-51 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out new file mode 100644 index 0000000000..ec3b038bd9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out @@ -0,0 +1,5 @@ +BrokerComm::incoming_connection_established +flow_clear, 42 +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=, nw_tos=, nw_proto=, nw_src=, nw_dst=, tp_src=, tp_dst=], [cookie=4398046511105, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0, out_port=, out_group=, flags=0, actions=[out_ports=[3, 7], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=2048, nw_tos=, nw_proto=6, nw_src=10.10.1.4/32, nw_dst=74.53.140.153/32, tp_src=1470, tp_dst=25], [cookie=4398046511146, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, actions=[out_ports=[], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=2048, nw_tos=, nw_proto=6, nw_src=74.53.140.153/32, nw_dst=10.10.1.4/32, tp_src=25, tp_dst=1470], [cookie=4398046511146, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, actions=[out_ports=[], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out new file mode 100644 index 0000000000..d81ed49aee --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out @@ -0,0 +1,8 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +Flow_mod_success +Flow_mod_failure +connection established +Flow_mod_success +Flow_mod_failure +Flow_mod_success +Flow_mod_failure diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log new file mode 100644 index 0000000000..eed7c20caf --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -0,0 +1,16 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-11-20-32-05 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +0.000000 42 - - - - - - - - - - - - 4398046511105 - OpenFlow::OFPFC_ADD 0 0 0 - - 0 3,7 - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511147 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 1470 4398046511147 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.100/32 192.168.133.102/32 49648 25 4398046511148 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.102/32 192.168.133.100/32 25 49648 4398046511148 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 192.168.133.100/32 17.167.150.73/32 49655 443 4398046511149 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 17.167.150.73/32 192.168.133.100/32 443 49655 4398046511149 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2016-02-11-20-32-05 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log new file mode 100644 index 0000000000..a6b8e30871 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-11-21-06-45 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1455224805.349129 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511146 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1455224805.349129 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 1470 4398046511146 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2016-02-11-21-06-46 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout new file mode 100644 index 0000000000..f31aec1a92 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -0,0 +1,22 @@ +http://127.0.0.1:8080/stats/flowentry/clear/42 +http://127.0.0.1:8080/stats/flowentry/add +{"match": {}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 0, "actions": [{"port": 3, "type": "OUTPUT"}, {"port": 7, "type": "OUTPUT"}], "cookie": 4398046511105, "idle_timeout": 0} +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 25, "nw_dst": "74.53.140.153/32", "nw_src": "10.10.1.4/32", "dl_type": 2048, "tp_src": 1470, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 1470, "nw_dst": "10.10.1.4/32", "nw_src": "74.53.140.153/32", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 25, "nw_dst": "192.168.133.102/32", "nw_src": "192.168.133.100/32", "dl_type": 2048, "tp_src": 49648, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 49648, "nw_dst": "192.168.133.100/32", "nw_src": "192.168.133.102/32", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 443, "nw_dst": "17.167.150.73/32", "nw_src": "192.168.133.100/32", "dl_type": 2048, "tp_src": 49655, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 49655, "nw_dst": "192.168.133.100/32", "nw_src": "17.167.150.73/32", "dl_type": 2048, "tp_src": 443, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log new file mode 100644 index 0000000000..e4e7d8b877 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ftp +#open 2016-03-11-17-40-18 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type file_size reply_code reply_msg data_channel.passive data_channel.orig_h data_channel.resp_h data_channel.resp_p fuid +#types time string addr port addr port string string string string string count count string bool addr addr port string +1457455890.667768 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,187) T 192.168.21.95 164.107.123.6 47035 - +1457455890.667768 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,187) - - - - - +1457455891.781896 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,231) T 192.168.21.95 164.107.123.6 47079 FaFkMs3Gc0F1kvwXD +1457455894.380514 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,211) T 192.168.21.95 164.107.123.6 47059 Fm58Rm14ZG2Ai7nW9g +1457455900.398202 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,197) T 192.168.21.95 164.107.123.6 47045 FnxQXApi8WTTWNyH1 +1457455900.530943 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - RETR ftp://164.107.123.6/mirror/internic/rfc/rfc1001.txt text/plain 154427 226 File send OK. - - - - FJblKh2PaOnGa8zcmg +#close 2016-03-11-17-40-18 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/http.log new file mode 100644 index 0000000000..91f26e75e7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/http.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open 2016-02-05-13-13-06 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer version user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied orig_fuids orig_mime_types resp_fuids resp_mime_types +#types time string addr port addr port count string string string string string string count count count string count string string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] +1452204358.910557 CXWv6p3arKYeMETxOg 192.168.122.130 49157 202.7.177.41 80 1 - - - - 1.1 - 0 14 200 OK - - - (empty) - - - - - FGec0Miu9FfcsYUT4 text/plain +#close 2016-02-05-13-13-06 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/weird.log new file mode 100644 index 0000000000..92a669b060 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-bad-request-with-version/weird.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open 2016-03-07-21-06-28 +#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 +1452204358.172926 CXWv6p3arKYeMETxOg 192.168.122.130 49157 202.7.177.41 80 bad_HTTP_request_with_version - F bro +#close 2016-03-07-21-06-28 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log index e10847fe2d..aa30f48131 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path weird -#open 2016-01-15-20-54-31 +#open 2016-03-07-21-06-12 #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 1354328874.237327 CjhGID4nQcgTWjvg4c 128.2.6.136 46563 173.194.75.103 80 missing_HTTP_uri - F bro @@ -13,9 +13,9 @@ 1354328882.949510 C7XEbhP654jzLoe3a 128.2.6.136 46570 173.194.75.103 80 bad_HTTP_request - F bro 1354328887.094494 CMXxB5GvmoxJFXdTa 128.2.6.136 46572 173.194.75.103 80 bad_HTTP_request - F bro 1354328891.141058 Caby8b1slFea8xwSmb 128.2.6.136 46573 173.194.75.103 80 bad_HTTP_request - F bro -1354328891.183942 Che1bq3i2rO3KD1Syg 128.2.6.136 46574 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.183942 Che1bq3i2rO3KD1Syg 128.2.6.136 46574 173.194.75.103 80 bad_HTTP_request_with_version - F bro 1354328891.226199 C3SfNE4BWaU4aSuwkc 128.2.6.136 46575 173.194.75.103 80 bad_HTTP_request - F bro -1354328891.267625 CEle3f3zno26fFZkrh 128.2.6.136 46576 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.267625 CEle3f3zno26fFZkrh 128.2.6.136 46576 173.194.75.103 80 bad_HTTP_request_with_version - F bro 1354328891.309065 CwSkQu4eWZCH7OONC1 128.2.6.136 46577 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro 1354328895.355012 CfTOmO0HKorjr8Zp7 128.2.6.136 46578 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro 1354328895.396634 CzA03V1VcgagLjnO92 128.2.6.136 46579 173.194.75.103 80 bad_HTTP_request - F bro @@ -33,4 +33,4 @@ 1354328924.518204 CuChlg202P8sUFuXrg 128.2.6.136 46605 173.194.75.103 80 bad_HTTP_request - F bro 1354328932.734579 CY93mM3aViMiLKuSw3 128.2.6.136 46609 173.194.75.103 80 bad_HTTP_request - F bro 1354328932.776609 CXgISq6dA2DVPzqp9 128.2.6.136 46610 173.194.75.103 80 bad_HTTP_request - F bro -#close 2016-01-15-20-54-32 +#close 2016-03-07-21-06-12 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log new file mode 100644 index 0000000000..674c0c0e3e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log @@ -0,0 +1,34 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2016-03-08-15-45-10 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1324071333.493287 CXWv6p3arKYeMETxOg 192.168.1.79 51880 131.159.21.1 22 tcp ssh 6.159326 2669 2501 SF - - 0 ShAdDaFf 25 3981 20 3549 (empty) +1409516196.337184 CjhGID4nQcgTWjvg4c 10.0.0.18 40184 128.2.6.88 41644 tcp ssh 2.079071 3813 3633 SF - - 0 ShADadFf 22 4965 26 5017 (empty) +1419870189.485611 CCvvfg3TEfuqmmG4bh 192.168.2.1 57189 192.168.2.158 22 tcp ssh 6.641754 5253 3489 SF - - 0 ShADadFf 38 7241 29 5005 (empty) +1419870206.101883 CsRx2w45OKnoww6xl4 192.168.2.1 57191 192.168.2.158 22 tcp ssh 3.862198 576 813 SF - - 0 ShAdDaFf 23 1784 16 1653 (empty) +1419996264.318569 CRJuHdVW0XPVINV8a 192.168.2.1 55179 192.168.2.158 2200 tcp ssh 2.557930 2757 1721 RSTR - - 0 ShADadFr 37 4693 29 3225 (empty) +1420588548.721272 CPbrpk1qSsw6ESzHV4 192.168.2.1 56594 192.168.2.158 22 tcp ssh 8.841749 480 537 SF - - 0 ShAdDaFf 17 1376 14 1273 (empty) +1420590124.879760 C6pKV8GSxOnSLghOa 192.168.2.1 56821 192.168.2.158 22 tcp ssh 1.106250 820 1125 SF - - 0 ShAdDaFf 26 2184 20 2173 (empty) +1420590308.775525 CIPOse170MGiRM1Qf4 192.168.2.1 56837 192.168.2.158 22 tcp ssh 1.080767 692 997 SF - - 0 ShAdDaFf 25 2004 19 1993 (empty) +1420590322.673363 C7XEbhP654jzLoe3a 192.168.2.1 56845 192.168.2.158 22 tcp ssh 1.302395 660 965 SF - - 0 ShAdDaFf 26 2024 20 2013 (empty) +1420590636.473213 CJ3xTn1c4Zw9TmAE05 192.168.2.1 56875 192.168.2.158 22 tcp ssh 12.013506 588 549 SF - - 0 ShAdDaFf 19 1588 16 1389 (empty) +1420590659.422161 CMXxB5GvmoxJFXdTa 192.168.2.1 56878 192.168.2.158 22 tcp ssh 3.628964 684 825 SF - - 0 ShAdDaFf 25 1996 19 1821 (empty) +1420591379.650462 Caby8b1slFea8xwSmb 192.168.2.1 56940 192.168.2.158 22 tcp ssh 0.104978 500 609 SF - - 0 ShAdDaFf 14 1240 10 1137 (empty) +1420599430.822385 Che1bq3i2rO3KD1Syg 192.168.2.1 57831 192.168.2.158 22 tcp ssh 2.758790 576 813 SF - - 0 ShAdDaFf 23 1784 18 1757 (empty) +1420851448.309629 C3SfNE4BWaU4aSuwkc 192.168.2.1 59246 192.168.2.158 22 tcp ssh 3.076752 3049 4165 SF - - 0 ShADadFf 32 4725 23 5369 (empty) +1420860283.029061 CEle3f3zno26fFZkrh 192.168.1.32 41164 128.2.10.238 22 tcp ssh 8.485357 6087 3015 SF - - 0 ShADadFf 32 7759 33 4763 (empty) +1420860616.400297 CwSkQu4eWZCH7OONC1 192.168.1.32 33910 128.2.13.133 22 tcp ssh 1.910959 6471 6037 SF - - 0 ShADadFf 33 8195 29 7565 (empty) +1420868281.639103 CfTOmO0HKorjr8Zp7 192.168.1.32 41268 128.2.10.238 22 tcp ssh 2.710778 5613 2487 SF - - 0 ShADadFf 24 6869 20 3535 (empty) +1420917487.220407 Cab0vO1xNYSS2hJkle 192.168.1.31 52294 192.168.1.32 22 tcp ssh 3.658968 3729 2229 SF - - 0 ShADadFf 36 5613 24 3497 (empty) +1420917487.213378 CzA03V1VcgagLjnO92 192.168.1.31 57621 192.168.1.255 57621 udp - - - - S0 - - 0 D 1 72 0 0 (empty) +1420917487.213468 CyAhVIzHqb7t7kv28 192.168.1.32 57621 192.168.1.31 57621 udp - - - - S0 - - 0 D 1 72 0 0 (empty) +1421006072.431795 Cx3C534wEyF3OvvcQe 192.168.1.31 51476 192.168.1.32 8118 tcp - 0.000539 76 0 SF - - 0 DaFfA 6 388 5 284 (empty) +1421006072.001012 Cx2FqO23omNawSNrxj 192.168.1.31 51489 192.168.1.32 22 tcp ssh 4.926958 4029 2497 SF - - 0 ShAdDaFf 42 6249 27 3937 (empty) +1421041176.944687 CkDsfG2YIeWJmXWNWj 192.168.1.32 58641 131.103.20.168 22 tcp ssh 0.587601 2885 2309 SF - - 0 ShADdaFf 16 3725 13 2993 (empty) +1421041299.738916 CUKS0W3HFYOnBqSE5e 192.168.1.32 58646 131.103.20.168 22 tcp ssh 2.236727 4477 535101 SF - - 0 ShADadFf 179 13793 226 546861 (empty) +1421041526.312919 CRrfvP2lalMAYOCLhj 192.168.1.32 58649 131.103.20.168 22 tcp ssh 2.066433 4477 534861 SF - - 0 ShADadFf 183 14001 236 547141 (empty) +#close 2016-03-08-15-45-10 diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log index 5b75945aeb..b69c74b717 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log @@ -1,5 +1,6 @@ 0.000000 bro_init 0.000000 filter_change_tracking + 0.000000 NetControl::init 1254722767.492060 protocol_confirmation 1254722767.492060 ChecksumOffloading::check 1254722767.492060 filter_change_tracking diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log index 485c4318e2..27cf2dab34 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log @@ -1,5 +1,6 @@ 0.000000 bro_init 0.000000 filter_change_tracking + 0.000000 NetControl::init 1254722767.492060 protocol_confirmation [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={\x0a\x0a}, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_DNS diff --git a/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap b/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap new file mode 100644 index 0000000000..02b4254ef2 Binary files /dev/null and b/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap differ diff --git a/testing/btest/Traces/http/http-bad-request-with-version.trace b/testing/btest/Traces/http/http-bad-request-with-version.trace new file mode 100644 index 0000000000..6503d1b366 Binary files /dev/null and b/testing/btest/Traces/http/http-bad-request-with-version.trace differ diff --git a/testing/btest/bifs/check_subnet.bro b/testing/btest/bifs/check_subnet.bro new file mode 100644 index 0000000000..b725cae73c --- /dev/null +++ b/testing/btest/bifs/check_subnet.bro @@ -0,0 +1,39 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testt: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +function check_member(s: subnet) + { + if ( s in testt ) + print fmt("in says: %s is member", s); + else + print fmt("in says: %s is no member", s); + + if ( check_subnet(s, testt) ) + print fmt("check_subnet says: %s is member", s); + else + print fmt("check_subnet says: %s is no member", s); + + } + +event bro_init() + { + check_member(10.2.0.2/32); + check_member(10.2.0.2/31); + check_member(10.6.0.0/9); + check_member(10.2.0.0/8); + } diff --git a/testing/btest/bifs/filter_subnet_table.bro b/testing/btest/bifs/filter_subnet_table.bro new file mode 100644 index 0000000000..7659096a71 --- /dev/null +++ b/testing/btest/bifs/filter_subnet_table.bro @@ -0,0 +1,49 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testa: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +global testb: table[subnet] of string = { + [10.0.0.0/8] = "a", + [10.2.0.0/16] = "b", + [10.2.0.2/31] = "c", + [10.1.0.0/16] = "d", + [10.3.0.0/16] = "e", + [5.0.0.0/8] = "f", + [5.5.0.0/25] = "g", + [5.2.0.0/32] = "h", + [7.2.0.0/32] = "i", + [[2607:f8b0:4008:807::200e]/64] = "j", + [[2607:f8b0:4007:807::200e]/64] = "k", + [[2607:f8b0:4007:807::200e]/128] = "l" +}; + + +event bro_init() + { + local c = filter_subnet_table(10.2.0.2/32, testa); + print c; + c = filter_subnet_table(10.2.0.2/32, testb); + print c; + c = filter_subnet_table(10.3.0.2/32, testb); + print c; + c = filter_subnet_table(1.0.0.0/8, testb); + print c; + + local unspecified: table[subnet] of string = table(); + c = filter_subnet_table(10.2.0.2/32, unspecified); + print c; + } diff --git a/testing/btest/bifs/matching_subnets.bro b/testing/btest/bifs/matching_subnets.bro new file mode 100644 index 0000000000..87effed19f --- /dev/null +++ b/testing/btest/bifs/matching_subnets.bro @@ -0,0 +1,30 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testt: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +event bro_init() + { + print testt; + local c = matching_subnets(10.2.0.2/32, testt); + print c; + c = matching_subnets([2607:f8b0:4007:807::200e]/128, testt); + print c; + c = matching_subnets(128.0.0.1/32, testt); + print c; + c = matching_subnets(10.0.0.2/8, testt); + print c; + } diff --git a/testing/btest/bifs/subnet_to_addr.bro b/testing/btest/bifs/subnet_to_addr.bro new file mode 100644 index 0000000000..02bb6254e0 --- /dev/null +++ b/testing/btest/bifs/subnet_to_addr.bro @@ -0,0 +1,14 @@ +# @TEST-EXEC: bro -b %INPUT >output 2>error +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff error + +function test_to_addr(sn: subnet, expect: addr) + { + local result = subnet_to_addr(sn); + print fmt("subnet_to_addr(%s) = %s (%s)", sn, result, + result == expect ? "SUCCESS" : "FAILURE"); + } + +test_to_addr(0.0.0.0/32, 0.0.0.0); +test_to_addr(1.2.3.4/16, 1.2.0.0); +test_to_addr([2607:f8b0:4005:803::200e]/128, [2607:f8b0:4005:803::200e]); diff --git a/testing/btest/bifs/subnet_version.bro b/testing/btest/bifs/subnet_version.bro new file mode 100644 index 0000000000..1efd633f68 --- /dev/null +++ b/testing/btest/bifs/subnet_version.bro @@ -0,0 +1,7 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +print is_v4_subnet(1.2.3.4/16); +print is_v4_subnet([2607:f8b0:4005:801::200e]/64); +print is_v6_subnet(1.2.3.4/24); +print is_v6_subnet([2607:f8b0:4005:801::200e]/12); diff --git a/testing/btest/language/expire_multiple.test b/testing/btest/language/expire_multiple.test new file mode 100644 index 0000000000..1e4aaa0975 --- /dev/null +++ b/testing/btest/language/expire_multiple.test @@ -0,0 +1,12 @@ +# @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output + +global s: set[string] &create_expire=1secs &read_expire=1secs; + +# @TEST-START-NEXT: + +global s: set[string] &write_expire=1secs &create_expire=3secs; + +# @TEST-START-NEXT: + +global s: set[string] &write_expire=1secs &read_expire=3secs; diff --git a/testing/btest/language/expire_subnet.test b/testing/btest/language/expire_subnet.test new file mode 100644 index 0000000000..12d5e56b5a --- /dev/null +++ b/testing/btest/language/expire_subnet.test @@ -0,0 +1,96 @@ +# @TEST-EXEC: bro -C -r $TRACES/var-services-std-ports.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +redef table_expire_interval = 1sec; + +global start_time: time; + +function time_past(): interval + { + return network_time() - start_time; + } + +function expire_nums(tbl: table[count] of string, idx: count): interval + { + print fmt("Expired Num: %s --> %s at %s", idx, tbl[idx], time_past()); + return 0sec; + } + +function expire_nets(tbl: table[subnet] of string, idx: subnet): interval + { + print fmt("Expired Subnet: %s --> %s at %s", idx, tbl[idx], time_past()); + return 0sec; + } + +global nums: table[count] of string &read_expire=8sec &expire_func=expire_nums; +global nets: table[subnet] of string &read_expire=8sec &expire_func=expire_nets; +global step: count; + +### Test ### + +function execute_test() + { + local num_a = nums[2]; + local num_b = nums[3]; + + local net_a = nets[192.168.2.0/24]; + #local net_b = nets[192.168.3.0/24]; + local nets_b = ""; + local nets_b_tbl: table[subnet] of string; + + nets_b_tbl = filter_subnet_table(192.168.3.0/24, nets); + for ( idx in nets_b_tbl ) + nets_b += cat(", ", nets_b_tbl[idx]); + nets_b = nets_b[2:]; + + # writing resets expire as expected + #nets[192.168.2.0/24] = "accessed"; + #nets[192.168.3.0/24] = "accessed"; + + print fmt("Accessed table nums: %s; %s", num_a, num_b); + print fmt("Accessed table nets: %s; %s", net_a, nets_b); + print fmt("Time: %s", time_past()); + print ""; + } + +### Events ### + +event bro_init() + { + step = 0; + + nums[0] = "zero"; + nums[1] = "one"; + nums[2] = "two"; + nums[3] = "three"; + nums[4] = "four"; + + nets[192.168.0.0/16] = "zero"; + nets[192.168.1.0/24] = "one"; + nets[192.168.2.0/24] = "two"; + nets[192.168.3.0/24] = "three"; + nets[192.168.4.0/24] = "four"; + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( step == 0 ) + { + ++step; + start_time = network_time(); + + print "All:"; + for ( num in nums ) + print fmt("%s --> %s", num, nums[num]); + for ( net in nets ) + print fmt("%s --> %s", net, nets[net]); + print fmt("Time: %s", time_past()); + print ""; + } + + if ( (time_past() > 7sec) && (step == 1) ) + { + ++step; + execute_test(); + } + } diff --git a/testing/btest/language/record-function-recursion.bro b/testing/btest/language/record-function-recursion.bro new file mode 100644 index 0000000000..90832bfa69 --- /dev/null +++ b/testing/btest/language/record-function-recursion.bro @@ -0,0 +1,20 @@ +# @TEST-EXEC: bro -b %INPUT 2>&1 >out +# @TEST-EXEC: btest-diff out + +type Outer: record { + id: count &optional; +}; + +type Inner: record { + create: function(input: Outer) : string; +}; + +redef record Outer += { + inner: Inner &optional; +}; + +event bro_init() { + local o = Outer(); + print o; + print type_name(o); +} diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro new file mode 100644 index 0000000000..566739c0b7 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro @@ -0,0 +1,122 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b -r $TRACES/tls/ecdhe.pcap --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_acld = NetControl::create_acld(NetControl::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/netcontroltest")); + NetControl::activate(netcontrol_acld, 0); + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +hook NetControl::acld_rule_policy(p: NetControl::PluginState, r: NetControl::Rule, ar: NetControl::AclRule) + { + # use nullzero instead of drop for address drops + if ( r$ty == NetControl::DROP && r$entity$ty == NetControl::ADDRESS && ar$command == "drop" ) + ar$command = "nullzero"; + } + +event connection_established(c: connection) + { + local id = c$id; + + local flow1 = NetControl::Flow( + $src_h=addr_to_subnet(c$id$orig_h), + $dst_h=addr_to_subnet(c$id$resp_h) + ); + local e1: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow1]; + local r1: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + + local flow2 = NetControl::Flow( + $dst_p=c$id$resp_p + ); + local e2: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow2]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="there"]; + + NetControl::add_rule(r1); + NetControl::add_rule(r2); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "add_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_added, id, r, ar$command)); + } + +event NetControl::acld_remove_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "remove_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_removed, id, r, ar$command)); + + if ( r$cid == 4 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro new file mode 100644 index 0000000000..dfeaee1055 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -0,0 +1,115 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b -r $TRACES/tls/ecdhe.pcap --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_acld = NetControl::create_acld(NetControl::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/netcontroltest")); + NetControl::activate(netcontrol_acld, 0); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + local id = c$id; + + local flow1 = NetControl::Flow( + $src_h=addr_to_subnet(c$id$orig_h), + $dst_h=addr_to_subnet(c$id$resp_h) + ); + local e1: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow1]; + local r1: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + + local flow2 = NetControl::Flow( + $dst_p=c$id$resp_p + ); + local e2: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow2]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="there"]; + + NetControl::add_rule(r1); + NetControl::add_rule(r2); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "add_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_added, id, r, ar$command)); + } + +event NetControl::acld_remove_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "remove_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_removed, id, r, ar$command)); + + if ( r$cid == 4 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro new file mode 100644 index 0000000000..5c42f0d8eb --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -0,0 +1,62 @@ +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=manager-1 bro %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-1 bro --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-2 bro --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT" +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff manager-1/netcontrol.log + +@TEST-START-FILE cluster-layout.bro +redef Cluster::nodes = { + ["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=37757/tcp, $workers=set("worker-1", "worker-2")], + ["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37760/tcp, $manager="manager-1", $interface="eth0"], + ["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37761/tcp, $manager="manager-1", $interface="eth0"], +}; +@TEST-END-FILE + +redef Log::default_rotation_interval = 0secs; +#redef exit_only_after_terminate = T; + +@load base/frameworks/netcontrol + +@if ( Cluster::local_node_type() == Cluster::WORKER ) +event bro_init() + { + suspend_processing(); + } +@endif + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +@if ( Cluster::local_node_type() == Cluster::WORKER ) +event remote_connection_handshake_done(p: event_peer) + { + continue_processing(); + } +@endif + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 1sec); + NetControl::drop_address(id$orig_h, 1sec); + } + +event terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string &default="") + { + print "Rule added", r$id, r$cid; + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro new file mode 100644 index 0000000000..1efe420d73 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -0,0 +1,44 @@ +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff netcontrol_shunt.log +# @TEST-EXEC: btest-diff netcontrol_drop.log +# @TEST-EXEC: btest-diff .stdout + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +function test_mac_flow() + { + local flow = NetControl::Flow( + $src_m = "FF:FF:FF:FF:FF:FF" + ); + local e: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow]; + local r: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e, $expire=15sec]; + + NetControl::add_rule(r); + } + +function test_mac() + { + local e: NetControl::Entity = [$ty=NetControl::MAC, $mac="FF:FF:FF:FF:FF:FF"]; + local r: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e, $expire=15sec]; + + NetControl::add_rule(r); + } + +event NetControl::init_done() &priority=-5 + { + NetControl::shunt_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 30sec); + NetControl::drop_address(1.1.2.2, 15sec, "Hi there"); + NetControl::whitelist_address(1.2.3.4, 15sec); + NetControl::redirect_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 5, 30sec); + NetControl::quarantine_host(127.0.0.2, 8.8.8.8, 127.0.0.3, 15sec); + test_mac(); + test_mac_flow(); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro new file mode 100644 index 0000000000..56a76433f2 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -0,0 +1,107 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b -r $TRACES/smtp.trace --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff send/netcontrol.log +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_broker = NetControl::create_broker(127.0.0.1, broker_port, "bro/event/netcontroltest", T); + NetControl::activate(netcontrol_broker, 0); + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 10hrs); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +event NetControl::rule_timeout(r: NetControl::Rule, i: NetControl::FlowInfo, p: NetControl::PluginState) + { + print "rule timeout", r$entity, r$ty, i; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::broker_add_rule(id: count, r: NetControl::Rule) + { + print "add_rule", id, r$entity, r$ty; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_added, id, r, "")); + } + +event NetControl::broker_remove_rule(id: count, r: NetControl::Rule) + { + print "remove_rule", id, r$entity, r$ty; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_timeout, id, r, NetControl::FlowInfo())); + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_removed, id, r, "")); + + if ( r$cid == 3 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro new file mode 100644 index 0000000000..a809833ecf --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -0,0 +1,31 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +module NetControl; + +event connection_established(c: connection) + { + local id = c$id; + NetControl::drop_address_catch_release(id$orig_h); + # second one should be ignored because duplicate + NetControl::drop_address_catch_release(id$orig_h); + + # mean call directly into framework - simulate new connection + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro b/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro new file mode 100644 index 0000000000..9b8c995fac --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro @@ -0,0 +1,54 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff .stdout + +# Verify the state of internal tables after rules have been deleted... + +@load base/frameworks/netcontrol + +module NetControl; + +export { + global dump_state: function(); +} + +function dump_state() + { + print "Dumping state"; + print rules; + print rule_entities; + print rules_by_subnets; + } + +module GLOBAL; + +global rules: vector of string; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 10); + } + +event remove_all() + { + for ( i in rules ) + NetControl::remove_rule(rules[i]); + } + +event dump_info() + { + NetControl::dump_state(); + } + +event connection_established(c: connection) + { + local id = c$id; + rules[|rules|] = NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs); + rules[|rules|] = NetControl::drop_address(id$orig_h, 0secs); + rules[|rules|] = NetControl::whitelist_address(id$orig_h, 0secs); + rules[|rules|] = NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs); + + schedule 1sec { remove_all() }; + schedule 2sec { dump_info() }; + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro b/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro new file mode 100644 index 0000000000..c64bd9e16b --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b -r $TRACES/tls/google-duplicate.trace %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + NetControl::drop_address(c$id$orig_h, 0secs); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro b/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro new file mode 100644 index 0000000000..e7bb61cc04 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro @@ -0,0 +1,34 @@ +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff out + +@load base/frameworks/netcontrol + +global outfile: file; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event NetControl::init_done() &priority=-5 + { + NetControl::shunt_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 30sec); + NetControl::drop_address(1.1.2.2, 15sec, "Hi there"); + NetControl::whitelist_address(1.2.3.4, 15sec); + NetControl::redirect_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 5, 30sec); + NetControl::quarantine_host(127.0.0.2, 8.8.8.8, 127.0.0.3, 15sec); + + outfile = open("out"); + local rules = NetControl::find_rules_addr(1.2.3.4); + print outfile, |rules|; + print outfile, rules[0]$entity; + rules = NetControl::find_rules_addr(1.2.3.5); + print outfile, |rules|; + rules = NetControl::find_rules_addr(127.0.0.2); + print outfile, |rules|; + print outfile, rules[0]$entity, rules[0]$ty; + print outfile, rules[3]$entity, rules[3]$ty; + close(outfile); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro new file mode 100644 index 0000000000..02056a1e0a --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro @@ -0,0 +1,27 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + NetControl::drop_address(id$orig_h, 15sec); + NetControl::whitelist_address(id$orig_h, 15sec); + NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); + } + +hook NetControl::rule_policy(r: NetControl::Rule) + { + if ( r$expire == 15sec ) + break; + + r$entity$flow$src_h = 0.0.0.0/0; + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro new file mode 100644 index 0000000000..56a764f2e9 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -0,0 +1,37 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global rules: vector of string; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + local netcontrol_debug_2 = NetControl::create_debug(T); + local of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_debug, 10); + NetControl::activate(netcontrol_of, 10); + NetControl::activate(netcontrol_debug_2, 0); + } + +event remove_all() + { + for ( i in rules ) + NetControl::remove_rule(rules[i]); + } + + +event connection_established(c: connection) + { + local id = c$id; + rules[|rules|] = NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs); + rules[|rules|] = NetControl::drop_address(id$orig_h, 0secs); + rules[|rules|] = NetControl::whitelist_address(id$orig_h, 0secs); + rules[|rules|] = NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs); + + schedule 1sec { remove_all() }; + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro new file mode 100644 index 0000000000..36c06fcc3d --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro @@ -0,0 +1,21 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global of_controller: OpenFlow::Controller; + +event NetControl::init() + { + of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_of, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + NetControl::drop_address(id$resp_h, 15sec); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro new file mode 100644 index 0000000000..46a1193a21 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro @@ -0,0 +1,18 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff conn.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_packetfilter = NetControl::create_packetfilter(); + NetControl::activate(netcontrol_packetfilter, 0); + } + +event connection_established(c: connection) + { + local e = NetControl::Entity($ty=NetControl::ADDRESS, $ip=addr_to_subnet(c$id$orig_h)); + local r = NetControl::Rule($ty=NetControl::DROP, $target=NetControl::MONITOR, $entity=e, $expire=10min); + + NetControl::add_rule(r); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro new file mode 100644 index 0000000000..9356253c98 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global of_controller: OpenFlow::Controller; + +event NetControl::init() + { + of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_of, 0); + } + +event connection_established(c: connection) + { + NetControl::quarantine_host(c$id$orig_h, 8.8.8.8, 192.169.18.1, 10hrs); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro b/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro new file mode 100644 index 0000000000..e308205ffc --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b -r $TRACES/tls/ecdhe.pcap --pseudo-realtime %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + NetControl::drop_address(c$id$orig_h, 1secs); + } diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro new file mode 100644 index 0000000000..e973517d44 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -0,0 +1,120 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b -r $TRACES/smtp.trace --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +@load base/protocols/conn +@load base/frameworks/openflow + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + suspend_processing(); + of_controller = OpenFlow::broker_new("broker1", 127.0.0.1, broker_port, "bro/event/openflow", 42); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event OpenFlow::controller_activated(name: string, controller: OpenFlow::Controller) + { + continue_processing(); + OpenFlow::flow_clear(of_controller); + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + print "connection established"; + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } + +event OpenFlow::flow_mod_failure(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_failure"; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/openflow + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global msg_count: count = 0; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/openflow"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +function got_message() + { + ++msg_count; + + if ( msg_count >= 4 ) + terminate(); + } + +event OpenFlow::broker_flow_mod(name: string, dpid: count, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod) + { + print "got flow_mod", dpid, match, flow_mod; + BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_success, name, match, flow_mod, "")); + BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_failure, name, match, flow_mod, "")); + got_message(); + } + +event OpenFlow::broker_flow_clear(name: string, dpid: count) + { + print "flow_clear", dpid; + got_message(); + } + + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro new file mode 100644 index 0000000000..d4f08e7822 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro @@ -0,0 +1,32 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff openflow.log + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +global cookie_id: count = 42; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event connection_established(c: connection) + { + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(++cookie_id), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } diff --git a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro new file mode 100644 index 0000000000..cccf60cf99 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro @@ -0,0 +1,55 @@ +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=manager-1 bro %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-1 bro --pseudo-realtime -C -r $TRACES/smtp.trace %INPUT" +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff manager-1/openflow.log + +@TEST-START-FILE cluster-layout.bro +redef Cluster::nodes = { + ["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=37757/tcp, $workers=set("worker-1", "worker-2")], + ["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37760/tcp, $manager="manager-1", $interface="eth0"], +}; +@TEST-END-FILE + +redef Log::default_rotation_interval = 0secs; +#redef exit_only_after_terminate = T; + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + } + +event connection_established(c: connection) + { + print "conn established"; + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + + terminate(); + } + +event terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + diff --git a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro new file mode 100644 index 0000000000..3bfaa4c076 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -0,0 +1,37 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::ryu_new(127.0.0.1, 8080, 42); + of_controller$state$ryu_debug=T; + + OpenFlow::flow_clear(of_controller); + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event connection_established(c: connection) + { + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } diff --git a/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro b/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro new file mode 100644 index 0000000000..4791d31460 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro @@ -0,0 +1,5 @@ +# This tests extracting the server reported file size +# from FTP sessions. +# +# @TEST-EXEC: bro -r $TRACES/ftp/ftp-with-numbers-in-filename.pcap +# @TEST-EXEC: btest-diff ftp.log diff --git a/testing/btest/scripts/base/protocols/http/http-bad-request-with-version.bro b/testing/btest/scripts/base/protocols/http/http-bad-request-with-version.bro new file mode 100644 index 0000000000..f95196e8bd --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/http-bad-request-with-version.bro @@ -0,0 +1,4 @@ +# @TEST-EXEC: bro -Cr $TRACES/http/http-bad-request-with-version.trace %INPUT +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff weird.log + diff --git a/testing/btest/scripts/base/protocols/ssh/basic.test b/testing/btest/scripts/base/protocols/ssh/basic.test index 30e726e1f5..dfa7eb0d49 100644 --- a/testing/btest/scripts/base/protocols/ssh/basic.test +++ b/testing/btest/scripts/base/protocols/ssh/basic.test @@ -1,4 +1,5 @@ # This tests some SSH connections and the output log. # @TEST-EXEC: bro -r $TRACES/ssh/ssh.trace %INPUT -# @TEST-EXEC: btest-diff ssh.log \ No newline at end of file +# @TEST-EXEC: btest-diff ssh.log +# @TEST-EXEC: btest-diff conn.log