[Bro] Converting a Bro Script to A New Stream

Chris Crawford christopher.p.crawford at gmail.com
Thu Aug 16 14:32:28 PDT 2012


I have a short bro script that I wrote that hooks the DNS log
(http://www.bro-ids.org/documentation/logging.html#hooking-into-the-logging).
 Each time a DNS::log_dns event fires, if a specific IP is in
rec$answers, the script prints out rec$ts, rec$uid, rec$id$orig_h, and
rec$query.

I want the entries from the script to go to their own log, though.  I
am struggling to figure out how to make that work.  Based on the
documentation for logging, it looks like I'd need to define a new
Stream to create a new log file.
(http://www.bro-ids.org/documentation/logging.html#adding-streams)

Here's my original script that hooks the DNS logs:

event DNS::log_dns(rec: DNS::Info)
    {
        for( i in rec$answers )
                if( "1.2.3.4" in rec$answers[i] )
                        print fmt("%s %s %s %s", rec$ts, rec$uid,
rec$id$orig_h, rec$query);
    }


To make this go to its own log, I tried this:



module Foo;

export {
    # Create an ID for the our new stream. By convention, this is
    # called "LOG".
    redef enum Log::ID += { LOG };

    # Define the fields. By convention, the type is called "Info".
    type Info: record {
        ts:                      time      &log;
        uid:                     string    &log;
        orig_ip:                 string    &log;
        query:                   string    &log;
    };

    # Define a hook event. By convention, this is called
    # "log_<stream>".
    global log_foo: event(rec: Info);

}

redef record rec += {
        foo: Info &optional;
};

# This event should be handled at a higher priority so that when
# users modify your stream later and they do it at priority 0,
# their code runs after this.
event bro_init() &priority=5
    {
    # Create the stream. This also adds a default filter automatically.
    Log::create_stream(Foo::LOG, [$columns=Info]);
    }

event DNS::log_dns(rec: DNS::Info)
    {
        for( i in rec$answers )
                if( "1.2.3.4" in rec$answers[i] )
                        local rec: Foo::Info = [ $ts=rec$ts,
$uid=rec$uid, $orig_h=rec$id$orig_h, $query=rec$query];
                        rec$foo = rec;
                        Log::write(Foo::LOG, rec);
    }

I get the errors:

error in ./test.bro, line 22: unknown identifier (Foo::rec)
error in ./test.bro, line 35 and ./test.bro, line 39: already defined (Foo::rec)


I am new to writing Bro scripts.  Any pointers on what I'm doing wrong?


-Chris



More information about the Bro mailing list