Bro is a network security monitoring platform. The reason for calling it a platform is due to the fact that Bro is a domain specific programming language and a collection of tools and APIs. Together, they comprise a platform for network monitoring. In this article, we will attempt to solidify the fact that Bro is a language by using it as such.

Data Types

The Bro scripting language supports the following built-in types:

[bool]( "bool type")Boolean
[count]( "count type"), [int]( "int type"), [double]( "double type")Numeric types
[time]( "time type"), [interval]( "interval type")Time types
[string]( "string type")String
[pattern]( "pattern type")Regular expression
[port]( "port type"), [addr]( "addr type"), [subnet]( "subnet type")Network types
[enum]( "enum type")Enumeration (user-defined type)
[table]( "table type"), [set]( "set type"), [vector]( "vector type"), [record]( "record type")Container types
[function]( "function type"), [event]( "event type"), [hook]( "hook type")Executable types
[file]( "file type")File type (only for writing)
[opaque]( "opaque type")Opaque type (for some built-in functions)
[any]( "any type")Any type (for functions or containers)
We will cover a few of them with introductory examples.


Most people run Bro by reading a PCAP but Bro is an interpreter, we only need to supply a Bro script for it to begin interpreting.

 $ bro blah.bro

We can also use the shebang to call the interpreter. This way we can just execute the script by its filename. We’ll use the conventional first programming example.

 print "Hello World!";

Make it executable and then execute it.

 $ chmod 755 blah.bro 
 $ ./blah.bro 
 Hello World!

In addition, Bro accepts instructions on standard in:

 $ echo 'print "Hello World!";' | bro 
 Hello World!


Examples of using some of the data types are listed below. Variable declarations take the form of

scope varname: type;

where scope can be global or local, varname can be any alphanumeric and underscore combination, and type is one of the aforementioned data types. Note that some data structure types require more parameters such as an index type.

Here, we declare and add two numeric data types.

 # Numbers 
 local t: int; 
 local s: count; 
 s = 5; 
 t = 1 + 1; 
 print fmt("Numbers: %d, %d", t, s);
 $ bro num.bro 
 Numbers: 2, 5

A simple string declaration

 # Strings 
 local a: string = "abc"; 
 print fmt("String: %s", a);
 $ bro string.bro 
 String: abc

Setting and testing Boolean values.

 # Boolean 
 local val: bool = T; 
 if (val) 
 print fmt("Bool: %s", val);
 $ bro bool.bro 
 Bool: T

Sets are a data structure that maintain uniqueness i.e. there cannot be elements of the same value.

 local uniq_addr: set[addr]; 
 uniq_addr = set(, ); # Initialize set 
 add uniq_addr[]; # Add another element to set 
 add uniq_addr[]; # Add another element to set 
 print fmt("Set has %d elements:", |uniq_addr|); 
 print uniq_addr;
 $ bro set.bro 
 Set has 3 elements: 

Tables are similar to dictionaries in Python where the table is indexed by a key. The keys are used as a reference to obtain the values they point to.

 # Tables 
 local things: table[string] of string; 
 things = table(); # Initialize table 
 things["food"]   = "hot"; 
 things["animal"] = "dog"; 
 print fmt("Table: %s, has %d elements", things, |things|); 
 print fmt("Who doesn't like a salty %s %s?", things["food"], things["animal"]);
 $ bro table.bro 
 Table has 2 elements 
 [animal] = dog, 
 [food] = hot 
 Who doesn't like a salty hot dog?

A vector is a data structure that is indexed by a count. It’s similar to an one-dimensional array in other languages and is efficient at iterations.

 # Vector 
 local array: vector of string;
 array = vector(); 
 array[0] = "first element"; 
 array[1] = "second element"; 
 print fmt("Vector: %s, has %d elements", array, |array|);
 $ bro vector.bro 
 Vector: [first element, second element], has 2 elements

Try to play around with a few more data types and you’ll be comfortable with the language in little time.

Complementary Tools

More Reading & Other Resources