Load Single Column Table with Input Framework

I’m following the tutorial on the input framework:

Everything works great. But, if my blacklist is only one column (i.e. I remove the other columns so that I’m only left with the “ip” column), I run into issues.

The docs for Input::add_table say that val is optional:

val: `any` `&optional`

Record that defines the values used as the elements of the table If val is undefined, destination has to be a set.

So, I fixed my script to look like this:

type Idx: record {
ip: addr;

global blacklist: set[addr];

event bro_init() {
Input::add_table([$source=“blacklist.file”, $name=“blacklist”, $idx=Idx, $destination=blacklist]);


No more val and changed the table to a set of addr.

The size for blacklist that gets printed out is 0, even though blacklist.file looks like this:

#fields ip
#types addr


I expected print(|blacklist|) to print out 3.

I know I must be missing something simple. What am I missing? How should I read in a single column table?


The table doesn't get loaded immediately.  There is an "input file loaded" event you can print from, or for testing try using bro_done

The input framework is asynchronous. You are printing before that data has been loaded in. You could try waiting a moment (by scheduling an event perhaps) and checking again.

event try_again()
  print |blacklist|;

event bro_init()
        Input::add_table([$source="blacklist.file", $name="blacklist", $idx=Idx, $destination=blacklist]);
  schedule 2secs { try_again() };


This is a bother when running Bro on trace files. Bro will finish processing a trace before reading in an entire table. One hack is to build the table in a separate file and @load it.

We also have the exit_only_after_terminate variable to prevent Bro from terminating automatically. You will have to manually kill it if you set this.

redef exit_only_after_terminate = T;