├── modules ├── __load__.bro ├── helper.bro └── main.bro ├── README.md ├── broverview.bro ├── variables_and_simple_data_types.bro ├── built_in_functions.bro ├── logic_flowControl_functions.bro ├── strings.bif └── complex_data_types.bro /modules/__load__.bro: -------------------------------------------------------------------------------- 1 | @load ./main 2 | @load ./helper 3 | -------------------------------------------------------------------------------- /modules/helper.bro: -------------------------------------------------------------------------------- 1 | function do_it(s: string): string 2 | { 3 | return fmt(" %s ", s); 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Beginner Bro 2 | ============ 3 | 4 | Code snippets for beginner programmers in Bro. 5 | -------------------------------------------------------------------------------- /broverview.bro: -------------------------------------------------------------------------------- 1 | event new_connection(c: connection) 2 | { 3 | print "Yo bro, a new connection happened"; 4 | } 5 | 6 | event bro_init() 7 | { 8 | print "Sup bro, sup?"; 9 | } 10 | 11 | event bro_done() 12 | { 13 | print "I'm going down, bro"; 14 | } 15 | -------------------------------------------------------------------------------- /variables_and_simple_data_types.bro: -------------------------------------------------------------------------------- 1 | global myname: string = "anthony"; 2 | 3 | event bro_init() 4 | { 5 | local myage: count = 42; 6 | print fmt("my name is %s and my age is %d", myname, myage); 7 | } 8 | 9 | event bro_done() 10 | { 11 | local myage: count = 42 + 9; 12 | print fmt("my name is %s and my age is %d", myname, myage); 13 | } 14 | -------------------------------------------------------------------------------- /built_in_functions.bro: -------------------------------------------------------------------------------- 1 | global s: string = "123 example 123"; 2 | global c: count = 10; 3 | global d: double = 3.8; 4 | global p: pattern = / /; 5 | 6 | event bro_init() 7 | { 8 | local tmp: string_array = split(s, p); 9 | if ( is_ascii(s) ) 10 | { 11 | for (each in tmp) 12 | { 13 | print tmp[each]; 14 | } 15 | } 16 | } 17 | 18 | print current_time(); 19 | print count_to_port(c, tcp); 20 | print floor(d); 21 | 22 | -------------------------------------------------------------------------------- /logic_flowControl_functions.bro: -------------------------------------------------------------------------------- 1 | # scheduling and when 2 | global x: count = 0; 3 | 4 | event e(c: count) 5 | { 6 | print c; 7 | x = c; 8 | } 9 | 10 | schedule 10 sec { e(2) }; 11 | schedule 15 sec { e(10) }; 12 | 13 | when (x == 10) 14 | { 15 | print "x now equals 10"; 16 | } 17 | 18 | 19 | 20 | # conditionals 21 | local b1: bool = T; 22 | local b2: bool = F; 23 | 24 | if (b2) 25 | { 26 | print "b2 is False, this should never print..."; 27 | } else if (b2) 28 | { 29 | print "b2 is still False, dumby"; 30 | } else 31 | { 32 | print "you should see this statement"; 33 | } 34 | 35 | local s: string; 36 | b1 ? (s = "b1 is true") : (s = "b1 was false"); 37 | print s; 38 | print ""; 39 | 40 | 41 | 42 | #loops 43 | local ss: set[string] = { 44 | "one", 45 | "two", 46 | "three", 47 | "four", 48 | }; 49 | 50 | for (s in ss) 51 | { 52 | print s; 53 | } 54 | print ""; 55 | -------------------------------------------------------------------------------- /strings.bif: -------------------------------------------------------------------------------- 1 | 2 | ## This function takes two string values and calculates the Levenshtein distance 3 | ## between the two strings. 4 | ## 5 | ## Returns: The Levenshtien distance of two strings as a count. 6 | ## 7 | function levenshtein_distance%(string1: string, string2: string%): count 8 | %{ 9 | unsigned int n = string1->Len(); 10 | unsigned int m = string2->Len(); 11 | 12 | const string s1 = string((const char*)string1->Bytes(), n); 13 | const string s2 = string((const char*)string2->Bytes(), m); 14 | 15 | if (n == 0) return new Val(m, TYPE_COUNT); 16 | if (m == 0) return new Val(n, TYPE_COUNT); 17 | 18 | vector > d(n + 1, vector(m + 1)); 19 | 20 | d[0][0] = 0; 21 | 22 | for (unsigned int i = 1; i <= n; ++i) d[i][0] = i; 23 | for (unsigned int i = 1; i <= m; ++i) d[0][i] = i; 24 | 25 | for (unsigned int i = 1; i <= n; ++i) 26 | for (unsigned int j = 1; j <= m; ++j) 27 | d[i][j] = min( min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) ); 28 | 29 | return new Val( d[n][m], TYPE_COUNT ); 30 | %} 31 | 32 | -------------------------------------------------------------------------------- /complex_data_types.bro: -------------------------------------------------------------------------------- 1 | # records 2 | type NewType: record { 3 | s1: string; 4 | c: count &default = 0; 5 | s2: string &optional; 6 | }; 7 | 8 | local r1: NewType; 9 | r1 = [$s1="a required string", $c=11, $s2="an optional string"]; 10 | print r1; 11 | 12 | local r2: NewType; 13 | r2 = [$s1="a required string"]; 14 | print r2; 15 | 16 | 17 | # sets 18 | local my_port: port = 80/tcp; 19 | local my_ports: set [port] = {22/tcp, 53/udp, 8080/tcp}; 20 | local my_port_lookups: set [port, string] = { 21 | [22/tcp, "ssh"], 22 | [53/udp, "dns"], 23 | [8080/tcp, "http-alt"], 24 | [23/tcp, "telnet"], 25 | [1337/tcp, "farts! farts!"], 26 | }; 27 | 28 | add my_ports[my_port]; 29 | add my_port_lookups[my_port, "http"]; 30 | delete my_ports[my_port]; 31 | 32 | local my_ports_size_c: count = |my_ports|; 33 | local my_ports_size_i: int = |my_ports|; 34 | 35 | print ( |my_ports| ); 36 | 37 | 38 | # tables 39 | local port_table: table[port] of string = { 40 | [80/tcp] = "http, whatever...", 41 | [53/udp] = "dns, boring...", 42 | [443/tcp] = "https, i can't see, but stil..", 43 | [1337/tcp] = "FARTS!", 44 | }; 45 | 46 | for (each in port_table) 47 | { 48 | print each, port_table[each]; 49 | } 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /modules/main.bro: -------------------------------------------------------------------------------- 1 | ##! Describe the module here. 2 | ##! What does it do? Who does it call? How does it work? 3 | ##! This will possibly be used for auto-generated documentation, so explain things well. 4 | ##! 5 | ##! For readability and constancy, be sure to follow scripting conventions outlined here: 6 | ##! http://www.bro.org/development/script-conventions.html 7 | ##! 8 | 9 | # The best way to learn to program with Bro is by reading other Bro programs. 10 | # Explore the Bro directory structure and read .bro scripts. 11 | # A good script to explorer is base/protocols/conn/main.bro 12 | 13 | # The following line will import scripts from the defined path, in this case base. 14 | # If writing a script for a specific framework, it only makes sense to import that framework's scripts. 15 | # Think of @load as Perl's use, Python's import, Ruby's require, or C's #include. 16 | @load base/frameworks/logging 17 | 18 | # This creates a new namespace Template. 19 | # Name the module by replacing 'Template'. 20 | module Template; 21 | 22 | # Export the module so the rest of Bro can use and is affected by it's goodness. 23 | export { 24 | 25 | # Create new constant variable for other pieces of Bro to use. 26 | # const is the variable scope. global and local are other common options. 27 | # test_message is the name of the variable. 28 | # string is the type of the variable. Bro has a large selection of strict variable types. 29 | # The text in quotes is the value of the variable. 30 | # &redef makes the variable redefinable along the way. It is convention to add this to all const varibales. 31 | # &redef is one of many variable attributes which alter the behavior of the variable 32 | const template_message: string = "This is the message from the template" &redef; 33 | 34 | # The below line redefines a piece of the framework Bro uses to log stuff. 35 | # It adds an addition stream (logging thing), called TEMP_LOG, to what Bro currently uses to log stuff. 36 | # Bro logs things that it sees happen with the use of three things. 37 | # Log stream - A single log. Streams include what is included in a log (e.g. fields and field names). 38 | # Filters - A set of things that describe what information is written to a stream. 39 | # - Filters trim down or change the behavior of streams. 40 | # - Each stream has a default filter that logs everything. 41 | # - Filters can duplicate streams, split streams into multiple streams, and subset streams. 42 | # Writers - Alter how the log stream is output. Text files, binary files, database, etc. 43 | # - Default behavior dictates ASCII files are written to the directory Bro is called from. 44 | redef enum Log::ID += { TEMP_LOG }; 45 | 46 | # The below line defines the record type for this module's log stream. 47 | # Records are lines in a log stream. Records consist of fields. Each field has a type and a name. 48 | # When the time comes, an instance of Template::Info (this module's record type) will be passed to Bro's logging framework 49 | # When does the time come? When Bro witnesses a defined event on the network. Events are explained below. 50 | type Info: record { 51 | # The first field in this record is named ts 52 | # ts has a type of time 53 | # ts has an attribute of &log (this just means log the variable to a field in a record) 54 | ts: time &log; 55 | # The second field in this records is the constant string defined above. 56 | template_message: string &log; 57 | }; 58 | 59 | # A new log ID has been created, a new record has been defined, and now it is time to define a hook event. 60 | # The below line declares a global variable named template_log_hook with a type of event. 61 | # The event takes one parameter named rec of type Info (which has been defined above with a type record). 62 | # Events are described below and are similar (but not the same) to signal handling in C. 63 | global template_log_hook: event(rec: Info); 64 | 65 | } 66 | 67 | # Bro has the concept of events. Events occur throughout a Bro instance's life. The initialization of Bro happens when Bro begins running. 68 | # The first event which happens is named bro_init. The very last event that happens is bro_done. 69 | # Bro has events about its internals as well as events for things it witnesses on the network. 70 | # For example, the http_request event is raised each time Bro sees an HTTP request on the wire. 71 | # A list of built-in events Bro has at a programmer's exposal are listed here: 72 | # http://www.bro.org/documentation/scripts/base/event.bif.html 73 | 74 | # The following is a bro_init event. Each time Bro is started, this event will run. 75 | # This event is a good location to add or alter pieces of Bro. 76 | # The bro_init event below was created with the following documentation page: 77 | # http://www.bro.org/documentation/logging.html 78 | event bro_init() 79 | { 80 | # The following line creates a new log stream, associates the stream with the Template module and creates the default filter. 81 | # The 82 | Log::create_stream(Template::TEMP_LOG, [$columns=Info, $ev=template_log_hook]); 83 | 84 | # Below is a log filter definition. It inlcudes three key pieces of information about the filter. 85 | # $name - The name of the filter. This is used to refer to the filter. 86 | # $path - The path of the output file for the stream. 87 | # $incude - The fields to include. Any fields defined in the stream but not in the $include will not be included. 88 | # - The $include variable is a set of strings which correspond to field names. 89 | # $exclude- A set of field names to exclude from the stream. $exclude is the opposite of $include. 90 | local template_filter: Log::Filter = [$name="template-filter-name", $path="template-log-filepath", $include=set("ts", "template_message")]; 91 | 92 | # The following line applies the log stream filter, template_filter to the Template module's log stream. 93 | Log::add_filter(Template::TEMP_LOG, template_filter); 94 | 95 | # Recall, a default filter includes all fields in a stream's record. 96 | # The below line removes the default filter created for the TEMP_LOG stream. 97 | Log::remove_filter(Template::TEMP_LOG, "default"); 98 | 99 | # The following commented line completely disables the Template log stream. No Template log file will be created. 100 | # Log::disable_stream(Template::LOG); 101 | } 102 | 103 | # The following line defines what happens when Bro sees a new TCP connection establishes itself. 104 | # This event has one parameter named c of type connection. 105 | # Each time a TCP connection is established a line is written to the log stream. 106 | # For more information about this event, see here: 107 | # http://www.bro.org/documentation/scripts/base/event.bif.html#id-connection_established 108 | event connection_established(c: connection) 109 | { 110 | # The below line defines a local varible named m of type string 111 | local m: string = "This is the message from the connection_established event"; 112 | 113 | # The below line defines a local varibale named rec of type Template::Info 114 | # The Template::Info type is defined in the export function corresponding to the export function of the Template module from above. 115 | # The Template::Info type is a record with two variables: 116 | # $ts - named ts 117 | # - type time 118 | # $template_message - named template_message 119 | # - type string 120 | # The function network_time() is a built-in-function which returns the timestamp of the most recently seen packet. 121 | local rec: Template::Info = [$ts=network_time(), $template_message=do_it(m)]; 122 | 123 | # The write function from the Log namespace takes two parameters. The log stream ID to write to and the field values. 124 | # The stream ID is the stream defined in the Template module above and the field values are in the local record variable 125 | # named rec. 126 | # The following link contains a description of this built in function: 127 | # http://www.bro.org/documentation/scripts/base/frameworks/logging/main.html#id-Log::write 128 | Log::write(Template::TEMP_LOG, rec); 129 | } 130 | 131 | # The following function hooks into an event which occurs every time Bro witnesses a DNS request happen 132 | # Similar to the above event, a line is written to the custom log stream. 133 | # This event has five paramters which describe the DNS request. 134 | # More information about the dns_request event can be found here: 135 | # http://www.bro.org/documentation/scripts/base/event.bif.html#id-dns_request 136 | event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count) 137 | { 138 | # Similar to the connection_established event, this event declares a local variable named m of type string. 139 | # Unlike the connection_established event, this string consists of hard coded text concatenated with a variable 140 | local m: string = "This is the message from the dns_request event. THe following name was queried for: " + query; 141 | 142 | # This line is the same as the connection_established event 143 | local rec: Template::Info = [$ts=network_time(), $template_message=do_it(m)]; 144 | 145 | # This line is the same as the connection_established event 146 | Log::write(Template::TEMP_LOG, rec); 147 | } 148 | --------------------------------------------------------------------------------